Merge branch 'ma/fast-export-skip-merge-fix'
authorJunio C Hamano <gitster@pobox.com>
Tue, 8 May 2018 06:59:33 +0000 (15:59 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 8 May 2018 06:59:33 +0000 (15:59 +0900)
"git fast-export" had a regression in v2.15.0 era where it skipped
some merge commits in certain cases, which has been corrected.

* ma/fast-export-skip-merge-fix:
  fast-export: fix regression skipping some merge-commits

1  2 
builtin/fast-export.c
t/t9350-fast-export.sh

diff --combined builtin/fast-export.c
@@@ -237,10 -237,10 +237,10 @@@ static void export_blob(const struct ob
                object = (struct object *)lookup_blob(oid);
                eaten = 0;
        } else {
 -              buf = read_sha1_file(oid->hash, &type, &size);
 +              buf = read_object_file(oid, &type, &size);
                if (!buf)
                        die ("Could not read blob %s", oid_to_hex(oid));
 -              if (check_sha1_signature(oid->hash, buf, size, typename(type)) < 0)
 +              if (check_object_signature(oid, buf, size, type_name(type)) < 0)
                        die("sha1 mismatch in blob %s", oid_to_hex(oid));
                object = parse_object_buffer(oid, type, size, buf, &eaten);
        }
@@@ -651,8 -651,11 +651,11 @@@ static void handle_tail(struct object_a
        struct commit *commit;
        while (commits->nr) {
                commit = (struct commit *)object_array_pop(commits);
-               if (has_unshown_parent(commit))
+               if (has_unshown_parent(commit)) {
+                       /* Queue again, to be handled later */
+                       add_object_array(&commit->object, NULL, commits);
                        return;
+               }
                handle_commit(commit, revs, paths_of_changed_objects);
        }
  }
@@@ -682,7 -685,7 +685,7 @@@ static void handle_tag(const char *name
                return;
        }
  
 -      buf = read_sha1_file(tag->object.oid.hash, &type, &size);
 +      buf = read_object_file(&tag->object.oid, &type, &size);
        if (!buf)
                die ("Could not read tag %s", oid_to_hex(&tag->object.oid));
        message = memmem(buf, size, "\n\n", 2);
                        if (tagged->type != OBJ_COMMIT) {
                                die ("Tag %s tags unexported %s!",
                                     oid_to_hex(&tag->object.oid),
 -                                   typename(tagged->type));
 +                                   type_name(tagged->type));
                        }
                        p = (struct commit *)tagged;
                        for (;;) {
@@@ -839,7 -842,7 +842,7 @@@ static void get_tags_and_duplicates(str
                if (!commit) {
                        warning("%s: Unexpected object of type %s, skipping.",
                                e->name,
 -                              typename(e->item->type));
 +                              type_name(e->item->type));
                        continue;
                }
  
                        continue;
                default: /* OBJ_TAG (nested tags) is already handled */
                        warning("Tag points to object of unexpected type %s, skipping.",
 -                              typename(commit->object.type));
 +                              type_name(commit->object.type));
                        continue;
                }
  
