566f7bdd30436006615aa882d67531c29e41f3b2
   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 'A: create pack from stdin' '
 104        git fast-import --export-marks=marks.out <input &&
 105        git whatchanged master
 106'
 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 'A: verify commit' '
 119        git cat-file commit master | sed 1d >actual &&
 120        test_cmp expect actual
 121'
 122
 123cat >expect <<EOF
 124100644 blob file2
 125100644 blob file3
 126100755 blob file4
 127EOF
 128test_expect_success 'A: verify tree' '
 129        git cat-file -p master^{tree} | sed "s/ [0-9a-f]*       / /" >actual &&
 130        test_cmp expect actual
 131'
 132
 133echo "$file2_data" >expect
 134test_expect_success 'A: verify file2' '
 135        git cat-file blob master:file2 >actual && test_cmp expect actual
 136'
 137
 138echo "$file3_data" >expect
 139test_expect_success 'A: verify file3' '
 140        git cat-file blob master:file3 >actual && test_cmp expect actual
 141'
 142
 143printf "$file4_data" >expect
 144test_expect_success 'A: verify file4' '
 145        git cat-file blob master:file4 >actual && test_cmp expect actual
 146'
 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 'A: verify marks output' '
 179        test_cmp expect marks.out
 180'
 181
 182test_expect_success 'A: verify marks import' '
 183        git fast-import \
 184                --import-marks=marks.out \
 185                --export-marks=marks.new \
 186                </dev/null &&
 187        test_cmp expect marks.new
 188'
 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 'A: tag blob by sha1' '
 233        git fast-import <input &&
 234        git cat-file tag tags/series-A-blob-2 >actual &&
 235        git cat-file tag tags/series-A-blob-3 >>actual &&
 236        test_cmp expect actual
 237'
 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 'A: verify marks import does not crash' '
 252        git fast-import --import-marks=marks.out <input &&
 253        git whatchanged verify--import-marks
 254'
 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 'A: verify diff' '
 265        compare_diff_raw expect actual &&
 266        test `git rev-parse --verify master:file2` \
 267            = `git rev-parse --verify verify--import-marks:copy-of-file2`
 268'
 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###
 329### series B
 330###
 331
 332test_tick
 333cat >input <<INPUT_END
 334commit refs/heads/branch
 335mark :1
 336committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 337data <<COMMIT
 338corrupt
 339COMMIT
 340
 341from refs/heads/master
 342M 755 0000000000000000000000000000000000000001 zero1
 343
 344INPUT_END
 345test_expect_success 'B: fail on invalid blob sha1' '
 346        test_must_fail git fast-import <input
 347'
 348rm -f .git/objects/pack_* .git/objects/index_*
 349
 350cat >input <<INPUT_END
 351commit TEMP_TAG
 352committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 353data <<COMMIT
 354tag base
 355COMMIT
 356
 357from refs/heads/master
 358
 359INPUT_END
 360test_expect_success 'B: accept branch name "TEMP_TAG"' '
 361        git fast-import <input &&
 362        test -f .git/TEMP_TAG &&
 363        test `git rev-parse master` = `git rev-parse TEMP_TAG^`
 364'
 365rm -f .git/TEMP_TAG
 366
 367git gc 2>/dev/null >/dev/null
 368git prune 2>/dev/null >/dev/null
 369
 370cat >input <<INPUT_END
 371commit refs/heads/empty-committer-1
 372committer  <> $GIT_COMMITTER_DATE
 373data <<COMMIT
 374empty commit
 375COMMIT
 376INPUT_END
 377test_expect_success 'B: accept empty committer' '
 378        git fast-import <input &&
 379        out=$(git fsck) &&
 380        echo "$out" &&
 381        test -z "$out"
 382'
 383git update-ref -d refs/heads/empty-committer-1 || true
 384
 385git gc 2>/dev/null >/dev/null
 386git prune 2>/dev/null >/dev/null
 387
 388cat >input <<INPUT_END
 389commit refs/heads/empty-committer-2
 390committer <a@b.com> $GIT_COMMITTER_DATE
 391data <<COMMIT
 392empty commit
 393COMMIT
 394INPUT_END
 395test_expect_success 'B: accept and fixup committer with no name' '
 396        git fast-import <input &&
 397        out=$(git fsck) &&
 398        echo "$out" &&
 399        test -z "$out"
 400'
 401git update-ref -d refs/heads/empty-committer-2 || true
 402
 403git gc 2>/dev/null >/dev/null
 404git prune 2>/dev/null >/dev/null
 405
 406cat >input <<INPUT_END
 407commit refs/heads/invalid-committer
 408committer Name email> $GIT_COMMITTER_DATE
 409data <<COMMIT
 410empty commit
 411COMMIT
 412INPUT_END
 413test_expect_success 'B: fail on invalid committer (1)' '
 414        test_must_fail git fast-import <input
 415'
 416git update-ref -d refs/heads/invalid-committer || true
 417
 418cat >input <<INPUT_END
 419commit refs/heads/invalid-committer
 420committer Name <e<mail> $GIT_COMMITTER_DATE
 421data <<COMMIT
 422empty commit
 423COMMIT
 424INPUT_END
 425test_expect_success 'B: fail on invalid committer (2)' '
 426        test_must_fail git fast-import <input
 427'
 428git update-ref -d refs/heads/invalid-committer || true
 429
 430cat >input <<INPUT_END
 431commit refs/heads/invalid-committer
 432committer Name <email>> $GIT_COMMITTER_DATE
 433data <<COMMIT
 434empty commit
 435COMMIT
 436INPUT_END
 437test_expect_success 'B: fail on invalid committer (3)' '
 438        test_must_fail git fast-import <input
 439'
 440git update-ref -d refs/heads/invalid-committer || true
 441
 442cat >input <<INPUT_END
 443commit refs/heads/invalid-committer
 444committer Name <email $GIT_COMMITTER_DATE
 445data <<COMMIT
 446empty commit
 447COMMIT
 448INPUT_END
 449test_expect_success 'B: fail on invalid committer (4)' '
 450        test_must_fail git fast-import <input
 451'
 452git update-ref -d refs/heads/invalid-committer || true
 453
 454cat >input <<INPUT_END
 455commit refs/heads/invalid-committer
 456committer Name<email> $GIT_COMMITTER_DATE
 457data <<COMMIT
 458empty commit
 459COMMIT
 460INPUT_END
 461test_expect_success 'B: fail on invalid committer (5)' '
 462        test_must_fail git fast-import <input
 463'
 464git update-ref -d refs/heads/invalid-committer || true
 465
 466###
 467### series C
 468###
 469
 470newf=`echo hi newf | git hash-object -w --stdin`
 471oldf=`git rev-parse --verify master:file2`
 472test_tick
 473cat >input <<INPUT_END
 474commit refs/heads/branch
 475committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 476data <<COMMIT
 477second
 478COMMIT
 479
 480from refs/heads/master
 481M 644 $oldf file2/oldf
 482M 755 $newf file2/newf
 483D file3
 484
 485INPUT_END
 486test_expect_success 'C: incremental import create pack from stdin' '
 487        git fast-import <input &&
 488        git whatchanged branch
 489'
 490
 491test_expect_success 'C: verify pack' '
 492        verify_packs
 493'
 494
 495test_expect_success 'C: validate reuse existing blob' '
 496        test $newf = `git rev-parse --verify branch:file2/newf` &&
 497        test $oldf = `git rev-parse --verify branch:file2/oldf`
 498'
 499
 500cat >expect <<EOF
 501parent `git rev-parse --verify master^0`
 502author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 503committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 504
 505second
 506EOF
 507test_expect_success 'C: verify commit' '
 508        git cat-file commit branch | sed 1d >actual &&
 509        test_cmp expect actual
 510'
 511
 512cat >expect <<EOF
 513:000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A      file2/newf
 514:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100   file2   file2/oldf
 515:100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D      file3
 516EOF
 517git diff-tree -M -r master branch >actual
 518test_expect_success 'C: validate rename result' '
 519        compare_diff_raw expect actual
 520'
 521
 522###
 523### series D
 524###
 525
 526test_tick
 527cat >input <<INPUT_END
 528commit refs/heads/branch
 529committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 530data <<COMMIT
 531third
 532COMMIT
 533
 534from refs/heads/branch^0
 535M 644 inline newdir/interesting
 536data <<EOF
 537$file5_data
 538EOF
 539
 540M 755 inline newdir/exec.sh
 541data <<EOF
 542$file6_data
 543EOF
 544
 545INPUT_END
 546test_expect_success 'D: inline data in commit' '
 547        git fast-import <input &&
 548        git whatchanged branch
 549'
 550
 551test_expect_success 'D: verify pack' '
 552        verify_packs
 553'
 554
 555cat >expect <<EOF
 556:000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A      newdir/exec.sh
 557:000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A      newdir/interesting
 558EOF
 559git diff-tree -M -r branch^ branch >actual
 560test_expect_success 'D: validate new files added' '
 561        compare_diff_raw expect actual
 562'
 563
 564echo "$file5_data" >expect
 565test_expect_success 'D: verify file5' '
 566        git cat-file blob branch:newdir/interesting >actual &&
 567        test_cmp expect actual
 568'
 569
 570echo "$file6_data" >expect
 571test_expect_success 'D: verify file6' '
 572        git cat-file blob branch:newdir/exec.sh >actual &&
 573        test_cmp expect actual
 574'
 575
 576###
 577### series E
 578###
 579
 580cat >input <<INPUT_END
 581commit refs/heads/branch
 582author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> Tue Feb 6 11:22:18 2007 -0500
 583committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> Tue Feb 6 12:35:02 2007 -0500
 584data <<COMMIT
 585RFC 2822 type date
 586COMMIT
 587
 588from refs/heads/branch^0
 589
 590INPUT_END
 591test_expect_success 'E: rfc2822 date, --date-format=raw' '
 592        test_must_fail git fast-import --date-format=raw <input
 593'
 594test_expect_success 'E: rfc2822 date, --date-format=rfc2822' '
 595        git fast-import --date-format=rfc2822 <input
 596'
 597
 598test_expect_success 'E: verify pack' '
 599        verify_packs
 600'
 601
 602cat >expect <<EOF
 603author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500
 604committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1170783302 -0500
 605
 606RFC 2822 type date
 607EOF
 608test_expect_success 'E: verify commit' '
 609        git cat-file commit branch | sed 1,2d >actual &&
 610        test_cmp expect actual
 611'
 612
 613###
 614### series F
 615###
 616
 617old_branch=`git rev-parse --verify branch^0`
 618test_tick
 619cat >input <<INPUT_END
 620commit refs/heads/branch
 621committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 622data <<COMMIT
 623losing things already?
 624COMMIT
 625
 626from refs/heads/branch~1
 627
 628reset refs/heads/other
 629from refs/heads/branch
 630
 631INPUT_END
 632test_expect_success 'F: non-fast-forward update skips' '
 633        if git fast-import <input
 634        then
 635                echo BAD gfi did not fail
 636                return 1
 637        else
 638                if test $old_branch = `git rev-parse --verify branch^0`
 639                then
 640                        : branch unaffected and failure returned
 641                        return 0
 642                else
 643                        echo BAD gfi changed branch $old_branch
 644                        return 1
 645                fi
 646        fi
 647'
 648
 649test_expect_success 'F: verify pack' '
 650        verify_packs
 651'
 652
 653cat >expect <<EOF
 654tree `git rev-parse branch~1^{tree}`
 655parent `git rev-parse branch~1`
 656author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 657committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 658
 659losing things already?
 660EOF
 661test_expect_success 'F: verify other commit' '
 662        git cat-file commit other >actual &&
 663        test_cmp expect actual
 664'
 665
 666###
 667### series G
 668###
 669
 670old_branch=`git rev-parse --verify branch^0`
 671test_tick
 672cat >input <<INPUT_END
 673commit refs/heads/branch
 674committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 675data <<COMMIT
 676losing things already?
 677COMMIT
 678
 679from refs/heads/branch~1
 680
 681INPUT_END
 682test_expect_success 'G: non-fast-forward update forced' '
 683        git fast-import --force <input
 684'
 685
 686test_expect_success 'G: verify pack' '
 687        verify_packs
 688'
 689
 690test_expect_success 'G: branch changed, but logged' '
 691        test $old_branch != `git rev-parse --verify branch^0` &&
 692        test $old_branch = `git rev-parse --verify branch@{1}`
 693'
 694
 695###
 696### series H
 697###
 698
 699test_tick
 700cat >input <<INPUT_END
 701commit refs/heads/H
 702committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 703data <<COMMIT
 704third
 705COMMIT
 706
 707from refs/heads/branch^0
 708M 644 inline i-will-die
 709data <<EOF
 710this file will never exist.
 711EOF
 712
 713deleteall
 714M 644 inline h/e/l/lo
 715data <<EOF
 716$file5_data
 717EOF
 718
 719INPUT_END
 720test_expect_success 'H: deletall, add 1' '
 721        git fast-import <input &&
 722        git whatchanged H
 723'
 724
 725test_expect_success 'H: verify pack' '
 726        verify_packs
 727'
 728
 729cat >expect <<EOF
 730:100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D      file2/newf
 731:100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D      file2/oldf
 732:100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D      file4
 733:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100   newdir/interesting      h/e/l/lo
 734:100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D      newdir/exec.sh
 735EOF
 736git diff-tree -M -r H^ H >actual
 737test_expect_success 'H: validate old files removed, new files added' '
 738        compare_diff_raw expect actual
 739'
 740
 741echo "$file5_data" >expect
 742test_expect_success 'H: verify file' '
 743        git cat-file blob H:h/e/l/lo >actual &&
 744        test_cmp expect actual
 745'
 746
 747###
 748### series I
 749###
 750
 751cat >input <<INPUT_END
 752commit refs/heads/export-boundary
 753committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 754data <<COMMIT
 755we have a border.  its only 40 characters wide.
 756COMMIT
 757
 758from refs/heads/branch
 759
 760INPUT_END
 761test_expect_success 'I: export-pack-edges' '
 762        git fast-import --export-pack-edges=edges.list <input
 763'
 764
 765cat >expect <<EOF
 766.git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary`
 767EOF
 768test_expect_success 'I: verify edge list' '
 769        sed -e s/pack-.*pack/pack-.pack/ edges.list >actual &&
 770        test_cmp expect actual
 771'
 772
 773###
 774### series J
 775###
 776
 777cat >input <<INPUT_END
 778commit refs/heads/J
 779committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 780data <<COMMIT
 781create J
 782COMMIT
 783
 784from refs/heads/branch
 785
 786reset refs/heads/J
 787
 788commit refs/heads/J
 789committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 790data <<COMMIT
 791initialize J
 792COMMIT
 793
 794INPUT_END
 795test_expect_success 'J: reset existing branch creates empty commit' '
 796        git fast-import <input
 797'
 798test_expect_success 'J: branch has 1 commit, empty tree' '
 799        test 1 = `git rev-list J | wc -l` &&
 800        test 0 = `git ls-tree J | wc -l`
 801'
 802
 803cat >input <<INPUT_END
 804reset refs/heads/J2
 805
 806tag wrong_tag
 807from refs/heads/J2
 808data <<EOF
 809Tag branch that was reset.
 810EOF
 811INPUT_END
 812test_expect_success 'J: tag must fail on empty branch' '
 813        test_must_fail git fast-import <input
 814'
 815###
 816### series K
 817###
 818
 819cat >input <<INPUT_END
 820commit refs/heads/K
 821committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 822data <<COMMIT
 823create K
 824COMMIT
 825
 826from refs/heads/branch
 827
 828commit refs/heads/K
 829committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 830data <<COMMIT
 831redo K
 832COMMIT
 833
 834from refs/heads/branch^1
 835
 836INPUT_END
 837test_expect_success 'K: reinit branch with from' '
 838        git fast-import <input
 839'
 840test_expect_success 'K: verify K^1 = branch^1' '
 841        test `git rev-parse --verify branch^1` \
 842                = `git rev-parse --verify K^1`
 843'
 844
 845###
 846### series L
 847###
 848
 849cat >input <<INPUT_END
 850blob
 851mark :1
 852data <<EOF
 853some data
 854EOF
 855
 856blob
 857mark :2
 858data <<EOF
 859other data
 860EOF
 861
 862commit refs/heads/L
 863committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 864data <<COMMIT
 865create L
 866COMMIT
 867
 868M 644 :1 b.
 869M 644 :1 b/other
 870M 644 :1 ba
 871
 872commit refs/heads/L
 873committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 874data <<COMMIT
 875update L
 876COMMIT
 877
 878M 644 :2 b.
 879M 644 :2 b/other
 880M 644 :2 ba
 881INPUT_END
 882
 883cat >expect <<EXPECT_END
 884:100644 100644 4268632... 55d3a52... M  b.
 885:040000 040000 0ae5cac... 443c768... M  b
 886:100644 100644 4268632... 55d3a52... M  ba
 887EXPECT_END
 888
 889test_expect_success 'L: verify internal tree sorting' '
 890        git fast-import <input &&
 891        git diff-tree --abbrev --raw L^ L >output &&
 892        test_cmp expect output
 893'
 894
 895cat >input <<INPUT_END
 896blob
 897mark :1
 898data <<EOF
 899the data
 900EOF
 901
 902commit refs/heads/L2
 903committer C O Mitter <committer@example.com> 1112912473 -0700
 904data <<COMMIT
 905init L2
 906COMMIT
 907M 644 :1 a/b/c
 908M 644 :1 a/b/d
 909M 644 :1 a/e/f
 910
 911commit refs/heads/L2
 912committer C O Mitter <committer@example.com> 1112912473 -0700
 913data <<COMMIT
 914update L2
 915COMMIT
 916C a g
 917C a/e g/b
 918M 644 :1 g/b/h
 919INPUT_END
 920
 921cat <<EOF >expect
 922g/b/f
 923g/b/h
 924EOF
 925
 926test_expect_success 'L: nested tree copy does not corrupt deltas' '
 927        git fast-import <input &&
 928        git ls-tree L2 g/b/ >tmp &&
 929        cat tmp | cut -f 2 >actual &&
 930        test_cmp expect actual &&
 931        git fsck `git rev-parse L2`
 932'
 933
 934git update-ref -d refs/heads/L2
 935
 936###
 937### series M
 938###
 939
 940test_tick
 941cat >input <<INPUT_END
 942commit refs/heads/M1
 943committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 944data <<COMMIT
 945file rename
 946COMMIT
 947
 948from refs/heads/branch^0
 949R file2/newf file2/n.e.w.f
 950
 951INPUT_END
 952
 953cat >expect <<EOF
 954:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   file2/newf      file2/n.e.w.f
 955EOF
 956test_expect_success 'M: rename file in same subdirectory' '
 957        git fast-import <input &&
 958        git diff-tree -M -r M1^ M1 >actual &&
 959        compare_diff_raw expect actual
 960'
 961
 962cat >input <<INPUT_END
 963commit refs/heads/M2
 964committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 965data <<COMMIT
 966file rename
 967COMMIT
 968
 969from refs/heads/branch^0
 970R file2/newf i/am/new/to/you
 971
 972INPUT_END
 973
 974cat >expect <<EOF
 975:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   file2/newf      i/am/new/to/you
 976EOF
 977test_expect_success 'M: rename file to new subdirectory' '
 978        git fast-import <input &&
 979        git diff-tree -M -r M2^ M2 >actual &&
 980        compare_diff_raw expect actual
 981'
 982
 983cat >input <<INPUT_END
 984commit refs/heads/M3
 985committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 986data <<COMMIT
 987file rename
 988COMMIT
 989
 990from refs/heads/M2^0
 991R i other/sub
 992
 993INPUT_END
 994
 995cat >expect <<EOF
 996:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   i/am/new/to/you other/sub/am/new/to/you
 997EOF
 998test_expect_success 'M: rename subdirectory to new subdirectory' '
 999        git fast-import <input &&
1000        git diff-tree -M -r M3^ M3 >actual &&
1001        compare_diff_raw expect actual
1002'
1003
1004cat >input <<INPUT_END
1005commit refs/heads/M4
1006committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1007data <<COMMIT
1008rename root
1009COMMIT
1010
1011from refs/heads/M2^0
1012R "" sub
1013
1014INPUT_END
1015
1016cat >expect <<EOF
1017:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100   file2/oldf      sub/file2/oldf
1018:100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100   file4   sub/file4
1019:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100   i/am/new/to/you sub/i/am/new/to/you
1020:100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100   newdir/exec.sh  sub/newdir/exec.sh
1021:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100   newdir/interesting      sub/newdir/interesting
1022EOF
1023test_expect_success 'M: rename root to subdirectory' '
1024        git fast-import <input &&
1025        git diff-tree -M -r M4^ M4 >actual &&
1026        cat actual &&
1027        compare_diff_raw expect actual
1028'
1029
1030###
1031### series N
1032###
1033
1034test_tick
1035cat >input <<INPUT_END
1036commit refs/heads/N1
1037committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1038data <<COMMIT
1039file copy
1040COMMIT
1041
1042from refs/heads/branch^0
1043C file2/newf file2/n.e.w.f
1044
1045INPUT_END
1046
1047cat >expect <<EOF
1048:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file2/n.e.w.f
1049EOF
1050test_expect_success 'N: copy file in same subdirectory' '
1051        git fast-import <input &&
1052        git diff-tree -C --find-copies-harder -r N1^ N1 >actual &&
1053        compare_diff_raw expect actual
1054'
1055
1056cat >input <<INPUT_END
1057commit refs/heads/N2
1058committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1059data <<COMMIT
1060clean directory copy
1061COMMIT
1062
1063from refs/heads/branch^0
1064C file2 file3
1065
1066commit refs/heads/N2
1067committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1068data <<COMMIT
1069modify directory copy
1070COMMIT
1071
1072M 644 inline file3/file5
1073data <<EOF
1074$file5_data
1075EOF
1076
1077INPUT_END
1078
1079cat >expect <<EOF
1080:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      file3/file5
1081:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1082:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1083EOF
1084test_expect_success 'N: copy then modify subdirectory' '
1085        git fast-import <input &&
1086        git diff-tree -C --find-copies-harder -r N2^^ N2 >actual &&
1087        compare_diff_raw expect actual
1088'
1089
1090cat >input <<INPUT_END
1091commit refs/heads/N3
1092committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1093data <<COMMIT
1094dirty directory copy
1095COMMIT
1096
1097from refs/heads/branch^0
1098M 644 inline file2/file5
1099data <<EOF
1100$file5_data
1101EOF
1102
1103C file2 file3
1104D file2/file5
1105
1106INPUT_END
1107
1108test_expect_success 'N: copy dirty subdirectory' '
1109        git fast-import <input &&
1110        test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`
1111'
1112
1113test_expect_success 'N: copy directory by id' '
1114        cat >expect <<-\EOF &&
1115        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1116        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1117        EOF
1118        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1119        cat >input <<-INPUT_END &&
1120        commit refs/heads/N4
1121        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1122        data <<COMMIT
1123        copy by tree hash
1124        COMMIT
1125
1126        from refs/heads/branch^0
1127        M 040000 $subdir file3
1128        INPUT_END
1129        git fast-import <input &&
1130        git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
1131        compare_diff_raw expect actual
1132'
1133
1134test_expect_success PIPE 'N: read and copy directory' '
1135        cat >expect <<-\EOF &&
1136        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1137        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1138        EOF
1139        git update-ref -d refs/heads/N4 &&
1140        rm -f backflow &&
1141        mkfifo backflow &&
1142        (
1143                exec <backflow &&
1144                cat <<-EOF &&
1145                commit refs/heads/N4
1146                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1147                data <<COMMIT
1148                copy by tree hash, part 2
1149                COMMIT
1150
1151                from refs/heads/branch^0
1152                ls "file2"
1153                EOF
1154                read mode type tree filename &&
1155                echo "M 040000 $tree file3"
1156        ) |
1157        git fast-import --cat-blob-fd=3 3>backflow &&
1158        git diff-tree -C --find-copies-harder -r N4^ N4 >actual &&
1159        compare_diff_raw expect actual
1160'
1161
1162test_expect_success PIPE 'N: empty directory reads as missing' '
1163        cat <<-\EOF >expect &&
1164        OBJNAME
1165        :000000 100644 OBJNAME OBJNAME A        unrelated
1166        EOF
1167        echo "missing src" >expect.response &&
1168        git update-ref -d refs/heads/read-empty &&
1169        rm -f backflow &&
1170        mkfifo backflow &&
1171        (
1172                exec <backflow &&
1173                cat <<-EOF &&
1174                commit refs/heads/read-empty
1175                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1176                data <<COMMIT
1177                read "empty" (missing) directory
1178                COMMIT
1179
1180                M 100644 inline src/greeting
1181                data <<BLOB
1182                hello
1183                BLOB
1184                C src/greeting dst1/non-greeting
1185                C src/greeting unrelated
1186                # leave behind "empty" src directory
1187                D src/greeting
1188                ls "src"
1189                EOF
1190                read -r line &&
1191                printf "%s\n" "$line" >response &&
1192                cat <<-\EOF
1193                D dst1
1194                D dst2
1195                EOF
1196        ) |
1197        git fast-import --cat-blob-fd=3 3>backflow &&
1198        test_cmp expect.response response &&
1199        git rev-list read-empty |
1200        git diff-tree -r --root --stdin |
1201        sed "s/$_x40/OBJNAME/g" >actual &&
1202        test_cmp expect actual
1203'
1204
1205test_expect_success 'N: copy root directory by tree hash' '
1206        cat >expect <<-\EOF &&
1207        :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D      file3/newf
1208        :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D      file3/oldf
1209        EOF
1210        root=$(git rev-parse refs/heads/branch^0^{tree}) &&
1211        cat >input <<-INPUT_END &&
1212        commit refs/heads/N6
1213        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1214        data <<COMMIT
1215        copy root directory by tree hash
1216        COMMIT
1217
1218        from refs/heads/branch^0
1219        M 040000 $root ""
1220        INPUT_END
1221        git fast-import <input &&
1222        git diff-tree -C --find-copies-harder -r N4 N6 >actual &&
1223        compare_diff_raw expect actual
1224'
1225
1226test_expect_success 'N: copy root by path' '
1227        cat >expect <<-\EOF &&
1228        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      oldroot/file2/newf
1229        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      oldroot/file2/oldf
1230        :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100   file4   oldroot/file4
1231        :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100   newdir/exec.sh  oldroot/newdir/exec.sh
1232        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      oldroot/newdir/interesting
1233        EOF
1234        cat >input <<-INPUT_END &&
1235        commit refs/heads/N-copy-root-path
1236        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1237        data <<COMMIT
1238        copy root directory by (empty) path
1239        COMMIT
1240
1241        from refs/heads/branch^0
1242        C "" oldroot
1243        INPUT_END
1244        git fast-import <input &&
1245        git diff-tree -C --find-copies-harder -r branch N-copy-root-path >actual &&
1246        compare_diff_raw expect actual
1247'
1248
1249test_expect_success 'N: delete directory by copying' '
1250        cat >expect <<-\EOF &&
1251        OBJID
1252        :100644 000000 OBJID OBJID D    foo/bar/qux
1253        OBJID
1254        :000000 100644 OBJID OBJID A    foo/bar/baz
1255        :000000 100644 OBJID OBJID A    foo/bar/qux
1256        EOF
1257        empty_tree=$(git mktree </dev/null) &&
1258        cat >input <<-INPUT_END &&
1259        commit refs/heads/N-delete
1260        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1261        data <<COMMIT
1262        collect data to be deleted
1263        COMMIT
1264
1265        deleteall
1266        M 100644 inline foo/bar/baz
1267        data <<DATA_END
1268        hello
1269        DATA_END
1270        C "foo/bar/baz" "foo/bar/qux"
1271        C "foo/bar/baz" "foo/bar/quux/1"
1272        C "foo/bar/baz" "foo/bar/quuux"
1273        M 040000 $empty_tree foo/bar/quux
1274        M 040000 $empty_tree foo/bar/quuux
1275
1276        commit refs/heads/N-delete
1277        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1278        data <<COMMIT
1279        delete subdirectory
1280        COMMIT
1281
1282        M 040000 $empty_tree foo/bar/qux
1283        INPUT_END
1284        git fast-import <input &&
1285        git rev-list N-delete |
1286                git diff-tree -r --stdin --root --always |
1287                sed -e "s/$_x40/OBJID/g" >actual &&
1288        test_cmp expect actual
1289'
1290
1291test_expect_success 'N: modify copied tree' '
1292        cat >expect <<-\EOF &&
1293        :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100   newdir/interesting      file3/file5
1294        :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100   file2/newf      file3/newf
1295        :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100   file2/oldf      file3/oldf
1296        EOF
1297        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1298        cat >input <<-INPUT_END &&
1299        commit refs/heads/N5
1300        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1301        data <<COMMIT
1302        copy by tree hash
1303        COMMIT
1304
1305        from refs/heads/branch^0
1306        M 040000 $subdir file3
1307
1308        commit refs/heads/N5
1309        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1310        data <<COMMIT
1311        modify directory copy
1312        COMMIT
1313
1314        M 644 inline file3/file5
1315        data <<EOF
1316        $file5_data
1317        EOF
1318        INPUT_END
1319        git fast-import <input &&
1320        git diff-tree -C --find-copies-harder -r N5^^ N5 >actual &&
1321        compare_diff_raw expect actual
1322'
1323
1324test_expect_success 'N: reject foo/ syntax' '
1325        subdir=$(git rev-parse refs/heads/branch^0:file2) &&
1326        test_must_fail git fast-import <<-INPUT_END
1327        commit refs/heads/N5B
1328        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1329        data <<COMMIT
1330        copy with invalid syntax
1331        COMMIT
1332
1333        from refs/heads/branch^0
1334        M 040000 $subdir file3/
1335        INPUT_END
1336'
1337
1338test_expect_success 'N: reject foo/ syntax in copy source' '
1339        test_must_fail git fast-import <<-INPUT_END
1340        commit refs/heads/N5C
1341        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1342        data <<COMMIT
1343        copy with invalid syntax
1344        COMMIT
1345
1346        from refs/heads/branch^0
1347        C file2/ file3
1348        INPUT_END
1349'
1350
1351test_expect_success 'N: reject foo/ syntax in rename source' '
1352        test_must_fail git fast-import <<-INPUT_END
1353        commit refs/heads/N5D
1354        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1355        data <<COMMIT
1356        rename with invalid syntax
1357        COMMIT
1358
1359        from refs/heads/branch^0
1360        R file2/ file3
1361        INPUT_END
1362'
1363
1364test_expect_success 'N: reject foo/ syntax in ls argument' '
1365        test_must_fail git fast-import <<-INPUT_END
1366        commit refs/heads/N5E
1367        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1368        data <<COMMIT
1369        copy with invalid syntax
1370        COMMIT
1371
1372        from refs/heads/branch^0
1373        ls "file2/"
1374        INPUT_END
1375'
1376
1377test_expect_success 'N: copy to root by id and modify' '
1378        echo "hello, world" >expect.foo &&
1379        echo hello >expect.bar &&
1380        git fast-import <<-SETUP_END &&
1381        commit refs/heads/N7
1382        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1383        data <<COMMIT
1384        hello, tree
1385        COMMIT
1386
1387        deleteall
1388        M 644 inline foo/bar
1389        data <<EOF
1390        hello
1391        EOF
1392        SETUP_END
1393
1394        tree=$(git rev-parse --verify N7:) &&
1395        git fast-import <<-INPUT_END &&
1396        commit refs/heads/N8
1397        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1398        data <<COMMIT
1399        copy to root by id and modify
1400        COMMIT
1401
1402        M 040000 $tree ""
1403        M 644 inline foo/foo
1404        data <<EOF
1405        hello, world
1406        EOF
1407        INPUT_END
1408        git show N8:foo/foo >actual.foo &&
1409        git show N8:foo/bar >actual.bar &&
1410        test_cmp expect.foo actual.foo &&
1411        test_cmp expect.bar actual.bar
1412'
1413
1414test_expect_success 'N: extract subtree' '
1415        branch=$(git rev-parse --verify refs/heads/branch^{tree}) &&
1416        cat >input <<-INPUT_END &&
1417        commit refs/heads/N9
1418        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1419        data <<COMMIT
1420        extract subtree branch:newdir
1421        COMMIT
1422
1423        M 040000 $branch ""
1424        C "newdir" ""
1425        INPUT_END
1426        git fast-import <input &&
1427        git diff --exit-code branch:newdir N9
1428'
1429
1430test_expect_success 'N: modify subtree, extract it, and modify again' '
1431        echo hello >expect.baz &&
1432        echo hello, world >expect.qux &&
1433        git fast-import <<-SETUP_END &&
1434        commit refs/heads/N10
1435        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1436        data <<COMMIT
1437        hello, tree
1438        COMMIT
1439
1440        deleteall
1441        M 644 inline foo/bar/baz
1442        data <<EOF
1443        hello
1444        EOF
1445        SETUP_END
1446
1447        tree=$(git rev-parse --verify N10:) &&
1448        git fast-import <<-INPUT_END &&
1449        commit refs/heads/N11
1450        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1451        data <<COMMIT
1452        copy to root by id and modify
1453        COMMIT
1454
1455        M 040000 $tree ""
1456        M 100644 inline foo/bar/qux
1457        data <<EOF
1458        hello, world
1459        EOF
1460        R "foo" ""
1461        C "bar/qux" "bar/quux"
1462        INPUT_END
1463        git show N11:bar/baz >actual.baz &&
1464        git show N11:bar/qux >actual.qux &&
1465        git show N11:bar/quux >actual.quux &&
1466        test_cmp expect.baz actual.baz &&
1467        test_cmp expect.qux actual.qux &&
1468        test_cmp expect.qux actual.quux'
1469
1470###
1471### series O
1472###
1473
1474cat >input <<INPUT_END
1475#we will
1476commit refs/heads/O1
1477# -- ignore all of this text
1478committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1479# $GIT_COMMITTER_NAME has inserted here for his benefit.
1480data <<COMMIT
1481dirty directory copy
1482COMMIT
1483
1484# don't forget the import blank line!
1485#
1486# yes, we started from our usual base of branch^0.
1487# i like branch^0.
1488from refs/heads/branch^0
1489# and we need to reuse file2/file5 from N3 above.
1490M 644 inline file2/file5
1491# otherwise the tree will be different
1492data <<EOF
1493$file5_data
1494EOF
1495
1496# don't forget to copy file2 to file3
1497C file2 file3
1498#
1499# or to delete file5 from file2.
1500D file2/file5
1501# are we done yet?
1502
1503INPUT_END
1504
1505test_expect_success 'O: comments are all skipped' '
1506        git fast-import <input &&
1507        test `git rev-parse N3` = `git rev-parse O1`
1508'
1509
1510cat >input <<INPUT_END
1511commit refs/heads/O2
1512committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1513data <<COMMIT
1514dirty directory copy
1515COMMIT
1516from refs/heads/branch^0
1517M 644 inline file2/file5
1518data <<EOF
1519$file5_data
1520EOF
1521C file2 file3
1522D file2/file5
1523
1524INPUT_END
1525
1526test_expect_success 'O: blank lines not necessary after data commands' '
1527        git fast-import <input &&
1528        test `git rev-parse N3` = `git rev-parse O2`
1529'
1530
1531test_expect_success 'O: repack before next test' '
1532        git repack -a -d
1533'
1534
1535cat >input <<INPUT_END
1536commit refs/heads/O3
1537committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1538data <<COMMIT
1539zstring
1540COMMIT
1541commit refs/heads/O3
1542committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1543data <<COMMIT
1544zof
1545COMMIT
1546checkpoint
1547commit refs/heads/O3
1548mark :5
1549committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1550data <<COMMIT
1551zempty
1552COMMIT
1553checkpoint
1554commit refs/heads/O3
1555committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1556data <<COMMIT
1557zcommits
1558COMMIT
1559reset refs/tags/O3-2nd
1560from :5
1561reset refs/tags/O3-3rd
1562from :5
1563INPUT_END
1564
1565cat >expect <<INPUT_END
1566string
1567of
1568empty
1569commits
1570INPUT_END
1571test_expect_success 'O: blank lines not necessary after other commands' '
1572        git fast-import <input &&
1573        test 8 = `find .git/objects/pack -type f | wc -l` &&
1574        test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` &&
1575        git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
1576        test_cmp expect actual
1577'
1578
1579cat >input <<INPUT_END
1580commit refs/heads/O4
1581committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1582data <<COMMIT
1583zstring
1584COMMIT
1585commit refs/heads/O4
1586committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1587data <<COMMIT
1588zof
1589COMMIT
1590progress Two commits down, 2 to go!
1591commit refs/heads/O4
1592committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1593data <<COMMIT
1594zempty
1595COMMIT
1596progress Three commits down, 1 to go!
1597commit refs/heads/O4
1598committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1599data <<COMMIT
1600zcommits
1601COMMIT
1602progress I'm done!
1603INPUT_END
1604test_expect_success 'O: progress outputs as requested by input' '
1605        git fast-import <input >actual &&
1606        grep "progress " <input >expect &&
1607        test_cmp expect actual
1608'
1609
1610###
1611### series P (gitlinks)
1612###
1613
1614cat >input <<INPUT_END
1615blob
1616mark :1
1617data 10
1618test file
1619
1620reset refs/heads/sub
1621commit refs/heads/sub
1622mark :2
1623committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1624data 12
1625sub_initial
1626M 100644 :1 file
1627
1628blob
1629mark :3
1630data <<DATAEND
1631[submodule "sub"]
1632        path = sub
1633        url = "`pwd`/sub"
1634DATAEND
1635
1636commit refs/heads/subuse1
1637mark :4
1638committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1639data 8
1640initial
1641from refs/heads/master
1642M 100644 :3 .gitmodules
1643M 160000 :2 sub
1644
1645blob
1646mark :5
1647data 20
1648test file
1649more data
1650
1651commit refs/heads/sub
1652mark :6
1653committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1654data 11
1655sub_second
1656from :2
1657M 100644 :5 file
1658
1659commit refs/heads/subuse1
1660mark :7
1661committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1662data 7
1663second
1664from :4
1665M 160000 :6 sub
1666
1667INPUT_END
1668
1669test_expect_success 'P: superproject & submodule mix' '
1670        git fast-import <input &&
1671        git checkout subuse1 &&
1672        rm -rf sub && mkdir sub && (cd sub &&
1673        git init &&
1674        git fetch --update-head-ok .. refs/heads/sub:refs/heads/master &&
1675        git checkout master) &&
1676        git submodule init &&
1677        git submodule update
1678'
1679
1680SUBLAST=$(git rev-parse --verify sub)
1681SUBPREV=$(git rev-parse --verify sub^)
1682
1683cat >input <<INPUT_END
1684blob
1685mark :1
1686data <<DATAEND
1687[submodule "sub"]
1688        path = sub
1689        url = "`pwd`/sub"
1690DATAEND
1691
1692commit refs/heads/subuse2
1693mark :2
1694committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1695data 8
1696initial
1697from refs/heads/master
1698M 100644 :1 .gitmodules
1699M 160000 $SUBPREV sub
1700
1701commit refs/heads/subuse2
1702mark :3
1703committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1704data 7
1705second
1706from :2
1707M 160000 $SUBLAST sub
1708
1709INPUT_END
1710
1711test_expect_success 'P: verbatim SHA gitlinks' '
1712        git branch -D sub &&
1713        git gc && git prune &&
1714        git fast-import <input &&
1715        test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
1716'
1717
1718test_tick
1719cat >input <<INPUT_END
1720commit refs/heads/subuse3
1721mark :1
1722committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1723data <<COMMIT
1724corrupt
1725COMMIT
1726
1727from refs/heads/subuse2
1728M 160000 inline sub
1729data <<DATA
1730$SUBPREV
1731DATA
1732
1733INPUT_END
1734
1735test_expect_success 'P: fail on inline gitlink' '
1736        test_must_fail git fast-import <input
1737'
1738
1739test_tick
1740cat >input <<INPUT_END
1741blob
1742mark :1
1743data <<DATA
1744$SUBPREV
1745DATA
1746
1747commit refs/heads/subuse3
1748mark :2
1749committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1750data <<COMMIT
1751corrupt
1752COMMIT
1753
1754from refs/heads/subuse2
1755M 160000 :1 sub
1756
1757INPUT_END
1758
1759test_expect_success 'P: fail on blob mark in gitlink' '
1760        test_must_fail git fast-import <input
1761'
1762
1763###
1764### series Q (notes)
1765###
1766
1767note1_data="The first note for the first commit"
1768note2_data="The first note for the second commit"
1769note3_data="The first note for the third commit"
1770note1b_data="The second note for the first commit"
1771note1c_data="The third note for the first commit"
1772note2b_data="The second note for the second commit"
1773
1774test_tick
1775cat >input <<INPUT_END
1776blob
1777mark :2
1778data <<EOF
1779$file2_data
1780EOF
1781
1782commit refs/heads/notes-test
1783mark :3
1784committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1785data <<COMMIT
1786first (:3)
1787COMMIT
1788
1789M 644 :2 file2
1790
1791blob
1792mark :4
1793data $file4_len
1794$file4_data
1795commit refs/heads/notes-test
1796mark :5
1797committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1798data <<COMMIT
1799second (:5)
1800COMMIT
1801
1802M 644 :4 file4
1803
1804commit refs/heads/notes-test
1805mark :6
1806committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1807data <<COMMIT
1808third (:6)
1809COMMIT
1810
1811M 644 inline file5
1812data <<EOF
1813$file5_data
1814EOF
1815
1816M 755 inline file6
1817data <<EOF
1818$file6_data
1819EOF
1820
1821blob
1822mark :7
1823data <<EOF
1824$note1_data
1825EOF
1826
1827blob
1828mark :8
1829data <<EOF
1830$note2_data
1831EOF
1832
1833commit refs/notes/foobar
1834mark :9
1835committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1836data <<COMMIT
1837notes (:9)
1838COMMIT
1839
1840N :7 :3
1841N :8 :5
1842N inline :6
1843data <<EOF
1844$note3_data
1845EOF
1846
1847commit refs/notes/foobar
1848mark :10
1849committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1850data <<COMMIT
1851notes (:10)
1852COMMIT
1853
1854N inline :3
1855data <<EOF
1856$note1b_data
1857EOF
1858
1859commit refs/notes/foobar2
1860mark :11
1861committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1862data <<COMMIT
1863notes (:11)
1864COMMIT
1865
1866N inline :3
1867data <<EOF
1868$note1c_data
1869EOF
1870
1871commit refs/notes/foobar
1872mark :12
1873committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1874data <<COMMIT
1875notes (:12)
1876COMMIT
1877
1878deleteall
1879N inline :5
1880data <<EOF
1881$note2b_data
1882EOF
1883
1884INPUT_END
1885
1886test_expect_success 'Q: commit notes' '
1887        git fast-import <input &&
1888        git whatchanged notes-test
1889'
1890
1891test_expect_success 'Q: verify pack' '
1892        verify_packs
1893'
1894
1895commit1=$(git rev-parse notes-test~2)
1896commit2=$(git rev-parse notes-test^)
1897commit3=$(git rev-parse notes-test)
1898
1899cat >expect <<EOF
1900author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1901committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1902
1903first (:3)
1904EOF
1905test_expect_success 'Q: verify first commit' '
1906        git cat-file commit notes-test~2 | sed 1d >actual &&
1907        test_cmp expect actual
1908'
1909
1910cat >expect <<EOF
1911parent $commit1
1912author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1913committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1914
1915second (:5)
1916EOF
1917test_expect_success 'Q: verify second commit' '
1918        git cat-file commit notes-test^ | sed 1d >actual &&
1919        test_cmp expect actual
1920'
1921
1922cat >expect <<EOF
1923parent $commit2
1924author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1925committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1926
1927third (:6)
1928EOF
1929test_expect_success 'Q: verify third commit' '
1930        git cat-file commit notes-test | sed 1d >actual &&
1931        test_cmp expect actual
1932'
1933
1934cat >expect <<EOF
1935author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1936committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1937
1938notes (:9)
1939EOF
1940test_expect_success 'Q: verify first notes commit' '
1941        git cat-file commit refs/notes/foobar~2 | sed 1d >actual &&
1942        test_cmp expect actual
1943'
1944
1945cat >expect.unsorted <<EOF
1946100644 blob $commit1
1947100644 blob $commit2
1948100644 blob $commit3
1949EOF
1950cat expect.unsorted | sort >expect
1951test_expect_success 'Q: verify first notes tree' '
1952        git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]*  / /" >actual &&
1953        test_cmp expect actual
1954'
1955
1956echo "$note1_data" >expect
1957test_expect_success 'Q: verify first note for first commit' '
1958        git cat-file blob refs/notes/foobar~2:$commit1 >actual && test_cmp expect actual
1959'
1960
1961echo "$note2_data" >expect
1962test_expect_success 'Q: verify first note for second commit' '
1963        git cat-file blob refs/notes/foobar~2:$commit2 >actual && test_cmp expect actual
1964'
1965
1966echo "$note3_data" >expect
1967test_expect_success 'Q: verify first note for third commit' '
1968        git cat-file blob refs/notes/foobar~2:$commit3 >actual && test_cmp expect actual
1969'
1970
1971cat >expect <<EOF
1972parent `git rev-parse --verify refs/notes/foobar~2`
1973author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1974committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1975
1976notes (:10)
1977EOF
1978test_expect_success 'Q: verify second notes commit' '
1979        git cat-file commit refs/notes/foobar^ | sed 1d >actual &&
1980        test_cmp expect actual
1981'
1982
1983cat >expect.unsorted <<EOF
1984100644 blob $commit1
1985100644 blob $commit2
1986100644 blob $commit3
1987EOF
1988cat expect.unsorted | sort >expect
1989test_expect_success 'Q: verify second notes tree' '
1990        git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]*   / /" >actual &&
1991        test_cmp expect actual
1992'
1993
1994echo "$note1b_data" >expect
1995test_expect_success 'Q: verify second note for first commit' '
1996        git cat-file blob refs/notes/foobar^:$commit1 >actual && test_cmp expect actual
1997'
1998
1999echo "$note2_data" >expect
2000test_expect_success 'Q: verify first note for second commit' '
2001        git cat-file blob refs/notes/foobar^:$commit2 >actual && test_cmp expect actual
2002'
2003
2004echo "$note3_data" >expect
2005test_expect_success 'Q: verify first note for third commit' '
2006        git cat-file blob refs/notes/foobar^:$commit3 >actual && test_cmp expect actual
2007'
2008
2009cat >expect <<EOF
2010author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2011committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2012
2013notes (:11)
2014EOF
2015test_expect_success 'Q: verify third notes commit' '
2016        git cat-file commit refs/notes/foobar2 | sed 1d >actual &&
2017        test_cmp expect actual
2018'
2019
2020cat >expect.unsorted <<EOF
2021100644 blob $commit1
2022EOF
2023cat expect.unsorted | sort >expect
2024test_expect_success 'Q: verify third notes tree' '
2025        git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]*   / /" >actual &&
2026        test_cmp expect actual
2027'
2028
2029echo "$note1c_data" >expect
2030test_expect_success 'Q: verify third note for first commit' '
2031        git cat-file blob refs/notes/foobar2:$commit1 >actual && test_cmp expect actual
2032'
2033
2034cat >expect <<EOF
2035parent `git rev-parse --verify refs/notes/foobar^`
2036author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2037committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2038
2039notes (:12)
2040EOF
2041test_expect_success 'Q: verify fourth notes commit' '
2042        git cat-file commit refs/notes/foobar | sed 1d >actual &&
2043        test_cmp expect actual
2044'
2045
2046cat >expect.unsorted <<EOF
2047100644 blob $commit2
2048EOF
2049cat expect.unsorted | sort >expect
2050test_expect_success 'Q: verify fourth notes tree' '
2051        git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]*    / /" >actual &&
2052        test_cmp expect actual
2053'
2054
2055echo "$note2b_data" >expect
2056test_expect_success 'Q: verify second note for second commit' '
2057        git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual
2058'
2059
2060cat >input <<EOF
2061reset refs/heads/Q0
2062
2063commit refs/heads/note-Q0
2064committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2065data <<COMMIT
2066Note for an empty branch.
2067COMMIT
2068
2069N inline refs/heads/Q0
2070data <<NOTE
2071some note
2072NOTE
2073EOF
2074test_expect_success 'Q: deny note on empty branch' '
2075        test_must_fail git fast-import <input
2076'
2077###
2078### series R (feature and option)
2079###
2080
2081cat >input <<EOF
2082feature no-such-feature-exists
2083EOF
2084
2085test_expect_success 'R: abort on unsupported feature' '
2086        test_must_fail git fast-import <input
2087'
2088
2089cat >input <<EOF
2090feature date-format=now
2091EOF
2092
2093test_expect_success 'R: supported feature is accepted' '
2094        git fast-import <input
2095'
2096
2097cat >input << EOF
2098blob
2099data 3
2100hi
2101feature date-format=now
2102EOF
2103
2104test_expect_success 'R: abort on receiving feature after data command' '
2105        test_must_fail git fast-import <input
2106'
2107
2108cat >input << EOF
2109feature import-marks=git.marks
2110feature import-marks=git2.marks
2111EOF
2112
2113test_expect_success 'R: only one import-marks feature allowed per stream' '
2114        test_must_fail git fast-import <input
2115'
2116
2117cat >input << EOF
2118feature export-marks=git.marks
2119blob
2120mark :1
2121data 3
2122hi
2123
2124EOF
2125
2126test_expect_success 'R: export-marks feature results in a marks file being created' '
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
2238cat >input << EOF
2239feature import-marks=marks.out
2240feature export-marks=marks.new
2241EOF
2242
2243test_expect_success 'R: import to output marks works without any content' '
2244        cat input | git fast-import &&
2245        test_cmp marks.out marks.new
2246'
2247
2248cat >input <<EOF
2249feature import-marks=nonexistent.marks
2250feature export-marks=marks.new
2251EOF
2252
2253test_expect_success 'R: import marks prefers commandline marks file over the stream' '
2254        cat input | git fast-import --import-marks=marks.out &&
2255        test_cmp marks.out marks.new
2256'
2257
2258
2259cat >input <<EOF
2260feature import-marks=nonexistent.marks
2261feature export-marks=combined.marks
2262EOF
2263
2264test_expect_success 'R: multiple --import-marks= should be honoured' '
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
2271cat >input <<EOF
2272feature relative-marks
2273feature import-marks=relative.in
2274feature export-marks=relative.out
2275EOF
2276
2277test_expect_success 'R: feature relative-marks should be honoured' '
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
2284cat >input <<EOF
2285feature relative-marks
2286feature import-marks=relative.in
2287feature no-relative-marks
2288feature export-marks=non-relative.out
2289EOF
2290
2291test_expect_success 'R: feature no-relative-marks should be honoured' '
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_cmp 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_cmp 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                head_c $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                head_c $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                head_c $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
2553cat >input << EOF
2554option git quiet
2555blob
2556data 3
2557hi
2558
2559EOF
2560
2561test_expect_success 'R: quiet option results in no stats being output' '
2562        cat input | git fast-import 2> output &&
2563        test_cmp 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
2608cat >input <<EOF
2609option git non-existing-option
2610EOF
2611
2612test_expect_success 'R: die on unknown option' '
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
2628cat >input <<EOF
2629option non-existing-vcs non-existing-option
2630EOF
2631
2632test_expect_success 'R: ignore non-git options' '
2633        git fast-import <input
2634'
2635
2636##
2637## R: very large blobs
2638##
2639blobsize=$((2*1024*1024 + 53))
2640test-genrandom bar $blobsize >expect
2641cat >input <<INPUT_END
2642commit refs/heads/big-file
2643committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2644data <<COMMIT
2645R - big file
2646COMMIT
2647
2648M 644 inline big1
2649data $blobsize
2650INPUT_END
2651cat expect >>input
2652cat >>input <<INPUT_END
2653M 644 inline big2
2654data $blobsize
2655INPUT_END
2656cat expect >>input
2657echo >>input
2658
2659test_expect_success 'R: blob bigger than threshold' '
2660        test_create_repo R &&
2661        git --git-dir=R/.git fast-import --big-file-threshold=1 <input
2662'
2663
2664test_expect_success 'R: verify created pack' '
2665        (
2666                cd R &&
2667                verify_packs -v > ../verify
2668        )
2669'
2670
2671test_expect_success 'R: verify written objects' '
2672        git --git-dir=R/.git cat-file blob big-file:big1 >actual &&
2673        test_cmp_bin expect actual &&
2674        a=$(git --git-dir=R/.git rev-parse big-file:big1) &&
2675        b=$(git --git-dir=R/.git rev-parse big-file:big2) &&
2676        test $a = $b
2677'
2678
2679test_expect_success 'R: blob appears only once' '
2680        n=$(grep $a verify | wc -l) &&
2681        test 1 = $n
2682'
2683
2684###
2685### series S
2686###
2687#
2688# Make sure missing spaces and EOLs after mark references
2689# cause errors.
2690#
2691# Setup:
2692#
2693#   1--2--4
2694#    \   /
2695#     -3-
2696#
2697#   commit marks:  301, 302, 303, 304
2698#   blob marks:              403, 404, resp.
2699#   note mark:          202
2700#
2701# The error message when a space is missing not at the
2702# end of the line is:
2703#
2704#   Missing space after ..
2705#
2706# or when extra characters come after the mark at the end
2707# of the line:
2708#
2709#   Garbage after ..
2710#
2711# or when the dataref is neither "inline " or a known SHA1,
2712#
2713#   Invalid dataref ..
2714#
2715test_tick
2716
2717cat >input <<INPUT_END
2718commit refs/heads/S
2719mark :301
2720committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2721data <<COMMIT
2722commit 1
2723COMMIT
2724M 100644 inline hello.c
2725data <<BLOB
2726blob 1
2727BLOB
2728
2729commit refs/heads/S
2730mark :302
2731committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2732data <<COMMIT
2733commit 2
2734COMMIT
2735from :301
2736M 100644 inline hello.c
2737data <<BLOB
2738blob 2
2739BLOB
2740
2741blob
2742mark :403
2743data <<BLOB
2744blob 3
2745BLOB
2746
2747blob
2748mark :202
2749data <<BLOB
2750note 2
2751BLOB
2752INPUT_END
2753
2754test_expect_success 'S: initialize for S tests' '
2755        git fast-import --export-marks=marks <input
2756'
2757
2758#
2759# filemodify, three datarefs
2760#
2761test_expect_success 'S: filemodify with garbage after mark must fail' '
2762        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2763        commit refs/heads/S
2764        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2765        data <<COMMIT
2766        commit N
2767        COMMIT
2768        M 100644 :403x hello.c
2769        EOF
2770        cat err &&
2771        test_i18ngrep "space after mark" err
2772'
2773
2774# inline is misspelled; fast-import thinks it is some unknown dataref
2775test_expect_success 'S: filemodify with garbage after inline must fail' '
2776        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2777        commit refs/heads/S
2778        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2779        data <<COMMIT
2780        commit N
2781        COMMIT
2782        M 100644 inlineX hello.c
2783        data <<BLOB
2784        inline
2785        BLOB
2786        EOF
2787        cat err &&
2788        test_i18ngrep "nvalid dataref" err
2789'
2790
2791test_expect_success 'S: filemodify with garbage after sha1 must fail' '
2792        sha1=$(grep :403 marks | cut -d\  -f2) &&
2793        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2794        commit refs/heads/S
2795        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2796        data <<COMMIT
2797        commit N
2798        COMMIT
2799        M 100644 ${sha1}x hello.c
2800        EOF
2801        cat err &&
2802        test_i18ngrep "space after SHA1" err
2803'
2804
2805#
2806# notemodify, three ways to say dataref
2807#
2808test_expect_success 'S: notemodify with garabge after mark dataref must fail' '
2809        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2810        commit refs/heads/S
2811        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2812        data <<COMMIT
2813        commit S note dataref markref
2814        COMMIT
2815        N :202x :302
2816        EOF
2817        cat err &&
2818        test_i18ngrep "space after mark" err
2819'
2820
2821test_expect_success 'S: notemodify with garbage after inline dataref must fail' '
2822        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2823        commit refs/heads/S
2824        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2825        data <<COMMIT
2826        commit S note dataref inline
2827        COMMIT
2828        N inlineX :302
2829        data <<BLOB
2830        note blob
2831        BLOB
2832        EOF
2833        cat err &&
2834        test_i18ngrep "nvalid dataref" err
2835'
2836
2837test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' '
2838        sha1=$(grep :202 marks | cut -d\  -f2) &&
2839        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2840        commit refs/heads/S
2841        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2842        data <<COMMIT
2843        commit S note dataref sha1
2844        COMMIT
2845        N ${sha1}x :302
2846        EOF
2847        cat err &&
2848        test_i18ngrep "space after SHA1" err
2849'
2850
2851#
2852# notemodify, mark in commit-ish
2853#
2854test_expect_success 'S: notemodify with garbage after mark commit-ish must fail' '
2855        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2856        commit refs/heads/Snotes
2857        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2858        data <<COMMIT
2859        commit S note commit-ish
2860        COMMIT
2861        N :202 :302x
2862        EOF
2863        cat err &&
2864        test_i18ngrep "after mark" err
2865'
2866
2867#
2868# from
2869#
2870test_expect_success 'S: from with garbage after mark must fail' '
2871        test_must_fail \
2872        git fast-import --import-marks=marks --export-marks=marks <<-EOF 2>err &&
2873        commit refs/heads/S2
2874        mark :303
2875        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2876        data <<COMMIT
2877        commit 3
2878        COMMIT
2879        from :301x
2880        M 100644 :403 hello.c
2881        EOF
2882
2883
2884        # go create the commit, need it for merge test
2885        git fast-import --import-marks=marks --export-marks=marks <<-EOF &&
2886        commit refs/heads/S2
2887        mark :303
2888        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2889        data <<COMMIT
2890        commit 3
2891        COMMIT
2892        from :301
2893        M 100644 :403 hello.c
2894        EOF
2895
2896        # now evaluate the error
2897        cat err &&
2898        test_i18ngrep "after mark" err
2899'
2900
2901
2902#
2903# merge
2904#
2905test_expect_success 'S: merge with garbage after mark must fail' '
2906        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2907        commit refs/heads/S
2908        mark :304
2909        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2910        data <<COMMIT
2911        merge 4
2912        COMMIT
2913        from :302
2914        merge :303x
2915        M 100644 :403 hello.c
2916        EOF
2917        cat err &&
2918        test_i18ngrep "after mark" err
2919'
2920
2921#
2922# tag, from markref
2923#
2924test_expect_success 'S: tag with garbage after mark must fail' '
2925        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2926        tag refs/tags/Stag
2927        from :302x
2928        tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2929        data <<TAG
2930        tag S
2931        TAG
2932        EOF
2933        cat err &&
2934        test_i18ngrep "after mark" err
2935'
2936
2937#
2938# cat-blob markref
2939#
2940test_expect_success 'S: cat-blob with garbage after mark must fail' '
2941        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2942        cat-blob :403x
2943        EOF
2944        cat err &&
2945        test_i18ngrep "after mark" err
2946'
2947
2948#
2949# ls markref
2950#
2951test_expect_success 'S: ls with garbage after mark must fail' '
2952        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2953        ls :302x hello.c
2954        EOF
2955        cat err &&
2956        test_i18ngrep "space after mark" err
2957'
2958
2959test_expect_success 'S: ls with garbage after sha1 must fail' '
2960        sha1=$(grep :302 marks | cut -d\  -f2) &&
2961        test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2962        ls ${sha1}x hello.c
2963        EOF
2964        cat err &&
2965        test_i18ngrep "space after tree-ish" err
2966'
2967
2968###
2969### series T (ls)
2970###
2971# Setup is carried over from series S.
2972
2973test_expect_success 'T: ls root tree' '
2974        sed -e "s/Z\$//" >expect <<-EOF &&
2975        040000 tree $(git rev-parse S^{tree})   Z
2976        EOF
2977        sha1=$(git rev-parse --verify S) &&
2978        git fast-import --import-marks=marks <<-EOF >actual &&
2979        ls $sha1 ""
2980        EOF
2981        test_cmp expect actual
2982'
2983
2984test_expect_success 'T: delete branch' '
2985        git branch to-delete &&
2986        git fast-import <<-EOF &&
2987        reset refs/heads/to-delete
2988        from 0000000000000000000000000000000000000000
2989        EOF
2990        test_must_fail git rev-parse --verify refs/heads/to-delete
2991'
2992
2993test_expect_success 'T: empty reset doesnt delete branch' '
2994        git branch not-to-delete &&
2995        git fast-import <<-EOF &&
2996        reset refs/heads/not-to-delete
2997        EOF
2998        git show-ref &&
2999        git rev-parse --verify refs/heads/not-to-delete
3000'
3001
3002###
3003### series U (filedelete)
3004###
3005
3006cat >input <<INPUT_END
3007commit refs/heads/U
3008committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3009data <<COMMIT
3010test setup
3011COMMIT
3012M 100644 inline hello.c
3013data <<BLOB
3014blob 1
3015BLOB
3016M 100644 inline good/night.txt
3017data <<BLOB
3018sleep well
3019BLOB
3020M 100644 inline good/bye.txt
3021data <<BLOB
3022au revoir
3023BLOB
3024
3025INPUT_END
3026
3027test_expect_success 'U: initialize for U tests' '
3028        git fast-import <input
3029'
3030
3031cat >input <<INPUT_END
3032commit refs/heads/U
3033committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3034data <<COMMIT
3035delete good/night.txt
3036COMMIT
3037from refs/heads/U^0
3038D good/night.txt
3039
3040INPUT_END
3041
3042test_expect_success 'U: filedelete file succeeds' '
3043        git fast-import <input
3044'
3045
3046cat >expect <<EOF
3047:100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D      good/night.txt
3048EOF
3049
3050git diff-tree -M -r U^1 U >actual
3051
3052test_expect_success 'U: validate file delete result' '
3053        compare_diff_raw expect actual
3054'
3055
3056cat >input <<INPUT_END
3057commit refs/heads/U
3058committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3059data <<COMMIT
3060delete good dir
3061COMMIT
3062from refs/heads/U^0
3063D good
3064
3065INPUT_END
3066
3067test_expect_success 'U: filedelete directory succeeds' '
3068        git fast-import <input
3069'
3070
3071cat >expect <<EOF
3072:100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D      good/bye.txt
3073EOF
3074
3075git diff-tree -M -r U^1 U >actual
3076
3077test_expect_success 'U: validate directory delete result' '
3078        compare_diff_raw expect actual
3079'
3080
3081cat >input <<INPUT_END
3082commit refs/heads/U
3083committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3084data <<COMMIT
3085must succeed
3086COMMIT
3087from refs/heads/U^0
3088D ""
3089
3090INPUT_END
3091
3092test_expect_success 'U: filedelete root succeeds' '
3093        git fast-import <input
3094'
3095
3096cat >expect <<EOF
3097:100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D      hello.c
3098EOF
3099
3100git diff-tree -M -r U^1 U >actual
3101
3102test_expect_success 'U: validate root delete result' '
3103        compare_diff_raw expect actual
3104'
3105
3106test_done