@matheusbsbs / matheus-bagliano / commits / eac5a40151
Fork 0

checkout --conflict=<style>: recreate merge in a non-default style

This new option does essentially the same thing as -m option when checking unmerged paths out of the index, but it uses the specified style instead of configured merge.conflictstyle. Setting "merge.conflictstyle" to "diff3" is usually less useful than using the default "merge" style, because the latter allows a conflict that results by both sides changing the same region in a very similar way to get simplified substancially by reducing the common lines. However, when one side removed a group of lines (perhaps a function was moved to some other file) while the other side modified it, the default "merge" style does not give any clue as to why the hunk is left conflicting. You would need the original to understand what is going on. The recommended use would be not to set merge.conflictstyle variable so that you would usually use the default "merge" style conflict, and when the result in a path in a particular merge is too hard to understand, use "git checkout --conflict=diff3 $path" to check it out with the original to review what is going on. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Aug 31, 2008 at 19:32 UTC eac5a401512181cd315a1031af2b8a25430e335a
3 files changed +72 -48
Documentation/git-checkout.txt
+9 -1
@@ -9,7 +9,7 @@ SYNOPSIS
9 --------
10 [verse]
11 'git checkout' [-q] [-f] [[--track | --no-track] -b <new_branch> [-l]] [-m] [<branch>]
12 -'git checkout' [-f|--ours|--theirs|-m] [<tree-ish>] [--] <paths>...
12 +'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
13
14 DESCRIPTION
15 -----------
@@ -84,6 +84,7 @@ entries; instead, unmerged entries are ignored.
84 based sha1 expressions such as "<branchname>@\{yesterday}".
85
86 -m::
87 +--merge::
88 When switching branches,
89 if you have local modifications to one or more files that
90 are different between the current branch and the branch to
@@ -101,6 +102,13 @@ should result in deletion of the path).
102 When checking out paths from the index, this option lets you recreate
103 the conflicted merge in the specified paths.
104
105 +--conflict=<style>::
106 + The same as --merge option above, but changes the way the
107 + conflicting hunks are presented, overriding the
108 + merge.conflictstyle configuration variable. Possible values are
109 + "merge" (default) and "diff3" (in addition to what is shown by
110 + "merge" style, shows the original contents).
111 +
112 <new_branch>::
113 Name for the new branch.
114
builtin-checkout.c
+9 -1
@@ -580,6 +580,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
580 const char *arg;
581 struct branch_info new;
582 struct tree *source_tree = NULL;
583 + char *conflict_style = NULL;
584 struct option options[] = {
585 OPT__QUIET(&opts.quiet),
586 OPT_STRING('b', NULL, &opts.new_branch, "new branch", "branch"),
@@ -591,7 +592,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
592 OPT_SET_INT('3', "theirs", &opts.writeout_stage, "stage",
593 3),
594 OPT_BOOLEAN('f', NULL, &opts.force, "force"),
594 - OPT_BOOLEAN('m', NULL, &opts.merge, "merge"),
595 + OPT_BOOLEAN('m', "merge", &opts.merge, "merge"),
596 + OPT_STRING(0, "conflict", &conflict_style, "style",
597 + "conflict style (merge or diff3)"),
598 OPT_END(),
599 };
600 int has_dash_dash;
@@ -606,6 +609,11 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
609 argc = parse_options(argc, argv, options, checkout_usage,
610 PARSE_OPT_KEEP_DASHDASH);
611
612 + if (conflict_style) {
613 + opts.merge = 1; /* implied */
614 + git_xmerge_config("merge.conflictstyle", conflict_style, NULL);
615 + }
616 +
617 if (!opts.new_branch && (opts.track != git_branch_track))
618 die("git checkout: --track and --no-track require -b");
619
t/t7201-co.sh
+54 -46
@@ -337,7 +337,7 @@ test_expect_success \
337 test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
338 test_must_fail git checkout --track -b track'
339
340 -test_expect_success 'checkout an unmerged path should fail' '
340 +setup_conflicting_index () {
341 rm -f .git/index &&
342 O=$(echo original | git hash-object -w --stdin) &&
343 A=$(echo ourside | git hash-object -w --stdin) &&
@@ -348,7 +348,11 @@ test_expect_success 'checkout an unmerged path should fail' '
348 echo "100644 $A 2 file" &&
349 echo "100644 $B 3 file" &&
350 echo "100644 $A 0 filf"
351 - ) | git update-index --index-info &&
351 + ) | git update-index --index-info
352 +}
353 +
354 +test_expect_success 'checkout an unmerged path should fail' '
355 + setup_conflicting_index &&
356 echo "none of the above" >sample &&
357 cat sample >fild &&
358 cat sample >file &&
@@ -360,17 +364,7 @@ test_expect_success 'checkout an unmerged path should fail' '
364 '
365
366 test_expect_success 'checkout with an unmerged path can be ignored' '
363 - rm -f .git/index &&
364 - O=$(echo original | git hash-object -w --stdin) &&
365 - A=$(echo ourside | git hash-object -w --stdin) &&
366 - B=$(echo theirside | git hash-object -w --stdin) &&
367 - (
368 - echo "100644 $A 0 fild" &&
369 - echo "100644 $O 1 file" &&
370 - echo "100644 $A 2 file" &&
371 - echo "100644 $B 3 file" &&
372 - echo "100644 $A 0 filf"
373 - ) | git update-index --index-info &&
367 + setup_conflicting_index &&
368 echo "none of the above" >sample &&
369 echo ourside >expect &&
370 cat sample >fild &&
@@ -383,17 +377,7 @@ test_expect_success 'checkout with an unmerged path can be ignored' '
377 '
378
379 test_expect_success 'checkout unmerged stage' '
386 - rm -f .git/index &&
387 - O=$(echo original | git hash-object -w --stdin) &&
388 - A=$(echo ourside | git hash-object -w --stdin) &&
389 - B=$(echo theirside | git hash-object -w --stdin) &&
390 - (
391 - echo "100644 $A 0 fild" &&
392 - echo "100644 $O 1 file" &&
393 - echo "100644 $A 2 file" &&
394 - echo "100644 $B 3 file" &&
395 - echo "100644 $A 0 filf"
396 - ) | git update-index --index-info &&
380 + setup_conflicting_index &&
381 echo "none of the above" >sample &&
382 echo ourside >expect &&
383 cat sample >fild &&
@@ -408,17 +392,7 @@ test_expect_success 'checkout unmerged stage' '
392 '
393
394 test_expect_success 'checkout with --merge' '
411 - rm -f .git/index &&
412 - O=$(echo original | git hash-object -w --stdin) &&
413 - A=$(echo ourside | git hash-object -w --stdin) &&
414 - B=$(echo theirside | git hash-object -w --stdin) &&
415 - (
416 - echo "100644 $A 0 fild" &&
417 - echo "100644 $O 1 file" &&
418 - echo "100644 $A 2 file" &&
419 - echo "100644 $B 3 file" &&
420 - echo "100644 $A 0 filf"
421 - ) | git update-index --index-info &&
395 + setup_conflicting_index &&
396 echo "none of the above" >sample &&
397 echo ourside >expect &&
398 cat sample >fild &&
@@ -439,17 +413,7 @@ test_expect_success 'checkout with --merge' '
413
414 test_expect_success 'checkout with --merge, in diff3 -m style' '
415 git config merge.conflictstyle diff3 &&
442 - rm -f .git/index &&
443 - O=$(echo original | git hash-object -w --stdin) &&
444 - A=$(echo ourside | git hash-object -w --stdin) &&
445 - B=$(echo theirside | git hash-object -w --stdin) &&
446 - (
447 - echo "100644 $A 0 fild" &&
448 - echo "100644 $O 1 file" &&
449 - echo "100644 $A 2 file" &&
450 - echo "100644 $B 3 file" &&
451 - echo "100644 $A 0 filf"
452 - ) | git update-index --index-info &&
416 + setup_conflicting_index &&
417 echo "none of the above" >sample &&
418 echo ourside >expect &&
419 cat sample >fild &&
@@ -470,4 +434,48 @@ test_expect_success 'checkout with --merge, in diff3 -m style' '
434 test_cmp merged file
435 '
436
437 +test_expect_success 'checkout --conflict=merge, overriding config' '
438 + git config merge.conflictstyle diff3 &&
439 + setup_conflicting_index &&
440 + echo "none of the above" >sample &&
441 + echo ourside >expect &&
442 + cat sample >fild &&
443 + cat sample >file &&
444 + cat sample >filf &&
445 + git checkout --conflict=merge -- fild file filf &&
446 + (
447 + echo "<<<<<<< ours"
448 + echo ourside
449 + echo "======="
450 + echo theirside
451 + echo ">>>>>>> theirs"
452 + ) >merged &&
453 + test_cmp expect fild &&
454 + test_cmp expect filf &&
455 + test_cmp merged file
456 +'
457 +
458 +test_expect_success 'checkout --conflict=diff3' '
459 + git config --unset merge.conflictstyle
460 + setup_conflicting_index &&
461 + echo "none of the above" >sample &&
462 + echo ourside >expect &&
463 + cat sample >fild &&
464 + cat sample >file &&
465 + cat sample >filf &&
466 + git checkout --conflict=diff3 -- fild file filf &&
467 + (
468 + echo "<<<<<<< ours"
469 + echo ourside
470 + echo "|||||||"
471 + echo original
472 + echo "======="
473 + echo theirside
474 + echo ">>>>>>> theirs"
475 + ) >merged &&
476 + test_cmp expect fild &&
477 + test_cmp expect filf &&
478 + test_cmp merged file
479 +'
480 +
481 test_done