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