]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'hv/receive-denycurrent-everywhere'
authorJunio C Hamano <gitster@pobox.com>
Thu, 5 Mar 2020 18:43:02 +0000 (10:43 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 5 Mar 2020 18:43:03 +0000 (10:43 -0800)
"git push" should stop from updating a branch that is checked out
when receive.denyCurrentBranch configuration is set, but it failed
to pay attention to checkouts in secondary worktrees.  This has
been corrected.

* hv/receive-denycurrent-everywhere:
  t2402: test worktree path when called in .git directory
  receive.denyCurrentBranch: respect all worktrees
  t5509: use a bare repository for test push target
  get_main_worktree(): allow it to be called in the Git directory

1  2 
t/t5516-fetch-push.sh
worktree.c

diff --combined t/t5516-fetch-push.sh
index f12cbef09728d9c49b0ad66eab77c57043df0596,49982b0fd90d62b310907f698d00c5b718d8aa15..9ff041a093e71aac932f5e563d4922930bc62ff2
@@@ -1151,7 -1151,7 +1151,7 @@@ test_expect_success 'fetch exact SHA1' 
                # unadvertised objects, so restrict this test to v0.
  
                # fetching the hidden object should fail by default
 -              test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +              test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                        git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
                test_i18ngrep "Server does not allow request for unadvertised object" err &&
                test_must_fail git rev-parse --verify refs/heads/copy &&
                        cd shallow &&
                        # Some protocol versions (e.g. 2) support fetching
                        # unadvertised objects, so restrict this test to v0.
 -                      test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +                      test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                                git fetch --depth=1 ../testrepo/.git $SHA1 &&
                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
                        git fetch --depth=1 ../testrepo/.git $SHA1 &&
                        cd shallow &&
                        # Some protocol versions (e.g. 2) support fetching
                        # unadvertised objects, so restrict this test to v0.
 -                      test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +                      test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                                git fetch ../testrepo/.git $SHA1_3 &&
 -                      test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +                      test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                                git fetch ../testrepo/.git $SHA1_1 &&
                        git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
                        git fetch ../testrepo/.git $SHA1_1 &&
                        test_must_fail git cat-file commit $SHA1_2 &&
                        git fetch ../testrepo/.git $SHA1_2 &&
                        git cat-file commit $SHA1_2 &&
 -                      test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +                      test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                                git fetch ../testrepo/.git $SHA1_3 2>err &&
                        test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
                )
@@@ -1291,7 -1291,7 +1291,7 @@@ test_expect_success 'peeled advertiseme
        git -C testrepo commit --allow-empty -m two &&
        git -C testrepo tag -m foo mytag HEAD^ &&
        oid=$(git -C testrepo rev-parse mytag^{commit}) &&
 -      test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
 +      test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \
                git fetch testrepo $oid 2>err &&
        test_i18ngrep "Server does not allow request for unadvertised object" err
  '
@@@ -1712,4 -1712,15 +1712,15 @@@ test_expect_success 'updateInstead wit
        )
  '
  
+ test_expect_success 'denyCurrentBranch and worktrees' '
+       git worktree add new-wt &&
+       git clone . cloned &&
+       test_commit -C cloned first &&
+       test_config receive.denyCurrentBranch refuse &&
+       test_must_fail git -C cloned push origin HEAD:new-wt &&
+       test_config receive.denyCurrentBranch updateInstead &&
+       git -C cloned push origin HEAD:new-wt &&
+       test_must_fail git -C cloned push --delete origin new-wt
+ '
  test_done
diff --combined worktree.c
index 52971f7082eb00d38282fad793264ab1bfd1a7e3,7c8cd2131713dd53ee3e716df6e5451d67c3ec69..eba4fd3a03812f046dadc1baf9d7644ba8dfcce9
@@@ -47,12 -47,16 +47,13 @@@ static void add_head_info(struct worktr
  static struct worktree *get_main_worktree(void)
  {
        struct worktree *worktree = NULL;
 -      struct strbuf path = STRBUF_INIT;
        struct strbuf worktree_path = STRBUF_INIT;
  
        strbuf_add_absolute_path(&worktree_path, get_git_common_dir());
+       strbuf_strip_suffix(&worktree_path, "/.");
        if (!strbuf_strip_suffix(&worktree_path, "/.git"))
                strbuf_strip_suffix(&worktree_path, "/.");
  
 -      strbuf_addf(&path, "%s/HEAD", get_git_common_dir());
 -
        worktree = xcalloc(1, sizeof(*worktree));
        worktree->path = strbuf_detach(&worktree_path, NULL);
        /*
@@@ -66,6 -70,7 +67,6 @@@
                is_bare_repository();
        add_head_info(worktree);
  
 -      strbuf_release(&path);
        strbuf_release(&worktree_path);
        return worktree;
  }
@@@ -211,6 -216,7 +212,6 @@@ struct worktree *find_worktree(struct w
                               const char *arg)
  {
        struct worktree *wt;
 -      char *path;
        char *to_free = NULL;
  
        if ((wt = find_worktree_by_suffix(list, arg)))
  
        if (prefix)
                arg = to_free = prefix_filename(prefix, arg);
 -      path = real_pathdup(arg, 0);
 -      if (!path) {
 -              free(to_free);
 +      wt = find_worktree_by_path(list, arg);
 +      free(to_free);
 +      return wt;
 +}
 +
 +struct worktree *find_worktree_by_path(struct worktree **list, const char *p)
 +{
 +      char *path = real_pathdup(p, 0);
 +
 +      if (!path)
                return NULL;
 -      }
        for (; *list; list++) {
                const char *wt_path = real_path_if_valid((*list)->path);
  
                        break;
        }
        free(path);
 -      free(to_free);
        return *list;
  }