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>

David Aguilar committed Jan 19, 2012 at 23:47 UTC ec245ba04944473ba6657a826643ef90ed02b51d
2 files changed +35 -5
git-mergetool.sh
+8 -4
@@ -181,10 +181,14 @@ stage_submodule () {
181 }
182
183 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 + : '\([^ ]*\) ')
187
188 if test $? -eq 0 -a -n "$tmpfile" ; then
189 mv -- "$(git rev-parse --show-cdup)$tmpfile" "$3"
190 + else
191 + >"$3"
192 fi
193 }
194
@@ -224,9 +228,9 @@ merge_file () {
228 mv -- "$MERGED" "$BACKUP"
229 cp -- "$BACKUP" "$MERGED"
230
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"
234
235 if test -z "$local_mode" -o -z "$remote_mode"; then
236 echo "Deleted merge conflict for '$MERGED':"
t/t7610-mergetool.sh
+27 -1
@@ -39,6 +39,7 @@ test_expect_success 'setup' '
39 echo branch1 change >file1 &&
40 echo branch1 newfile >file2 &&
41 echo branch1 spaced >"spaced name" &&
42 + echo branch1 both added >both &&
43 echo branch1 change file11 >file11 &&
44 echo branch1 change file13 >file13 &&
45 echo branch1 sub >subdir/file3 &&
@@ -50,6 +51,7 @@ test_expect_success 'setup' '
51 git checkout -b submod-branch1
52 ) &&
53 git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
54 + git add both &&
55 git rm file12 &&
56 git commit -m "branch1 changes" &&
57
@@ -58,6 +60,7 @@ test_expect_success 'setup' '
60 echo master updated >file1 &&
61 echo master new >file2 &&
62 echo master updated spaced >"spaced name" &&
63 + echo master both added >both &&
64 echo master updated file12 >file12 &&
65 echo master updated file14 >file14 &&
66 echo master new sub >subdir/file3 &&
@@ -69,18 +72,22 @@ test_expect_success 'setup' '
72 git checkout -b submod-master
73 ) &&
74 git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
75 + git add both &&
76 git rm file11 &&
77 git commit -m "master updates" &&
78
79 git config merge.tool mytool &&
80 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
84 '
85
86 test_expect_success 'custom mergetool' '
87 git checkout -b test1 branch1 &&
88 git submodule update -N &&
89 test_must_fail git merge master >/dev/null 2>&1 &&
90 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
91 ( yes "" | git mergetool file1 file1 ) &&
92 ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
93 ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
@@ -101,6 +108,7 @@ test_expect_success 'mergetool crlf' '
108 ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
109 ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
110 ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
111 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
112 ( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
113 ( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
114 ( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@@ -131,6 +139,7 @@ test_expect_success 'mergetool on file in parent dir' '
139 cd subdir &&
140 ( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
141 ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
142 + ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
143 ( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
144 ( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
145 ( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
@@ -212,6 +221,7 @@ test_expect_success 'deleted vs modified submodule' '
221 test_must_fail git merge master &&
222 test -n "$(git ls-files -u)" &&
223 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
224 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
225 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
226 ( yes "r" | git mergetool submod ) &&
227 rmdir submod && mv submod-movedaside submod &&
@@ -228,6 +238,7 @@ test_expect_success 'deleted vs modified submodule' '
238 test_must_fail git merge master &&
239 test -n "$(git ls-files -u)" &&
240 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
241 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
242 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
243 ( yes "l" | git mergetool submod ) &&
244 test ! -e submod &&
@@ -241,6 +252,7 @@ test_expect_success 'deleted vs modified submodule' '
252 test_must_fail git merge test6 &&
253 test -n "$(git ls-files -u)" &&
254 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
255 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
256 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
257 ( yes "r" | git mergetool submod ) &&
258 test ! -e submod &&
@@ -256,6 +268,7 @@ test_expect_success 'deleted vs modified submodule' '
268 test_must_fail git merge test6 &&
269 test -n "$(git ls-files -u)" &&
270 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
271 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
272 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
273 ( yes "l" | git mergetool submod ) &&
274 test "$(cat submod/bar)" = "master submodule" &&
@@ -279,6 +292,7 @@ test_expect_success 'file vs modified submodule' '
292 test_must_fail git merge master &&
293 test -n "$(git ls-files -u)" &&
294 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
295 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
296 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
297 ( yes "r" | git mergetool submod ) &&
298 rmdir submod && mv submod-movedaside submod &&
@@ -294,6 +308,7 @@ test_expect_success 'file vs modified submodule' '
308 test_must_fail git merge master &&
309 test -n "$(git ls-files -u)" &&
310 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
311 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
312 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
313 ( yes "l" | git mergetool submod ) &&
314 git submodule update -N &&
@@ -309,6 +324,7 @@ test_expect_success 'file vs modified submodule' '
324 test_must_fail git merge test7 &&
325 test -n "$(git ls-files -u)" &&
326 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
327 + ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
328 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
329 ( yes "r" | git mergetool submod ) &&
330 test -d submod.orig &&
@@ -324,6 +340,7 @@ test_expect_success 'file vs modified submodule' '
340 test_must_fail git merge test7 &&
341 test -n "$(git ls-files -u)" &&
342 ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
343 + ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
344 ( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
345 ( yes "l" | git mergetool submod ) &&
346 test "$(cat submod/bar)" = "master submodule" &&
@@ -445,4 +462,13 @@ test_expect_success 'directory vs modified submodule' '
462 git submodule update -N
463 '
464
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 +
474 test_done