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