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