d7d73061d0d95ef667753ca6f7be9a82c56ac779
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Johannes E. Schindelin
   4#
   5
   6test_description='git fast-export'
   7. ./test-lib.sh
   8
   9test_expect_success 'setup' '
  10
  11        echo break it > file0 &&
  12        git add file0 &&
  13        test_tick &&
  14        echo Wohlauf > file &&
  15        git add file &&
  16        test_tick &&
  17        git commit -m initial &&
  18        echo die Luft > file &&
  19        echo geht frisch > file2 &&
  20        git add file file2 &&
  21        test_tick &&
  22        git commit -m second &&
  23        echo und > file2 &&
  24        test_tick &&
  25        git commit -m third file2 &&
  26        test_tick &&
  27        git tag rein &&
  28        git checkout -b wer HEAD^ &&
  29        echo lange > file2 &&
  30        test_tick &&
  31        git commit -m sitzt file2 &&
  32        test_tick &&
  33        git tag -a -m valentin muss &&
  34        git merge -s ours master
  35
  36'
  37
  38test_expect_success 'fast-export | fast-import' '
  39
  40        MASTER=$(git rev-parse --verify master) &&
  41        REIN=$(git rev-parse --verify rein) &&
  42        WER=$(git rev-parse --verify wer) &&
  43        MUSS=$(git rev-parse --verify muss) &&
  44        mkdir new &&
  45        git --git-dir=new/.git init &&
  46        git fast-export --all >actual &&
  47        (cd new &&
  48         git fast-import &&
  49         test $MASTER = $(git rev-parse --verify refs/heads/master) &&
  50         test $REIN = $(git rev-parse --verify refs/tags/rein) &&
  51         test $WER = $(git rev-parse --verify refs/heads/wer) &&
  52         test $MUSS = $(git rev-parse --verify refs/tags/muss)) <actual
  53
  54'
  55
  56test_expect_success 'fast-export master~2..master' '
  57
  58        git fast-export master~2..master >actual &&
  59        sed "s/master/partial/" actual |
  60                (cd new &&
  61                 git fast-import &&
  62                 test $MASTER != $(git rev-parse --verify refs/heads/partial) &&
  63                 git diff --exit-code master partial &&
  64                 git diff --exit-code master^ partial^ &&
  65                 test_must_fail git rev-parse partial~2)
  66
  67'
  68
  69test_expect_success 'fast-export --reference-excluded-parents master~2..master' '
  70
  71        git fast-export --reference-excluded-parents master~2..master >actual &&
  72        grep commit.refs/heads/master actual >commit-count &&
  73        test_line_count = 2 commit-count &&
  74        sed "s/master/rewrite/" actual |
  75                (cd new &&
  76                 git fast-import &&
  77                 test $MASTER = $(git rev-parse --verify refs/heads/rewrite))
  78'
  79
  80test_expect_success 'iso-8859-1' '
  81
  82        git config i18n.commitencoding ISO8859-1 &&
  83        # use author and committer name in ISO-8859-1 to match it.
  84        . "$TEST_DIRECTORY"/t3901/8859-1.txt &&
  85        test_tick &&
  86        echo rosten >file &&
  87        git commit -s -m den file &&
  88        git fast-export wer^..wer >iso8859-1.fi &&
  89        sed "s/wer/i18n/" iso8859-1.fi |
  90                (cd new &&
  91                 git fast-import &&
  92                 git cat-file commit i18n >actual &&
  93                 grep "Áéí óú" actual)
  94
  95'
  96test_expect_success 'import/export-marks' '
  97
  98        git checkout -b marks master &&
  99        git fast-export --export-marks=tmp-marks HEAD &&
 100        test -s tmp-marks &&
 101        test_line_count = 3 tmp-marks &&
 102        git fast-export --import-marks=tmp-marks \
 103                --export-marks=tmp-marks HEAD >actual &&
 104        test $(grep ^commit actual | wc -l) -eq 0 &&
 105        echo change > file &&
 106        git commit -m "last commit" file &&
 107        git fast-export --import-marks=tmp-marks \
 108                --export-marks=tmp-marks HEAD >actual &&
 109        test $(grep ^commit\  actual | wc -l) -eq 1 &&
 110        test_line_count = 4 tmp-marks
 111
 112'
 113
 114cat > signed-tag-import << EOF
 115tag sign-your-name
 116from $(git rev-parse HEAD)
 117tagger C O Mitter <committer@example.com> 1112911993 -0700
 118data 210
 119A message for a sign
 120-----BEGIN PGP SIGNATURE-----
 121Version: GnuPG v1.4.5 (GNU/Linux)
 122
 123fakedsignaturefakedsignaturefakedsignaturefakedsignaturfakedsign
 124aturefakedsignaturefake=
 125=/59v
 126-----END PGP SIGNATURE-----
 127EOF
 128
 129test_expect_success 'set up faked signed tag' '
 130
 131        cat signed-tag-import | git fast-import
 132
 133'
 134
 135test_expect_success 'signed-tags=abort' '
 136
 137        test_must_fail git fast-export --signed-tags=abort sign-your-name
 138
 139'
 140
 141test_expect_success 'signed-tags=verbatim' '
 142
 143        git fast-export --signed-tags=verbatim sign-your-name > output &&
 144        grep PGP output
 145
 146'
 147
 148test_expect_success 'signed-tags=strip' '
 149
 150        git fast-export --signed-tags=strip sign-your-name > output &&
 151        ! grep PGP output
 152
 153'
 154
 155test_expect_success 'signed-tags=warn-strip' '
 156        git fast-export --signed-tags=warn-strip sign-your-name >output 2>err &&
 157        ! grep PGP output &&
 158        test -s err
 159'
 160
 161test_expect_success 'setup submodule' '
 162
 163        git checkout -f master &&
 164        mkdir sub &&
 165        (
 166                cd sub &&
 167                git init  &&
 168                echo test file > file &&
 169                git add file &&
 170                git commit -m sub_initial
 171        ) &&
 172        git submodule add "$(pwd)/sub" sub &&
 173        git commit -m initial &&
 174        test_tick &&
 175        (
 176                cd sub &&
 177                echo more data >> file &&
 178                git add file &&
 179                git commit -m sub_second
 180        ) &&
 181        git add sub &&
 182        git commit -m second
 183
 184'
 185
 186test_expect_success 'submodule fast-export | fast-import' '
 187
 188        SUBENT1=$(git ls-tree master^ sub) &&
 189        SUBENT2=$(git ls-tree master sub) &&
 190        rm -rf new &&
 191        mkdir new &&
 192        git --git-dir=new/.git init &&
 193        git fast-export --signed-tags=strip --all >actual &&
 194        (cd new &&
 195         git fast-import &&
 196         test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" &&
 197         test "$SUBENT2" = "$(git ls-tree refs/heads/master sub)" &&
 198         git checkout master &&
 199         git submodule init &&
 200         git submodule update &&
 201         cmp sub/file ../sub/file) <actual
 202
 203'
 204
 205GIT_AUTHOR_NAME='A U Thor'; export GIT_AUTHOR_NAME
 206GIT_COMMITTER_NAME='C O Mitter'; export GIT_COMMITTER_NAME
 207
 208test_expect_success 'setup copies' '
 209
 210        git config --unset i18n.commitencoding &&
 211        git checkout -b copy rein &&
 212        git mv file file3 &&
 213        git commit -m move1 &&
 214        test_tick &&
 215        cp file2 file4 &&
 216        git add file4 &&
 217        git mv file2 file5 &&
 218        git commit -m copy1 &&
 219        test_tick &&
 220        cp file3 file6 &&
 221        git add file6 &&
 222        git commit -m copy2 &&
 223        test_tick &&
 224        echo more text >> file6 &&
 225        echo even more text >> file6 &&
 226        git add file6 &&
 227        git commit -m modify &&
 228        test_tick &&
 229        cp file6 file7 &&
 230        echo test >> file7 &&
 231        git add file7 &&
 232        git commit -m copy_modify
 233
 234'
 235
 236test_expect_success 'fast-export -C -C | fast-import' '
 237
 238        ENTRY=$(git rev-parse --verify copy) &&
 239        rm -rf new &&
 240        mkdir new &&
 241        git --git-dir=new/.git init &&
 242        git fast-export -C -C --signed-tags=strip --all > output &&
 243        grep "^C file2 file4\$" output &&
 244        cat output |
 245        (cd new &&
 246         git fast-import &&
 247         test $ENTRY = $(git rev-parse --verify refs/heads/copy))
 248
 249'
 250
 251test_expect_success 'fast-export | fast-import when master is tagged' '
 252
 253        git tag -m msg last &&
 254        git fast-export -C -C --signed-tags=strip --all > output &&
 255        test $(grep -c "^tag " output) = 3
 256
 257'
 258
 259cat > tag-content << EOF
 260object $(git rev-parse HEAD)
 261type commit
 262tag rosten
 263EOF
 264
 265test_expect_success 'cope with tagger-less tags' '
 266
 267        TAG=$(git hash-object -t tag -w tag-content) &&
 268        git update-ref refs/tags/sonnenschein $TAG &&
 269        git fast-export -C -C --signed-tags=strip --all > output &&
 270        test $(grep -c "^tag " output) = 4 &&
 271        ! grep "Unspecified Tagger" output &&
 272        git fast-export -C -C --signed-tags=strip --all \
 273                --fake-missing-tagger > output &&
 274        test $(grep -c "^tag " output) = 4 &&
 275        grep "Unspecified Tagger" output
 276
 277'
 278
 279test_expect_success 'setup for limiting exports by PATH' '
 280        mkdir limit-by-paths &&
 281        (
 282                cd limit-by-paths &&
 283                git init &&
 284                echo hi > there &&
 285                git add there &&
 286                git commit -m "First file" &&
 287                echo foo > bar &&
 288                git add bar &&
 289                git commit -m "Second file" &&
 290                git tag -a -m msg mytag &&
 291                echo morefoo >> bar &&
 292                git add bar &&
 293                git commit -m "Change to second file"
 294        )
 295'
 296
 297cat > limit-by-paths/expected << EOF
 298blob
 299mark :1
 300data 3
 301hi
 302
 303reset refs/tags/mytag
 304commit refs/tags/mytag
 305mark :2
 306author A U Thor <author@example.com> 1112912713 -0700
 307committer C O Mitter <committer@example.com> 1112912713 -0700
 308data 11
 309First file
 310M 100644 :1 there
 311
 312EOF
 313
 314test_expect_success 'dropping tag of filtered out object' '
 315(
 316        cd limit-by-paths &&
 317        git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
 318        test_cmp expected output
 319)
 320'
 321
 322cat >> limit-by-paths/expected << EOF
 323tag mytag
 324from :2
 325tagger C O Mitter <committer@example.com> 1112912713 -0700
 326data 4
 327msg
 328
 329EOF
 330
 331test_expect_success 'rewriting tag of filtered out object' '
 332(
 333        cd limit-by-paths &&
 334        git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
 335        test_cmp expected output
 336)
 337'
 338
 339test_expect_success 'rewrite tag predating pathspecs to nothing' '
 340        test_create_repo rewrite_tag_predating_pathspecs &&
 341        (
 342                cd rewrite_tag_predating_pathspecs &&
 343
 344                test_commit initial &&
 345
 346                git tag -a -m "Some old tag" v0.0.0.0.0.0.1 &&
 347
 348                test_commit bar &&
 349
 350                git fast-export --tag-of-filtered-object=rewrite --all -- bar.t >output &&
 351                grep from.$ZERO_OID output
 352        )
 353'
 354
 355cat > limit-by-paths/expected << EOF
 356blob
 357mark :1
 358data 4
 359foo
 360
 361blob
 362mark :2
 363data 3
 364hi
 365
 366reset refs/heads/master
 367commit refs/heads/master
 368mark :3
 369author A U Thor <author@example.com> 1112912713 -0700
 370committer C O Mitter <committer@example.com> 1112912713 -0700
 371data 12
 372Second file
 373M 100644 :1 bar
 374M 100644 :2 there
 375
 376EOF
 377
 378test_expect_failure 'no exact-ref revisions included' '
 379        (
 380                cd limit-by-paths &&
 381                git fast-export master~2..master~1 > output &&
 382                test_cmp expected output
 383        )
 384'
 385
 386test_expect_success 'path limiting with import-marks does not lose unmodified files'        '
 387        git checkout -b simple marks~2 &&
 388        git fast-export --export-marks=marks simple -- file > /dev/null &&
 389        echo more content >> file &&
 390        test_tick &&
 391        git commit -mnext file &&
 392        git fast-export --import-marks=marks simple -- file file0 >actual &&
 393        grep file0 actual
 394'
 395
 396test_expect_success 'avoid corrupt stream with non-existent mark' '
 397        test_create_repo avoid_non_existent_mark &&
 398        (
 399                cd avoid_non_existent_mark &&
 400
 401                test_commit important-path &&
 402
 403                test_commit ignored &&
 404
 405                git branch A &&
 406                git branch B &&
 407
 408                echo foo >>important-path.t &&
 409                git add important-path.t &&
 410                test_commit more changes &&
 411
 412                git fast-export --all -- important-path.t | git fast-import --force
 413        )
 414'
 415
 416test_expect_success 'full-tree re-shows unmodified files'        '
 417        git checkout -f simple &&
 418        git fast-export --full-tree simple >actual &&
 419        test $(grep -c file0 actual) -eq 3
 420'
 421
 422test_expect_success 'set-up a few more tags for tag export tests' '
 423        git checkout -f master &&
 424        HEAD_TREE=$(git show -s --pretty=raw HEAD | grep tree | sed "s/tree //") &&
 425        git tag    tree_tag        -m "tagging a tree" $HEAD_TREE &&
 426        git tag -a tree_tag-obj    -m "tagging a tree" $HEAD_TREE &&
 427        git tag    tag-obj_tag     -m "tagging a tag" tree_tag-obj &&
 428        git tag -a tag-obj_tag-obj -m "tagging a tag" tree_tag-obj
 429'
 430
 431test_expect_success 'tree_tag'        '
 432        mkdir result &&
 433        (cd result && git init) &&
 434        git fast-export tree_tag > fe-stream &&
 435        (cd result && git fast-import < ../fe-stream)
 436'
 437
 438# NEEDSWORK: not just check return status, but validate the output
 439test_expect_success 'tree_tag-obj'    'git fast-export tree_tag-obj'
 440test_expect_success 'tag-obj_tag'     'git fast-export tag-obj_tag'
 441test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj'
 442
 443test_expect_success 'directory becomes symlink'        '
 444        git init dirtosymlink &&
 445        git init result &&
 446        (
 447                cd dirtosymlink &&
 448                mkdir foo &&
 449                mkdir bar &&
 450                echo hello > foo/world &&
 451                echo hello > bar/world &&
 452                git add foo/world bar/world &&
 453                git commit -q -mone &&
 454                git rm -r foo &&
 455                test_ln_s_add bar foo &&
 456                git commit -q -mtwo
 457        ) &&
 458        (
 459                cd dirtosymlink &&
 460                git fast-export master -- foo |
 461                (cd ../result && git fast-import --quiet)
 462        ) &&
 463        (cd result && git show master:foo)
 464'
 465
 466test_expect_success 'fast-export quotes pathnames' '
 467        git init crazy-paths &&
 468        (cd crazy-paths &&
 469         blob=$(echo foo | git hash-object -w --stdin) &&
 470         git update-index --add \
 471                --cacheinfo 100644 $blob "$(printf "path with\\nnewline")" \
 472                --cacheinfo 100644 $blob "path with \"quote\"" \
 473                --cacheinfo 100644 $blob "path with \\backslash" \
 474                --cacheinfo 100644 $blob "path with space" &&
 475         git commit -m addition &&
 476         git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index &&
 477         git read-tree --empty &&
 478         git update-index -z --index-info <index &&
 479         git commit -m rename &&
 480         git read-tree --empty &&
 481         git commit -m deletion &&
 482         git fast-export -M HEAD >export.out &&
 483         git rev-list HEAD >expect &&
 484         git init result &&
 485         cd result &&
 486         git fast-import <../export.out &&
 487         git rev-list HEAD >actual &&
 488         test_cmp ../expect actual
 489        )
 490'
 491
 492test_expect_success 'test bidirectionality' '
 493        >marks-cur &&
 494        >marks-new &&
 495        git init marks-test &&
 496        git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
 497        git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
 498        (cd marks-test &&
 499        git reset --hard &&
 500        echo Wohlauf > file &&
 501        git commit -a -m "back in time") &&
 502        git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
 503        git fast-import --export-marks=marks-cur --import-marks=marks-cur
 504'
 505
 506cat > expected << EOF
 507blob
 508mark :13
 509data 5
 510bump
 511
 512commit refs/heads/master
 513mark :14
 514author A U Thor <author@example.com> 1112912773 -0700
 515committer C O Mitter <committer@example.com> 1112912773 -0700
 516data 5
 517bump
 518from :12
 519M 100644 :13 file
 520
 521EOF
 522
 523test_expect_success 'avoid uninteresting refs' '
 524        > tmp-marks &&
 525        git fast-export --import-marks=tmp-marks \
 526                --export-marks=tmp-marks master > /dev/null &&
 527        git tag v1.0 &&
 528        git branch uninteresting &&
 529        echo bump > file &&
 530        git commit -a -m bump &&
 531        git fast-export --import-marks=tmp-marks \
 532                --export-marks=tmp-marks ^uninteresting ^v1.0 master > actual &&
 533        test_cmp expected actual
 534'
 535
 536cat > expected << EOF
 537reset refs/heads/master
 538from :14
 539
 540EOF
 541
 542test_expect_success 'refs are updated even if no commits need to be exported' '
 543        > tmp-marks &&
 544        git fast-export --import-marks=tmp-marks \
 545                --export-marks=tmp-marks master > /dev/null &&
 546        git fast-export --import-marks=tmp-marks \
 547                --export-marks=tmp-marks master > actual &&
 548        test_cmp expected actual
 549'
 550
 551test_expect_success 'use refspec' '
 552        git fast-export --refspec refs/heads/master:refs/heads/foobar master >actual2 &&
 553        grep "^commit " actual2 | sort | uniq >actual &&
 554        echo "commit refs/heads/foobar" > expected &&
 555        test_cmp expected actual
 556'
 557
 558test_expect_success 'delete ref because entire history excluded' '
 559        git branch to-delete &&
 560        git fast-export to-delete ^to-delete >actual &&
 561        cat >expected <<-EOF &&
 562        reset refs/heads/to-delete
 563        from 0000000000000000000000000000000000000000
 564
 565        EOF
 566        test_cmp expected actual
 567'
 568
 569test_expect_success 'delete refspec' '
 570        git fast-export --refspec :refs/heads/to-delete >actual &&
 571        cat >expected <<-EOF &&
 572        reset refs/heads/to-delete
 573        from 0000000000000000000000000000000000000000
 574
 575        EOF
 576        test_cmp expected actual
 577'
 578
 579test_expect_success 'when using -C, do not declare copy when source of copy is also modified' '
 580        test_create_repo src &&
 581        echo a_line >src/file.txt &&
 582        git -C src add file.txt &&
 583        git -C src commit -m 1st_commit &&
 584
 585        cp src/file.txt src/file2.txt &&
 586        echo another_line >>src/file.txt &&
 587        git -C src add file.txt file2.txt &&
 588        git -C src commit -m 2nd_commit &&
 589
 590        test_create_repo dst &&
 591        git -C src fast-export --all -C >actual &&
 592        git -C dst fast-import <actual &&
 593        git -C src show >expected &&
 594        git -C dst show >actual &&
 595        test_cmp expected actual
 596'
 597
 598test_expect_success 'merge commit gets exported with --import-marks' '
 599        test_create_repo merging &&
 600        (
 601                cd merging &&
 602                test_commit initial &&
 603                git checkout -b topic &&
 604                test_commit on-topic &&
 605                git checkout master &&
 606                test_commit on-master &&
 607                test_tick &&
 608                git merge --no-ff -m Yeah topic &&
 609
 610                echo ":1 $(git rev-parse HEAD^^)" >marks &&
 611                git fast-export --import-marks=marks master >out &&
 612                grep Yeah out
 613        )
 614'
 615
 616test_done