t / t9300-fast-import.shon commit archive-tar: make write_extended_header() void (560b0e8)
   1#!/bin/sh
   2#
   3# Copyright (c) 2007 Shawn Pearce
   4#
   5
   6test_description='test git fast-import utility'
   7. ./test-lib.sh
   8. "$TEST_DIRECTORY"/diff-lib.sh ;# test-lib chdir's into trash
   9
  10verify_packs () {
  11        for p in .git/objects/pack/*.pack
  12        do
  13                git verify-pack "$@" "$p" || return
  14        done
  15}
  16
  17file2_data='file2
  18second line of EOF'
  19
  20file3_data='EOF
  21in 3rd file
  22 END'
  23
  24file4_data=abcd
  25file4_len=4
  26
  27file5_data='an inline file.
  28  we should see it later.'
  29
  30file6_data='#!/bin/sh
  31echo "$@"'
  32
  33###
  34### series A
  35###
  36
  37test_expect_success 'empty stream succeeds' '
  38        git fast-import </dev/null
  39'
  40
  41test_expect_success 'truncated stream complains' '
  42        echo "tag foo" | test_must_fail git fast-import
  43'
  44
  45test_expect_success 'A: create pack from stdin' '
  46        test_tick &&
  47        cat >input <<-INPUT_END &&
  48        blob
  49        mark :2
  50        data <<EOF
  51        $file2_data
  52        EOF
  53
  54        blob
  55        mark :3
  56        data <<END
  57        $file3_data
  58        END
  59
  60        blob
  61        mark :4
  62        data $file4_len
  63        $file4_data
  64        commit refs/heads/master
  65        mark :5
  66        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  67        data <<COMMIT
  68        initial
  69        COMMIT
  70
  71        M 644 :2 file2
  72        M 644 :3 file3
  73        M 755 :4 file4
  74
  75        tag series-A
  76        from :5
  77        data <<EOF
  78        An annotated tag without a tagger
  79        EOF
  80
  81        tag series-A-blob
  82        from :3
  83        data <<EOF
  84        An annotated tag that annotates a blob.
  85        EOF
  86
  87        INPUT_END
  88        git fast-import --export-marks=marks.out <input &&
  89        git whatchanged master
  90'
  91
  92test_expect_success 'A: verify pack' '
  93        verify_packs
  94'
  95
  96test_expect_success 'A: verify commit' '
  97        cat >expect <<-EOF &&
  98        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
  99        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 100
 101        initial
 102        EOF
 103        git cat-file commit master | sed 1d >actual &&
 104        test_cmp expect actual
 105'
 106
 107test_expect_success 'A: verify tree' '
 108        cat >expect <<-EOF &&
 109        100644 blob file2
 110        100644 blob file3
 111        100755 blob file4
 112        EOF
 113        git cat-file -p master^{tree} | sed "s/ [0-9a-f]*       / /" >actual &&
 114        test_cmp expect actual
 115'
 116
 117test_expect_success 'A: verify file2' '
 118        echo "$file2_data" >expect &&
 119        git cat-file blob master:file2 >actual &&
 120        test_cmp expect actual
 121'
 122
 123test_expect_success 'A: verify file3' '
 124        echo "$file3_data" >expect &&
 125        git cat-file blob master:file3 >actual &&
 126        test_cmp expect actual
 127'
 128
 129test_expect_success 'A: verify file4' '
 130        printf "$file4_data" >expect &&
 131        git cat-file blob master:file4 >actual &&
 132        test_cmp expect actual
 133'
 134
 135test_expect_success 'A: verify tag/series-A' '
 136        cat >expect <<-EOF &&
 137        object $(git rev-parse refs/heads/master)
 138        type commit
 139        tag series-A
 140
 141        An annotated tag without a tagger
 142        EOF
 143        git cat-file tag tags/series-A >actual &&
 144        test_cmp expect actual
 145'
 146
 147test_expect_success 'A: verify tag/series-A-blob' '
 148        cat >expect <<-EOF &&
 149        object $(git rev-parse refs/heads/master:file3)
 150        type blob
 151        tag series-A-blob
 152
 153        An annotated tag that annotates a blob.
 154        EOF
 155        git cat-file tag tags/series-A-blob >actual &&
 156        test_cmp expect actual
 157'
 158
 159test_expect_success 'A: verify marks output' '
 160        cat >expect <<-EOF &&
 161        :2 $(git rev-parse --verify master:file2)
 162        :3 $(git rev-parse --verify master:file3)
 163        :4 $(git rev-parse --verify master:file4)
 164        :5 $(git rev-parse --verify master^0)
 165        EOF
 166        test_cmp expect marks.out
 167'
 168
 169test_expect_success 'A: verify marks import' '
 170        git fast-import \
 171                --import-marks=marks.out \
 172                --export-marks=marks.new \
 173                </dev/null &&
 174        test_cmp expect marks.new
 175'
 176
 177test_expect_success 'A: tag blob by sha1' '
 178        test_tick &&
 179        new_blob=$(echo testing | git hash-object --stdin) &&
 180        cat >input <<-INPUT_END &&
 181        tag series-A-blob-2
 182        from $(git rev-parse refs/heads/master:file3)
 183        data <<EOF
 184        Tag blob by sha1.
 185        EOF
 186
 187        blob
 188        mark :6
 189        data <<EOF
 190        testing
 191        EOF
 192
 193        commit refs/heads/new_blob
 194        committer  <> 0 +0000
 195        data 0
 196        M 644 :6 new_blob
 197        #pretend we got sha1 from fast-import
 198        ls "new_blob"
 199
 200        tag series-A-blob-3
 201        from $new_blob
 202        data <<EOF
 203        Tag new_blob.
 204        EOF
 205        INPUT_END
 206
 207        cat >expect <<-EOF &&
 208        object $(git rev-parse refs/heads/master:file3)
 209        type blob
 210        tag series-A-blob-2
 211
 212        Tag blob by sha1.
 213        object $new_blob
 214        type blob
 215        tag series-A-blob-3
 216
 217        Tag new_blob.
 218        EOF
 219
 220        git fast-import <input &&
 221        git cat-file tag tags/series-A-blob-2 >actual &&
 222        git cat-file tag tags/series-A-blob-3 >>actual &&
 223        test_cmp expect actual
 224'
 225
 226test_expect_success 'A: verify marks import does not crash' '
 227        test_tick &&
 228        cat >input <<-INPUT_END &&
 229        commit refs/heads/verify--import-marks
 230        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 231        data <<COMMIT
 232        recreate from :5
 233        COMMIT
 234
 235        from :5
 236        M 755 :2 copy-of-file2
 237
 238        INPUT_END
 239
 240        git fast-import --import-marks=marks.out <input &&
 241        git whatchanged verify--import-marks
 242'
 243
 244test_expect_success 'A: verify pack' '
 245        verify_packs
 246'
 247
 248test_expect_success 'A: verify diff' '
 249        cat >expect <<-EOF &&
 250        :000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A      copy-of-file2
 251        EOF
 252        git diff-tree -M -r master verify--import-marks >actual &&
 253        compare_diff_raw expect actual &&
 254        test $(git rev-parse --verify master:file2) \
 255            = $(git rev-parse --verify verify--import-marks:copy-of-file2)
 256'
 257
 258test_expect_success 'A: export marks with large values' '
 259        test_tick &&
 260        mt=$(git hash-object --stdin < /dev/null) &&
 261        >input.blob &&
 262        >marks.exp &&
 263        >tree.exp &&
 264
 265        cat >input.commit <<-EOF &&
 266        commit refs/heads/verify--dump-marks
 267        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 268        data <<COMMIT
 269        test the sparse array dumping routines with exponentially growing marks
 270        COMMIT
 271        EOF
 272
 273        i=0 l=4 m=6 n=7 &&
 274        while test "$i" -lt 27
 275        do
 276                cat >>input.blob <<-EOF &&
 277                blob
 278                mark :$l
 279                data 0
 280                blob
 281                mark :$m
 282                data 0
 283                blob
 284                mark :$n
 285                data 0
 286                EOF
 287                echo "M 100644 :$l l$i" >>input.commit &&
 288                echo "M 100644 :$m m$i" >>input.commit &&
 289                echo "M 100644 :$n n$i" >>input.commit &&
 290
 291                echo ":$l $mt" >>marks.exp &&
 292                echo ":$m $mt" >>marks.exp &&
 293                echo ":$n $mt" >>marks.exp &&
 294
 295                printf "100644 blob $mt\tl$i\n" >>tree.exp &&
 296                printf "100644 blob $mt\tm$i\n" >>tree.exp &&
 297                printf "100644 blob $mt\tn$i\n" >>tree.exp &&
 298
 299                l=$(($l + $l)) &&
 300                m=$(($m + $m)) &&
 301                n=$(($l + $n)) &&
 302
 303                i=$((1 + $i)) || return 1
 304        done &&
 305
 306        sort tree.exp > tree.exp_s &&
 307
 308        cat input.blob input.commit | git fast-import --export-marks=marks.large &&
 309        git ls-tree refs/heads/verify--dump-marks >tree.out &&
 310        test_cmp tree.exp_s tree.out &&
 311        test_cmp marks.exp marks.large
 312'
 313
 314###
 315### series B
 316###
 317
 318test_expect_success 'B: fail on invalid blob sha1' '
 319        test_tick &&
 320        cat >input <<-INPUT_END &&
 321        commit refs/heads/branch
 322        mark :1
 323        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 324        data <<COMMIT
 325        corrupt
 326        COMMIT
 327
 328        from refs/heads/master
 329        M 755 0000000000000000000000000000000000000001 zero1
 330
 331        INPUT_END
 332
 333        test_when_finished "rm -f .git/objects/pack_* .git/objects/index_*" &&
 334        test_must_fail git fast-import <input
 335'
 336
 337test_expect_success 'B: accept branch name "TEMP_TAG"' '
 338        cat >input <<-INPUT_END &&
 339        commit TEMP_TAG
 340        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 341        data <<COMMIT
 342        tag base
 343        COMMIT
 344
 345        from refs/heads/master
 346
 347        INPUT_END
 348
 349        test_when_finished "rm -f .git/TEMP_TAG
 350                git gc
 351                git prune" &&
 352        git fast-import <input &&
 353        test -f .git/TEMP_TAG &&
 354        test $(git rev-parse master) = $(git rev-parse TEMP_TAG^)
 355'
 356
 357test_expect_success 'B: accept empty committer' '
 358        cat >input <<-INPUT_END &&
 359        commit refs/heads/empty-committer-1
 360        committer  <> $GIT_COMMITTER_DATE
 361        data <<COMMIT
 362        empty commit
 363        COMMIT
 364        INPUT_END
 365
 366        test_when_finished "git update-ref -d refs/heads/empty-committer-1
 367                git gc
 368                git prune" &&
 369        git fast-import <input &&
 370        out=$(git fsck) &&
 371        echo "$out" &&
 372        test -z "$out"
 373'
 374
 375test_expect_success 'B: accept and fixup committer with no name' '
 376        cat >input <<-INPUT_END &&
 377        commit refs/heads/empty-committer-2
 378        committer <a@b.com> $GIT_COMMITTER_DATE
 379        data <<COMMIT
 380        empty commit
 381        COMMIT
 382        INPUT_END
 383
 384        test_when_finished "git update-ref -d refs/heads/empty-committer-2
 385                git gc
 386                git prune" &&
 387        git fast-import <input &&
 388        out=$(git fsck) &&
 389        echo "$out" &&
 390        test -z "$out"
 391'
 392
 393test_expect_success 'B: fail on invalid committer (1)' '
 394        cat >input <<-INPUT_END &&
 395        commit refs/heads/invalid-committer
 396        committer Name email> $GIT_COMMITTER_DATE
 397        data <<COMMIT
 398        empty commit
 399        COMMIT
 400        INPUT_END
 401
 402        test_when_finished "git update-ref -d refs/heads/invalid-committer" &&
 403        test_must_fail git fast-import <input
 404'
 405
 406test_expect_success 'B: fail on invalid committer (2)' '
 407        cat >input <<-INPUT_END &&
 408        commit refs/heads/invalid-committer
 409        committer Name <e<mail> $GIT_COMMITTER_DATE
 410        data <<COMMIT
 411        empty commit
 412        COMMIT
 413        INPUT_END
 414
 415        test_when_finished "git update-ref -d refs/heads/invalid-committer" &&
 416        test_must_fail git fast-import <input
 417'
 418
 419test_expect_success 'B: fail on invalid committer (3)' '
 420        cat >input <<-INPUT_END &&
 421        commit refs/heads/invalid-committer
 422        committer Name <email>> $GIT_COMMITTER_DATE
 423        data <<COMMIT
 424        empty commit
 425        COMMIT
 426        INPUT_END
 427
 428        test_when_finished "git update-ref -d refs/heads/invalid-committer" &&
 429        test_must_fail git fast-import <input
 430'
 431
 432test_expect_success 'B: fail on invalid committer (4)' '
 433        cat >input <<-INPUT_END &&
 434        commit refs/heads/invalid-committer
 435        committer Name <email $GIT_COMMITTER_DATE
 436        data <<COMMIT
 437        empty commit
 438        COMMIT
 439        INPUT_END
 440
 441        test_when_finished "git update-ref -d refs/heads/invalid-committer" &&
 442        test_must_fail git fast-import <input
 443'
 444
 445test_expect_success 'B: fail on invalid committer (5)' '
 446        cat >input <<-INPUT_END &&
 447        commit refs/heads/invalid-committer
 448        committer Name<email> $GIT_COMMITTER_DATE
 449        data <<COMMIT
 450        empty commit
 451        COMMIT
 452        INPUT_END
 453
 454        test_when_finished "git update-ref -d refs/heads/invalid-committer" &&
 455        test_must_fail git fast-import <input
 456'
 457
 458###
 459### series C
 460###
 461
 462test_expect_success 'C: incremental import create pack from stdin' '
 463        newf=$(echo hi newf | git hash-object -w --stdin) &&
 464        oldf=$(git rev-parse --verify master:file2) &&
 465        test_tick &&
 466        cat >input <<-INPUT_END &&
 467        commit refs/heads/branch
 468        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 469        data <<COMMIT
 470        second
 471        COMMIT
 472
 473        from refs/heads/master
 474        M 644 $oldf file2/oldf
 475        M 755 $newf file2/newf
 476        D file3
 477
 478        INPUT_END
 479
 480        git fast-import <input &&
 481        git whatchanged branch
 482'
 483
 484test_expect_success 'C: verify pack' '
 485        verify_packs
 486'
 487
 488test_expect_success 'C: validate reuse existing blob' '
 489        test $newf = $(git rev-parse --verify branch:file2/newf) &&
 490        test $oldf = $(git rev-parse --verify branch:file2/oldf)
 491'
 492
 493test_expect_success 'C: verify commit' '
 494        cat >expect <<-EOF &&
 495        parent $(git rev-parse --verify master^0)
 496        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 497        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 498
 499        second
 500        EOF
 501
 502        git cat-file commit branch | sed 1d >actual &&
 503        test_cmp expect actual
 504'
 505
 506test_expect_success 'C: validate rename result' '
 507        cat >expect <<-EOF &&
 508        :000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A      file2/newf
 509        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100   file2   file2/oldf
 510        :100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D      file3
 511        EOF
 512        git diff-tree -M -r master branch >actual &&
 513        compare_diff_raw expect actual
 514'
 515
 516###
 517### series D
 518###
 519
 520test_expect_success 'D: inline data in commit' '
 521        test_tick &&
 522        cat >input <<-INPUT_END &&
 523        commit refs/heads/branch
 524        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 525        data <<COMMIT
 526        third
 527        COMMIT
 528
 529        from refs/heads/branch^0
 530        M 644 inline newdir/interesting
 531        data <<EOF
 532        $file5_data
 533        EOF
 534
 535        M 755 inline newdir/exec.sh
 536        data <<EOF
 537        $file6_data
 538        EOF
 539
 540        INPUT_END
 541
 542        git fast-import <input &&
 543        git whatchanged branch
 544'
 545
 546test_expect_success 'D: verify pack' '
 547        verify_packs
 548'
 549
 550test_expect_success 'D: validate new files added' '
 551        cat >expect <<-EOF &&
 552        :000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A      newdir/exec.sh
 553        :000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A      newdir/interesting
 554        EOF
 555        git diff-tree -M -r branch^ branch >actual &&
 556        compare_diff_raw expect actual
 557'
 558
 559test_expect_success 'D: verify file5' '
 560        echo "$file5_data" >expect &&
 561        git cat-file blob branch:newdir/interesting >actual &&
 562        test_cmp expect actual
 563'
 564
 565test_expect_success 'D: verify file6' '
 566        echo "$file6_data" >expect &&
 567        git cat-file blob branch:newdir/exec.sh >actual &&
 568        test_cmp expect actual
 569'
 570
 571###
 572### series E
 573###
 574
 575test_expect_success 'E: rfc2822 date, --date-format=raw' '
 576        cat >input <<-INPUT_END &&
 577        commit refs/heads/branch
 578        author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> Tue Feb 6 11:22:18 2007 -0500
 579        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> Tue Feb 6 12:35:02 2007 -0500
 580        data <<COMMIT
 581        RFC 2822 type date
 582        COMMIT
 583
 584        from refs/heads/branch^0
 585
 586        INPUT_END
 587
 588        test_must_fail git fast-import --date-format=raw <input
 589'
 590test_expect_success 'E: rfc2822 date, --date-format=rfc2822' '
 591        git fast-import --date-format=rfc2822 <input
 592'
 593
 594test_expect_success 'E: verify pack' '
 595        verify_packs
 596'
 597
 598test_expect_success 'E: verify commit' '
 599        cat >expect <<-EOF &&
 600        author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500
 601        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1170783302 -0500
 602
 603        RFC 2822 type date
 604        EOF
 605        git cat-file commit branch | sed 1,2d >actual &&
 606        test_cmp expect actual
 607'
 608
 609###
 610### series F
 611###
 612
 613test_expect_success 'F: non-fast-forward update skips' '
 614        old_branch=$(git rev-parse --verify branch^0) &&
 615        test_tick &&
 616        cat >input <<-INPUT_END &&
 617        commit refs/heads/branch
 618        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 619        data <<COMMIT
 620        losing things already?
 621        COMMIT
 622
 623        from refs/heads/branch~1
 624
 625        reset refs/heads/other
 626        from refs/heads/branch
 627
 628        INPUT_END
 629
 630        test_must_fail git fast-import <input &&
 631        # branch must remain unaffected
 632        test $old_branch = $(git rev-parse --verify branch^0)
 633'
 634
 635test_expect_success 'F: verify pack' '
 636        verify_packs
 637'
 638
 639test_expect_success 'F: verify other commit' '
 640        cat >expect <<-EOF &&
 641        tree $(git rev-parse branch~1^{tree})
 642        parent $(git rev-parse branch~1)
 643        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 644        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 645
 646        losing things already?
 647        EOF
 648        git cat-file commit other >actual &&
 649        test_cmp expect actual
 650'
 651
 652###
 653### series G
 654###
 655
 656test_expect_success 'G: non-fast-forward update forced' '
 657        old_branch=$(git rev-parse --verify branch^0) &&
 658        test_tick &&
 659        cat >input <<-INPUT_END &&
 660        commit refs/heads/branch
 661        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 662        data <<COMMIT
 663        losing things already?
 664        COMMIT
 665
 666        from refs/heads/branch~1
 667
 668        INPUT_END
 669        git fast-import --force <input
 670'
 671
 672test_expect_success 'G: verify pack' '
 673        verify_packs
 674'
 675
 676test_expect_success 'G: branch changed, but logged' '
 677        test $old_branch != $(git rev-parse --verify branch^0) &&
 678        test $old_branch = $(git rev-parse --verify branch@{1})
 679'
 680
 681###
 682### series H
 683###
 684
 685test_expect_success 'H: deletall, add 1' '
 686        test_tick &&
 687        cat >input <<-INPUT_END &&
 688        commit refs/heads/H
 689        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 690        data <<COMMIT
 691        third
 692        COMMIT
 693
 694        from refs/heads/branch^0
 695        M 644 inline i-will-die
 696        data <<EOF
 697        this file will never exist.
 698        EOF
 699
 700        deleteall
 701        M 644 inline h/e/l/lo
 702        data <<EOF
 703        $file5_data
 704        EOF
 705
 706        INPUT_END
 707        git fast-import <input &&
 708        git whatchanged H
 709'
 710
 711test_expect_success 'H: verify pack' '
 712        verify_packs
 713'
 714
 715test_expect_success 'H: validate old files removed, new files added' '
 716        cat >expect <<-EOF &&
 717        :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D      file2/newf
 718        :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D      file2/oldf
 719        :100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D      file4
 720        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100   newdir/interesting      h/e/l/lo
 721        :100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D      newdir/exec.sh
 722        EOF
 723        git diff-tree -M -r H^ H >actual &&
 724        compare_diff_raw expect actual
 725'
 726
 727test_expect_success 'H: verify file' '
 728        echo "$file5_data" >expect &&
 729        git cat-file blob H:h/e/l/lo >actual &&
 730        test_cmp expect actual
 731'
 732
 733###
 734### series I
 735###
 736
 737test_expect_success 'I: export-pack-edges' '
 738        cat >input <<-INPUT_END &&
 739        commit refs/heads/export-boundary
 740        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 741        data <<COMMIT
 742        we have a border.  its only 40 characters wide.
 743        COMMIT
 744
 745        from refs/heads/branch
 746
 747        INPUT_END
 748        git fast-import --export-pack-edges=edges.list <input
 749'
 750
 751test_expect_success 'I: verify edge list' '
 752        cat >expect <<-EOF &&
 753        .git/objects/pack/pack-.pack: $(git rev-parse --verify export-boundary)
 754        EOF
 755        sed -e s/pack-.*pack/pack-.pack/ edges.list >actual &&
 756        test_cmp expect actual
 757'
 758
 759###
 760### series J
 761###
 762
 763test_expect_success 'J: reset existing branch creates empty commit' '
 764        cat >input <<-INPUT_END &&
 765        commit refs/heads/J
 766        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 767        data <<COMMIT
 768        create J
 769        COMMIT
 770
 771        from refs/heads/branch
 772
 773        reset refs/heads/J
 774
 775        commit refs/heads/J
 776        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 777        data <<COMMIT
 778        initialize J
 779        COMMIT
 780
 781        INPUT_END
 782        git fast-import <input
 783'
 784test_expect_success 'J: branch has 1 commit, empty tree' '
 785        test 1 = $(git rev-list J | wc -l) &&
 786        test 0 = $(git ls-tree J | wc -l)
 787'
 788
 789test_expect_success 'J: tag must fail on empty branch' '
 790        cat >input <<-INPUT_END &&
 791        reset refs/heads/J2
 792
 793        tag wrong_tag
 794        from refs/heads/J2
 795        data <<EOF
 796        Tag branch that was reset.
 797        EOF
 798        INPUT_END
 799        test_must_fail git fast-import <input
 800'
 801
 802###
 803### series K
 804###
 805
 806test_expect_success 'K: reinit branch with from' '
 807        cat >input <<-INPUT_END &&
 808        commit refs/heads/K
 809        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 810        data <<COMMIT
 811        create K
 812        COMMIT
 813
 814        from refs/heads/branch
 815
 816        commit refs/heads/K
 817        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 818        data <<COMMIT
 819        redo K
 820        COMMIT
 821
 822        from refs/heads/branch^1
 823
 824        INPUT_END
 825        git fast-import <input
 826'
 827test_expect_success 'K: verify K^1 = branch^1' '
 828        test $(git rev-parse --verify branch^1) \
 829                = $(git rev-parse --verify K^1)
 830'
 831
 832###
 833### series L
 834###
 835
 836test_expect_success 'L: verify internal tree sorting' '
 837        cat >input <<-INPUT_END &&
 838        blob
 839        mark :1
 840        data <<EOF
 841        some data
 842        EOF
 843
 844        blob
 845        mark :2
 846        data <<EOF
 847        other data
 848        EOF
 849
 850        commit refs/heads/L
 851        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 852        data <<COMMIT
 853        create L
 854        COMMIT
 855
 856        M 644 :1 b.
 857        M 644 :1 b/other
 858        M 644 :1 ba
 859
 860        commit refs/heads/L
 861        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 862        data <<COMMIT
 863        update L
 864        COMMIT
 865
 866        M 644 :2 b.
 867        M 644 :2 b/other
 868        M 644 :2 ba
 869        INPUT_END
 870
 871        cat >expect <<-EXPECT_END &&
 872        :100644 100644 4268632... 55d3a52... M  b.
 873        :040000 040000 0ae5cac... 443c768... M  b
 874        :100644 100644 4268632... 55d3a52... M  ba
 875        EXPECT_END
 876
 877        git fast-import <input &&
 878        git diff-tree --abbrev --raw L^ L >output &&
 879        test_cmp expect output
 880'
 881
 882test_expect_success 'L: nested tree copy does not corrupt deltas' '
 883        cat >input <<-INPUT_END &&
 884        blob
 885        mark :1
 886        data <<EOF
 887        the data
 888        EOF
 889
 890        commit refs/heads/L2
 891        committer C O Mitter <committer@example.com> 1112912473 -0700
 892        data <<COMMIT
 893        init L2
 894        COMMIT
 895        M 644 :1 a/b/c
 896        M 644 :1 a/b/d
 897        M 644 :1 a/e/f
 898
 899        commit refs/heads/L2
 900        committer C O Mitter <committer@example.com> 1112912473 -0700
 901        data <<COMMIT
 902        update L2
 903        COMMIT
 904        C a g
 905        C a/e g/b
 906        M 644 :1 g/b/h
 907        INPUT_END
 908
 909        cat >expect <<-\EOF &&
 910        g/b/f
 911        g/b/h
 912        EOF
 913
 914        test_when_finished "git update-ref -d refs/heads/L2" &&
 915        git fast-import <input &&
 916        git ls-tree L2 g/b/ >tmp &&
 917        cat tmp | cut -f 2 >actual &&
 918        test_cmp expect actual &&
 919        git fsck $(git rev-parse L2)
 920'
 921
 922###
 923### series M
 924###
 925
 926test_expect_success 'M: rename file in same subdirectory' '
 927        test_tick &&
 928        cat >input <<-INPUT_END &&
 929        commit refs/heads/M1
 930        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 931        data <<COMMIT
 932        file rename
 933        COMMIT
 934
 935        from refs/heads/branch^0
 936        R file2/newf file2/n.e.w.f
 937
 938        INPUT_END
 939
 940        cat >expect <<-EOF &&
 941        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   file2/newf      file2/n.e.w.f
 942        EOF
 943        git fast-import <input &&
 944        git diff-tree -M -r M1^ M1 >actual &&
 945        compare_diff_raw expect actual
 946'
 947
 948test_expect_success 'M: rename file to new subdirectory' '
 949        cat >input <<-INPUT_END &&
 950        commit refs/heads/M2
 951        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 952        data <<COMMIT
 953        file rename
 954        COMMIT
 955
 956        from refs/heads/branch^0
 957        R file2/newf i/am/new/to/you
 958
 959        INPUT_END
 960
 961        cat >expect <<-EOF &&
 962        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   file2/newf      i/am/new/to/you
 963        EOF
 964        git fast-import <input &&
 965        git diff-tree -M -r M2^ M2 >actual &&
 966        compare_diff_raw expect actual
 967'
 968
 969test_expect_success 'M: rename subdirectory to new subdirectory' '
 970        cat >input <<-INPUT_END &&
 971        commit refs/heads/M3
 972        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 973        data <<COMMIT
 974        file rename
 975        COMMIT
 976
 977        from refs/heads/M2^0
 978        R i other/sub
 979
 980        INPUT_END
 981
 982        cat >expect <<-EOF &&
 983        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   i/am/new/to/you other/sub/am/new/to/you
 984        EOF
 985        git fast-import <input &&
 986        git diff-tree -M -r M3^ M3 >actual &&
 987        compare_diff_raw expect actual
 988'
 989
 990test_expect_success 'M: rename root to subdirectory' '
 991        cat >input <<-INPUT_END &&
 992        commit refs/heads/M4
 993        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 994        data <<COMMIT
 995        rename root
 996        COMMIT
 997
 998        from refs/heads/M2^0
 999        R "" sub
1000
1001        INPUT_END
1002
1003        cat >expect <<-EOF &&
1004        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100   file2/oldf      sub/file2/oldf
1005        :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100   file4   sub/file4
1006        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   i/am/new/to/you sub/i/am/new/to/you
1007        :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100   newdir/exec.sh  sub/newdir/exec.sh
1008        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100   newdir/interesting      sub/newdir/interesting
1009        EOF
1010        git fast-import <input &&
1011        git diff-tree -M -r M4^ M4 >actual &&
1012        cat actual &&
1013        compare_diff_raw expect actual
1014'
1015
1016###
1017### series N
1018###
1019
1020test_expect_success 'N: copy file in same subdirectory' '
1021        test_tick &&
1022        cat >input <<-INPUT_END &&
1023        commit refs/heads/N1
1024        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1025        data <<COMMIT
1026        file copy
1027        COMMIT
1028
1029        from refs/heads/branch^0
1030        C file2/newf file2/n.e.w.f
1031
1032        INPUT_END
1033
1034        cat >expect <<-EOF &&
1035        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file2/n.e.w.f
1036        EOF
1037        git fast-import <input &&
1038        git diff-tree -C --find-copies-harder -r N1^ N1 >actual &&
1039        compare_diff_raw expect actual
1040'
1041
1042test_expect_success 'N: copy then modify subdirectory' '
1043        cat >input <<-INPUT_END &&
1044        commit refs/heads/N2
1045        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1046        data <<COMMIT
1047        clean directory copy
1048        COMMIT
1049
1050        from refs/heads/branch^0
1051        C file2 file3
1052
1053        commit refs/heads/N2
1054        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1055        data <<COMMIT
1056        modify directory copy
1057        COMMIT
1058
1059        M 644 inline file3/file5
1060        data <<EOF
1061        $file5_data
1062        EOF
1063
1064        INPUT_END
1065
1066        cat >expect <<-EOF &&
1067        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      file3/file5
1068        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1069        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1070        EOF
1071        git fast-import <input &&
1072        git diff-tree -C --find-copies-harder -r N2^^ N2 >actual &&
1073        compare_diff_raw expect actual
1074'
1075
1076test_expect_success 'N: copy dirty subdirectory' '
1077        cat >input <<-INPUT_END &&
1078        commit refs/heads/N3
1079        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1080        data <<COMMIT
1081        dirty directory copy
1082        COMMIT
1083
1084        from refs/heads/branch^0
1085        M 644 inline file2/file5
1086        data <<EOF
1087        $file5_data
1088        EOF
1089
1090        C file2 file3
1091        D file2/file5
1092
1093        INPUT_END
1094
1095        git fast-import <input &&
1096        test $(git rev-parse N2^{tree}) = $(git rev-parse N3^{tree})
1097'
1098
1099test_expect_success 'N: copy directory by id' '
1100        cat >expect <<-\EOF &&
1101        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1102        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1103        EOF
1104        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1105        cat >input <<-INPUT_END &&
1106        commit refs/heads/N4
1107        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1108        data <<COMMIT
1109        copy by tree hash
1110        COMMIT
1111
1112        from refs/heads/branch^0
1113        M 040000 $subdir file3
1114        INPUT_END
1115        git fast-import <input &&
1116        git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
1117        compare_diff_raw expect actual
1118'
1119
1120test_expect_success PIPE 'N: read and copy directory' '
1121        cat >expect <<-\EOF &&
1122        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1123        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1124        EOF
1125        git update-ref -d refs/heads/N4 &&
1126        rm -f backflow &&
1127        mkfifo backflow &&
1128        (
1129                exec <backflow &&
1130                cat <<-EOF &&
1131                commit refs/heads/N4
1132                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1133                data <<COMMIT
1134                copy by tree hash, part 2
1135                COMMIT
1136
1137                from refs/heads/branch^0
1138                ls "file2"
1139                EOF
1140                read mode type tree filename &&
1141                echo "M 040000 $tree file3"
1142        ) |
1143        git fast-import --cat-blob-fd=3 3>backflow &&
1144        git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
1145        compare_diff_raw expect actual
1146'
1147
1148test_expect_success PIPE 'N: empty directory reads as missing' '
1149        cat <<-\EOF >expect &&
1150        OBJNAME
1151        :000000 100644 OBJNAME OBJNAME A        unrelated
1152        EOF
1153        echo "missing src" >expect.response &&
1154        git update-ref -d refs/heads/read-empty &&
1155        rm -f backflow &&
1156        mkfifo backflow &&
1157        (
1158                exec <backflow &&
1159                cat <<-EOF &&
1160                commit refs/heads/read-empty
1161                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1162                data <<COMMIT
1163                read "empty" (missing) directory
1164                COMMIT
1165
1166                M 100644 inline src/greeting
1167                data <<BLOB
1168                hello
1169                BLOB
1170                C src/greeting dst1/non-greeting
1171                C src/greeting unrelated
1172                # leave behind "empty" src directory
1173                D src/greeting
1174                ls "src"
1175                EOF
1176                read -r line &&
1177                printf "%s\n" "$line" >response &&
1178                cat <<-\EOF
1179                D dst1
1180                D dst2
1181                EOF
1182        ) |
1183        git fast-import --cat-blob-fd=3 3>backflow &&
1184        test_cmp expect.response response &&
1185        git rev-list read-empty |
1186        git diff-tree -r --root --stdin |
1187        sed "s/$_x40/OBJNAME/g" >actual &&
1188        test_cmp expect actual
1189'
1190
1191test_expect_success 'N: copy root directory by tree hash' '
1192        cat >expect <<-\EOF &&
1193        :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D      file3/newf
1194        :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D      file3/oldf
1195        EOF
1196        root=$(git rev-parse refs/heads/branch^0^{tree}) &&
1197        cat >input <<-INPUT_END &&
1198        commit refs/heads/N6
1199        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1200        data <<COMMIT
1201        copy root directory by tree hash
1202        COMMIT
1203
1204        from refs/heads/branch^0
1205        M 040000 $root ""
1206        INPUT_END
1207        git fast-import <input &&
1208        git diff-tree -C --find-copies-harder -r N4 N6 >actual &&
1209        compare_diff_raw expect actual
1210'
1211
1212test_expect_success 'N: copy root by path' '
1213        cat >expect <<-\EOF &&
1214        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      oldroot/file2/newf
1215        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      oldroot/file2/oldf
1216        :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100   file4   oldroot/file4
1217        :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100   newdir/exec.sh  oldroot/newdir/exec.sh
1218        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      oldroot/newdir/interesting
1219        EOF
1220        cat >input <<-INPUT_END &&
1221        commit refs/heads/N-copy-root-path
1222        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1223        data <<COMMIT
1224        copy root directory by (empty) path
1225        COMMIT
1226
1227        from refs/heads/branch^0
1228        C "" oldroot
1229        INPUT_END
1230        git fast-import <input &&
1231        git diff-tree -C --find-copies-harder -r branch N-copy-root-path >actual &&
1232        compare_diff_raw expect actual
1233'
1234
1235test_expect_success 'N: delete directory by copying' '
1236        cat >expect <<-\EOF &&
1237        OBJID
1238        :100644 000000 OBJID OBJID D    foo/bar/qux
1239        OBJID
1240        :000000 100644 OBJID OBJID A    foo/bar/baz
1241        :000000 100644 OBJID OBJID A    foo/bar/qux
1242        EOF
1243        empty_tree=$(git mktree </dev/null) &&
1244        cat >input <<-INPUT_END &&
1245        commit refs/heads/N-delete
1246        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1247        data <<COMMIT
1248        collect data to be deleted
1249        COMMIT
1250
1251        deleteall
1252        M 100644 inline foo/bar/baz
1253        data <<DATA_END
1254        hello
1255        DATA_END
1256        C "foo/bar/baz" "foo/bar/qux"
1257        C "foo/bar/baz" "foo/bar/quux/1"
1258        C "foo/bar/baz" "foo/bar/quuux"
1259        M 040000 $empty_tree foo/bar/quux
1260        M 040000 $empty_tree foo/bar/quuux
1261
1262        commit refs/heads/N-delete
1263        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1264        data <<COMMIT
1265        delete subdirectory
1266        COMMIT
1267
1268        M 040000 $empty_tree foo/bar/qux
1269        INPUT_END
1270        git fast-import <input &&
1271        git rev-list N-delete |
1272                git diff-tree -r --stdin --root --always |
1273                sed -e "s/$_x40/OBJID/g" >actual &&
1274        test_cmp expect actual
1275'
1276
1277test_expect_success 'N: modify copied tree' '
1278        cat >expect <<-\EOF &&
1279        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      file3/file5
1280        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1281        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1282        EOF
1283        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1284        cat >input <<-INPUT_END &&
1285        commit refs/heads/N5
1286        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1287        data <<COMMIT
1288        copy by tree hash
1289        COMMIT
1290
1291        from refs/heads/branch^0
1292        M 040000 $subdir file3
1293
1294        commit refs/heads/N5
1295        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1296        data <<COMMIT
1297        modify directory copy
1298        COMMIT
1299
1300        M 644 inline file3/file5
1301        data <<EOF
1302        $file5_data
1303        EOF
1304        INPUT_END
1305        git fast-import <input &&
1306        git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
1307        compare_diff_raw expect actual
1308'
1309
1310test_expect_success 'N: reject foo/ syntax' '
1311        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1312        test_must_fail git fast-import <<-INPUT_END
1313        commit refs/heads/N5B
1314        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1315        data <<COMMIT
1316        copy with invalid syntax
1317        COMMIT
1318
1319        from refs/heads/branch^0
1320        M 040000 $subdir file3/
1321        INPUT_END
1322'
1323
1324test_expect_success 'N: reject foo/ syntax in copy source' '
1325        test_must_fail git fast-import <<-INPUT_END
1326        commit refs/heads/N5C
1327        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1328        data <<COMMIT
1329        copy with invalid syntax
1330        COMMIT
1331
1332        from refs/heads/branch^0
1333        C file2/ file3
1334        INPUT_END
1335'
1336
1337test_expect_success 'N: reject foo/ syntax in rename source' '
1338        test_must_fail git fast-import <<-INPUT_END
1339        commit refs/heads/N5D
1340        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1341        data <<COMMIT
1342        rename with invalid syntax
1343        COMMIT
1344
1345        from refs/heads/branch^0
1346        R file2/ file3
1347        INPUT_END
1348'
1349
1350test_expect_success 'N: reject foo/ syntax in ls argument' '
1351        test_must_fail git fast-import <<-INPUT_END
1352        commit refs/heads/N5E
1353        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1354        data <<COMMIT
1355        copy with invalid syntax
1356        COMMIT
1357
1358        from refs/heads/branch^0
1359        ls "file2/"
1360        INPUT_END
1361'
1362
1363test_expect_success 'N: copy to root by id and modify' '
1364        echo "hello, world" >expect.foo &&
1365        echo hello >expect.bar &&
1366        git fast-import <<-SETUP_END &&
1367        commit refs/heads/N7
1368        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1369        data <<COMMIT
1370        hello, tree
1371        COMMIT
1372
1373        deleteall
1374        M 644 inline foo/bar
1375        data <<EOF
1376        hello
1377        EOF
1378        SETUP_END
1379
1380        tree=$(git rev-parse --verify N7:) &&
1381        git fast-import <<-INPUT_END &&
1382        commit refs/heads/N8
1383        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1384        data <<COMMIT
1385        copy to root by id and modify
1386        COMMIT
1387
1388        M 040000 $tree ""
1389        M 644 inline foo/foo
1390        data <<EOF
1391        hello, world
1392        EOF
1393        INPUT_END
1394        git show N8:foo/foo >actual.foo &&
1395        git show N8:foo/bar >actual.bar &&
1396        test_cmp expect.foo actual.foo &&
1397        test_cmp expect.bar actual.bar
1398'
1399
1400test_expect_success 'N: extract subtree' '
1401        branch=$(git rev-parse --verify refs/heads/branch^{tree}) &&
1402        cat >input <<-INPUT_END &&
1403        commit refs/heads/N9
1404        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1405        data <<COMMIT
1406        extract subtree branch:newdir
1407        COMMIT
1408
1409        M 040000 $branch ""
1410        C "newdir" ""
1411        INPUT_END
1412        git fast-import <input &&
1413        git diff --exit-code branch:newdir N9
1414'
1415
1416test_expect_success 'N: modify subtree, extract it, and modify again' '
1417        echo hello >expect.baz &&
1418        echo hello, world >expect.qux &&
1419        git fast-import <<-SETUP_END &&
1420        commit refs/heads/N10
1421        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1422        data <<COMMIT
1423        hello, tree
1424        COMMIT
1425
1426        deleteall
1427        M 644 inline foo/bar/baz
1428        data <<EOF
1429        hello
1430        EOF
1431        SETUP_END
1432
1433        tree=$(git rev-parse --verify N10:) &&
1434        git fast-import <<-INPUT_END &&
1435        commit refs/heads/N11
1436        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1437        data <<COMMIT
1438        copy to root by id and modify
1439        COMMIT
1440
1441        M 040000 $tree ""
1442        M 100644 inline foo/bar/qux
1443        data <<EOF
1444        hello, world
1445        EOF
1446        R "foo" ""
1447        C "bar/qux" "bar/quux"
1448        INPUT_END
1449        git show N11:bar/baz >actual.baz &&
1450        git show N11:bar/qux >actual.qux &&
1451        git show N11:bar/quux >actual.quux &&
1452        test_cmp expect.baz actual.baz &&
1453        test_cmp expect.qux actual.qux &&
1454        test_cmp expect.qux actual.quux'
1455
1456###
1457### series O
1458###
1459
1460test_expect_success 'O: comments are all skipped' '
1461        cat >input <<-INPUT_END &&
1462        #we will
1463        commit refs/heads/O1
1464        # -- ignore all of this text
1465        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1466        # $GIT_COMMITTER_NAME has inserted here for his benefit.
1467        data <<COMMIT
1468        dirty directory copy
1469        COMMIT
1470
1471        # do not forget the import blank line!
1472        #
1473        # yes, we started from our usual base of branch^0.
1474        # i like branch^0.
1475        from refs/heads/branch^0
1476        # and we need to reuse file2/file5 from N3 above.
1477        M 644 inline file2/file5
1478        # otherwise the tree will be different
1479        data <<EOF
1480        $file5_data
1481        EOF
1482
1483        # do not forget to copy file2 to file3
1484        C file2 file3
1485        #
1486        # or to delete file5 from file2.
1487        D file2/file5
1488        # are we done yet?
1489
1490        INPUT_END
1491
1492        git fast-import <input &&
1493        test $(git rev-parse N3) = $(git rev-parse O1)
1494'
1495
1496test_expect_success 'O: blank lines not necessary after data commands' '
1497        cat >input <<-INPUT_END &&
1498        commit refs/heads/O2
1499        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1500        data <<COMMIT
1501        dirty directory copy
1502        COMMIT
1503        from refs/heads/branch^0
1504        M 644 inline file2/file5
1505        data <<EOF
1506        $file5_data
1507        EOF
1508        C file2 file3
1509        D file2/file5
1510
1511        INPUT_END
1512
1513        git fast-import <input &&
1514        test $(git rev-parse N3) = $(git rev-parse O2)
1515'
1516
1517test_expect_success 'O: repack before next test' '
1518        git repack -a -d
1519'
1520
1521test_expect_success 'O: blank lines not necessary after other commands' '
1522        cat >input <<-INPUT_END &&
1523        commit refs/heads/O3
1524        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1525        data <<COMMIT
1526        zstring
1527        COMMIT
1528        commit refs/heads/O3
1529        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1530        data <<COMMIT
1531        zof
1532        COMMIT
1533        checkpoint
1534        commit refs/heads/O3
1535        mark :5
1536        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1537        data <<COMMIT
1538        zempty
1539        COMMIT
1540        checkpoint
1541        commit refs/heads/O3
1542        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1543        data <<COMMIT
1544        zcommits
1545        COMMIT
1546        reset refs/tags/O3-2nd
1547        from :5
1548        reset refs/tags/O3-3rd
1549        from :5
1550        INPUT_END
1551
1552        cat >expect <<-INPUT_END &&
1553        string
1554        of
1555        empty
1556        commits
1557        INPUT_END
1558
1559        git fast-import <input &&
1560        test 8 = $(find .git/objects/pack -type f | wc -l) &&
1561        test $(git rev-parse refs/tags/O3-2nd) = $(git rev-parse O3^) &&
1562        git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
1563        test_cmp expect actual
1564'
1565
1566test_expect_success 'O: progress outputs as requested by input' '
1567        cat >input <<-INPUT_END &&
1568        commit refs/heads/O4
1569        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1570        data <<COMMIT
1571        zstring
1572        COMMIT
1573        commit refs/heads/O4
1574        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1575        data <<COMMIT
1576        zof
1577        COMMIT
1578        progress Two commits down, 2 to go!
1579        commit refs/heads/O4
1580        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1581        data <<COMMIT
1582        zempty
1583        COMMIT
1584        progress Three commits down, 1 to go!
1585        commit refs/heads/O4
1586        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1587        data <<COMMIT
1588        zcommits
1589        COMMIT
1590        progress done!
1591        INPUT_END
1592        git fast-import <input >actual &&
1593        grep "progress " <input >expect &&
1594        test_cmp expect actual
1595'
1596
1597###
1598### series P (gitlinks)
1599###
1600
1601test_expect_success 'P: superproject & submodule mix' '
1602        cat >input <<-INPUT_END &&
1603        blob
1604        mark :1
1605        data 10
1606        test file
1607
1608        reset refs/heads/sub
1609        commit refs/heads/sub
1610        mark :2
1611        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1612        data 12
1613        sub_initial
1614        M 100644 :1 file
1615
1616        blob
1617        mark :3
1618        data <<DATAEND
1619        [submodule "sub"]
1620                path = sub
1621                url = "$(pwd)/sub"
1622        DATAEND
1623
1624        commit refs/heads/subuse1
1625        mark :4
1626        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1627        data 8
1628        initial
1629        from refs/heads/master
1630        M 100644 :3 .gitmodules
1631        M 160000 :2 sub
1632
1633        blob
1634        mark :5
1635        data 20
1636        test file
1637        more data
1638
1639        commit refs/heads/sub
1640        mark :6
1641        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1642        data 11
1643        sub_second
1644        from :2
1645        M 100644 :5 file
1646
1647        commit refs/heads/subuse1
1648        mark :7
1649        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1650        data 7
1651        second
1652        from :4
1653        M 160000 :6 sub
1654
1655        INPUT_END
1656
1657        git fast-import <input &&
1658        git checkout subuse1 &&
1659        rm -rf sub &&
1660        mkdir sub &&
1661        (
1662                cd sub &&
1663                git init &&
1664                git fetch --update-head-ok .. refs/heads/sub:refs/heads/master &&
1665                git checkout master
1666        ) &&
1667        git submodule init &&
1668        git submodule update
1669'
1670
1671test_expect_success 'P: verbatim SHA gitlinks' '
1672        SUBLAST=$(git rev-parse --verify sub) &&
1673        SUBPREV=$(git rev-parse --verify sub^) &&
1674
1675        cat >input <<-INPUT_END &&
1676        blob
1677        mark :1
1678        data <<DATAEND
1679        [submodule "sub"]
1680                path = sub
1681                url = "$(pwd)/sub"
1682        DATAEND
1683
1684        commit refs/heads/subuse2
1685        mark :2
1686        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1687        data 8
1688        initial
1689        from refs/heads/master
1690        M 100644 :1 .gitmodules
1691        M 160000 $SUBPREV sub
1692
1693        commit refs/heads/subuse2
1694        mark :3
1695        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1696        data 7
1697        second
1698        from :2
1699        M 160000 $SUBLAST sub
1700
1701        INPUT_END
1702
1703        git branch -D sub &&
1704        git gc &&
1705        git prune &&
1706        git fast-import <input &&
1707        test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
1708'
1709
1710test_expect_success 'P: fail on inline gitlink' '
1711        test_tick &&
1712        cat >input <<-INPUT_END &&
1713        commit refs/heads/subuse3
1714        mark :1
1715        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1716        data <<COMMIT
1717        corrupt
1718        COMMIT
1719
1720        from refs/heads/subuse2
1721        M 160000 inline sub
1722        data <<DATA
1723        $SUBPREV
1724        DATA
1725
1726        INPUT_END
1727
1728        test_must_fail git fast-import <input
1729'
1730
1731test_expect_success 'P: fail on blob mark in gitlink' '
1732        test_tick &&
1733        cat >input <<-INPUT_END &&
1734        blob
1735        mark :1
1736        data <<DATA
1737        $SUBPREV
1738        DATA
1739
1740        commit refs/heads/subuse3
1741        mark :2
1742        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1743        data <<COMMIT
1744        corrupt
1745        COMMIT
1746
1747        from refs/heads/subuse2
1748        M 160000 :1 sub
1749
1750        INPUT_END
1751
1752        test_must_fail git fast-import <input
1753'
1754
1755###
1756### series Q (notes)
1757###
1758
1759test_expect_success 'Q: commit notes' '
1760        note1_data="The first note for the first commit" &&
1761        note2_data="The first note for the second commit" &&
1762        note3_data="The first note for the third commit" &&
1763        note1b_data="The second note for the first commit" &&
1764        note1c_data="The third note for the first commit" &&
1765        note2b_data="The second note for the second commit" &&
1766
1767        test_tick &&
1768        cat >input <<-INPUT_END &&
1769        blob
1770        mark :2
1771        data <<EOF
1772        $file2_data
1773        EOF
1774
1775        commit refs/heads/notes-test
1776        mark :3
1777        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1778        data <<COMMIT
1779        first (:3)
1780        COMMIT
1781
1782        M 644 :2 file2
1783
1784        blob
1785        mark :4
1786        data $file4_len
1787        $file4_data
1788        commit refs/heads/notes-test
1789        mark :5
1790        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1791        data <<COMMIT
1792        second (:5)
1793        COMMIT
1794
1795        M 644 :4 file4
1796
1797        commit refs/heads/notes-test
1798        mark :6
1799        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1800        data <<COMMIT
1801        third (:6)
1802        COMMIT
1803
1804        M 644 inline file5
1805        data <<EOF
1806        $file5_data
1807        EOF
1808
1809        M 755 inline file6
1810        data <<EOF
1811        $file6_data
1812        EOF
1813
1814        blob
1815        mark :7
1816        data <<EOF
1817        $note1_data
1818        EOF
1819
1820        blob
1821        mark :8
1822        data <<EOF
1823        $note2_data
1824        EOF
1825
1826        commit refs/notes/foobar
1827        mark :9
1828        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1829        data <<COMMIT
1830        notes (:9)
1831        COMMIT
1832
1833        N :7 :3
1834        N :8 :5
1835        N inline :6
1836        data <<EOF
1837        $note3_data
1838        EOF
1839
1840        commit refs/notes/foobar
1841        mark :10
1842        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1843        data <<COMMIT
1844        notes (:10)
1845        COMMIT
1846
1847        N inline :3
1848        data <<EOF
1849        $note1b_data
1850        EOF
1851
1852        commit refs/notes/foobar2
1853        mark :11
1854        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1855        data <<COMMIT
1856        notes (:11)
1857        COMMIT
1858
1859        N inline :3
1860        data <<EOF
1861        $note1c_data
1862        EOF
1863
1864        commit refs/notes/foobar
1865        mark :12
1866        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1867        data <<COMMIT
1868        notes (:12)
1869        COMMIT
1870
1871        deleteall
1872        N inline :5
1873        data <<EOF
1874        $note2b_data
1875        EOF
1876
1877        INPUT_END
1878
1879        git fast-import <input &&
1880        git whatchanged notes-test
1881'
1882
1883test_expect_success 'Q: verify pack' '
1884        verify_packs
1885'
1886
1887test_expect_success 'Q: verify first commit' '
1888        commit1=$(git rev-parse notes-test~2) &&
1889        commit2=$(git rev-parse notes-test^) &&
1890        commit3=$(git rev-parse notes-test) &&
1891
1892        cat >expect <<-EOF &&
1893        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1894        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1895
1896        first (:3)
1897        EOF
1898        git cat-file commit notes-test~2 | sed 1d >actual &&
1899        test_cmp expect actual
1900'
1901
1902test_expect_success 'Q: verify second commit' '
1903        cat >expect <<-EOF &&
1904        parent $commit1
1905        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1906        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1907
1908        second (:5)
1909        EOF
1910        git cat-file commit notes-test^ | sed 1d >actual &&
1911        test_cmp expect actual
1912'
1913
1914test_expect_success 'Q: verify third commit' '
1915        cat >expect <<-EOF &&
1916        parent $commit2
1917        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1918        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1919
1920        third (:6)
1921        EOF
1922        git cat-file commit notes-test | sed 1d >actual &&
1923        test_cmp expect actual
1924'
1925
1926test_expect_success 'Q: verify first notes commit' '
1927        cat >expect <<-EOF &&
1928        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1929        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1930
1931        notes (:9)
1932        EOF
1933        git cat-file commit refs/notes/foobar~2 | sed 1d >actual &&
1934        test_cmp expect actual
1935'
1936
1937test_expect_success 'Q: verify first notes tree' '
1938        cat >expect.unsorted <<-EOF &&
1939        100644 blob $commit1
1940        100644 blob $commit2
1941        100644 blob $commit3
1942        EOF
1943        cat expect.unsorted | sort >expect &&
1944        git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]*  / /" >actual &&
1945        test_cmp expect actual
1946'
1947
1948test_expect_success 'Q: verify first note for first commit' '
1949        echo "$note1_data" >expect &&
1950        git cat-file blob refs/notes/foobar~2:$commit1 >actual &&
1951        test_cmp expect actual
1952'
1953
1954test_expect_success 'Q: verify first note for second commit' '
1955        echo "$note2_data" >expect &&
1956        git cat-file blob refs/notes/foobar~2:$commit2 >actual &&
1957        test_cmp expect actual
1958'
1959
1960test_expect_success 'Q: verify first note for third commit' '
1961        echo "$note3_data" >expect &&
1962        git cat-file blob refs/notes/foobar~2:$commit3 >actual &&
1963        test_cmp expect actual
1964'
1965
1966test_expect_success 'Q: verify second notes commit' '
1967        cat >expect <<-EOF &&
1968        parent $(git rev-parse --verify refs/notes/foobar~2)
1969        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1970        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1971
1972        notes (:10)
1973        EOF
1974        git cat-file commit refs/notes/foobar^ | sed 1d >actual &&
1975        test_cmp expect actual
1976'
1977
1978test_expect_success 'Q: verify second notes tree' '
1979        cat >expect.unsorted <<-EOF &&
1980        100644 blob $commit1
1981        100644 blob $commit2
1982        100644 blob $commit3
1983        EOF
1984        cat expect.unsorted | sort >expect &&
1985        git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]*   / /" >actual &&
1986        test_cmp expect actual
1987'
1988
1989test_expect_success 'Q: verify second note for first commit' '
1990        echo "$note1b_data" >expect &&
1991        git cat-file blob refs/notes/foobar^:$commit1 >actual &&
1992        test_cmp expect actual
1993'
1994
1995test_expect_success 'Q: verify first note for second commit' '
1996        echo "$note2_data" >expect &&
1997        git cat-file blob refs/notes/foobar^:$commit2 >actual &&
1998        test_cmp expect actual
1999'
2000
2001test_expect_success 'Q: verify first note for third commit' '
2002        echo "$note3_data" >expect &&
2003        git cat-file blob refs/notes/foobar^:$commit3 >actual &&
2004        test_cmp expect actual
2005'
2006
2007test_expect_success 'Q: verify third notes commit' '
2008        cat >expect <<-EOF &&
2009        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2010        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2011
2012        notes (:11)
2013        EOF
2014        git cat-file commit refs/notes/foobar2 | sed 1d >actual &&
2015        test_cmp expect actual
2016'
2017
2018test_expect_success 'Q: verify third notes tree' '
2019        cat >expect.unsorted <<-EOF &&
2020        100644 blob $commit1
2021        EOF
2022        cat expect.unsorted | sort >expect &&
2023        git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]*   / /" >actual &&
2024        test_cmp expect actual
2025'
2026
2027test_expect_success 'Q: verify third note for first commit' '
2028        echo "$note1c_data" >expect &&
2029        git cat-file blob refs/notes/foobar2:$commit1 >actual &&
2030        test_cmp expect actual
2031'
2032
2033test_expect_success 'Q: verify fourth notes commit' '
2034        cat >expect <<-EOF &&
2035        parent $(git rev-parse --verify refs/notes/foobar^)
2036        author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2037        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2038
2039        notes (:12)
2040        EOF
2041        git cat-file commit refs/notes/foobar | sed 1d >actual &&
2042        test_cmp expect actual
2043'
2044
2045test_expect_success 'Q: verify fourth notes tree' '
2046        cat >expect.unsorted <<-EOF &&
2047        100644 blob $commit2
2048        EOF
2049        cat expect.unsorted | sort >expect &&
2050        git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]*    / /" >actual &&
2051        test_cmp expect actual
2052'
2053
2054test_expect_success 'Q: verify second note for second commit' '
2055        echo "$note2b_data" >expect &&
2056        git cat-file blob refs/notes/foobar:$commit2 >actual &&
2057        test_cmp expect actual
2058'
2059
2060test_expect_success 'Q: deny note on empty branch' '
2061        cat >input <<-EOF &&
2062        reset refs/heads/Q0
2063
2064        commit refs/heads/note-Q0
2065        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2066        data <<COMMIT
2067        Note for an empty branch.
2068        COMMIT
2069
2070        N inline refs/heads/Q0
2071        data <<NOTE
2072        some note
2073        NOTE
2074        EOF
2075        test_must_fail git fast-import <input
2076'
2077###
2078### series R (feature and option)
2079###
2080
2081test_expect_success 'R: abort on unsupported feature' '
2082        cat >input <<-EOF &&
2083        feature no-such-feature-exists
2084        EOF
2085
2086        test_must_fail git fast-import <input
2087'
2088
2089test_expect_success 'R: supported feature is accepted' '
2090        cat >input <<-EOF &&
2091        feature date-format=now
2092        EOF
2093
2094        git fast-import <input
2095'
2096
2097test_expect_success 'R: abort on receiving feature after data command' '
2098        cat >input <<-EOF &&
2099        blob
2100        data 3
2101        hi
2102        feature date-format=now
2103        EOF
2104
2105        test_must_fail git fast-import <input
2106'
2107
2108test_expect_success 'R: only one import-marks feature allowed per stream' '
2109        cat >input <<-EOF &&
2110        feature import-marks=git.marks
2111        feature import-marks=git2.marks
2112        EOF
2113
2114        test_must_fail git fast-import <input
2115'
2116
2117test_expect_success 'R: export-marks feature results in a marks file being created' '
2118        cat >input <<-EOF &&
2119        feature export-marks=git.marks
2120        blob
2121        mark :1
2122        data 3
2123        hi
2124
2125        EOF
2126
2127        cat input | git fast-import &&
2128        grep :1 git.marks
2129'
2130
2131test_expect_success 'R: export-marks options can be overridden by commandline options' '
2132        cat input | git fast-import --export-marks=other.marks &&
2133        grep :1 other.marks
2134'
2135
2136test_expect_success 'R: catch typo in marks file name' '
2137        test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
2138        echo "feature import-marks=nonexistent.marks" |
2139        test_must_fail git fast-import
2140'
2141
2142test_expect_success 'R: import and output marks can be the same file' '
2143        rm -f io.marks &&
2144        blob=$(echo hi | git hash-object --stdin) &&
2145        cat >expect <<-EOF &&
2146        :1 $blob
2147        :2 $blob
2148        EOF
2149        git fast-import --export-marks=io.marks <<-\EOF &&
2150        blob
2151        mark :1
2152        data 3
2153        hi
2154
2155        EOF
2156        git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
2157        blob
2158        mark :2
2159        data 3
2160        hi
2161
2162        EOF
2163        test_cmp expect io.marks
2164'
2165
2166test_expect_success 'R: --import-marks=foo --output-marks=foo to create foo fails' '
2167        rm -f io.marks &&
2168        test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF
2169        blob
2170        mark :1
2171        data 3
2172        hi
2173
2174        EOF
2175'
2176
2177test_expect_success 'R: --import-marks-if-exists' '
2178        rm -f io.marks &&
2179        blob=$(echo hi | git hash-object --stdin) &&
2180        echo ":1 $blob" >expect &&
2181        git fast-import --import-marks-if-exists=io.marks --export-marks=io.marks <<-\EOF &&
2182        blob
2183        mark :1
2184        data 3
2185        hi
2186
2187        EOF
2188        test_cmp expect io.marks
2189'
2190
2191test_expect_success 'R: feature import-marks-if-exists' '
2192        rm -f io.marks &&
2193        >expect &&
2194
2195        git fast-import --export-marks=io.marks <<-\EOF &&
2196        feature import-marks-if-exists=not_io.marks
2197        EOF
2198        test_cmp expect io.marks &&
2199
2200        blob=$(echo hi | git hash-object --stdin) &&
2201
2202        echo ":1 $blob" >io.marks &&
2203        echo ":1 $blob" >expect &&
2204        echo ":2 $blob" >>expect &&
2205
2206        git fast-import --export-marks=io.marks <<-\EOF &&
2207        feature import-marks-if-exists=io.marks
2208        blob
2209        mark :2
2210        data 3
2211        hi
2212
2213        EOF
2214        test_cmp expect io.marks &&
2215
2216        echo ":3 $blob" >>expect &&
2217
2218        git fast-import --import-marks=io.marks \
2219                        --export-marks=io.marks <<-\EOF &&
2220        feature import-marks-if-exists=not_io.marks
2221        blob
2222        mark :3
2223        data 3
2224        hi
2225
2226        EOF
2227        test_cmp expect io.marks &&
2228
2229        >expect &&
2230
2231        git fast-import --import-marks-if-exists=not_io.marks \
2232                        --export-marks=io.marks <<-\EOF &&
2233        feature import-marks-if-exists=io.marks
2234        EOF
2235        test_cmp expect io.marks
2236'
2237
2238test_expect_success 'R: import to output marks works without any content' '
2239        cat >input <<-EOF &&
2240        feature import-marks=marks.out
2241        feature export-marks=marks.new
2242        EOF
2243
2244        cat input | git fast-import &&
2245        test_cmp marks.out marks.new
2246'
2247
2248test_expect_success 'R: import marks prefers commandline marks file over the stream' '
2249        cat >input <<-EOF &&
2250        feature import-marks=nonexistent.marks
2251        feature export-marks=marks.new
2252        EOF
2253
2254        cat input | git fast-import --import-marks=marks.out &&
2255        test_cmp marks.out marks.new
2256'
2257
2258
2259test_expect_success 'R: multiple --import-marks= should be honoured' '
2260        cat >input <<-EOF &&
2261        feature import-marks=nonexistent.marks
2262        feature export-marks=combined.marks
2263        EOF
2264
2265        head -n2 marks.out > one.marks &&
2266        tail -n +3 marks.out > two.marks &&
2267        git fast-import --import-marks=one.marks --import-marks=two.marks <input &&
2268        test_cmp marks.out combined.marks
2269'
2270
2271test_expect_success 'R: feature relative-marks should be honoured' '
2272        cat >input <<-EOF &&
2273        feature relative-marks
2274        feature import-marks=relative.in
2275        feature export-marks=relative.out
2276        EOF
2277
2278        mkdir -p .git/info/fast-import/ &&
2279        cp marks.new .git/info/fast-import/relative.in &&
2280        git fast-import <input &&
2281        test_cmp marks.new .git/info/fast-import/relative.out
2282'
2283
2284test_expect_success 'R: feature no-relative-marks should be honoured' '
2285        cat >input <<-EOF &&
2286        feature relative-marks
2287        feature import-marks=relative.in
2288        feature no-relative-marks
2289        feature export-marks=non-relative.out
2290        EOF
2291
2292        git fast-import <input &&
2293        test_cmp marks.new non-relative.out
2294'
2295
2296test_expect_success 'R: feature ls supported' '
2297        echo "feature ls" |
2298        git fast-import
2299'
2300
2301test_expect_success 'R: feature cat-blob supported' '
2302        echo "feature cat-blob" |
2303        git fast-import
2304'
2305
2306test_expect_success 'R: cat-blob-fd must be a nonnegative integer' '
2307        test_must_fail git fast-import --cat-blob-fd=-1 </dev/null
2308'
2309
2310test_expect_success !MINGW 'R: print old blob' '
2311        blob=$(echo "yes it can" | git hash-object -w --stdin) &&
2312        cat >expect <<-EOF &&
2313        ${blob} blob 11
2314        yes it can
2315
2316        EOF
2317        echo "cat-blob $blob" |
2318        git fast-import --cat-blob-fd=6 6>actual &&
2319        test_cmp expect actual
2320'
2321
2322test_expect_success !MINGW 'R: in-stream cat-blob-fd not respected' '
2323        echo hello >greeting &&
2324        blob=$(git hash-object -w greeting) &&
2325        cat >expect <<-EOF &&
2326        ${blob} blob 6
2327        hello
2328
2329        EOF
2330        git fast-import --cat-blob-fd=3 3>actual.3 >actual.1 <<-EOF &&
2331        cat-blob $blob
2332        EOF
2333        test_cmp expect actual.3 &&
2334        test_must_be_empty actual.1 &&
2335        git fast-import 3>actual.3 >actual.1 <<-EOF &&
2336        option cat-blob-fd=3
2337        cat-blob $blob
2338        EOF
2339        test_must_be_empty actual.3 &&
2340        test_cmp expect actual.1
2341'
2342
2343test_expect_success !MINGW 'R: print mark for new blob' '
2344        echo "effluentish" | git hash-object --stdin >expect &&
2345        git fast-import --cat-blob-fd=6 6>actual <<-\EOF &&
2346        blob
2347        mark :1
2348        data <<BLOB_END
2349        effluentish
2350        BLOB_END
2351        get-mark :1
2352        EOF
2353        test_cmp expect actual
2354'
2355
2356test_expect_success !MINGW 'R: print new blob' '
2357        blob=$(echo "yep yep yep" | git hash-object --stdin) &&
2358        cat >expect <<-EOF &&
2359        ${blob} blob 12
2360        yep yep yep
2361
2362        EOF
2363        git fast-import --cat-blob-fd=6 6>actual <<-\EOF &&
2364        blob
2365        mark :1
2366        data <<BLOB_END
2367        yep yep yep
2368        BLOB_END
2369        cat-blob :1
2370        EOF
2371        test_cmp expect actual
2372'
2373
2374test_expect_success !MINGW 'R: print new blob by sha1' '
2375        blob=$(echo "a new blob named by sha1" | git hash-object --stdin) &&
2376        cat >expect <<-EOF &&
2377        ${blob} blob 25
2378        a new blob named by sha1
2379
2380        EOF
2381        git fast-import --cat-blob-fd=6 6>actual <<-EOF &&
2382        blob
2383        data <<BLOB_END
2384        a new blob named by sha1
2385        BLOB_END
2386        cat-blob $blob
2387        EOF
2388        test_cmp expect actual
2389'
2390
2391test_expect_success 'setup: big file' '
2392        (
2393                echo "the quick brown fox jumps over the lazy dog" >big &&
2394                for i in 1 2 3
2395                do
2396                        cat big big big big >bigger &&
2397                        cat bigger bigger bigger bigger >big ||
2398                        exit
2399                done
2400        )
2401'
2402
2403test_expect_success 'R: print two blobs to stdout' '
2404        blob1=$(git hash-object big) &&
2405        blob1_len=$(wc -c <big) &&
2406        blob2=$(echo hello | git hash-object --stdin) &&
2407        {
2408                echo ${blob1} blob $blob1_len &&
2409                cat big &&
2410                cat <<-EOF
2411
2412                ${blob2} blob 6
2413                hello
2414
2415                EOF
2416        } >expect &&
2417        {
2418                cat <<-\END_PART1 &&
2419                        blob
2420                        mark :1
2421                        data <<data_end
2422                END_PART1
2423                cat big &&
2424                cat <<-\EOF
2425                        data_end
2426                        blob
2427                        mark :2
2428                        data <<data_end
2429                        hello
2430                        data_end
2431                        cat-blob :1
2432                        cat-blob :2
2433                EOF
2434        } |
2435        git fast-import >actual &&
2436        test_cmp expect actual
2437'
2438
2439test_expect_success PIPE 'R: copy using cat-file' '
2440        expect_id=$(git hash-object big) &&
2441        expect_len=$(wc -c <big) &&
2442        echo $expect_id blob $expect_len >expect.response &&
2443
2444        rm -f blobs &&
2445        cat >frontend <<-\FRONTEND_END &&
2446        #!/bin/sh
2447        FRONTEND_END
2448
2449        mkfifo blobs &&
2450        (
2451                export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_COMMITTER_DATE &&
2452                cat <<-\EOF &&
2453                feature cat-blob
2454                blob
2455                mark :1
2456                data <<BLOB
2457                EOF
2458                cat big &&
2459                cat <<-\EOF &&
2460                BLOB
2461                cat-blob :1
2462                EOF
2463
2464                read blob_id type size <&3 &&
2465                echo "$blob_id $type $size" >response &&
2466                test_copy_bytes $size >blob <&3 &&
2467                read newline <&3 &&
2468
2469                cat <<-EOF &&
2470                commit refs/heads/copied
2471                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2472                data <<COMMIT
2473                copy big file as file3
2474                COMMIT
2475                M 644 inline file3
2476                data <<BLOB
2477                EOF
2478                cat blob &&
2479                echo BLOB
2480        ) 3<blobs |
2481        git fast-import --cat-blob-fd=3 3>blobs &&
2482        git show copied:file3 >actual &&
2483        test_cmp expect.response response &&
2484        test_cmp big actual
2485'
2486
2487test_expect_success PIPE 'R: print blob mid-commit' '
2488        rm -f blobs &&
2489        echo "A blob from _before_ the commit." >expect &&
2490        mkfifo blobs &&
2491        (
2492                exec 3<blobs &&
2493                cat <<-EOF &&
2494                feature cat-blob
2495                blob
2496                mark :1
2497                data <<BLOB
2498                A blob from _before_ the commit.
2499                BLOB
2500                commit refs/heads/temporary
2501                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2502                data <<COMMIT
2503                Empty commit
2504                COMMIT
2505                cat-blob :1
2506                EOF
2507
2508                read blob_id type size <&3 &&
2509                test_copy_bytes $size >actual <&3 &&
2510                read newline <&3 &&
2511
2512                echo
2513        ) |
2514        git fast-import --cat-blob-fd=3 3>blobs &&
2515        test_cmp expect actual
2516'
2517
2518test_expect_success PIPE 'R: print staged blob within commit' '
2519        rm -f blobs &&
2520        echo "A blob from _within_ the commit." >expect &&
2521        mkfifo blobs &&
2522        (
2523                exec 3<blobs &&
2524                cat <<-EOF &&
2525                feature cat-blob
2526                commit refs/heads/within
2527                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2528                data <<COMMIT
2529                Empty commit
2530                COMMIT
2531                M 644 inline within
2532                data <<BLOB
2533                A blob from _within_ the commit.
2534                BLOB
2535                EOF
2536
2537                to_get=$(
2538                        echo "A blob from _within_ the commit." |
2539                        git hash-object --stdin
2540                ) &&
2541                echo "cat-blob $to_get" &&
2542
2543                read blob_id type size <&3 &&
2544                test_copy_bytes $size >actual <&3 &&
2545                read newline <&3 &&
2546
2547                echo deleteall
2548        ) |
2549        git fast-import --cat-blob-fd=3 3>blobs &&
2550        test_cmp expect actual
2551'
2552
2553test_expect_success 'R: quiet option results in no stats being output' '
2554        cat >input <<-EOF &&
2555        option git quiet
2556        blob
2557        data 3
2558        hi
2559
2560        EOF
2561
2562        cat input | git fast-import 2> output &&
2563        test_must_be_empty output
2564'
2565
2566test_expect_success 'R: feature done means terminating "done" is mandatory' '
2567        echo feature done | test_must_fail git fast-import &&
2568        test_must_fail git fast-import --done </dev/null
2569'
2570
2571test_expect_success 'R: terminating "done" with trailing gibberish is ok' '
2572        git fast-import <<-\EOF &&
2573        feature done
2574        done
2575        trailing gibberish
2576        EOF
2577        git fast-import <<-\EOF
2578        done
2579        more trailing gibberish
2580        EOF
2581'
2582
2583test_expect_success 'R: terminating "done" within commit' '
2584        cat >expect <<-\EOF &&
2585        OBJID
2586        :000000 100644 OBJID OBJID A    hello.c
2587        :000000 100644 OBJID OBJID A    hello2.c
2588        EOF
2589        git fast-import <<-EOF &&
2590        commit refs/heads/done-ends
2591        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2592        data <<EOT
2593        Commit terminated by "done" command
2594        EOT
2595        M 100644 inline hello.c
2596        data <<EOT
2597        Hello, world.
2598        EOT
2599        C hello.c hello2.c
2600        done
2601        EOF
2602        git rev-list done-ends |
2603        git diff-tree -r --stdin --root --always |
2604        sed -e "s/$_x40/OBJID/g" >actual &&
2605        test_cmp expect actual
2606'
2607
2608test_expect_success 'R: die on unknown option' '
2609        cat >input <<-EOF &&
2610        option git non-existing-option
2611        EOF
2612
2613        test_must_fail git fast-import <input
2614'
2615
2616test_expect_success 'R: unknown commandline options are rejected' '\
2617        test_must_fail git fast-import --non-existing-option < /dev/null
2618'
2619
2620test_expect_success 'R: die on invalid option argument' '
2621        echo "option git active-branches=-5" |
2622        test_must_fail git fast-import &&
2623        echo "option git depth=" |
2624        test_must_fail git fast-import &&
2625        test_must_fail git fast-import --depth="5 elephants" </dev/null
2626'
2627
2628test_expect_success 'R: ignore non-git options' '
2629        cat >input <<-EOF &&
2630        option non-existing-vcs non-existing-option
2631        EOF
2632
2633        git fast-import <input
2634'
2635
2636test_expect_success 'R: corrupt lines do not mess marks file' '
2637        rm -f io.marks &&
2638        blob=$(echo hi | git hash-object --stdin) &&
2639        cat >expect <<-EOF &&
2640        :3 0000000000000000000000000000000000000000
2641        :1 $blob
2642        :2 $blob
2643        EOF
2644        cp expect io.marks &&
2645        test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
2646
2647        EOF
2648        test_cmp expect io.marks
2649'
2650
2651##
2652## R: very large blobs
2653##
2654test_expect_success 'R: blob bigger than threshold' '
2655        blobsize=$((2*1024*1024 + 53)) &&
2656        test-genrandom bar $blobsize >expect &&
2657        cat >input <<-INPUT_END &&
2658        commit refs/heads/big-file
2659        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2660        data <<COMMIT
2661        R - big file
2662        COMMIT
2663
2664        M 644 inline big1
2665        data $blobsize
2666        INPUT_END
2667        cat expect >>input &&
2668        cat >>input <<-INPUT_END &&
2669        M 644 inline big2
2670        data $blobsize
2671        INPUT_END
2672        cat expect >>input &&
2673        echo >>input &&
2674
2675        test_create_repo R &&
2676        git --git-dir=R/.git fast-import --big-file-threshold=1 <input
2677'
2678
2679test_expect_success 'R: verify created pack' '
2680        (
2681                cd R &&
2682                verify_packs -v > ../verify
2683        )
2684'
2685
2686test_expect_success 'R: verify written objects' '
2687        git --git-dir=R/.git cat-file blob big-file:big1 >actual &&
2688        test_cmp_bin expect actual &&
2689        a=$(git --git-dir=R/.git rev-parse big-file:big1) &&
2690        b=$(git --git-dir=R/.git rev-parse big-file:big2) &&
2691        test $a = $b
2692'
2693
2694test_expect_success 'R: blob appears only once' '
2695        n=$(grep $a verify | wc -l) &&
2696        test 1 = $n
2697'
2698
2699###
2700### series S
2701###
2702#
2703# Make sure missing spaces and EOLs after mark references
2704# cause errors.
2705#
2706# Setup:
2707#
2708#   1--2--4
2709#    \   /
2710#     -3-
2711#
2712#   commit marks:  301, 302, 303, 304
2713#   blob marks:              403, 404, resp.
2714#   note mark:          202
2715#
2716# The error message when a space is missing not at the
2717# end of the line is:
2718#
2719#   Missing space after ..
2720#
2721# or when extra characters come after the mark at the end
2722# of the line:
2723#
2724#   Garbage after ..
2725#
2726# or when the dataref is neither "inline " or a known SHA1,
2727#
2728#   Invalid dataref ..
2729#
2730test_expect_success 'S: initialize for S tests' '
2731        test_tick &&
2732
2733        cat >input <<-INPUT_END &&
2734        commit refs/heads/S
2735        mark :301
2736        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2737        data <<COMMIT
2738        commit 1
2739        COMMIT
2740        M 100644 inline hello.c
2741        data <<BLOB
2742        blob 1
2743        BLOB
2744
2745        commit refs/heads/S
2746        mark :302
2747        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2748        data <<COMMIT
2749        commit 2
2750        COMMIT
2751        from :301
2752        M 100644 inline hello.c
2753        data <<BLOB
2754        blob 2
2755        BLOB
2756
2757        blob
2758        mark :403
2759        data <<BLOB
2760        blob 3
2761        BLOB
2762
2763        blob
2764        mark :202
2765        data <<BLOB
2766        note 2
2767        BLOB
2768        INPUT_END
2769
2770        git fast-import --export-marks=marks <input
2771'
2772
2773#
2774# filemodify, three datarefs
2775#
2776test_expect_success 'S: filemodify with garbage after mark must fail' '
2777        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2778        commit refs/heads/S
2779        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2780        data <<COMMIT
2781        commit N
2782        COMMIT
2783        M 100644 :403x hello.c
2784        EOF
2785        cat err &&
2786        test_i18ngrep "space after mark" err
2787'
2788
2789# inline is misspelled; fast-import thinks it is some unknown dataref
2790test_expect_success 'S: filemodify with garbage after inline must fail' '
2791        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2792        commit refs/heads/S
2793        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2794        data <<COMMIT
2795        commit N
2796        COMMIT
2797        M 100644 inlineX hello.c
2798        data <<BLOB
2799        inline
2800        BLOB
2801        EOF
2802        cat err &&
2803        test_i18ngrep "nvalid dataref" err
2804'
2805
2806test_expect_success 'S: filemodify with garbage after sha1 must fail' '
2807        sha1=$(grep :403 marks | cut -d\  -f2) &&
2808        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2809        commit refs/heads/S
2810        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2811        data <<COMMIT
2812        commit N
2813        COMMIT
2814        M 100644 ${sha1}x hello.c
2815        EOF
2816        cat err &&
2817        test_i18ngrep "space after SHA1" err
2818'
2819
2820#
2821# notemodify, three ways to say dataref
2822#
2823test_expect_success 'S: notemodify with garabge after mark dataref must fail' '
2824        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2825        commit refs/heads/S
2826        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2827        data <<COMMIT
2828        commit S note dataref markref
2829        COMMIT
2830        N :202x :302
2831        EOF
2832        cat err &&
2833        test_i18ngrep "space after mark" err
2834'
2835
2836test_expect_success 'S: notemodify with garbage after inline dataref must fail' '
2837        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2838        commit refs/heads/S
2839        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2840        data <<COMMIT
2841        commit S note dataref inline
2842        COMMIT
2843        N inlineX :302
2844        data <<BLOB
2845        note blob
2846        BLOB
2847        EOF
2848        cat err &&
2849        test_i18ngrep "nvalid dataref" err
2850'
2851
2852test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' '
2853        sha1=$(grep :202 marks | cut -d\  -f2) &&
2854        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2855        commit refs/heads/S
2856        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2857        data <<COMMIT
2858        commit S note dataref sha1
2859        COMMIT
2860        N ${sha1}x :302
2861        EOF
2862        cat err &&
2863        test_i18ngrep "space after SHA1" err
2864'
2865
2866#
2867# notemodify, mark in commit-ish
2868#
2869test_expect_success 'S: notemodify with garbage after mark commit-ish must fail' '
2870        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2871        commit refs/heads/Snotes
2872        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2873        data <<COMMIT
2874        commit S note commit-ish
2875        COMMIT
2876        N :202 :302x
2877        EOF
2878        cat err &&
2879        test_i18ngrep "after mark" err
2880'
2881
2882#
2883# from
2884#
2885test_expect_success 'S: from with garbage after mark must fail' '
2886        test_must_fail \
2887        git fast-import --import-marks=marks --export-marks=marks <<-EOF 2>err &&
2888        commit refs/heads/S2
2889        mark :303
2890        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2891        data <<COMMIT
2892        commit 3
2893        COMMIT
2894        from :301x
2895        M 100644 :403 hello.c
2896        EOF
2897
2898
2899        # go create the commit, need it for merge test
2900        git fast-import --import-marks=marks --export-marks=marks <<-EOF &&
2901        commit refs/heads/S2
2902        mark :303
2903        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2904        data <<COMMIT
2905        commit 3
2906        COMMIT
2907        from :301
2908        M 100644 :403 hello.c
2909        EOF
2910
2911        # now evaluate the error
2912        cat err &&
2913        test_i18ngrep "after mark" err
2914'
2915
2916
2917#
2918# merge
2919#
2920test_expect_success 'S: merge with garbage after mark must fail' '
2921        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2922        commit refs/heads/S
2923        mark :304
2924        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2925        data <<COMMIT
2926        merge 4
2927        COMMIT
2928        from :302
2929        merge :303x
2930        M 100644 :403 hello.c
2931        EOF
2932        cat err &&
2933        test_i18ngrep "after mark" err
2934'
2935
2936#
2937# tag, from markref
2938#
2939test_expect_success 'S: tag with garbage after mark must fail' '
2940        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2941        tag refs/tags/Stag
2942        from :302x
2943        tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2944        data <<TAG
2945        tag S
2946        TAG
2947        EOF
2948        cat err &&
2949        test_i18ngrep "after mark" err
2950'
2951
2952#
2953# cat-blob markref
2954#
2955test_expect_success 'S: cat-blob with garbage after mark must fail' '
2956        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2957        cat-blob :403x
2958        EOF
2959        cat err &&
2960        test_i18ngrep "after mark" err
2961'
2962
2963#
2964# ls markref
2965#
2966test_expect_success 'S: ls with garbage after mark must fail' '
2967        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2968        ls :302x hello.c
2969        EOF
2970        cat err &&
2971        test_i18ngrep "space after mark" err
2972'
2973
2974test_expect_success 'S: ls with garbage after sha1 must fail' '
2975        sha1=$(grep :302 marks | cut -d\  -f2) &&
2976        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2977        ls ${sha1}x hello.c
2978        EOF
2979        cat err &&
2980        test_i18ngrep "space after tree-ish" err
2981'
2982
2983###
2984### series T (ls)
2985###
2986# Setup is carried over from series S.
2987
2988test_expect_success 'T: ls root tree' '
2989        sed -e "s/Z\$//" >expect <<-EOF &&
2990        040000 tree $(git rev-parse S^{tree})   Z
2991        EOF
2992        sha1=$(git rev-parse --verify S) &&
2993        git fast-import --import-marks=marks <<-EOF >actual &&
2994        ls $sha1 ""
2995        EOF
2996        test_cmp expect actual
2997'
2998
2999test_expect_success 'T: delete branch' '
3000        git branch to-delete &&
3001        git fast-import <<-EOF &&
3002        reset refs/heads/to-delete
3003        from 0000000000000000000000000000000000000000
3004        EOF
3005        test_must_fail git rev-parse --verify refs/heads/to-delete
3006'
3007
3008test_expect_success 'T: empty reset doesnt delete branch' '
3009        git branch not-to-delete &&
3010        git fast-import <<-EOF &&
3011        reset refs/heads/not-to-delete
3012        EOF
3013        git show-ref &&
3014        git rev-parse --verify refs/heads/not-to-delete
3015'
3016
3017###
3018### series U (filedelete)
3019###
3020
3021test_expect_success 'U: initialize for U tests' '
3022        cat >input <<-INPUT_END &&
3023        commit refs/heads/U
3024        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3025        data <<COMMIT
3026        test setup
3027        COMMIT
3028        M 100644 inline hello.c
3029        data <<BLOB
3030        blob 1
3031        BLOB
3032        M 100644 inline good/night.txt
3033        data <<BLOB
3034        sleep well
3035        BLOB
3036        M 100644 inline good/bye.txt
3037        data <<BLOB
3038        au revoir
3039        BLOB
3040
3041        INPUT_END
3042
3043        git fast-import <input
3044'
3045
3046test_expect_success 'U: filedelete file succeeds' '
3047        cat >input <<-INPUT_END &&
3048        commit refs/heads/U
3049        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3050        data <<COMMIT
3051        delete good/night.txt
3052        COMMIT
3053        from refs/heads/U^0
3054        D good/night.txt
3055
3056        INPUT_END
3057
3058        git fast-import <input
3059'
3060
3061test_expect_success 'U: validate file delete result' '
3062        cat >expect <<-EOF &&
3063        :100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D      good/night.txt
3064        EOF
3065
3066        git diff-tree -M -r U^1 U >actual &&
3067
3068        compare_diff_raw expect actual
3069'
3070
3071test_expect_success 'U: filedelete directory succeeds' '
3072        cat >input <<-INPUT_END &&
3073        commit refs/heads/U
3074        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3075        data <<COMMIT
3076        delete good dir
3077        COMMIT
3078        from refs/heads/U^0
3079        D good
3080
3081        INPUT_END
3082
3083        git fast-import <input
3084'
3085
3086test_expect_success 'U: validate directory delete result' '
3087        cat >expect <<-EOF &&
3088        :100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D      good/bye.txt
3089        EOF
3090
3091        git diff-tree -M -r U^1 U >actual &&
3092
3093        compare_diff_raw expect actual
3094'
3095
3096test_expect_success 'U: filedelete root succeeds' '
3097        cat >input <<-INPUT_END &&
3098        commit refs/heads/U
3099        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3100        data <<COMMIT
3101        must succeed
3102        COMMIT
3103        from refs/heads/U^0
3104        D ""
3105
3106        INPUT_END
3107
3108        git fast-import <input
3109'
3110
3111test_expect_success 'U: validate root delete result' '
3112        cat >expect <<-EOF &&
3113        :100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D      hello.c
3114        EOF
3115
3116        git diff-tree -M -r U^1 U >actual &&
3117
3118        compare_diff_raw expect actual
3119'
3120
3121test_done