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