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
t4013-diff-various.sh
#!/bin/sh
#
# Copyright (c) 2006 Junio C Hamano
#

test_description='Various diff formatting options'

. ./test-lib.sh

LF='
'

test_expect_success setup '

	GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	mkdir dir &&
	mkdir dir2 &&
	for i in 1 2 3; do echo $i; done >file0 &&
	for i in A B; do echo $i; done >dir/sub &&
	cat file0 >file2 &&
	git add file0 file2 dir/sub &&
	git commit -m Initial &&

	git branch initial &&
	git branch side &&

	GIT_AUTHOR_DATE="2006-06-26 00:01:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:01:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	for i in 4 5 6; do echo $i; done >>file0 &&
	for i in C D; do echo $i; done >>dir/sub &&
	rm -f file2 &&
	git update-index --remove file0 file2 dir/sub &&
	git commit -m "Second${LF}${LF}This is the second commit." &&

	GIT_AUTHOR_DATE="2006-06-26 00:02:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:02:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	for i in A B C; do echo $i; done >file1 &&
	git add file1 &&
	for i in E F; do echo $i; done >>dir/sub &&
	git update-index dir/sub &&
	git commit -m Third &&

	GIT_AUTHOR_DATE="2006-06-26 00:03:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:03:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	git checkout side &&
	for i in A B C; do echo $i; done >>file0 &&
	for i in 1 2; do echo $i; done >>dir/sub &&
	cat dir/sub >file3 &&
	git add file3 &&
	git update-index file0 dir/sub &&
	git commit -m Side &&

	GIT_AUTHOR_DATE="2006-06-26 00:04:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:04:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	git checkout master &&
	git pull -s ours . side &&

	GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&

	for i in A B C; do echo $i; done >>file0 &&
	for i in 1 2; do echo $i; done >>dir/sub &&
	git update-index file0 dir/sub &&

	mkdir dir3 &&
	cp dir/sub dir3/sub &&
	test-chmtime +1 dir3/sub &&

	git config log.showroot false &&
	git commit --amend &&

	GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" &&
	GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" &&
	export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
	git checkout -b rearrange initial &&
	for i in B A; do echo $i; done >dir/sub &&
	git add dir/sub &&
	git commit -m "Rearranged lines in dir/sub" &&
	git checkout master &&

	git show-branch
'

: <<\EOF
! [initial] Initial
 * [master] Merge branch 'side'
  ! [rearrange] Rearranged lines in dir/sub
   ! [side] Side
----
  +  [rearrange] Rearranged lines in dir/sub
 -   [master] Merge branch 'side'
 * + [side] Side
 *   [master^] Third
 *   [master~2] Second
+*++ [initial] Initial
EOF

V=`git version | sed -e 's/^git version //' -e 's/\./\\./g'`
while read cmd
do
	case "$cmd" in
	'' | '#'*) continue ;;
	esac
	test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'`
	pfx=`printf "%04d" $test_count`
	expect="$TEST_DIRECTORY/t4013/diff.$test"
	actual="$pfx-diff.$test"

	test_expect_success "git $cmd" '
		{
			echo "\$ git $cmd"
			git $cmd |
			sed -e "s/^\\(-*\\)$V\\(-*\\)\$/\\1g-i-t--v-e-r-s-i-o-n\2/" \
			    -e "s/^\\(.*mixed; boundary=\"-*\\)$V\\(-*\\)\"\$/\\1g-i-t--v-e-r-s-i-o-n\2\"/"
			echo "\$"
		} >"$actual" &&
		if test -f "$expect"
		then
			test_cmp "$expect" "$actual" &&
			rm -f "$actual"
		else
			# this is to help developing new tests.
			cp "$actual" "$expect"
			false
		fi
	'
done <<\EOF
diff-tree initial
diff-tree -r initial
diff-tree -r --abbrev initial
diff-tree -r --abbrev=4 initial
diff-tree --root initial
diff-tree --root --abbrev initial
diff-tree --root -r initial
diff-tree --root -r --abbrev initial
diff-tree --root -r --abbrev=4 initial
diff-tree -p initial
diff-tree --root -p initial
diff-tree --patch-with-stat initial
diff-tree --root --patch-with-stat initial
diff-tree --patch-with-raw initial
diff-tree --root --patch-with-raw initial

diff-tree --pretty initial
diff-tree --pretty --root initial
diff-tree --pretty -p initial
diff-tree --pretty --stat initial
diff-tree --pretty --summary initial
diff-tree --pretty --stat --summary initial
diff-tree --pretty --root -p initial
diff-tree --pretty --root --stat initial
# improved by Timo's patch
diff-tree --pretty --root --summary initial
# improved by Timo's patch
diff-tree --pretty --root --summary -r initial
diff-tree --pretty --root --stat --summary initial
diff-tree --pretty --patch-with-stat initial
diff-tree --pretty --root --patch-with-stat initial
diff-tree --pretty --patch-with-raw initial
diff-tree --pretty --root --patch-with-raw initial

