Skip to content

Commit ec245ba

Browse files
davvidgitster
authored andcommitted
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 <[email protected]> Signed-off-by: David Aguilar <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5fbdb9c commit ec245ba

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

git-mergetool.sh

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,14 @@ stage_submodule () {
181181
}
182182

183183
checkout_staged_file () {
184-
tmpfile=$(expr "$(git checkout-index --temp --stage="$1" "$2")" : '\([^ ]*\) ')
184+
tmpfile=$(expr \
185+
"$(git checkout-index --temp --stage="$1" "$2" 2>/dev/null)" \
186+
: '\([^ ]*\) ')
185187

186188
if test $? -eq 0 -a -n "$tmpfile" ; then
187189
mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
190+
else
191+
>"$3"
188192
fi
189193
}
190194

@@ -224,9 +228,9 @@ merge_file () {
224228
mv -- "$MERGED" "$BACKUP"
225229
cp -- "$BACKUP" "$MERGED"
226230

227-
base_present && checkout_staged_file 1 "$MERGED" "$BASE"
228-
local_present && checkout_staged_file 2 "$MERGED" "$LOCAL"
229-
remote_present && checkout_staged_file 3 "$MERGED" "$REMOTE"
231+
checkout_staged_file 1 "$MERGED" "$BASE"
232+
checkout_staged_file 2 "$MERGED" "$LOCAL"
233+
checkout_staged_file 3 "$MERGED" "$REMOTE"
230234

231235
if test -z "$local_mode" -o -z "$remote_mode"; then
232236
echo "Deleted merge conflict for '$MERGED':"

t/t7610-mergetool.sh

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ test_expect_success 'setup' '
3939
echo branch1 change >file1 &&
4040
echo branch1 newfile >file2 &&
4141
echo branch1 spaced >"spaced name" &&
42+
echo branch1 both added >both &&
4243
echo branch1 change file11 >file11 &&
4344
echo branch1 change file13 >file13 &&
4445
echo branch1 sub >subdir/file3 &&
@@ -50,6 +51,7 @@ test_expect_success 'setup' '
5051
git checkout -b submod-branch1
5152
) &&
5253
git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
54+
git add both &&
5355
git rm file12 &&
5456
git commit -m "branch1 changes" &&
5557
@@ -58,6 +60,7 @@ test_expect_success 'setup' '
5860
echo master updated >file1 &&
5961
echo master new >file2 &&
6062
echo master updated spaced >"spaced name" &&
63+
echo master both added >both &&
6164
echo master updated file12 >file12 &&
6265
echo master updated file14 >file14 &&
6366
echo master new sub >subdir/file3 &&
@@ -69,18 +72,22 @@ test_expect_success 'setup' '
6972
git checkout -b submod-master
7073
) &&
7174
git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
75+
git add both &&
7276
git rm file11 &&
7377
git commit -m "master updates" &&
7478
7579
git config merge.tool mytool &&
7680
git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
77-
git config mergetool.mytool.trustExitCode true
81+
git config mergetool.mytool.trustExitCode true &&
82+
git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
83+
git config mergetool.mybase.trustExitCode true
7884
'
7985

8086
test_expect_success 'custom mergetool' '
8187
git checkout -b test1 branch1 &&
8288
git submodule update -N &&
8389
test_must_fail git merge master >/dev/null 2>&1 &&
90+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
8491
( yes "" | git mergetool file1 file1 ) &&
8592
( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
8693
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
@@ -101,6 +108,7 @@ test_expect_success 'mergetool crlf' '
101108
( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
102109
( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
103110
( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
111+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
104112
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
105113
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
106114
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@@ -131,6 +139,7 @@ test_expect_success 'mergetool on file in parent dir' '
131139
cd subdir &&
132140
( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
133141
( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
142+
( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
134143
( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
135144
( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
136145
( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
@@ -212,6 +221,7 @@ test_expect_success 'deleted vs modified submodule' '
212221
test_must_fail git merge master &&
213222
test -n "$(git ls-files -u)" &&
214223
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
224+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
215225
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
216226
( yes "r" | git mergetool submod ) &&
217227
rmdir submod && mv submod-movedaside submod &&
@@ -228,6 +238,7 @@ test_expect_success 'deleted vs modified submodule' '
228238
test_must_fail git merge master &&
229239
test -n "$(git ls-files -u)" &&
230240
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
241+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
231242
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
232243
( yes "l" | git mergetool submod ) &&
233244
test ! -e submod &&
@@ -241,6 +252,7 @@ test_expect_success 'deleted vs modified submodule' '
241252
test_must_fail git merge test6 &&
242253
test -n "$(git ls-files -u)" &&
243254
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
255+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
244256
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
245257
( yes "r" | git mergetool submod ) &&
246258
test ! -e submod &&
@@ -256,6 +268,7 @@ test_expect_success 'deleted vs modified submodule' '
256268
test_must_fail git merge test6 &&
257269
test -n "$(git ls-files -u)" &&
258270
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
271+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
259272
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
260273
( yes "l" | git mergetool submod ) &&
261274
test "$(cat submod/bar)" = "master submodule" &&
@@ -279,6 +292,7 @@ test_expect_success 'file vs modified submodule' '
279292
test_must_fail git merge master &&
280293
test -n "$(git ls-files -u)" &&
281294
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
295+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
282296
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
283297
( yes "r" | git mergetool submod ) &&
284298
rmdir submod && mv submod-movedaside submod &&
@@ -294,6 +308,7 @@ test_expect_success 'file vs modified submodule' '
294308
test_must_fail git merge master &&
295309
test -n "$(git ls-files -u)" &&
296310
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
311+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
297312
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
298313
( yes "l" | git mergetool submod ) &&
299314
git submodule update -N &&
@@ -309,6 +324,7 @@ test_expect_success 'file vs modified submodule' '
309324
test_must_fail git merge test7 &&
310325
test -n "$(git ls-files -u)" &&
311326
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
327+
( yes "" | git mergetool both >/dev/null 2>&1 ) &&
312328
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
313329
( yes "r" | git mergetool submod ) &&
314330
test -d submod.orig &&
@@ -324,6 +340,7 @@ test_expect_success 'file vs modified submodule' '
324340
test_must_fail git merge test7 &&
325341
test -n "$(git ls-files -u)" &&
326342
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
343+
( yes "" | git mergetool both>/dev/null 2>&1 ) &&
327344
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
328345
( yes "l" | git mergetool submod ) &&
329346
test "$(cat submod/bar)" = "master submodule" &&
@@ -445,4 +462,13 @@ test_expect_success 'directory vs modified submodule' '
445462
git submodule update -N
446463
'
447464

465+
test_expect_success 'file with no base' '
466+
git checkout -b test13 branch1 &&
467+
test_must_fail git merge master &&
468+
git mergetool --no-prompt --tool mybase -- both &&
469+
>expected &&
470+
test_cmp both expected &&
471+
git reset --hard master >/dev/null 2>&1
472+
'
473+
448474
test_done

0 commit comments

Comments
 (0)