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