Merge branch 'sb/submodule-clone-rr'
"git clone --resurse-submodules --reference $path $URL" is a way to reduce network transfer cost by borrowing objects in an existing $path repository when cloning the superproject from $URL; it learned to also peek into $path for presense of corresponding repositories of submodules and borrow objects from there when able. * sb/submodule-clone-rr: clone: recursive and reference option triggers submodule alternates clone: implement optional references clone: clarify option_reference as required clone: factor out checking for an alternate path submodule--helper update-clone: allow multiple references submodule--helper module-clone: allow multiple references t7408: merge short tests, factor out testing method t7408: modernize style
This commit is contained in:
76
sha1_file.c
76
sha1_file.c
@ -419,6 +419,82 @@ void add_to_alternates_file(const char *reference)
|
||||
free(alts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the exact path an alternate is at and returns it. In case of
|
||||
* error NULL is returned and the human readable error is added to `err`
|
||||
* `path` may be relative and should point to $GITDIR.
|
||||
* `err` must not be null.
|
||||
*/
|
||||
char *compute_alternate_path(const char *path, struct strbuf *err)
|
||||
{
|
||||
char *ref_git = NULL;
|
||||
const char *repo, *ref_git_s;
|
||||
int seen_error = 0;
|
||||
|
||||
ref_git_s = real_path_if_valid(path);
|
||||
if (!ref_git_s) {
|
||||
seen_error = 1;
|
||||
strbuf_addf(err, _("path '%s' does not exist"), path);
|
||||
goto out;
|
||||
} else
|
||||
/*
|
||||
* Beware: read_gitfile(), real_path() and mkpath()
|
||||
* return static buffer
|
||||
*/
|
||||
ref_git = xstrdup(ref_git_s);
|
||||
|
||||
repo = read_gitfile(ref_git);
|
||||
if (!repo)
|
||||
repo = read_gitfile(mkpath("%s/.git", ref_git));
|
||||
if (repo) {
|
||||
free(ref_git);
|
||||
ref_git = xstrdup(repo);
|
||||
}
|
||||
|
||||
if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
|
||||
char *ref_git_git = mkpathdup("%s/.git", ref_git);
|
||||
free(ref_git);
|
||||
ref_git = ref_git_git;
|
||||
} else if (!is_directory(mkpath("%s/objects", ref_git))) {
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
seen_error = 1;
|
||||
if (get_common_dir(&sb, ref_git)) {
|
||||
strbuf_addf(err,
|
||||
_("reference repository '%s' as a linked "
|
||||
"checkout is not supported yet."),
|
||||
path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
strbuf_addf(err, _("reference repository '%s' is not a "
|
||||
"local repository."), path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!access(mkpath("%s/shallow", ref_git), F_OK)) {
|
||||
strbuf_addf(err, _("reference repository '%s' is shallow"),
|
||||
path);
|
||||
seen_error = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) {
|
||||
strbuf_addf(err,
|
||||
_("reference repository '%s' is grafted"),
|
||||
path);
|
||||
seen_error = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (seen_error) {
|
||||
free(ref_git);
|
||||
ref_git = NULL;
|
||||
}
|
||||
|
||||
return ref_git;
|
||||
}
|
||||
|
||||
int foreach_alt_odb(alt_odb_fn fn, void *cb)
|
||||
{
|
||||
struct alternate_object_database *ent;
|
||||
|
||||
Reference in New Issue
Block a user