Merge branch 'maint-1.6.2' into maint-1.6.3
authorJunio C Hamano <gitster@pobox.com>
Thu, 3 Sep 2009 16:42:38 +0000 (09:42 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 3 Sep 2009 16:42:38 +0000 (09:42 -0700)
* maint-1.6.2:
git-clone: add missing comma in --reference documentation
clone: disconnect transport after fetching

1  2 
Documentation/git-clone.txt
builtin-clone.c
t/t5601-clone.sh
index b14de6c407b8bd0bc001c608ca4f26fc619abf3e,0c7486d782c6cda30a26090239fa849f0a773e76..87c13ab13eb05e67312bf45de3e31ca30f7a01ab
@@@ -76,7 -76,7 +76,7 @@@ then the cloned repository will become 
  
  
  --reference <repository>::
-       If the reference repository is on the local machine
+       If the reference repository is on the local machine,
        automatically setup .git/objects/info/alternates to
        obtain objects from the reference repository.  Using
        an already existing repository as an alternate will
        part of the source repository is used if no directory is
        explicitly given ("repo" for "/path/to/repo.git" and "foo"
        for "host.xz:foo/.git").  Cloning into an existing directory
 -      is not allowed.
 +      is only allowed if the directory is empty.
  
  :git-clone: 1
  include::urls.txt[]
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