mirror of
https://github.com/git/git
synced 2024-08-25 02:35:46 +00:00
git-blame shouldn't crash if run in an unmerged tree
If we are in the middle of resolving a merge conflict there may be one or more files whose entries in the index represent an unmerged state (index entries in the higher-order stages). Attempting to run git-blame on any file in such a working directory resulted in "fatal: internal error: ce_mode is 0" as we use the magic marker for an unmerged entry is 0 (set up by things like diff-lib.c's do_diff_cache() and builtin-read-tree.c's read_tree_unmerged()) and the ce_match_stat_basic() function gets upset about this. I'm not entirely sure that the whole "ce_mode = 0" case is a good idea to begin with, and maybe the right thing to do is to remove that horrid freakish special case, but removing the internal error seems to be the simplest fix for now. Linus [sp: Thanks to Björn Steinbrink for the test case] Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
93a56c2cf7
commit
cd8ae20195
|
@ -149,6 +149,8 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
|
||||||
else if (ce_compare_gitlink(ce))
|
else if (ce_compare_gitlink(ce))
|
||||||
changed |= DATA_CHANGED;
|
changed |= DATA_CHANGED;
|
||||||
return changed;
|
return changed;
|
||||||
|
case 0: /* Special case: unmerged file in index */
|
||||||
|
return MODE_CHANGED | DATA_CHANGED | TYPE_CHANGED;
|
||||||
default:
|
default:
|
||||||
die("internal error: ce_mode is %o", ntohl(ce->ce_mode));
|
die("internal error: ce_mode is %o", ntohl(ce->ce_mode));
|
||||||
}
|
}
|
||||||
|
|
73
t/t8004-blame.sh
Executable file
73
t/t8004-blame.sh
Executable file
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Based on a test case submitted by Björn Steinbrink.
|
||||||
|
|
||||||
|
test_description='git blame on conflicted files'
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success 'setup first case' '
|
||||||
|
# Create the old file
|
||||||
|
echo "Old line" > file1 &&
|
||||||
|
git add file1 &&
|
||||||
|
git commit --author "Old Line <ol@localhost>" -m file1.a &&
|
||||||
|
|
||||||
|
# Branch
|
||||||
|
git checkout -b foo &&
|
||||||
|
|
||||||
|
# Do an ugly move and change
|
||||||
|
git rm file1 &&
|
||||||
|
echo "New line ..." > file2 &&
|
||||||
|
echo "... and more" >> file2 &&
|
||||||
|
git add file2 &&
|
||||||
|
git commit --author "U Gly <ug@localhost>" -m ugly &&
|
||||||
|
|
||||||
|
# Back to master and change something
|
||||||
|
git checkout master &&
|
||||||
|
echo "
|
||||||
|
|
||||||
|
bla" >> file1 &&
|
||||||
|
git commit --author "Old Line <ol@localhost>" -a -m file1.b &&
|
||||||
|
|
||||||
|
# Back to foo and merge master
|
||||||
|
git checkout foo &&
|
||||||
|
if git merge master; then
|
||||||
|
echo needed conflict here
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo merge failed - resolving automatically
|
||||||
|
fi &&
|
||||||
|
echo "New line ...
|
||||||
|
... and more
|
||||||
|
|
||||||
|
bla
|
||||||
|
Even more" > file2 &&
|
||||||
|
git rm file1 &&
|
||||||
|
git commit --author "M Result <mr@localhost>" -a -m merged &&
|
||||||
|
|
||||||
|
# Back to master and change file1 again
|
||||||
|
git checkout master &&
|
||||||
|
sed s/bla/foo/ <file1 >X &&
|
||||||
|
rm file1 &&
|
||||||
|
mv X file1 &&
|
||||||
|
git commit --author "No Bla <nb@localhost>" -a -m replace &&
|
||||||
|
|
||||||
|
# Try to merge into foo again
|
||||||
|
git checkout foo &&
|
||||||
|
if git merge master; then
|
||||||
|
echo needed conflict here
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo merge failed - test is setup
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success \
|
||||||
|
'blame runs on unconflicted file while other file has conflicts' '
|
||||||
|
git blame file2
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'blame runs on conflicted file in stages 1,3' '
|
||||||
|
git blame file1
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in a new issue