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