mergetool: Use args as pathspec to unmerged files
Mergetool now treats its path arguments as a pathspec (like other git subcommands), restricting action to the given files and directories. Files matching the pathspec are filtered so mergetool only acts on unmerged paths; previously it would assume each path argument was in an unresolved state, and get confused when it couldn't check out their other stages. Running "git mergetool subdir" will prompt to resolve all conflicted blobs under subdir. Signed-off-by: Jonathon Mah <me@JonathonMah.com> Acked-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jonathon Mah committed
Sep 15, 2011 at 19:12 UTC
3e8e691abe4e1cce73a8a2ef413dada0278e7b3b
3 files changed
+72
-69
Documentation/git-mergetool.txt
+4
-3
@@ -16,9 +16,10 @@ Use `git mergetool` to run one of several merge utilities to resolve
16
merge conflicts. It is typically run after 'git merge'.
17
18
If one or more <file> parameters are given, the merge tool program will
19
-be run to resolve differences on each file. If no <file> names are
20
-specified, 'git mergetool' will run the merge tool program on every file
21
-with merge conflicts.
19
+be run to resolve differences on each file (skipping those without
20
+conflicts). Specifying a directory will include all unresolved files in
21
+that path. If no <file> names are specified, 'git mergetool' will run
22
+the merge tool program on every file with merge conflicts.
23
24
OPTIONS
25
-------
git-mergetool.sh
+28
-48
@@ -342,64 +342,44 @@ merge_keep_temporaries="$(git config --bool mergetool.keepTemporaries || echo fa
342
343
last_status=0
344
rollup_status=0
345
-rerere=false
346
-
347
-files_to_merge() {
348
- if test "$rerere" = true
349
- then
350
- git rerere remaining
351
- else
352
- git ls-files -u | sed -e 's/^[^ ]* //' | sort -u
353
- fi
354
-}
355
-
345
+files=
346
347
if test $# -eq 0 ; then
348
cd_to_toplevel
349
350
if test -e "$GIT_DIR/MERGE_RR"
351
then
362
- rerere=true
352
+ files=$(git rerere remaining)
353
+ else
354
+ files=$(git ls-files -u | sed -e 's/^[^ ]* //' | sort -u)
355
fi
356
+else
357
+ files=$(git ls-files -u -- "$@" | sed -e 's/^[^ ]* //' | sort -u)
358
+fi
359
365
- files=$(files_to_merge)
366
- if test -z "$files" ; then
367
- echo "No files need merging"
368
- exit 0
369
- fi
360
+if test -z "$files" ; then
361
+ echo "No files need merging"
362
+ exit 0
363
+fi
364
371
- # Save original stdin
372
- exec 3<&0
365
+# Save original stdin
366
+exec 3<&0
367
374
- printf "Merging:\n"
375
- printf "$files\n"
368
+printf "Merging:\n"
369
+printf "$files\n"
370
377
- files_to_merge |
378
- while IFS= read i
379
- do
380
- if test $last_status -ne 0; then
381
- prompt_after_failed_merge <&3 || exit 1
382
- fi
383
- printf "\n"
384
- merge_file "$i" <&3
385
- last_status=$?
386
- if test $last_status -ne 0; then
387
- rollup_status=1
388
- fi
389
- done
390
-else
391
- while test $# -gt 0; do
392
- if test $last_status -ne 0; then
393
- prompt_after_failed_merge || exit 1
394
- fi
395
- printf "\n"
396
- merge_file "$1"
397
- last_status=$?
398
- if test $last_status -ne 0; then
399
- rollup_status=1
400
- fi
401
- shift
402
- done
403
-fi
371
+IFS='
372
+'; for i in $files
373
+do
374
+ if test $last_status -ne 0; then
375
+ prompt_after_failed_merge <&3 || exit 1
376
+ fi
377
+ printf "\n"
378
+ merge_file "$i" <&3
379
+ last_status=$?
380
+ if test $last_status -ne 0; then
381
+ rollup_status=1
382
+ fi
383
+done
384
385
exit $rollup_status
t/t7610-mergetool.sh
+40
-18
@@ -16,6 +16,7 @@ Testing basic merge tool invocation'
16
test_expect_success 'setup' '
17
git config rerere.enabled true &&
18
echo master >file1 &&
19
+ echo master spaced >"spaced name" &&
20
echo master file11 >file11 &&
21
echo master file12 >file12 &&
22
echo master file13 >file13 &&
@@ -30,13 +31,14 @@ test_expect_success 'setup' '
31
git commit -m "Add foo"
32
) &&
33
git submodule add git://example.com/submod submod &&
33
- git add file1 file1[1-4] subdir/file3 .gitmodules submod &&
34
+ git add file1 "spaced name" file1[1-4] subdir/file3 .gitmodules submod &&
35
git commit -m "add initial versions" &&
36
37
git checkout -b branch1 master &&
38
git submodule update -N &&
39
echo branch1 change >file1 &&
40
echo branch1 newfile >file2 &&
41
+ echo branch1 spaced >"spaced name" &&
42
echo branch1 change file11 >file11 &&
43
echo branch1 change file13 >file13 &&
44
echo branch1 sub >subdir/file3 &&
@@ -47,7 +49,7 @@ test_expect_success 'setup' '
49
git commit -m "Add bar on branch1" &&
50
git checkout -b submod-branch1
51
) &&
50
- git add file1 file11 file13 file2 subdir/file3 submod &&
52
+ git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
53
git rm file12 &&
54
git commit -m "branch1 changes" &&
55
@@ -55,6 +57,7 @@ test_expect_success 'setup' '
57
git submodule update -N &&
58
echo master updated >file1 &&
59
echo master new >file2 &&
60
+ echo master updated spaced >"spaced name" &&
61
echo master updated file12 >file12 &&
62
echo master updated file14 >file14 &&
63
echo master new sub >subdir/file3 &&
@@ -65,7 +68,7 @@ test_expect_success 'setup' '
68
git commit -m "Add bar on master" &&
69
git checkout -b submod-master
70
) &&
68
- git add file1 file12 file14 file2 subdir/file3 submod &&
71
+ git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
72
git rm file11 &&
73
git commit -m "master updates" &&
74
@@ -78,8 +81,8 @@ test_expect_success 'custom mergetool' '
81
git checkout -b test1 branch1 &&
82
git submodule update -N &&
83
test_must_fail git merge master >/dev/null 2>&1 &&
81
- ( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
82
- ( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
84
+ ( yes "" | git mergetool file1 file1 ) &&
85
+ ( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
86
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
87
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
88
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@@ -97,6 +100,7 @@ test_expect_success 'mergetool crlf' '
100
test_must_fail git merge master >/dev/null 2>&1 &&
101
( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
102
( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
103
+ ( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
104
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
105
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
106
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@@ -126,7 +130,7 @@ test_expect_success 'mergetool on file in parent dir' '
130
(
131
cd subdir &&
132
( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
129
- ( yes "" | git mergetool ../file2 >/dev/null 2>&1 ) &&
133
+ ( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
134
( yes "d" | git mergetool ../file11 >/dev/null 2>&1 ) &&
135
( yes "d" | git mergetool ../file12 >/dev/null 2>&1 ) &&
136
( yes "l" | git mergetool ../submod >/dev/null 2>&1 ) &&
@@ -180,6 +184,24 @@ test_expect_success 'mergetool skips resolved paths when rerere is active' '
184
git reset --hard
185
'
186
187
+test_expect_success 'mergetool takes partial path' '
188
+ git config rerere.enabled false &&
189
+ git checkout -b test12 branch1 &&
190
+ git submodule update -N &&
191
+ test_must_fail git merge master &&
192
+
193
+ #shouldnt need these lines
194
+ #( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
195
+ #( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
196
+ #( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
197
+ #( yes "" | git mergetool file1 file2 >/dev/null 2>&1 ) &&
198
+
199
+ ( yes "" | git mergetool subdir ) &&
200
+
201
+ test "$(cat subdir/file3)" = "master new sub" &&
202
+ git reset --hard
203
+'
204
+
205
test_expect_success 'deleted vs modified submodule' '
206
git checkout -b test6 branch1 &&
207
git submodule update -N &&
@@ -189,7 +211,7 @@ test_expect_success 'deleted vs modified submodule' '
211
git checkout -b test6.a test6 &&
212
test_must_fail git merge master &&
213
test -n "$(git ls-files -u)" &&
192
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
214
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
215
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
216
( yes "r" | git mergetool submod ) &&
217
rmdir submod && mv submod-movedaside submod &&
@@ -205,7 +227,7 @@ test_expect_success 'deleted vs modified submodule' '
227
git submodule update -N &&
228
test_must_fail git merge master &&
229
test -n "$(git ls-files -u)" &&
208
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
230
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
231
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
232
( yes "l" | git mergetool submod ) &&
233
test ! -e submod &&
@@ -218,7 +240,7 @@ test_expect_success 'deleted vs modified submodule' '
240
git submodule update -N &&
241
test_must_fail git merge test6 &&
242
test -n "$(git ls-files -u)" &&
221
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
243
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
244
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
245
( yes "r" | git mergetool submod ) &&
246
test ! -e submod &&
@@ -233,7 +255,7 @@ test_expect_success 'deleted vs modified submodule' '
255
git submodule update -N &&
256
test_must_fail git merge test6 &&
257
test -n "$(git ls-files -u)" &&
236
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
258
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
259
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
260
( yes "l" | git mergetool submod ) &&
261
test "$(cat submod/bar)" = "master submodule" &&
@@ -256,7 +278,7 @@ test_expect_success 'file vs modified submodule' '
278
git checkout -b test7.a branch1 &&
279
test_must_fail git merge master &&
280
test -n "$(git ls-files -u)" &&
259
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
281
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
282
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
283
( yes "r" | git mergetool submod ) &&
284
rmdir submod && mv submod-movedaside submod &&
@@ -271,7 +293,7 @@ test_expect_success 'file vs modified submodule' '
293
git checkout -b test7.b test7 &&
294
test_must_fail git merge master &&
295
test -n "$(git ls-files -u)" &&
274
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
296
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
297
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
298
( yes "l" | git mergetool submod ) &&
299
git submodule update -N &&
@@ -286,7 +308,7 @@ test_expect_success 'file vs modified submodule' '
308
git submodule update -N &&
309
test_must_fail git merge test7 &&
310
test -n "$(git ls-files -u)" &&
289
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
311
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
312
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
313
( yes "r" | git mergetool submod ) &&
314
test -d submod.orig &&
@@ -301,7 +323,7 @@ test_expect_success 'file vs modified submodule' '
323
git submodule update -N &&
324
test_must_fail git merge test7 &&
325
test -n "$(git ls-files -u)" &&
304
- ( yes "" | git mergetool file1 file2 subdir/file3 >/dev/null 2>&1 ) &&
326
+ ( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
327
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
328
( yes "l" | git mergetool submod ) &&
329
test "$(cat submod/bar)" = "master submodule" &&
@@ -388,7 +410,7 @@ test_expect_success 'directory vs modified submodule' '
410
test "$(cat submod/file16)" = "not a submodule" &&
411
rm -rf submod.orig &&
412
391
- git reset --hard &&
413
+ git reset --hard >/dev/null 2>&1 &&
414
test_must_fail git merge master &&
415
test -n "$(git ls-files -u)" &&
416
test ! -e submod.orig &&
@@ -400,7 +422,7 @@ test_expect_success 'directory vs modified submodule' '
422
( cd submod && git clean -f && git reset --hard ) &&
423
git submodule update -N &&
424
test "$(cat submod/bar)" = "master submodule" &&
403
- git reset --hard && rm -rf submod-movedaside &&
425
+ git reset --hard >/dev/null 2>&1 && rm -rf submod-movedaside &&
426
427
git checkout -b test11.c master &&
428
git submodule update -N &&
@@ -410,7 +432,7 @@ test_expect_success 'directory vs modified submodule' '
432
git submodule update -N &&
433
test "$(cat submod/bar)" = "master submodule" &&
434
413
- git reset --hard &&
435
+ git reset --hard >/dev/null 2>&1 &&
436
git submodule update -N &&
437
test_must_fail git merge test11 &&
438
test -n "$(git ls-files -u)" &&
@@ -418,7 +440,7 @@ test_expect_success 'directory vs modified submodule' '
440
( yes "r" | git mergetool submod ) &&
441
test "$(cat submod/file16)" = "not a submodule" &&
442
421
- git reset --hard master &&
443
+ git reset --hard master >/dev/null 2>&1 &&
444
( cd submod && git clean -f && git reset --hard ) &&
445
git submodule update -N
446
'