Merge branch 'jk/merge-file-exit-code'
authorJunio C Hamano <gitster@pobox.com>
Fri, 30 Oct 2015 20:07:08 +0000 (13:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 30 Oct 2015 20:07:08 +0000 (13:07 -0700)
"git merge-file" tried to signal how many conflicts it found, which
obviously would not work well when there are too many of them.

* jk/merge-file-exit-code:
merge-file: clamp exit code to maximum 127

1  2 
builtin/merge-file.c
t/t7600-merge.sh
diff --combined builtin/merge-file.c
index 50d0bc873bee47ea6d1ab3b8e303e0a779465825,ab4330a3d0b0099c37acf12dbb3d02bd06b74287..55447053f2dde004ceffff9967b015b4a01c35d1
@@@ -5,7 -5,7 +5,7 @@@
  #include "parse-options.h"
  
  static const char *const merge_file_usage[] = {
 -      N_("git merge-file [options] [-L name1 [-L orig [-L name2]]] file1 orig_file file2"),
 +      N_("git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> <orig-file> <file2>"),
        NULL
  };
  
@@@ -42,7 -42,7 +42,7 @@@ int cmd_merge_file(int argc, const cha
                            N_("for conflicts, use this marker size")),
                OPT__QUIET(&quiet, N_("do not warn about conflicts")),
                OPT_CALLBACK('L', NULL, names, N_("name"),
 -                           N_("set labels for file1/orig_file/file2"), &label_cb),
 +                           N_("set labels for file1/orig-file/file2"), &label_cb),
                OPT_END(),
        };
  
@@@ -75,8 -75,7 +75,8 @@@
                        names[i] = argv[i];
                if (read_mmfile(mmfs + i, fname))
                        return -1;
 -              if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
 +              if (mmfs[i].size > MAX_XDIFF_SIZE ||
 +                  buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
                        return error("Cannot merge binary files: %s",
                                        argv[i]);
        }
@@@ -91,8 -90,7 +91,8 @@@
  
        if (ret >= 0) {
                const char *filename = argv[0];
 -              FILE *f = to_stdout ? stdout : fopen(filename, "wb");
 +              const char *fpath = prefix_filename(prefix, prefixlen, argv[0]);
 +              FILE *f = to_stdout ? stdout : fopen(fpath, "wb");
  
                if (!f)
                        ret = error("Could not open %s for writing", filename);
                free(result.ptr);
        }
  
+       if (ret > 127)
+               ret = 127;
        return ret;
  }
diff --combined t/t7600-merge.sh
index 75c50eea15e54995364fb8c81d0760446175f46e,ede496c76b3a1cd4e8d3bb7a0235b2bd1094df7a..302e23826341bce6c3797330b5f2996877dc5baf
@@@ -133,7 -133,7 +133,7 @@@ test_expect_success 'setup' 
        test_tick &&
        git commit -m "commit 3" &&
        git tag c3 &&
 -      c3=$(git rev-parse HEAD)
 +      c3=$(git rev-parse HEAD) &&
        git reset --hard "$c0" &&
        create_merge_msgs
  '
@@@ -692,4 -692,37 +692,37 @@@ test_expect_success GPG 'merge --no-edi
        test_cmp actual expect
  '
  
+ test_expect_success 'set up mod-256 conflict scenario' '
+       # 256 near-identical stanzas...
+       for i in $(test_seq 1 256); do
+               for j in 1 2 3 4 5; do
+                       echo $i-$j
+               done
+       done >file &&
+       git add file &&
+       git commit -m base &&
+       # one side changes the first line of each to "master"
+       sed s/-1/-master/ <file >tmp &&
+       mv tmp file &&
+       git commit -am master &&
+       # and the other to "side"; merging the two will
+       # yield 256 separate conflicts
+       git checkout -b side HEAD^ &&
+       sed s/-1/-side/ <file >tmp &&
+       mv tmp file &&
+       git commit -am side
+ '
+ test_expect_success 'merge detects mod-256 conflicts (recursive)' '
+       git reset --hard &&
+       test_must_fail git merge -s recursive master
+ '
+ test_expect_success 'merge detects mod-256 conflicts (resolve)' '
+       git reset --hard &&
+       test_must_fail git merge -s resolve master
+ '
  test_done