Revision b018ff60857ee7d79e3c4a8772bac08656a2a3c6 authored by Jeff King on 29 December 2012, 20:51:54 UTC, committed by Junio C Hamano on 04 November 2013, 18:13:27 UTC
When we call "read-tree --reset -u HEAD ORIG_HEAD", the first thing we
do with the index is to call read_cache_unmerged.  Originally that
would read the index, leaving aside any unmerged entries.  However, as
of d1a43f2 (reset --hard/read-tree --reset -u: remove unmerged new
paths, 2008-10-15), it actually creates a new cache entry to serve as
a placeholder, so that we later know to update the working tree.

However, we later noticed that the sha1 of that unmerged entry was
just copied from some higher stage, leaving you with random content in
the index.  That was fixed by e11d7b5 ("reset --merge": fix unmerged
case, 2009-12-31), which instead puts the null sha1 into the newly
created entry, and sets a CE_CONFLICTED flag. At the same time, it
teaches the unpack-trees machinery to pay attention to this flag, so
that oneway_merge throws away the current value.

However, it did not update the code paths for twoway_merge, which is
where we end up in the two-way read-tree with --reset. We notice that
the HEAD and ORIG_HEAD versions are the same, and say "oh, we can just
reuse the current version". But that's not true. The current version
is bogus.

Notice this case and make sure we do not keep the bogus entry; either
we do not have that path in the tree we are moving to (i.e. remove
it), or we want to have the cache entry we created for the tree we are
moving to (i.e. resolve by explicitly saying the "newtree" version is
what we want).

[jc: this is from the almost year-old $gmane/212316]

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c479d14
Raw File
t3413-rebase-hook.sh
#!/bin/sh

test_description='git rebase with its hook(s)'

. ./test-lib.sh

test_expect_success setup '
	echo hello >file &&
	git add file &&
	test_tick &&
	git commit -m initial &&
	echo goodbye >file &&
	git add file &&
	test_tick &&
	git commit -m second &&
	git checkout -b side HEAD^ &&
	echo world >git &&
	git add git &&
	test_tick &&
	git commit -m side &&
	git checkout master &&
	git log --pretty=oneline --abbrev-commit --graph --all &&
	git branch test side
'

test_expect_success 'rebase' '
	git checkout test &&
	git reset --hard side &&
	git rebase master &&
	test "z$(cat git)" = zworld
'

test_expect_success 'rebase -i' '
	git checkout test &&
	git reset --hard side &&
	EDITOR=true git rebase -i master &&
	test "z$(cat git)" = zworld
'

test_expect_success 'setup pre-rebase hook' '
	mkdir -p .git/hooks &&
	cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
echo "\$1,\$2" >.git/PRE-REBASE-INPUT
EOF
	chmod +x .git/hooks/pre-rebase
'

test_expect_success 'pre-rebase hook gets correct input (1)' '
	git checkout test &&
	git reset --hard side &&
	git rebase master &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,

'

test_expect_success 'pre-rebase hook gets correct input (2)' '
	git checkout test &&
	git reset --hard side &&
	git rebase master test &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (3)' '
	git checkout test &&
	git reset --hard side &&
	git checkout master &&
	git rebase master test &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (4)' '
	git checkout test &&
	git reset --hard side &&
	EDITOR=true git rebase -i master &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,

'

test_expect_success 'pre-rebase hook gets correct input (5)' '
	git checkout test &&
	git reset --hard side &&
	EDITOR=true git rebase -i master test &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'pre-rebase hook gets correct input (6)' '
	git checkout test &&
	git reset --hard side &&
	git checkout master &&
	EDITOR=true git rebase -i master test &&
	test "z$(cat git)" = zworld &&
	test "z$(cat .git/PRE-REBASE-INPUT)" = zmaster,test
'

test_expect_success 'setup pre-rebase hook that fails' '
	mkdir -p .git/hooks &&
	cat >.git/hooks/pre-rebase <<EOF &&
#!$SHELL_PATH
false
EOF
	chmod +x .git/hooks/pre-rebase
'

test_expect_success 'pre-rebase hook stops rebase (1)' '
	git checkout test &&
	git reset --hard side &&
	test_must_fail git rebase master &&
	test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
	test 0 = $(git rev-list HEAD...side | wc -l)
'

test_expect_success 'pre-rebase hook stops rebase (2)' '
	git checkout test &&
	git reset --hard side &&
	(
		EDITOR=:
		export EDITOR
		test_must_fail git rebase -i master
	) &&
	test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
	test 0 = $(git rev-list HEAD...side | wc -l)
'

test_expect_success 'rebase --no-verify overrides pre-rebase (1)' '
	git checkout test &&
	git reset --hard side &&
	git rebase --no-verify master &&
	test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
	test "z$(cat git)" = zworld
'

test_expect_success 'rebase --no-verify overrides pre-rebase (2)' '
	git checkout test &&
	git reset --hard side &&
	EDITOR=true git rebase --no-verify -i master &&
	test "z$(git symbolic-ref HEAD)" = zrefs/heads/test &&
	test "z$(cat git)" = zworld
'

test_done
back to top