mirror of
https://github.com/git/git
synced 2024-07-05 00:58:49 +00:00
Merge branch 'ps/remote-helper-repo-initialization-fix'
A custom remote helper no longer cannot access the newly created repository during "git clone", which is a regression in Git 2.44. This has been corrected. * ps/remote-helper-repo-initialization-fix: builtin/clone: allow remote helpers to detect repo
This commit is contained in:
commit
ce65a188b1
|
@ -927,6 +927,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
struct ref *mapped_refs = NULL;
|
||||
const struct ref *ref;
|
||||
struct strbuf key = STRBUF_INIT;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
|
||||
struct transport *transport = NULL;
|
||||
const char *src_ref_prefix = "refs/heads/";
|
||||
|
@ -1126,6 +1127,50 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
git_dir = real_git_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a chicken-and-egg situation between initializing the refdb
|
||||
* and spawning transport helpers:
|
||||
*
|
||||
* - Initializing the refdb requires us to know about the object
|
||||
* format. We thus have to spawn the transport helper to learn
|
||||
* about it.
|
||||
*
|
||||
* - The transport helper may want to access the Git repository. But
|
||||
* because the refdb has not been initialized, we don't have "HEAD"
|
||||
* or "refs/". Thus, the helper cannot find the Git repository.
|
||||
*
|
||||
* Ideally, we would have structured the helper protocol such that it's
|
||||
* mandatory for the helper to first announce its capabilities without
|
||||
* yet assuming a fully initialized repository. Like that, we could
|
||||
* have added a "lazy-refdb-init" capability that announces whether the
|
||||
* helper is ready to handle not-yet-initialized refdbs. If any helper
|
||||
* didn't support them, we would have fully initialized the refdb with
|
||||
* the SHA1 object format, but later on bailed out if we found out that
|
||||
* the remote repository used a different object format.
|
||||
*
|
||||
* But we didn't, and thus we use the following workaround to partially
|
||||
* initialize the repository's refdb such that it can be discovered by
|
||||
* Git commands. To do so, we:
|
||||
*
|
||||
* - Create an invalid HEAD ref pointing at "refs/heads/.invalid".
|
||||
*
|
||||
* - Create the "refs/" directory.
|
||||
*
|
||||
* - Set up the ref storage format and repository version as
|
||||
* required.
|
||||
*
|
||||
* This is sufficient for Git commands to discover the Git directory.
|
||||
*/
|
||||
initialize_repository_version(GIT_HASH_UNKNOWN,
|
||||
the_repository->ref_storage_format, 1);
|
||||
|
||||
strbuf_addf(&buf, "%s/HEAD", git_dir);
|
||||
write_file(buf.buf, "ref: refs/heads/.invalid");
|
||||
|
||||
strbuf_reset(&buf);
|
||||
strbuf_addf(&buf, "%s/refs", git_dir);
|
||||
safe_create_dir(buf.buf, 1);
|
||||
|
||||
/*
|
||||
* additional config can be injected with -c, make sure it's included
|
||||
* after init_db, which clears the entire config environment.
|
||||
|
@ -1454,6 +1499,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
|||
free(remote_name);
|
||||
strbuf_release(&reflog_msg);
|
||||
strbuf_release(&branch_top);
|
||||
strbuf_release(&buf);
|
||||
strbuf_release(&key);
|
||||
free_refs(mapped_refs);
|
||||
free_refs(remote_head_points_at);
|
||||
|
|
9
setup.c
9
setup.c
|
@ -1889,6 +1889,13 @@ void initialize_repository_version(int hash_algo,
|
|||
char repo_version_string[10];
|
||||
int repo_version = GIT_REPO_VERSION;
|
||||
|
||||
/*
|
||||
* Note that we initialize the repository version to 1 when the ref
|
||||
* storage format is unknown. This is on purpose so that we can add the
|
||||
* correct object format to the config during git-clone(1). The format
|
||||
* version will get adjusted by git-clone(1) once it has learned about
|
||||
* the remote repository's format.
|
||||
*/
|
||||
if (hash_algo != GIT_HASH_SHA1 ||
|
||||
ref_storage_format != REF_STORAGE_FORMAT_FILES)
|
||||
repo_version = GIT_REPO_VERSION_READ;
|
||||
|
@ -1898,7 +1905,7 @@ void initialize_repository_version(int hash_algo,
|
|||
"%d", repo_version);
|
||||
git_config_set("core.repositoryformatversion", repo_version_string);
|
||||
|
||||
if (hash_algo != GIT_HASH_SHA1)
|
||||
if (hash_algo != GIT_HASH_SHA1 && hash_algo != GIT_HASH_UNKNOWN)
|
||||
git_config_set("extensions.objectformat",
|
||||
hash_algos[hash_algo].name);
|
||||
else if (reinit)
|
||||
|
|
|
@ -12,6 +12,11 @@ url=$2
|
|||
|
||||
dir="$GIT_DIR/testgit/$alias"
|
||||
|
||||
if ! git rev-parse --is-inside-git-dir
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
h_refspec="refs/heads/*:refs/testgit/$alias/heads/*"
|
||||
t_refspec="refs/tags/*:refs/testgit/$alias/tags/*"
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user