Skip to content

Commit b66c97c

Browse files
committed
Merge branch 'ps/receive-pack-updateinstead-in-worktree'
The check in "receive-pack" to prevent a checked out branch from getting updated via updateInstead mechanism has been corrected. * ps/receive-pack-updateinstead-in-worktree: receive-pack: use worktree HEAD for updateInstead t5516: clean up cloned and new-wt in denyCurrentBranch and worktrees test t5516: test updateInstead with worktree and unborn bare HEAD
2 parents f1edda9 + 8151f4f commit b66c97c

File tree

2 files changed

+30
-24
lines changed

2 files changed

+30
-24
lines changed

builtin/receive-pack.c

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,32 +1384,16 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
13841384
return 0;
13851385
}
13861386

1387-
/*
1388-
* NEEDSWORK: we should consolidate various implementations of "are we
1389-
* on an unborn branch?" test into one, and make the unified one more
1390-
* robust. !get_sha1() based check used here and elsewhere would not
1391-
* allow us to tell an unborn branch from corrupt ref, for example.
1392-
* For the purpose of fixing "deploy-to-update does not work when
1393-
* pushing into an empty repository" issue, this should suffice for
1394-
* now.
1395-
*/
1396-
static int head_has_history(void)
1397-
{
1398-
struct object_id oid;
1399-
1400-
return !repo_get_oid(the_repository, "HEAD", &oid);
1401-
}
1402-
14031387
static const char *push_to_deploy(unsigned char *sha1,
14041388
struct strvec *env,
1405-
const char *work_tree)
1389+
const struct worktree *worktree)
14061390
{
14071391
struct child_process child = CHILD_PROCESS_INIT;
14081392

14091393
strvec_pushl(&child.args, "update-index", "-q", "--ignore-submodules",
14101394
"--refresh", NULL);
14111395
strvec_pushv(&child.env, env->v);
1412-
child.dir = work_tree;
1396+
child.dir = worktree->path;
14131397
child.no_stdin = 1;
14141398
child.stdout_to_stderr = 1;
14151399
child.git_cmd = 1;
@@ -1421,7 +1405,7 @@ static const char *push_to_deploy(unsigned char *sha1,
14211405
strvec_pushl(&child.args, "diff-files", "--quiet",
14221406
"--ignore-submodules", "--", NULL);
14231407
strvec_pushv(&child.env, env->v);
1424-
child.dir = work_tree;
1408+
child.dir = worktree->path;
14251409
child.no_stdin = 1;
14261410
child.stdout_to_stderr = 1;
14271411
child.git_cmd = 1;
@@ -1431,9 +1415,16 @@ static const char *push_to_deploy(unsigned char *sha1,
14311415
child_process_init(&child);
14321416
strvec_pushl(&child.args, "diff-index", "--quiet", "--cached",
14331417
"--ignore-submodules",
1434-
/* diff-index with either HEAD or an empty tree */
1435-
head_has_history() ? "HEAD" : empty_tree_oid_hex(the_repository->hash_algo),
1436-
"--", NULL);
1418+
/*
1419+
* diff-index with either HEAD or an empty tree
1420+
*
1421+
* NEEDSWORK: is_null_oid() cannot know whether it's an
1422+
* unborn HEAD or a corrupt ref. It works for now because
1423+
* it's only needed to know if we are comparing HEAD or an
1424+
* empty tree.
1425+
*/
1426+
!is_null_oid(&worktree->head_oid) ? "HEAD" :
1427+
empty_tree_oid_hex(the_repository->hash_algo), "--", NULL);
14371428
strvec_pushv(&child.env, env->v);
14381429
child.no_stdin = 1;
14391430
child.no_stdout = 1;
@@ -1446,7 +1437,7 @@ static const char *push_to_deploy(unsigned char *sha1,
14461437
strvec_pushl(&child.args, "read-tree", "-u", "-m", hash_to_hex(sha1),
14471438
NULL);
14481439
strvec_pushv(&child.env, env->v);
1449-
child.dir = work_tree;
1440+
child.dir = worktree->path;
14501441
child.no_stdin = 1;
14511442
child.no_stdout = 1;
14521443
child.stdout_to_stderr = 0;
@@ -1494,7 +1485,7 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w
14941485

14951486
retval = push_to_checkout(sha1, &invoked_hook, &env, worktree->path);
14961487
if (!invoked_hook)
1497-
retval = push_to_deploy(sha1, &env, worktree->path);
1488+
retval = push_to_deploy(sha1, &env, worktree);
14981489

14991490
strvec_clear(&env);
15001491
free(git_dir);

t/t5516-fetch-push.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
17921792
'
17931793

17941794
test_expect_success 'denyCurrentBranch and worktrees' '
1795+
test_when_finished "rm -fr cloned && git worktree remove --force new-wt" &&
17951796
git worktree add new-wt &&
17961797
git clone . cloned &&
17971798
test_commit -C cloned first &&
@@ -1816,6 +1817,20 @@ test_expect_success 'denyCurrentBranch and bare repository worktrees' '
18161817
test_must_fail git push --delete bare.git wt
18171818
'
18181819

1820+
test_expect_success 'updateInstead with bare repository worktree and unborn bare HEAD' '
1821+
test_when_finished "rm -fr bare.git cloned" &&
1822+
git clone --bare . bare.git &&
1823+
git -C bare.git worktree add wt &&
1824+
git -C bare.git config receive.denyCurrentBranch updateInstead &&
1825+
git -C bare.git symbolic-ref HEAD refs/heads/unborn &&
1826+
test_must_fail git -C bare.git rev-parse -q --verify HEAD^{commit} &&
1827+
git clone . cloned &&
1828+
test_commit -C cloned mozzarella &&
1829+
git -C cloned push ../bare.git HEAD:wt &&
1830+
test_path_exists bare.git/wt/mozzarella.t &&
1831+
test "$(git -C cloned rev-parse HEAD)" = "$(git -C bare.git/wt rev-parse HEAD)"
1832+
'
1833+
18191834
test_expect_success 'refuse fetch to current branch of worktree' '
18201835
test_when_finished "git worktree remove --force wt && git branch -D wt" &&
18211836
git worktree add wt &&

0 commit comments

Comments
 (0)