This forward-ports c6fef0bb(clone: support cloning full bundles) to the builtin clone. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- Now my private tree passes all tests again. Daniel, do you have a branch where you have your current version of builting clone? Mine is in "my-next" of http://repo.or.cz/w/git/dscho.git. builtin-clone.c | 59 ++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 37 insertions(+), 22 deletions(-) diff --git a/builtin-clone.c b/builtin-clone.c index f27d205..29cd09d 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -64,42 +64,52 @@ static struct option builtin_clone_options[] = { OPT_END() }; -static char *get_repo_path(const char *repo) +static char *get_repo_path(const char *repo, int *is_bundle) { - const char *path; - struct stat buf; - - path = mkpath("%s/.git", repo); - if (!stat(path, &buf) && S_ISDIR(buf.st_mode)) - return xstrdup(make_absolute_path(path)); - - path = mkpath("%s.git", repo); - if (!stat(path, &buf) && S_ISDIR(buf.st_mode)) - return xstrdup(make_absolute_path(path)); + static char *suffix[] = { "/.git", ".git", "" }; + static char *bundle_suffix[] = { ".bundle", "" }; + struct stat st; + int i; + + for (i = 0; i < ARRAY_SIZE(suffix); i++) { + const char *path; + path = mkpath("%s%s", repo, suffix[i]); + if (!stat(path, &st) && S_ISDIR(st.st_mode)) { + *is_bundle = 0; + return xstrdup(make_absolute_path(path)); + } + } - if (!stat(repo, &buf) && S_ISDIR(buf.st_mode)) - return xstrdup(make_absolute_path(repo)); + for (i = 0; i < ARRAY_SIZE(bundle_suffix); i++) { + const char *path; + path = mkpath("%s%s", repo, bundle_suffix[i]); + if (!stat(path, &st) && S_ISREG(st.st_mode)) { + *is_bundle = 1; + return xstrdup(make_absolute_path(path)); + } + } return NULL; } -static char *guess_dir_name(const char *repo) +static char *guess_dir_name(const char *repo, int is_bundle) { const char *p, *start, *end, *limit; int after_slash_or_colon; /* Guess dir name from repository: strip trailing '/', - * strip trailing '[:/]*git', strip leading '.*[/:]'. */ + * strip trailing '[:/]*.{git,bundle}', strip leading '.*[/:]'. */ after_slash_or_colon = 1; limit = repo + strlen(repo); start = repo; end = limit; for (p = repo; p < limit; p++) { - if (!prefixcmp(p, ".git")) { + const char *prefix = is_bundle ? ".bundle" : ".git"; + if (!prefixcmp(p, prefix)) { if (!after_slash_or_colon) end = p; - p += 3; + p += strlen(prefix) - 1; } else if (*p == '/' || *p == ':') { if (end == limit) end = p; @@ -287,7 +297,7 @@ walk_objects(char *src, char *dest) } static const struct ref * -clone_local(const char *src_repo, const char *dest_repo) +clone_local(const char *src_repo, const char *dest_repo, int is_bundle) { const struct ref *ret; char src[PATH_MAX]; @@ -295,7 +305,9 @@ clone_local(const char *src_repo, const char *dest_repo) struct remote *remote; struct transport *transport; - if (option_shared) { + if (is_bundle) + ; /* do nothing */ + else if (option_shared) { write_alternates_file(dest_repo, src_repo); } else { snprintf(src, PATH_MAX, "%s/objects", src_repo); @@ -307,6 +319,8 @@ clone_local(const char *src_repo, const char *dest_repo) remote = remote_get(src_repo); transport = transport_get(remote, src_repo); ret = transport_get_remote_refs(transport); + if (is_bundle && transport_fetch_refs(transport, (struct ref *)ret)) + die ("Could not read bundle"); transport_disconnect(transport); return ret; } @@ -339,6 +353,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) { int use_local_hardlinks = 1; int use_separate_remote = 1; + int is_bundle; struct stat buf; const char *repo, *work_tree, *git_dir; char *path, *dir, *head, *ref_temp; @@ -369,12 +384,12 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_origin = "origin"; repo = argv[0]; - path = get_repo_path(repo); + path = get_repo_path(repo, &is_bundle); if (argc == 2) { dir = xstrdup(argv[1]); } else { - dir = guess_dir_name(repo); + dir = guess_dir_name(repo, is_bundle); } if (!stat(dir, &buf)) @@ -429,7 +444,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) git_config_set("core.bare", "true"); if (path != NULL) { - refs = clone_local(path, git_dir); + refs = clone_local(path, git_dir, is_bundle); repo = make_absolute_path(path); } else { struct remote *remote = remote_get(argv[0]); -- 1.5.4.3.446.gbe8932 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html