Merge branch 'jk/fetch-reflog-df-conflict'
authorJunio C Hamano <gitster@pobox.com>
Thu, 6 Nov 2014 18:52:31 +0000 (10:52 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 6 Nov 2014 18:52:32 +0000 (10:52 -0800)
Corner-case bugfixes for "git fetch" around reflog handling.

* jk/fetch-reflog-df-conflict:
ignore stale directories when checking reflog existence
fetch: load all default config at startup

1  2 
builtin/fetch.c
refs.c
t/t1410-reflog.sh
t/t5516-fetch-push.sh
diff --cc builtin/fetch.c
index 6ffd02388b732c270cf9abef0c310d7855a69de8,36f386dbb31a5c859b20e4442eb5cae3c6e3d86e..7b84d35d83498bc51b06915818f63d1f365eec91
@@@ -68,22 -66,9 +68,22 @@@ static int git_fetch_config(const char 
                fetch_prune_config = git_config_bool(k, v);
                return 0;
        }
-       return 0;
+       return git_default_config(k, v, cb);
  }
  
 +static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 +{
 +      ALLOC_GROW(refmap_array, refmap_nr + 1, refmap_alloc);
 +
 +      /*
 +       * "git fetch --refmap='' origin foo"
 +       * can be used to tell the command not to store anywhere
 +       */
 +      if (*arg)
 +              refmap_array[refmap_nr++] = arg;
 +      return 0;
 +}
 +
  static struct option builtin_fetch_options[] = {
        OPT__VERBOSITY(&verbosity),
        OPT_BOOL(0, "all", &all,
diff --cc refs.c
index 0368ed461f3ef913a60da322247bca0f9d121a82,e9eda881d0d17fa5cfaac56e619059054e6036cd..5ff457ebfce7aba9cd470f3e2e1f3f5dbe9d9741
--- 1/refs.c
--- 2/refs.c
+++ b/refs.c
@@@ -2962,16 -2751,13 +2962,16 @@@ int log_ref_setup(const char *refname, 
  
        logfd = open(logfile, oflags, 0666);
        if (logfd < 0) {
-               if (!(oflags & O_CREAT) && errno == ENOENT)
+               if (!(oflags & O_CREAT) && (errno == ENOENT || errno == EISDIR))
                        return 0;
  
-               if ((oflags & O_CREAT) && errno == EISDIR) {
+               if (errno == EISDIR) {
                        if (remove_empty_directories(logfile)) {
 -                              return error("There are still logs under '%s'",
 -                                           logfile);
 +                              int save_errno = errno;
 +                              error("There are still logs under '%s'",
 +                                    logfile);
 +                              errno = save_errno;
 +                              return -1;
                        }
                        logfd = open(logfile, oflags, 0666);
                }
index 8cab06f90a52b82518aca6f7baa0530eb77ab986,e4409e38df7b19d64ed27495fb60da0ad44e85fd..976c1d4277ba902cd5b592c9bcbf72c7b9111cd3
@@@ -245,12 -245,38 +245,46 @@@ test_expect_success 'gc.reflogexpire=fa
  
  '
  
 +test_expect_success 'checkout should not delete log for packed ref' '
 +      test $(git reflog master | wc -l) = 4 &&
 +      git branch foo &&
 +      git pack-refs --all &&
 +      git checkout foo &&
 +      test $(git reflog master | wc -l) = 4
 +'
 +
+ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs on)' '
+       test_when_finished "git branch -d a || git branch -d a/b" &&
+       git branch a/b master &&
+       echo "a/b@{0} branch: Created from master" >expect &&
+       git log -g --format="%gd %gs" a/b >actual &&
+       test_cmp expect actual &&
+       git branch -d a/b &&
+       # now logs/refs/heads/a is a stale directory, but
+       # we should move it out of the way to create "a" reflog
+       git branch a master &&
+       echo "a@{0} branch: Created from master" >expect &&
+       git log -g --format="%gd %gs" a >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' '
+       test_when_finished "git branch -d a || git branch -d a/b" &&
+       git branch a/b master &&
+       echo "a/b@{0} branch: Created from master" >expect &&
+       git log -g --format="%gd %gs" a/b >actual &&
+       test_cmp expect actual &&
+       git branch -d a/b &&
+       # same as before, but we only create a reflog for "a" if
+       # it already exists, which it does not
+       git -c core.logallrefupdates=false branch a master &&
+       : >expect &&
+       git log -g --format="%gd %gs" a >actual &&
+       test_cmp expect actual
+ '
  test_done
index 7c8a769a90e4554500d73506c1df41483d846d98,2b69afaf376daf12cf37418c32017ffcab66b87f..f4da20aa9bf7df1b2ab1fda207b70e1913277603
        git push --no-thin --receive-pack="$rcvpck" no-thin/.git refs/heads/master:refs/heads/foo
  '
  
 +test_expect_success 'pushing a tag pushes the tagged object' '
 +      rm -rf dst.git &&
 +      blob=$(echo unreferenced | git hash-object -w --stdin) &&
 +      git tag -m foo tag-of-blob $blob &&
 +      git init --bare dst.git &&
 +      git push dst.git tag-of-blob &&
 +      # the receiving index-pack should have noticed
 +      # any problems, but we double check
 +      echo unreferenced >expect &&
 +      git --git-dir=dst.git cat-file blob tag-of-blob >actual &&
 +      test_cmp expect actual
 +'
 +
+ test_expect_success 'push into bare respects core.logallrefupdates' '
+       rm -rf dst.git &&
+       git init --bare dst.git &&
+       git -C dst.git config core.logallrefupdates true &&
+       # double push to test both with and without
+       # the actual pack transfer
+       git push dst.git master:one &&
+       echo "one@{0} push" >expect &&
+       git -C dst.git log -g --format="%gd %gs" one >actual &&
+       test_cmp expect actual &&
+       git push dst.git master:two &&
+       echo "two@{0} push" >expect &&
+       git -C dst.git log -g --format="%gd %gs" two >actual &&
+       test_cmp expect actual
+ '
+ test_expect_success 'fetch into bare respects core.logallrefupdates' '
+       rm -rf dst.git &&
+       git init --bare dst.git &&
+       (
+               cd dst.git &&
+               git config core.logallrefupdates true &&
+               # as above, we double-fetch to test both
+               # with and without pack transfer
+               git fetch .. master:one &&
+               echo "one@{0} fetch .. master:one: storing head" >expect &&
+               git log -g --format="%gd %gs" one >actual &&
+               test_cmp expect actual &&
+               git fetch .. master:two &&
+               echo "two@{0} fetch .. master:two: storing head" >expect &&
+               git log -g --format="%gd %gs" two >actual &&
+               test_cmp expect actual
+       )
+ '
  test_done