mirror of
https://github.com/git/git.git
synced 2025-12-12 20:36:24 +01:00
Merge branch 'kn/ref-location' into jch
A mechanism to specify what reference backend to use and store references in which directory is introduced, which would likely to be useful during ref migration. Comments? * kn/ref-location: refs: add GIT_REF_URI to specify reference backend and directory refs: support obtaining ref_store for given dir
This commit is contained in:
@@ -584,6 +584,14 @@ double-quotes and respecting backslash escapes. E.g., the value
|
||||
repositories will be set to this value. The default is "files".
|
||||
See `--ref-format` in linkgit:git-init[1].
|
||||
|
||||
`GIT_REF_URI`::
|
||||
Specify which reference backend to be used along with its URI. Reference
|
||||
backends like the files, reftable backend use the $GIT_DIR as their URI.
|
||||
+
|
||||
Expects the format `<ref_backend>://<URI-for-resource>`, where the
|
||||
_<ref_backend>_ specifies the reference backend and the _<URI-for-resource>_
|
||||
specifies the URI used by the backend.
|
||||
|
||||
Git Commits
|
||||
~~~~~~~~~~~
|
||||
`GIT_AUTHOR_NAME`::
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define GIT_OPTIONAL_LOCKS_ENVIRONMENT "GIT_OPTIONAL_LOCKS"
|
||||
#define GIT_TEXT_DOMAIN_DIR_ENVIRONMENT "GIT_TEXTDOMAINDIR"
|
||||
#define GIT_ATTR_SOURCE_ENVIRONMENT "GIT_ATTR_SOURCE"
|
||||
#define GIT_REF_URI_ENVIRONMENT "GIT_REF_URI"
|
||||
|
||||
/*
|
||||
* Environment variable used to propagate the --no-advice global option to the
|
||||
|
||||
68
refs.c
68
refs.c
@@ -2191,17 +2191,79 @@ void ref_store_release(struct ref_store *ref_store)
|
||||
free(ref_store->gitdir);
|
||||
}
|
||||
|
||||
static struct ref_store *get_ref_store_for_dir(struct repository *r,
|
||||
char *dir,
|
||||
enum ref_storage_format format)
|
||||
{
|
||||
struct ref_store *ref_store = ref_store_init(r, format, dir,
|
||||
REF_STORE_ALL_CAPS);
|
||||
return maybe_debug_wrap_ref_store(dir, ref_store);
|
||||
}
|
||||
|
||||
static struct ref_store *get_ref_store_from_uri(struct repository *repo,
|
||||
const char *uri)
|
||||
{
|
||||
struct string_list ref_backend_info = STRING_LIST_INIT_DUP;
|
||||
enum ref_storage_format format;
|
||||
struct ref_store *store = NULL;
|
||||
char *format_string;
|
||||
char *dir;
|
||||
|
||||
if (!uri) {
|
||||
error(_("reference backend uri is not provided"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (string_list_split(&ref_backend_info, uri, ":", 2) != 2) {
|
||||
error(_("invalid reference backend uri format '%s'"), uri);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
format_string = ref_backend_info.items[0].string;
|
||||
if (!starts_with(ref_backend_info.items[1].string, "//")) {
|
||||
error(_("invalid reference backend uri format '%s'"), uri);
|
||||
goto cleanup;
|
||||
}
|
||||
dir = ref_backend_info.items[1].string + 2;
|
||||
|
||||
if (!dir[0]) {
|
||||
error(_("invalid path in uri '%s'"), uri);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
format = ref_storage_format_by_name(format_string);
|
||||
if (format == REF_STORAGE_FORMAT_UNKNOWN) {
|
||||
error(_("unknown reference backend '%s'"), format_string);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
store = get_ref_store_for_dir(repo, dir, format);
|
||||
|
||||
cleanup:
|
||||
string_list_clear(&ref_backend_info, 0);
|
||||
return store;
|
||||
}
|
||||
|
||||
struct ref_store *get_main_ref_store(struct repository *r)
|
||||
{
|
||||
char *ref_uri;
|
||||
|
||||
if (r->refs_private)
|
||||
return r->refs_private;
|
||||
|
||||
if (!r->gitdir)
|
||||
BUG("attempting to get main_ref_store outside of repository");
|
||||
|
||||
r->refs_private = ref_store_init(r, r->ref_storage_format,
|
||||
r->gitdir, REF_STORE_ALL_CAPS);
|
||||
r->refs_private = maybe_debug_wrap_ref_store(r->gitdir, r->refs_private);
|
||||
ref_uri = getenv(GIT_REF_URI_ENVIRONMENT);
|
||||
if (ref_uri) {
|
||||
r->refs_private = get_ref_store_from_uri(r, ref_uri);
|
||||
if (!r->refs_private)
|
||||
die("failed to initialize ref store from URI: %s", ref_uri);
|
||||
|
||||
} else {
|
||||
r->refs_private = get_ref_store_for_dir(r, r->gitdir,
|
||||
r->ref_storage_format);
|
||||
}
|
||||
return r->refs_private;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ integration_tests = [
|
||||
't1420-lost-found.sh',
|
||||
't1421-reflog-write.sh',
|
||||
't1422-show-ref-exists.sh',
|
||||
't1423-ref-backend.sh',
|
||||
't1430-bad-ref-name.sh',
|
||||
't1450-fsck.sh',
|
||||
't1451-fsck-buffer.sh',
|
||||
|
||||
121
t/t1423-ref-backend.sh
Executable file
121
t/t1423-ref-backend.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='Test different reference backend URIs'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'empty uri provided' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=files repo &&
|
||||
(
|
||||
cd repo &&
|
||||
GIT_REF_URI="" &&
|
||||
export GIT_REF_URI &&
|
||||
test_must_fail git refs list 2>err &&
|
||||
test_grep "invalid reference backend uri format" err
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'invalid uri provided' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=files repo &&
|
||||
(
|
||||
cd repo &&
|
||||
GIT_REF_URI="reftable@/home/reftable" &&
|
||||
export GIT_REF_URI &&
|
||||
test_must_fail git refs list 2>err &&
|
||||
test_grep "invalid reference backend uri format" err
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'empty path in uri' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=files repo &&
|
||||
(
|
||||
cd repo &&
|
||||
GIT_REF_URI="reftable://" &&
|
||||
export GIT_REF_URI &&
|
||||
test_must_fail git refs list 2>err &&
|
||||
test_grep "invalid path in uri" err
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'uri ends at colon' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=files repo &&
|
||||
(
|
||||
cd repo &&
|
||||
GIT_REF_URI="reftable:" &&
|
||||
export GIT_REF_URI &&
|
||||
test_must_fail git refs list 2>err &&
|
||||
test_grep "invalid reference backend uri format" err
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success 'unknown reference backend' '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=files repo &&
|
||||
(
|
||||
cd repo &&
|
||||
GIT_REF_URI="db://.git" &&
|
||||
export GIT_REF_URI &&
|
||||
test_must_fail git refs list 2>err &&
|
||||
test_grep "unknown reference backend" err
|
||||
)
|
||||
'
|
||||
|
||||
ref_formats="files reftable"
|
||||
for from_format in $ref_formats
|
||||
do
|
||||
for to_format in $ref_formats
|
||||
do
|
||||
if test "$from_format" = "$to_format"
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
test_expect_success "read from $to_format backend" '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=$from_format repo &&
|
||||
(
|
||||
cd repo &&
|
||||
test_commit 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit 3 &&
|
||||
|
||||
git refs migrate --dry-run --ref-format=$to_format >out &&
|
||||
BACKEND_PATH=$(cat out | sed "s/.* ${SQ}\(.*\)${SQ}/\1/") &&
|
||||
git refs list >expect &&
|
||||
GIT_REF_URI="$to_format://$BACKEND_PATH" git refs list >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success "write to $to_format backend" '
|
||||
test_when_finished "rm -rf repo" &&
|
||||
git init --ref-format=$from_format repo &&
|
||||
(
|
||||
cd repo &&
|
||||
test_commit 1 &&
|
||||
test_commit 2 &&
|
||||
test_commit 3 &&
|
||||
|
||||
git refs migrate --dry-run --ref-format=$to_format >out &&
|
||||
git refs list >expect &&
|
||||
|
||||
BACKEND_PATH=$(cat out | sed "s/.* ${SQ}\(.*\)${SQ}/\1/") &&
|
||||
GIT_REF_URI="$to_format://$BACKEND_PATH" git tag -d 1 &&
|
||||
|
||||
git refs list >actual &&
|
||||
test_cmp expect actual &&
|
||||
|
||||
GIT_REF_URI="$to_format://$BACKEND_PATH" git refs list >expect &&
|
||||
git refs list >out &&
|
||||
cat out | grep -v "refs/tags/1" >actual &&
|
||||
test_cmp expect actual
|
||||
)
|
||||
'
|
||||
done
|
||||
done
|
||||
|
||||
test_done
|
||||
Reference in New Issue
Block a user