Merge branch 'maint-1.6.2' into maint-1.6.3
authorJunio C Hamano <gitster@pobox.com>
Thu, 3 Sep 2009 01:45:44 +0000 (18:45 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 Sep 2009 01:45:44 +0000 (18:45 -0700)
* maint-1.6.2:
clone: disconnect transport after fetching

1  2 
builtin-clone.c
t/t5601-clone.sh
diff --combined builtin-clone.c
index ba286e0160c494244810334e3a0b43a59756e84a,1c1d72911757c116b0cd19dd4b50c10ebbd68214..6605e83407ce70dbb77a4be51cfadec60b3db6ad
@@@ -20,9 -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:
@@@ -228,8 -225,7 +228,8 @@@ static void copy_or_link_directory(stru
                }
  
                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;
@@@ -271,7 -267,7 +271,7 @@@ static const struct ref *clone_local(co
  
  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)
  {
@@@ -297,6 -293,43 +297,6 @@@ static void remove_junk_on_signal(int s
        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)
  {
        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;
        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();
  
        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;
  
                        die("--bare and --origin %s options are incompatible.",
                            option_origin);
                option_no_checkout = 1;
 -              use_separate_remote = 0;
        }
  
        if (!option_origin)
        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);
                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");
  
                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);
        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.");
                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");
        }
  
                                      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) {
                option_no_checkout = 1;
        }
  
-       if (transport)
+       if (transport) {
                transport_unlock_pack(transport);
+               transport_disconnect(transport);
+       }
  
        if (!option_no_checkout) {
                struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
                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);
        strbuf_release(&key);
        strbuf_release(&value);
        junk_pid = 0;
 -      return 0;
 +      return err;
  }
diff --combined t/t5601-clone.sh
index 2335d8bc850b4b0010fcb9ac64a25d0c205e8a42,c3ffc8f15c6165713e29fecacdd0f335aba1d56c..214756731baf199e6a50f9ab2380a8b4bfc0fb18
@@@ -149,29 -149,16 +149,31 @@@ test_expect_success 'clone a void' 
        (
                cd src-0 && git init
        ) &&
-       git clone src-0 target-6 &&
+       git clone "file://$(pwd)/src-0" target-6 2>err-6 &&
+       ! grep "fatal:" err-6 &&
        (
                cd src-0 && test_commit A
        ) &&
-       git clone src-0 target-7 &&
+       git clone "file://$(pwd)/src-0" target-7 2>err-7 &&
+       ! grep "fatal:" err-7 &&
        # There is no reason to insist they are bit-for-bit
        # identical, but this test should suffice for now.
        test_cmp target-6/.git/config target-7/.git/config
  '
  
 +test_expect_success 'clone respects global branch.autosetuprebase' '
 +      (
 +              HOME=$(pwd) &&
 +              export HOME &&
 +              test_config="$HOME/.gitconfig" &&
 +              unset GIT_CONFIG_NOGLOBAL &&
 +              git config -f "$test_config" branch.autosetuprebase remote &&
 +              rm -fr dst &&
 +              git clone src dst &&
 +              cd dst &&
 +              actual="z$(git config branch.master.rebase)" &&
 +              test ztrue = $actual
 +      )
 +'
 +
  test_done