From: Junio C Hamano Date: Wed, 7 Jan 2015 20:42:13 +0000 (-0800) Subject: Merge branch 'jc/clone-borrow' X-Git-Tag: v2.3.0-rc0~30 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d35c8027937546e6b22a2f28123f731c84e3b380?hp=-c Merge branch 'jc/clone-borrow' Allow "git clone --reference" to be used more safely. * jc/clone-borrow: clone: --dissociate option to mark that reference is only temporary --- d35c8027937546e6b22a2f28123f731c84e3b380 diff --combined builtin/clone.c index d5e7532105,e1ad4df41f..316c75d0b3 --- a/builtin/clone.c +++ b/builtin/clone.c @@@ -9,7 -9,6 +9,7 @@@ */ #include "builtin.h" +#include "lockfile.h" #include "parse-options.h" #include "fetch-pack.h" #include "refs.h" @@@ -49,6 -48,7 +49,7 @@@ static int option_verbosity static int option_progress = -1; static struct string_list option_config; static struct string_list option_reference; + static int option_dissociate; static int opt_parse_reference(const struct option *opt, const char *arg, int unset) { @@@ -94,6 -94,8 +95,8 @@@ static struct option builtin_clone_opti N_("create a shallow clone of that depth")), OPT_BOOL(0, "single-branch", &option_single_branch, N_("clone only one branch, HEAD or --branch")), + OPT_BOOL(0, "dissociate", &option_dissociate, + N_("use --reference only while cloning")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), @@@ -391,6 -393,7 +394,6 @@@ static void clone_local(const char *src static const char *junk_work_tree; static const char *junk_git_dir; -static pid_t junk_pid; static enum { JUNK_LEAVE_NONE, JUNK_LEAVE_REPO, @@@ -417,6 -420,8 +420,6 @@@ static void remove_junk(void break; } - if (getpid() != junk_pid) - return; if (junk_git_dir) { strbuf_addstr(&sb, junk_git_dir); remove_dir_recursively(&sb, 0); @@@ -620,7 -625,7 +623,7 @@@ static int checkout(void if (option_no_checkout) return 0; - head = resolve_refdup("HEAD", sha1, 1, NULL); + head = resolve_refdup("HEAD", RESOLVE_REF_READING, sha1, NULL); if (!head) { warning(_("remote HEAD refers to nonexistent ref, " "unable to checkout.\n")); @@@ -683,10 -688,9 +686,10 @@@ static void write_config(struct string_ } } -static void write_refspec_config(const char* src_ref_prefix, - const struct ref* our_head_points_at, - const struct ref* remote_head_points_at, struct strbuf* branch_top) +static void write_refspec_config(const char *src_ref_prefix, + const struct ref *our_head_points_at, + const struct ref *remote_head_points_at, + struct strbuf *branch_top) { struct strbuf key = STRBUF_INIT; struct strbuf value = STRBUF_INIT; @@@ -735,6 -739,16 +738,16 @@@ strbuf_release(&value); } + static void dissociate_from_references(void) + { + static const char* argv[] = { "repack", "-a", "-d", NULL }; + + if (run_command_v_opt(argv, RUN_GIT_CMD|RUN_COMMAND_NO_STDIN)) + die(_("cannot repack to clean up")); + if (unlink(git_path("objects/info/alternates")) && errno != ENOENT) + die_errno(_("cannot unlink temporary alternates file")); + } + int cmd_clone(int argc, const char **argv, const char *prefix) { int is_bundle = 0, is_local; @@@ -757,6 -771,8 +770,6 @@@ struct refspec *refspec; const char *fetch_pattern; - junk_pid = getpid(); - packet_trace_identity("clone"); argc = parse_options(argc, argv, prefix, builtin_clone_options, builtin_clone_usage, 0); @@@ -880,6 -896,10 +893,10 @@@ if (option_reference.nr) setup_reference(); + else if (option_dissociate) { + warning(_("--dissociate given, but there is no --reference")); + option_dissociate = 0; + } fetch_pattern = value.buf; refspec = parse_fetch_refspec(1, &fetch_pattern); @@@ -993,6 -1013,9 +1010,9 @@@ transport_unlock_pack(transport); transport_disconnect(transport); + if (option_dissociate) + dissociate_from_references(); + junk_mode = JUNK_LEAVE_REPO; err = checkout(); @@@ -1001,7 -1024,5 +1021,7 @@@ strbuf_release(&key); strbuf_release(&value); junk_mode = JUNK_LEAVE_ALL; + + free(refspec); return err; }