mirror of
https://github.com/git-for-windows/git.git
synced 2026-04-09 15:01:59 -05:00
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
This commit is contained in:
@@ -1384,32 +1384,16 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NEEDSWORK: we should consolidate various implementations of "are we
|
||||
* on an unborn branch?" test into one, and make the unified one more
|
||||
* robust. !get_sha1() based check used here and elsewhere would not
|
||||
* allow us to tell an unborn branch from corrupt ref, for example.
|
||||
* For the purpose of fixing "deploy-to-update does not work when
|
||||
* pushing into an empty repository" issue, this should suffice for
|
||||
* now.
|
||||
*/
|
||||
static int head_has_history(void)
|
||||
{
|
||||
struct object_id oid;
|
||||
|
||||
return !repo_get_oid(the_repository, "HEAD", &oid);
|
||||
}
|
||||
|
||||
static const char *push_to_deploy(unsigned char *sha1,
|
||||
struct strvec *env,
|
||||
const char *work_tree)
|
||||
const struct worktree *worktree)
|
||||
{
|
||||
struct child_process child = CHILD_PROCESS_INIT;
|
||||
|
||||
strvec_pushl(&child.args, "update-index", "-q", "--ignore-submodules",
|
||||
"--refresh", NULL);
|
||||
strvec_pushv(&child.env, env->v);
|
||||
child.dir = work_tree;
|
||||
child.dir = worktree->path;
|
||||
child.no_stdin = 1;
|
||||
child.stdout_to_stderr = 1;
|
||||
child.git_cmd = 1;
|
||||
@@ -1421,7 +1405,7 @@ static const char *push_to_deploy(unsigned char *sha1,
|
||||
strvec_pushl(&child.args, "diff-files", "--quiet",
|
||||
"--ignore-submodules", "--", NULL);
|
||||
strvec_pushv(&child.env, env->v);
|
||||
child.dir = work_tree;
|
||||
child.dir = worktree->path;
|
||||
child.no_stdin = 1;
|
||||
child.stdout_to_stderr = 1;
|
||||
child.git_cmd = 1;
|
||||
@@ -1431,9 +1415,16 @@ static const char *push_to_deploy(unsigned char *sha1,
|
||||
child_process_init(&child);
|
||||
strvec_pushl(&child.args, "diff-index", "--quiet", "--cached",
|
||||
"--ignore-submodules",
|
||||
/* diff-index with either HEAD or an empty tree */
|
||||
head_has_history() ? "HEAD" : empty_tree_oid_hex(the_repository->hash_algo),
|
||||
"--", NULL);
|
||||
/*
|
||||
* diff-index with either HEAD or an empty tree
|
||||
*
|
||||
* NEEDSWORK: is_null_oid() cannot know whether it's an
|
||||
* unborn HEAD or a corrupt ref. It works for now because
|
||||
* it's only needed to know if we are comparing HEAD or an
|
||||
* empty tree.
|
||||
*/
|
||||
!is_null_oid(&worktree->head_oid) ? "HEAD" :
|
||||
empty_tree_oid_hex(the_repository->hash_algo), "--", NULL);
|
||||
strvec_pushv(&child.env, env->v);
|
||||
child.no_stdin = 1;
|
||||
child.no_stdout = 1;
|
||||
@@ -1446,7 +1437,7 @@ static const char *push_to_deploy(unsigned char *sha1,
|
||||
strvec_pushl(&child.args, "read-tree", "-u", "-m", hash_to_hex(sha1),
|
||||
NULL);
|
||||
strvec_pushv(&child.env, env->v);
|
||||
child.dir = work_tree;
|
||||
child.dir = worktree->path;
|
||||
child.no_stdin = 1;
|
||||
child.no_stdout = 1;
|
||||
child.stdout_to_stderr = 0;
|
||||
@@ -1494,7 +1485,7 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w
|
||||
|
||||
retval = push_to_checkout(sha1, &invoked_hook, &env, worktree->path);
|
||||
if (!invoked_hook)
|
||||
retval = push_to_deploy(sha1, &env, worktree->path);
|
||||
retval = push_to_deploy(sha1, &env, worktree);
|
||||
|
||||
strvec_clear(&env);
|
||||
free(git_dir);
|
||||
|
||||
@@ -1792,6 +1792,7 @@ test_expect_success 'updateInstead with push-to-checkout hook' '
|
||||
'
|
||||
|
||||
test_expect_success 'denyCurrentBranch and worktrees' '
|
||||
test_when_finished "rm -fr cloned && git worktree remove --force new-wt" &&
|
||||
git worktree add new-wt &&
|
||||
git clone . cloned &&
|
||||
test_commit -C cloned first &&
|
||||
@@ -1816,6 +1817,20 @@ test_expect_success 'denyCurrentBranch and bare repository worktrees' '
|
||||
test_must_fail git push --delete bare.git wt
|
||||
'
|
||||
|
||||
test_expect_success 'updateInstead with bare repository worktree and unborn bare HEAD' '
|
||||
test_when_finished "rm -fr bare.git cloned" &&
|
||||
git clone --bare . bare.git &&
|
||||
git -C bare.git worktree add wt &&
|
||||
git -C bare.git config receive.denyCurrentBranch updateInstead &&
|
||||
git -C bare.git symbolic-ref HEAD refs/heads/unborn &&
|
||||
test_must_fail git -C bare.git rev-parse -q --verify HEAD^{commit} &&
|
||||
git clone . cloned &&
|
||||
test_commit -C cloned mozzarella &&
|
||||
git -C cloned push ../bare.git HEAD:wt &&
|
||||
test_path_exists bare.git/wt/mozzarella.t &&
|
||||
test "$(git -C cloned rev-parse HEAD)" = "$(git -C bare.git/wt rev-parse HEAD)"
|
||||
'
|
||||
|
||||
test_expect_success 'refuse fetch to current branch of worktree' '
|
||||
test_when_finished "git worktree remove --force wt && git branch -D wt" &&
|
||||
git worktree add wt &&
|
||||
|
||||
Reference in New Issue
Block a user