@@@ -947,7 -950,7 +950,7 @@@ static void import_marks(char *input_fi
                if (last_idnum < mark)
                        last_idnum = mark;
  
 -              type = sha1_object_info(oid.hash, NULL);
 +              type = oid_object_info(&oid, NULL);
                if (type < 0)
                        die("object not found: %s", oid_to_hex(&oid));
  
diff --combined t/t9350-fast-export.sh
@@@ -43,20 -43,20 +43,20 @@@ test_expect_success 'fast-export | fast
        MUSS=$(git rev-parse --verify muss) &&
        mkdir new &&
        git --git-dir=new/.git init &&
 -      git fast-export --all |
 +      git fast-export --all >actual &&
        (cd new &&
         git fast-import &&
         test $MASTER = $(git rev-parse --verify refs/heads/master) &&
         test $REIN = $(git rev-parse --verify refs/tags/rein) &&
         test $WER = $(git rev-parse --verify refs/heads/wer) &&
 -       test $MUSS = $(git rev-parse --verify refs/tags/muss))
 +       test $MUSS = $(git rev-parse --verify refs/tags/muss)) <actual
  
  '
  
  test_expect_success 'fast-export master~2..master' '
  
 -      git fast-export master~2..master |
 -              sed "s/master/partial/" |
 +      git fast-export master~2..master >actual &&
 +      sed "s/master/partial/" actual |
                (cd new &&
                 git fast-import &&
                 test $MASTER != $(git rev-parse --verify refs/heads/partial) &&
@@@ -74,12 -74,11 +74,12 @@@ test_expect_success 'iso-8859-1' 
        test_tick &&
        echo rosten >file &&
        git commit -s -m den file &&
 -      git fast-export wer^..wer |
 -              sed "s/wer/i18n/" |
 +      git fast-export wer^..wer >iso8859-1.fi &&
 +      sed "s/wer/i18n/" iso8859-1.fi |
                (cd new &&
                 git fast-import &&
 -               git cat-file commit i18n | grep "Áéí óú")
 +               git cat-file commit i18n >actual &&
 +               grep "Áéí óú" actual)
  
  '
  test_expect_success 'import/export-marks' '
        git fast-export --export-marks=tmp-marks HEAD &&
        test -s tmp-marks &&
        test_line_count = 3 tmp-marks &&
 -      test $(
 -              git fast-export --import-marks=tmp-marks\
 -              --export-marks=tmp-marks HEAD |
 -              grep ^commit |
 -              wc -l) \
 -      -eq 0 &&
 +      git fast-export --import-marks=tmp-marks \
 +              --export-marks=tmp-marks HEAD >actual &&
 +      test $(grep ^commit actual | wc -l) -eq 0 &&
        echo change > file &&
        git commit -m "last commit" file &&
 -      test $(
 -              git fast-export --import-marks=tmp-marks \
 -              --export-marks=tmp-marks HEAD |
 -              grep ^commit\  |
 -              wc -l) \
 -      -eq 1 &&
 +      git fast-export --import-marks=tmp-marks \
 +              --export-marks=tmp-marks HEAD >actual &&
 +      test $(grep ^commit\  actual | wc -l) -eq 1 &&
        test_line_count = 4 tmp-marks
  
  '
@@@ -179,7 -184,7 +179,7 @@@ test_expect_success 'submodule fast-exp
        rm -rf new &&
        mkdir new &&
        git --git-dir=new/.git init &&
 -      git fast-export --signed-tags=strip --all |
 +      git fast-export --signed-tags=strip --all >actual &&
        (cd new &&
         git fast-import &&
         test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" &&
         git checkout master &&
         git submodule init &&
         git submodule update &&
 -       cmp sub/file ../sub/file)
 +       cmp sub/file ../sub/file) <actual
  
  '
  
@@@ -362,14 -367,12 +362,14 @@@ test_expect_success 'path limiting wit
        echo more content >> file &&
        test_tick &&
        git commit -mnext file &&
 -      git fast-export --import-marks=marks simple -- file file0 | grep file0
 +      git fast-export --import-marks=marks simple -- file file0 >actual &&
 +      grep file0 actual
  '
  
  test_expect_success 'full-tree re-shows unmodified files'        '
        git checkout -f simple &&
 -      test $(git fast-export --full-tree simple | grep -c file0) -eq 3
 +      git fast-export --full-tree simple >actual &&
 +      test $(grep -c file0 actual) -eq 3
  '
  
  test_expect_success 'set-up a few more tags for tag export tests' '
@@@ -502,8 -505,8 +502,8 @@@ test_expect_success 'refs are updated e
  '
  
  test_expect_success 'use refspec' '
 -      git fast-export --refspec refs/heads/master:refs/heads/foobar master | \
 -              grep "^commit " | sort | uniq > actual &&
 +      git fast-export --refspec refs/heads/master:refs/heads/foobar master >actual2 &&
 +      grep "^commit " actual2 | sort | uniq >actual &&
        echo "commit refs/heads/foobar" > expected &&
        test_cmp expected actual
  '
@@@ -531,11 -534,28 +531,29 @@@ test_expect_success 'when using -C, do 
        git -C src commit -m 2nd_commit &&
  
        test_create_repo dst &&
 -      git -C src fast-export --all -C | git -C dst fast-import &&
 +      git -C src fast-export --all -C >actual &&
 +      git -C dst fast-import <actual &&
        git -C src show >expected &&
        git -C dst show >actual &&
        test_cmp expected actual
  '
  
+ test_expect_success 'merge commit gets exported with --import-marks' '
+       test_create_repo merging &&
+       (
+               cd merging &&
+               test_commit initial &&
+               git checkout -b topic &&
+               test_commit on-topic &&
+               git checkout master &&
+               test_commit on-master &&
+               test_tick &&
+               git merge --no-ff -m Yeah topic &&
+               echo ":1 $(git rev-parse HEAD^^)" >marks &&
+               git fast-export --import-marks=marks master >out &&
+               grep Yeah out
+       )
+ '
  test_done