Merge branch 'ps/clone-into-reftable-repository'

"git clone" has been prepared to allow cloning a repository with
non-default hash function into a repository that uses the reftable
backend.

* ps/clone-into-reftable-repository:
  builtin/clone: create the refdb with the correct object format
  builtin/clone: skip reading HEAD when retrieving remote
  builtin/clone: set up sparse checkout later
  builtin/clone: fix bundle URIs with mismatching object formats
  remote-curl: rediscover repository when fetching refs
  setup: allow skipping creation of the refdb
  setup: extract function to create the refdb
This commit is contained in:
Junio C Hamano
2023-12-27 14:52:28 -08:00
8 changed files with 150 additions and 91 deletions

114
setup.c
View File

@ -1887,21 +1887,79 @@ void initialize_repository_version(int hash_algo, int reinit)
git_config_set_gently("extensions.objectformat", NULL);
}
static int is_reinit(void)
{
struct strbuf buf = STRBUF_INIT;
char junk[2];
int ret;
git_path_buf(&buf, "HEAD");
ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;
strbuf_release(&buf);
return ret;
}
void create_reference_database(const char *initial_branch, int quiet)
{
struct strbuf err = STRBUF_INIT;
int reinit = is_reinit();
/*
* We need to create a "refs" dir in any case so that older versions of
* Git can tell that this is a repository. This serves two main purposes:
*
* - Clients will know to stop walking the parent-directory chain when
* detecting the Git repository. Otherwise they may end up detecting
* a Git repository in a parent directory instead.
*
* - Instead of failing to detect a repository with unknown reference
* format altogether, old clients will print an error saying that
* they do not understand the reference format extension.
*/
safe_create_dir(git_path("refs"), 1);
adjust_shared_perm(git_path("refs"));
if (refs_init_db(&err))
die("failed to set up refs db: %s", err.buf);
/*
* Point the HEAD symref to the initial branch with if HEAD does
* not yet exist.
*/
if (!reinit) {
char *ref;
if (!initial_branch)
initial_branch = git_default_branch_name(quiet);
ref = xstrfmt("refs/heads/%s", initial_branch);
if (check_refname_format(ref, 0) < 0)
die(_("invalid initial branch name: '%s'"),
initial_branch);
if (create_symref("HEAD", ref, NULL) < 0)
exit(1);
free(ref);
}
if (reinit && initial_branch)
warning(_("re-init: ignored --initial-branch=%s"),
initial_branch);
strbuf_release(&err);
}
static int create_default_files(const char *template_path,
const char *original_git_dir,
const char *initial_branch,
const struct repository_format *fmt,
int prev_bare_repository,
int init_shared_repository,
int quiet)
int init_shared_repository)
{
struct stat st1;
struct strbuf buf = STRBUF_INIT;
char *path;
char junk[2];
int reinit;
int filemode;
struct strbuf err = STRBUF_INIT;
const char *init_template_dir = NULL;
const char *work_tree = get_git_work_tree();
@ -1921,6 +1979,8 @@ static int create_default_files(const char *template_path,
reset_shared_repository();
git_config(git_default_config, NULL);
reinit = is_reinit();
/*
* We must make sure command-line options continue to override any
* values we might have just re-read from the config.
@ -1964,39 +2024,6 @@ static int create_default_files(const char *template_path,
adjust_shared_perm(get_git_dir());
}
/*
* We need to create a "refs" dir in any case so that older
* versions of git can tell that this is a repository.
*/
safe_create_dir(git_path("refs"), 1);
adjust_shared_perm(git_path("refs"));
if (refs_init_db(&err))
die("failed to set up refs db: %s", err.buf);
/*
* Point the HEAD symref to the initial branch with if HEAD does
* not yet exist.
*/
path = git_path_buf(&buf, "HEAD");
reinit = (!access(path, R_OK)
|| readlink(path, junk, sizeof(junk)-1) != -1);
if (!reinit) {
char *ref;
if (!initial_branch)
initial_branch = git_default_branch_name(quiet);
ref = xstrfmt("refs/heads/%s", initial_branch);
if (check_refname_format(ref, 0) < 0)
die(_("invalid initial branch name: '%s'"),
initial_branch);
if (create_symref("HEAD", ref, NULL) < 0)
exit(1);
free(ref);
}
initialize_repository_version(fmt->hash_algo, 0);
/* Check filemode trustability */
@ -2156,14 +2183,11 @@ int init_db(const char *git_dir, const char *real_git_dir,
validate_hash_algorithm(&repo_fmt, hash);
reinit = create_default_files(template_dir, original_git_dir,
initial_branch, &repo_fmt,
prev_bare_repository,
init_shared_repository,
flags & INIT_DB_QUIET);
if (reinit && initial_branch)
warning(_("re-init: ignored --initial-branch=%s"),
initial_branch);
&repo_fmt, prev_bare_repository,
init_shared_repository);
if (!(flags & INIT_DB_SKIP_REFDB))
create_reference_database(initial_branch, flags & INIT_DB_QUIET);
create_object_directory();
if (get_shared_repository()) {