mergetool: Provide an empty file when needed

Some merge tools cannot cope when $LOCAL, $BASE, or $REMOTE are missing.
$BASE can be missing when two branches independently add the same
filename.

Provide an empty file to make these tools happy.

When a delete/modify conflict occurs, $LOCAL and $REMOTE can also be
missing. We have special case code to handle such case so this change
may not affect that codepath, but try to be consistent and create an
empty file for them anyway.

Reported-by: Jason Wenger <jcwenger@gmail.com>
Signed-off-by: David Aguilar <davvid@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
David Aguilar 2012-01-19 23:47:35 -08:00 committed by Junio C Hamano
parent 5fbdb9c2e8
commit ec245ba049
2 changed files with 35 additions and 5 deletions

View File

@ -181,10 +181,14 @@ stage_submodule () {
} }
checkout_staged_file () { checkout_staged_file () {
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ') tmpfile=$(expr \
"$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
: '\([^ ]*\) ')
if test $? -eq 0 -a -n "$tmpfile" ; then if test $? -eq 0 -a -n "$tmpfile" ; then
mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3" mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
else
>"$3"
fi fi
} }
@ -224,9 +228,9 @@ merge_file () {
mv -- "$MERGED" "$BACKUP" mv -- "$MERGED" "$BACKUP"
cp -- "$BACKUP" "$MERGED" cp -- "$BACKUP" "$MERGED"
base_present && checkout_staged_file 1 "$MERGED" "$BASE" checkout_staged_file 1 "$MERGED" "$BASE"
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL" checkout_staged_file 2 "$MERGED" "$LOCAL"
remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE" checkout_staged_file 3 "$MERGED" "$REMOTE"
if test -z "$local_mode" -o -z "$remote_mode"; then if test -z "$local_mode" -o -z "$remote_mode"; then
echo "Deleted merge conflict for '$MERGED':" echo "Deleted merge conflict for '$MERGED':"

View File

@ -39,6 +39,7 @@ test_expect_success 'setup' '
echo branch1 change >file1 && echo branch1 change >file1 &&
echo branch1 newfile >file2 && echo branch1 newfile >file2 &&
echo branch1 spaced >"spaced name" && echo branch1 spaced >"spaced name" &&
echo branch1 both added >both &&
echo branch1 change file11 >file11 && echo branch1 change file11 >file11 &&
echo branch1 change file13 >file13 && echo branch1 change file13 >file13 &&
echo branch1 sub >subdir/file3 && echo branch1 sub >subdir/file3 &&
@ -50,6 +51,7 @@ test_expect_success 'setup' '
git checkout -b submod-branch1 git checkout -b submod-branch1
) && ) &&
git add file1 "spaced name" file11 file13 file2 subdir/file3 submod && git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
git add both &&
git rm file12 && git rm file12 &&
git commit -m "branch1 changes" && git commit -m "branch1 changes" &&
@ -58,6 +60,7 @@ test_expect_success 'setup' '
echo master updated >file1 && echo master updated >file1 &&
echo master new >file2 && echo master new >file2 &&
echo master updated spaced >"spaced name" && echo master updated spaced >"spaced name" &&
echo master both added >both &&
echo master updated file12 >file12 && echo master updated file12 >file12 &&
echo master updated file14 >file14 && echo master updated file14 >file14 &&
echo master new sub >subdir/file3 && echo master new sub >subdir/file3 &&
@ -69,18 +72,22 @@ test_expect_success 'setup' '
git checkout -b submod-master git checkout -b submod-master
) && ) &&
git add file1 "spaced name" file12 file14 file2 subdir/file3 submod && git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
git add both &&
git rm file11 && git rm file11 &&
git commit -m "master updates" && git commit -m "master updates" &&
git config merge.tool mytool && git config merge.tool mytool &&
git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" && git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
git config mergetool.mytool.trustExitCode true git config mergetool.mytool.trustExitCode true &&
git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
git config mergetool.mybase.trustExitCode true
' '
test_expect_success 'custom mergetool' ' test_expect_success 'custom mergetool' '
git checkout -b test1 branch1 && git checkout -b test1 branch1 &&
git submodule update -N && git submodule update -N &&
test_must_fail git merge master >/dev/null 2>&1 && test_must_fail git merge master >/dev/null 2>&1 &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "" | git mergetool file1 file1 ) && ( yes "" | git mergetool file1 file1 ) &&
( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) && ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
@ -101,6 +108,7 @@ test_expect_success 'mergetool crlf' '
( yes "" | git mergetool file1 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
( yes "" | git mergetool file2 >/dev/null 2>&1 ) && ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) && ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@ -131,6 +139,7 @@ test_expect_success 'mergetool on file in parent dir' '
cd subdir && cd subdir &&
( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) && ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) && ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) && ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) && ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
@ -212,6 +221,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge master && test_must_fail git merge master &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) && ( yes "r" | git mergetool submod ) &&
rmdir submod && mv submod-movedaside submod && rmdir submod && mv submod-movedaside submod &&
@ -228,6 +238,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge master && test_must_fail git merge master &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) && ( yes "l" | git mergetool submod ) &&
test ! -e submod && test ! -e submod &&
@ -241,6 +252,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge test6 && test_must_fail git merge test6 &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) && ( yes "r" | git mergetool submod ) &&
test ! -e submod && test ! -e submod &&
@ -256,6 +268,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge test6 && test_must_fail git merge test6 &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) && ( yes "l" | git mergetool submod ) &&
test "$(cat submod/bar)" = "master submodule" && test "$(cat submod/bar)" = "master submodule" &&
@ -279,6 +292,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge master && test_must_fail git merge master &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) && ( yes "r" | git mergetool submod ) &&
rmdir submod && mv submod-movedaside submod && rmdir submod && mv submod-movedaside submod &&
@ -294,6 +308,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge master && test_must_fail git merge master &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) && ( yes "l" | git mergetool submod ) &&
git submodule update -N && git submodule update -N &&
@ -309,6 +324,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge test7 && test_must_fail git merge test7 &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) && ( yes "r" | git mergetool submod ) &&
test -d submod.orig && test -d submod.orig &&
@ -324,6 +340,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge test7 && test_must_fail git merge test7 &&
test -n "$(git ls-files -u)" && test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) && ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
( yes "" | git mergetool both>/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) && ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) && ( yes "l" | git mergetool submod ) &&
test "$(cat submod/bar)" = "master submodule" && test "$(cat submod/bar)" = "master submodule" &&
@ -445,4 +462,13 @@ test_expect_success 'directory vs modified submodule' '
git submodule update -N git submodule update -N
' '
test_expect_success 'file with no base' '
git checkout -b test13 branch1 &&
test_must_fail git merge master &&
git mergetool --no-prompt --tool mybase -- both &&
>expected &&
test_cmp both expected &&
git reset --hard master >/dev/null 2>&1
'
test_done test_done