diff-tree --pretty=oneline initial
diff-tree --pretty=oneline --root initial
diff-tree --pretty=oneline -p initial
diff-tree --pretty=oneline --root -p initial
diff-tree --pretty=oneline --patch-with-stat initial
# improved by Timo's patch
diff-tree --pretty=oneline --root --patch-with-stat initial
diff-tree --pretty=oneline --patch-with-raw initial
diff-tree --pretty=oneline --root --patch-with-raw initial

diff-tree --pretty side
diff-tree --pretty -p side
diff-tree --pretty --patch-with-stat side

diff-tree master
diff-tree -p master
diff-tree -p -m master
diff-tree -c master
diff-tree -c --abbrev master
diff-tree --cc master
# stat only should show the diffstat with the first parent
diff-tree -c --stat master
diff-tree --cc --stat master
diff-tree -c --stat --summary master
diff-tree --cc --stat --summary master
# stat summary should show the diffstat and summary with the first parent
diff-tree -c --stat --summary side
diff-tree --cc --stat --summary side
# improved by Timo's patch
diff-tree --cc --patch-with-stat master
# improved by Timo's patch
diff-tree --cc --patch-with-stat --summary master
# this is correct
diff-tree --cc --patch-with-stat --summary side

log master
log -p master
log --root master
log --root -p master
log --patch-with-stat master
log --root --patch-with-stat master
log --root --patch-with-stat --summary master
# improved by Timo's patch
log --root -c --patch-with-stat --summary master
# improved by Timo's patch
log --root --cc --patch-with-stat --summary master
log -p --first-parent master
log -m -p --first-parent master
log -m -p master
log -SF master
log -S F master
log -SF -p master
log -SF master --max-count=0
log -SF master --max-count=1
log -SF master --max-count=2
log -GF master
log -GF -p master
log -GF -p --pickaxe-all master
log --decorate --all
log --decorate=full --all

rev-list --parents HEAD
rev-list --children HEAD

whatchanged master
whatchanged -p master
whatchanged --root master
whatchanged --root -p master
whatchanged --patch-with-stat master
whatchanged --root --patch-with-stat master
whatchanged --root --patch-with-stat --summary master
# improved by Timo's patch
whatchanged --root -c --patch-with-stat --summary master
# improved by Timo's patch
whatchanged --root --cc --patch-with-stat --summary master
whatchanged -SF master
whatchanged -SF -p master

log --patch-with-stat master -- dir/
whatchanged --patch-with-stat master -- dir/
log --patch-with-stat --summary master -- dir/
whatchanged --patch-with-stat --summary master -- dir/

show initial
show --root initial
show side
show master
show -c master
show -m master
show --first-parent master
show --stat side
show --stat --summary side
show --patch-with-stat side
show --patch-with-raw side
show --patch-with-stat --summary side

format-patch --stdout initial..side
format-patch --stdout initial..master^
format-patch --stdout initial..master
format-patch --stdout --no-numbered initial..master
format-patch --stdout --numbered initial..master
format-patch --attach --stdout initial..side
format-patch --attach --stdout --suffix=.diff initial..side
format-patch --attach --stdout initial..master^
format-patch --attach --stdout initial..master
format-patch --inline --stdout initial..side
format-patch --inline --stdout initial..master^
format-patch --inline --stdout --numbered-files initial..master
format-patch --inline --stdout initial..master
format-patch --inline --stdout --subject-prefix=TESTCASE initial..master
config format.subjectprefix DIFFERENT_PREFIX
format-patch --inline --stdout initial..master^^
format-patch --stdout --cover-letter -n initial..master^

diff --abbrev initial..side
diff -r initial..side
diff --stat initial..side
diff -r --stat initial..side
diff initial..side
diff --patch-with-stat initial..side
diff --patch-with-raw initial..side
diff --patch-with-stat -r initial..side
diff --patch-with-raw -r initial..side
diff --name-status dir2 dir
diff --no-index --name-status dir2 dir
diff --no-index --name-status -- dir2 dir
diff --no-index dir dir3
diff master master^ side
diff --dirstat master~1 master~2
diff --dirstat initial rearrange
diff --dirstat-by-file initial rearrange
EOF

test_expect_success 'log -S requires an argument' '
	test_must_fail git log -S
'

test_expect_success 'diff --cached on unborn branch' '
	echo ref: refs/heads/unborn >.git/HEAD &&
	git diff --cached >result &&
	test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached" result
'

test_expect_success 'diff --cached -- file on unborn branch' '
	git diff --cached -- file0 >result &&
	test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result
'

test_done
back to top