diff options
Diffstat (limited to 'builtin-clone.c')
-rw-r--r-- | builtin-clone.c | 104 |
1 files changed, 29 insertions, 75 deletions
diff --git a/builtin-clone.c b/builtin-clone.c index 1c1d729117..6605e83407 100644 --- a/builtin-clone.c +++ b/builtin-clone.c @@ -20,6 +20,9 @@ #include "dir.h" #include "pack-refs.h" #include "sigchain.h" +#include "branch.h" +#include "remote.h" +#include "run-command.h" /* * Overall FIXMEs: @@ -225,7 +228,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest) } if (unlink(dest->buf) && errno != ENOENT) - die("failed to unlink %s", dest->buf); + die("failed to unlink %s: %s", + dest->buf, strerror(errno)); if (!option_no_hardlinks) { if (!link(src->buf, dest->buf)) continue; @@ -267,7 +271,7 @@ static const struct ref *clone_local(const char *src_repo, static const char *junk_work_tree; static const char *junk_git_dir; -pid_t junk_pid; +static pid_t junk_pid; static void remove_junk(void) { @@ -293,43 +297,6 @@ static void remove_junk_on_signal(int signo) raise(signo); } -static const struct ref *locate_head(const struct ref *refs, - const struct ref *mapped_refs, - const struct ref **remote_head_p) -{ - const struct ref *remote_head = NULL; - const struct ref *remote_master = NULL; - const struct ref *r; - for (r = refs; r; r = r->next) - if (!strcmp(r->name, "HEAD")) - remote_head = r; - - for (r = mapped_refs; r; r = r->next) - if (!strcmp(r->name, "refs/heads/master")) - remote_master = r; - - if (remote_head_p) - *remote_head_p = remote_head; - - /* If there's no HEAD value at all, never mind. */ - if (!remote_head) - return NULL; - - /* If refs/heads/master could be right, it is. */ - if (remote_master && !hashcmp(remote_master->old_sha1, - remote_head->old_sha1)) - return remote_master; - - /* Look for another ref that points there */ - for (r = mapped_refs; r; r = r->next) - if (r != remote_head && - !hashcmp(r->old_sha1, remote_head->old_sha1)) - return r; - - /* Nothing is the same */ - return NULL; -} - static struct ref *write_remote_refs(const struct ref *refs, struct refspec *refspec, const char *reflog) { @@ -350,23 +317,8 @@ static struct ref *write_remote_refs(const struct ref *refs, return local_refs; } -static void install_branch_config(const char *local, - const char *origin, - const char *remote) -{ - struct strbuf key = STRBUF_INIT; - strbuf_addf(&key, "branch.%s.remote", local); - git_config_set(key.buf, origin); - strbuf_reset(&key); - strbuf_addf(&key, "branch.%s.merge", local); - git_config_set(key.buf, remote); - strbuf_release(&key); -} - int cmd_clone(int argc, const char **argv, const char *prefix) { - int use_local_hardlinks = 1; - int use_separate_remote = 1; int is_bundle = 0; struct stat buf; const char *repo_name, *repo, *work_tree, *git_dir; @@ -377,8 +329,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT; struct transport *transport = NULL; char *src_ref_prefix = "refs/heads/"; + int err = 0; - struct refspec refspec; + struct refspec *refspec; + const char *fetch_pattern; junk_pid = getpid(); @@ -388,9 +342,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (argc == 0) die("You must specify a repository to clone."); - if (option_no_hardlinks) - use_local_hardlinks = 0; - if (option_mirror) option_bare = 1; @@ -399,7 +350,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) die("--bare and --origin %s options are incompatible.", option_origin); option_no_checkout = 1; - use_separate_remote = 0; } if (!option_origin) @@ -457,7 +407,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) atexit(remove_junk); sigchain_push_common(remove_junk_on_signal); - setenv(CONFIG_ENVIRONMENT, xstrdup(mkpath("%s/config", git_dir)), 1); + setenv(CONFIG_ENVIRONMENT, mkpath("%s/config", git_dir), 1); if (safe_create_leading_directories_const(git_dir) < 0) die("could not create leading directories of '%s'", git_dir); @@ -487,8 +437,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix) strbuf_addf(&branch_top, "refs/remotes/%s/", option_origin); } + strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf); + if (option_mirror || !option_bare) { /* Configure the remote */ + strbuf_addf(&key, "remote.%s.fetch", option_origin); + git_config_set_multivar(key.buf, value.buf, "^$", 0); + strbuf_reset(&key); + if (option_mirror) { strbuf_addf(&key, "remote.%s.mirror", option_origin); git_config_set(key.buf, "true"); @@ -497,19 +453,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix) strbuf_addf(&key, "remote.%s.url", option_origin); git_config_set(key.buf, repo); - strbuf_reset(&key); - - strbuf_addf(&key, "remote.%s.fetch", option_origin); - strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf); - git_config_set_multivar(key.buf, value.buf, "^$", 0); strbuf_reset(&key); - strbuf_reset(&value); } - refspec.force = 0; - refspec.pattern = 1; - refspec.src = src_ref_prefix; - refspec.dst = branch_top.buf; + fetch_pattern = value.buf; + refspec = parse_fetch_refspec(1, &fetch_pattern); + + strbuf_reset(&value); if (path && !is_bundle) refs = clone_local(path, git_dir); @@ -543,9 +493,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (refs) { clear_extra_refs(); - mapped_refs = write_remote_refs(refs, &refspec, reflog_msg.buf); + mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf); - head_points_at = locate_head(refs, mapped_refs, &remote_head); + remote_head = find_ref_by_name(refs, "HEAD"); + head_points_at = guess_remote_head(remote_head, mapped_refs, 0); } else { warning("You appear to have cloned an empty repository."); @@ -553,7 +504,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head = NULL; option_no_checkout = 1; if (!option_bare) - install_branch_config("master", option_origin, + install_branch_config(0, "master", option_origin, "refs/heads/master"); } @@ -583,7 +534,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) head_points_at->peer_ref->name, reflog_msg.buf); - install_branch_config(head, option_origin, + install_branch_config(0, head, option_origin, head_points_at->name); } } else if (remote_head) { @@ -633,6 +584,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (write_cache(fd, active_cache, active_nr) || commit_locked_index(lock_file)) die("unable to write new index file"); + + err |= run_hook(NULL, "post-checkout", sha1_to_hex(null_sha1), + sha1_to_hex(remote_head->old_sha1), "1", NULL); } strbuf_release(&reflog_msg); @@ -640,5 +594,5 @@ int cmd_clone(int argc, const char **argv, const char *prefix) strbuf_release(&key); strbuf_release(&value); junk_pid = 0; - return 0; + return err; } |