t / t9300-fast-import.shon commit Merge branch 'maint' (38a5932)
   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
 938test_expect_success \
 939        'N: reject foo/ syntax' \
 940        'subdir=$(git rev-parse refs/heads/branch^0:file2) &&
 941         test_must_fail git fast-import <<-INPUT_END
 942        commit refs/heads/N5B
 943        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 944        data <<COMMIT
 945        copy with invalid syntax
 946        COMMIT
 947
 948        from refs/heads/branch^0
 949        M 040000 $subdir file3/
 950        INPUT_END'
 951
 952test_expect_success \
 953        'N: copy to root by id and modify' \
 954        'echo "hello, world" >expect.foo &&
 955         echo hello >expect.bar &&
 956         git fast-import <<-SETUP_END &&
 957        commit refs/heads/N7
 958        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 959        data <<COMMIT
 960        hello, tree
 961        COMMIT
 962
 963        deleteall
 964        M 644 inline foo/bar
 965        data <<EOF
 966        hello
 967        EOF
 968        SETUP_END
 969
 970         tree=$(git rev-parse --verify N7:) &&
 971         git fast-import <<-INPUT_END &&
 972        commit refs/heads/N8
 973        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 974        data <<COMMIT
 975        copy to root by id and modify
 976        COMMIT
 977
 978        M 040000 $tree ""
 979        M 644 inline foo/foo
 980        data <<EOF
 981        hello, world
 982        EOF
 983        INPUT_END
 984         git show N8:foo/foo >actual.foo &&
 985         git show N8:foo/bar >actual.bar &&
 986         test_cmp expect.foo actual.foo &&
 987         test_cmp expect.bar actual.bar'
 988
 989test_expect_success \
 990        'N: extract subtree' \
 991        'branch=$(git rev-parse --verify refs/heads/branch^{tree}) &&
 992         cat >input <<-INPUT_END &&
 993        commit refs/heads/N9
 994        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
 995        data <<COMMIT
 996        extract subtree branch:newdir
 997        COMMIT
 998
 999        M 040000 $branch ""
1000        C "newdir" ""
1001        INPUT_END
1002         git fast-import <input &&
1003         git diff --exit-code branch:newdir N9'
1004
1005test_expect_success \
1006        'N: modify subtree, extract it, and modify again' \
1007        'echo hello >expect.baz &&
1008         echo hello, world >expect.qux &&
1009         git fast-import <<-SETUP_END &&
1010        commit refs/heads/N10
1011        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1012        data <<COMMIT
1013        hello, tree
1014        COMMIT
1015
1016        deleteall
1017        M 644 inline foo/bar/baz
1018        data <<EOF
1019        hello
1020        EOF
1021        SETUP_END
1022
1023         tree=$(git rev-parse --verify N10:) &&
1024         git fast-import <<-INPUT_END &&
1025        commit refs/heads/N11
1026        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1027        data <<COMMIT
1028        copy to root by id and modify
1029        COMMIT
1030
1031        M 040000 $tree ""
1032        M 100644 inline foo/bar/qux
1033        data <<EOF
1034        hello, world
1035        EOF
1036        R "foo" ""
1037        C "bar/qux" "bar/quux"
1038        INPUT_END
1039         git show N11:bar/baz >actual.baz &&
1040         git show N11:bar/qux >actual.qux &&
1041         git show N11:bar/quux >actual.quux &&
1042         test_cmp expect.baz actual.baz &&
1043         test_cmp expect.qux actual.qux &&
1044         test_cmp expect.qux actual.quux'
1045
1046###
1047### series O
1048###
1049
1050cat >input <<INPUT_END
1051#we will
1052commit refs/heads/O1
1053# -- ignore all of this text
1054committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1055# $GIT_COMMITTER_NAME has inserted here for his benefit.
1056data <<COMMIT
1057dirty directory copy
1058COMMIT
1059
1060# don't forget the import blank line!
1061#
1062# yes, we started from our usual base of branch^0.
1063# i like branch^0.
1064from refs/heads/branch^0
1065# and we need to reuse file2/file5 from N3 above.
1066M 644 inline file2/file5
1067# otherwise the tree will be different
1068data <<EOF
1069$file5_data
1070EOF
1071
1072# don't forget to copy file2 to file3
1073C file2 file3
1074#
1075# or to delete file5 from file2.
1076D file2/file5
1077# are we done yet?
1078
1079INPUT_END
1080
1081test_expect_success \
1082        'O: comments are all skipped' \
1083        'git fast-import <input &&
1084         test `git rev-parse N3` = `git rev-parse O1`'
1085
1086cat >input <<INPUT_END
1087commit refs/heads/O2
1088committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1089data <<COMMIT
1090dirty directory copy
1091COMMIT
1092from refs/heads/branch^0
1093M 644 inline file2/file5
1094data <<EOF
1095$file5_data
1096EOF
1097C file2 file3
1098D file2/file5
1099
1100INPUT_END
1101
1102test_expect_success \
1103        'O: blank lines not necessary after data commands' \
1104        'git fast-import <input &&
1105         test `git rev-parse N3` = `git rev-parse O2`'
1106
1107test_expect_success \
1108        'O: repack before next test' \
1109        'git repack -a -d'
1110
1111cat >input <<INPUT_END
1112commit refs/heads/O3
1113committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1114data <<COMMIT
1115zstring
1116COMMIT
1117commit refs/heads/O3
1118committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1119data <<COMMIT
1120zof
1121COMMIT
1122checkpoint
1123commit refs/heads/O3
1124mark :5
1125committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1126data <<COMMIT
1127zempty
1128COMMIT
1129checkpoint
1130commit refs/heads/O3
1131committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1132data <<COMMIT
1133zcommits
1134COMMIT
1135reset refs/tags/O3-2nd
1136from :5
1137reset refs/tags/O3-3rd
1138from :5
1139INPUT_END
1140
1141cat >expect <<INPUT_END
1142string
1143of
1144empty
1145commits
1146INPUT_END
1147test_expect_success \
1148        'O: blank lines not necessary after other commands' \
1149        'git fast-import <input &&
1150         test 8 = `find .git/objects/pack -type f | wc -l` &&
1151         test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` &&
1152         git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
1153         test_cmp expect actual'
1154
1155cat >input <<INPUT_END
1156commit refs/heads/O4
1157committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1158data <<COMMIT
1159zstring
1160COMMIT
1161commit refs/heads/O4
1162committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1163data <<COMMIT
1164zof
1165COMMIT
1166progress Two commits down, 2 to go!
1167commit refs/heads/O4
1168committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1169data <<COMMIT
1170zempty
1171COMMIT
1172progress Three commits down, 1 to go!
1173commit refs/heads/O4
1174committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1175data <<COMMIT
1176zcommits
1177COMMIT
1178progress I'm done!
1179INPUT_END
1180test_expect_success \
1181        'O: progress outputs as requested by input' \
1182        'git fast-import <input >actual &&
1183         grep "progress " <input >expect &&
1184         test_cmp expect actual'
1185
1186###
1187### series P (gitlinks)
1188###
1189
1190cat >input <<INPUT_END
1191blob
1192mark :1
1193data 10
1194test file
1195
1196reset refs/heads/sub
1197commit refs/heads/sub
1198mark :2
1199committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1200data 12
1201sub_initial
1202M 100644 :1 file
1203
1204blob
1205mark :3
1206data <<DATAEND
1207[submodule "sub"]
1208        path = sub
1209        url = "`pwd`/sub"
1210DATAEND
1211
1212commit refs/heads/subuse1
1213mark :4
1214committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1215data 8
1216initial
1217from refs/heads/master
1218M 100644 :3 .gitmodules
1219M 160000 :2 sub
1220
1221blob
1222mark :5
1223data 20
1224test file
1225more data
1226
1227commit refs/heads/sub
1228mark :6
1229committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1230data 11
1231sub_second
1232from :2
1233M 100644 :5 file
1234
1235commit refs/heads/subuse1
1236mark :7
1237committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1238data 7
1239second
1240from :4
1241M 160000 :6 sub
1242
1243INPUT_END
1244
1245test_expect_success \
1246        'P: supermodule & submodule mix' \
1247        'git fast-import <input &&
1248         git checkout subuse1 &&
1249         rm -rf sub && mkdir sub && (cd sub &&
1250         git init &&
1251         git fetch --update-head-ok .. refs/heads/sub:refs/heads/master &&
1252         git checkout master) &&
1253         git submodule init &&
1254         git submodule update'
1255
1256SUBLAST=$(git rev-parse --verify sub)
1257SUBPREV=$(git rev-parse --verify sub^)
1258
1259cat >input <<INPUT_END
1260blob
1261mark :1
1262data <<DATAEND
1263[submodule "sub"]
1264        path = sub
1265        url = "`pwd`/sub"
1266DATAEND
1267
1268commit refs/heads/subuse2
1269mark :2
1270committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1271data 8
1272initial
1273from refs/heads/master
1274M 100644 :1 .gitmodules
1275M 160000 $SUBPREV sub
1276
1277commit refs/heads/subuse2
1278mark :3
1279committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1280data 7
1281second
1282from :2
1283M 160000 $SUBLAST sub
1284
1285INPUT_END
1286
1287test_expect_success \
1288        'P: verbatim SHA gitlinks' \
1289        'git branch -D sub &&
1290         git gc && git prune &&
1291         git fast-import <input &&
1292         test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)'
1293
1294test_tick
1295cat >input <<INPUT_END
1296commit refs/heads/subuse3
1297mark :1
1298committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1299data <<COMMIT
1300corrupt
1301COMMIT
1302
1303from refs/heads/subuse2
1304M 160000 inline sub
1305data <<DATA
1306$SUBPREV
1307DATA
1308
1309INPUT_END
1310
1311test_expect_success 'P: fail on inline gitlink' '
1312    test_must_fail git fast-import <input'
1313
1314test_tick
1315cat >input <<INPUT_END
1316blob
1317mark :1
1318data <<DATA
1319$SUBPREV
1320DATA
1321
1322commit refs/heads/subuse3
1323mark :2
1324committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1325data <<COMMIT
1326corrupt
1327COMMIT
1328
1329from refs/heads/subuse2
1330M 160000 :1 sub
1331
1332INPUT_END
1333
1334test_expect_success 'P: fail on blob mark in gitlink' '
1335    test_must_fail git fast-import <input'
1336
1337###
1338### series Q (notes)
1339###
1340
1341note1_data="The first note for the first commit"
1342note2_data="The first note for the second commit"
1343note3_data="The first note for the third commit"
1344note1b_data="The second note for the first commit"
1345note1c_data="The third note for the first commit"
1346note2b_data="The second note for the second commit"
1347
1348test_tick
1349cat >input <<INPUT_END
1350blob
1351mark :2
1352data <<EOF
1353$file2_data
1354EOF
1355
1356commit refs/heads/notes-test
1357mark :3
1358committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1359data <<COMMIT
1360first (:3)
1361COMMIT
1362
1363M 644 :2 file2
1364
1365blob
1366mark :4
1367data $file4_len
1368$file4_data
1369commit refs/heads/notes-test
1370mark :5
1371committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1372data <<COMMIT
1373second (:5)
1374COMMIT
1375
1376M 644 :4 file4
1377
1378commit refs/heads/notes-test
1379mark :6
1380committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1381data <<COMMIT
1382third (:6)
1383COMMIT
1384
1385M 644 inline file5
1386data <<EOF
1387$file5_data
1388EOF
1389
1390M 755 inline file6
1391data <<EOF
1392$file6_data
1393EOF
1394
1395blob
1396mark :7
1397data <<EOF
1398$note1_data
1399EOF
1400
1401blob
1402mark :8
1403data <<EOF
1404$note2_data
1405EOF
1406
1407commit refs/notes/foobar
1408mark :9
1409committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1410data <<COMMIT
1411notes (:9)
1412COMMIT
1413
1414N :7 :3
1415N :8 :5
1416N inline :6
1417data <<EOF
1418$note3_data
1419EOF
1420
1421commit refs/notes/foobar
1422mark :10
1423committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1424data <<COMMIT
1425notes (:10)
1426COMMIT
1427
1428N inline :3
1429data <<EOF
1430$note1b_data
1431EOF
1432
1433commit refs/notes/foobar2
1434mark :11
1435committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1436data <<COMMIT
1437notes (:11)
1438COMMIT
1439
1440N inline :3
1441data <<EOF
1442$note1c_data
1443EOF
1444
1445commit refs/notes/foobar
1446mark :12
1447committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1448data <<COMMIT
1449notes (:12)
1450COMMIT
1451
1452deleteall
1453N inline :5
1454data <<EOF
1455$note2b_data
1456EOF
1457
1458INPUT_END
1459
1460test_expect_success \
1461        'Q: commit notes' \
1462        'git fast-import <input &&
1463         git whatchanged notes-test'
1464test_expect_success \
1465        'Q: verify pack' \
1466        'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done'
1467
1468commit1=$(git rev-parse notes-test~2)
1469commit2=$(git rev-parse notes-test^)
1470commit3=$(git rev-parse notes-test)
1471
1472cat >expect <<EOF
1473author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1474committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1475
1476first (:3)
1477EOF
1478test_expect_success \
1479        'Q: verify first commit' \
1480        'git cat-file commit notes-test~2 | sed 1d >actual &&
1481        test_cmp expect actual'
1482
1483cat >expect <<EOF
1484parent $commit1
1485author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1486committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1487
1488second (:5)
1489EOF
1490test_expect_success \
1491        'Q: verify second commit' \
1492        'git cat-file commit notes-test^ | sed 1d >actual &&
1493        test_cmp expect actual'
1494
1495cat >expect <<EOF
1496parent $commit2
1497author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1498committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1499
1500third (:6)
1501EOF
1502test_expect_success \
1503        'Q: verify third commit' \
1504        'git cat-file commit notes-test | sed 1d >actual &&
1505        test_cmp expect actual'
1506
1507cat >expect <<EOF
1508author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1509committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1510
1511notes (:9)
1512EOF
1513test_expect_success \
1514        'Q: verify first notes commit' \
1515        'git cat-file commit refs/notes/foobar~2 | sed 1d >actual &&
1516        test_cmp expect actual'
1517
1518cat >expect.unsorted <<EOF
1519100644 blob $commit1
1520100644 blob $commit2
1521100644 blob $commit3
1522EOF
1523cat expect.unsorted | sort >expect
1524test_expect_success \
1525        'Q: verify first notes tree' \
1526        'git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]* / /" >actual &&
1527         test_cmp expect actual'
1528
1529echo "$note1_data" >expect
1530test_expect_success \
1531        'Q: verify first note for first commit' \
1532        'git cat-file blob refs/notes/foobar~2:$commit1 >actual && test_cmp expect actual'
1533
1534echo "$note2_data" >expect
1535test_expect_success \
1536        'Q: verify first note for second commit' \
1537        'git cat-file blob refs/notes/foobar~2:$commit2 >actual && test_cmp expect actual'
1538
1539echo "$note3_data" >expect
1540test_expect_success \
1541        'Q: verify first note for third commit' \
1542        'git cat-file blob refs/notes/foobar~2:$commit3 >actual && test_cmp expect actual'
1543
1544cat >expect <<EOF
1545parent `git rev-parse --verify refs/notes/foobar~2`
1546author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1547committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1548
1549notes (:10)
1550EOF
1551test_expect_success \
1552        'Q: verify second notes commit' \
1553        'git cat-file commit refs/notes/foobar^ | sed 1d >actual &&
1554        test_cmp expect actual'
1555
1556cat >expect.unsorted <<EOF
1557100644 blob $commit1
1558100644 blob $commit2
1559100644 blob $commit3
1560EOF
1561cat expect.unsorted | sort >expect
1562test_expect_success \
1563        'Q: verify second notes tree' \
1564        'git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]*  / /" >actual &&
1565         test_cmp expect actual'
1566
1567echo "$note1b_data" >expect
1568test_expect_success \
1569        'Q: verify second note for first commit' \
1570        'git cat-file blob refs/notes/foobar^:$commit1 >actual && test_cmp expect actual'
1571
1572echo "$note2_data" >expect
1573test_expect_success \
1574        'Q: verify first note for second commit' \
1575        'git cat-file blob refs/notes/foobar^:$commit2 >actual && test_cmp expect actual'
1576
1577echo "$note3_data" >expect
1578test_expect_success \
1579        'Q: verify first note for third commit' \
1580        'git cat-file blob refs/notes/foobar^:$commit3 >actual && test_cmp expect actual'
1581
1582cat >expect <<EOF
1583author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1584committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1585
1586notes (:11)
1587EOF
1588test_expect_success \
1589        'Q: verify third notes commit' \
1590        'git cat-file commit refs/notes/foobar2 | sed 1d >actual &&
1591        test_cmp expect actual'
1592
1593cat >expect.unsorted <<EOF
1594100644 blob $commit1
1595EOF
1596cat expect.unsorted | sort >expect
1597test_expect_success \
1598        'Q: verify third notes tree' \
1599        'git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]*  / /" >actual &&
1600         test_cmp expect actual'
1601
1602echo "$note1c_data" >expect
1603test_expect_success \
1604        'Q: verify third note for first commit' \
1605        'git cat-file blob refs/notes/foobar2:$commit1 >actual && test_cmp expect actual'
1606
1607cat >expect <<EOF
1608parent `git rev-parse --verify refs/notes/foobar^`
1609author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1610committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1611
1612notes (:12)
1613EOF
1614test_expect_success \
1615        'Q: verify fourth notes commit' \
1616        'git cat-file commit refs/notes/foobar | sed 1d >actual &&
1617        test_cmp expect actual'
1618
1619cat >expect.unsorted <<EOF
1620100644 blob $commit2
1621EOF
1622cat expect.unsorted | sort >expect
1623test_expect_success \
1624        'Q: verify fourth notes tree' \
1625        'git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]*   / /" >actual &&
1626         test_cmp expect actual'
1627
1628echo "$note2b_data" >expect
1629test_expect_success \
1630        'Q: verify second note for second commit' \
1631        'git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual'
1632
1633###
1634### series R (feature and option)
1635###
1636
1637cat >input <<EOF
1638feature no-such-feature-exists
1639EOF
1640
1641test_expect_success 'R: abort on unsupported feature' '
1642        test_must_fail git fast-import <input
1643'
1644
1645cat >input <<EOF
1646feature date-format=now
1647EOF
1648
1649test_expect_success 'R: supported feature is accepted' '
1650        git fast-import <input
1651'
1652
1653cat >input << EOF
1654blob
1655data 3
1656hi
1657feature date-format=now
1658EOF
1659
1660test_expect_success 'R: abort on receiving feature after data command' '
1661        test_must_fail git fast-import <input
1662'
1663
1664cat >input << EOF
1665feature import-marks=git.marks
1666feature import-marks=git2.marks
1667EOF
1668
1669test_expect_success 'R: only one import-marks feature allowed per stream' '
1670        test_must_fail git fast-import <input
1671'
1672
1673cat >input << EOF
1674feature export-marks=git.marks
1675blob
1676mark :1
1677data 3
1678hi
1679
1680EOF
1681
1682test_expect_success \
1683    'R: export-marks feature results in a marks file being created' \
1684    'cat input | git fast-import &&
1685    grep :1 git.marks'
1686
1687test_expect_success \
1688    'R: export-marks options can be overriden by commandline options' \
1689    'cat input | git fast-import --export-marks=other.marks &&
1690    grep :1 other.marks'
1691
1692cat >input << EOF
1693feature import-marks=marks.out
1694feature export-marks=marks.new
1695EOF
1696
1697test_expect_success \
1698    'R: import to output marks works without any content' \
1699    'cat input | git fast-import &&
1700    test_cmp marks.out marks.new'
1701
1702cat >input <<EOF
1703feature import-marks=nonexistant.marks
1704feature export-marks=marks.new
1705EOF
1706
1707test_expect_success \
1708    'R: import marks prefers commandline marks file over the stream' \
1709    'cat input | git fast-import --import-marks=marks.out &&
1710    test_cmp marks.out marks.new'
1711
1712
1713cat >input <<EOF
1714feature import-marks=nonexistant.marks
1715feature export-marks=combined.marks
1716EOF
1717
1718test_expect_success 'R: multiple --import-marks= should be honoured' '
1719    head -n2 marks.out > one.marks &&
1720    tail -n +3 marks.out > two.marks &&
1721    git fast-import --import-marks=one.marks --import-marks=two.marks <input &&
1722    test_cmp marks.out combined.marks
1723'
1724
1725cat >input <<EOF
1726feature relative-marks
1727feature import-marks=relative.in
1728feature export-marks=relative.out
1729EOF
1730
1731test_expect_success 'R: feature relative-marks should be honoured' '
1732    mkdir -p .git/info/fast-import/ &&
1733    cp marks.new .git/info/fast-import/relative.in &&
1734    git fast-import <input &&
1735    test_cmp marks.new .git/info/fast-import/relative.out
1736'
1737
1738cat >input <<EOF
1739feature relative-marks
1740feature import-marks=relative.in
1741feature no-relative-marks
1742feature export-marks=non-relative.out
1743EOF
1744
1745test_expect_success 'R: feature no-relative-marks should be honoured' '
1746    git fast-import <input &&
1747    test_cmp marks.new non-relative.out
1748'
1749
1750test_expect_success 'R: feature cat-blob supported' '
1751        echo "feature cat-blob" |
1752        git fast-import
1753'
1754
1755test_expect_success 'R: cat-blob-fd must be a nonnegative integer' '
1756        test_must_fail git fast-import --cat-blob-fd=-1 </dev/null
1757'
1758
1759test_expect_success 'R: print old blob' '
1760        blob=$(echo "yes it can" | git hash-object -w --stdin) &&
1761        cat >expect <<-EOF &&
1762        ${blob} blob 11
1763        yes it can
1764
1765        EOF
1766        echo "cat-blob $blob" |
1767        git fast-import --cat-blob-fd=6 6>actual &&
1768        test_cmp expect actual
1769'
1770
1771test_expect_success 'R: in-stream cat-blob-fd not respected' '
1772        echo hello >greeting &&
1773        blob=$(git hash-object -w greeting) &&
1774        cat >expect <<-EOF &&
1775        ${blob} blob 6
1776        hello
1777
1778        EOF
1779        git fast-import --cat-blob-fd=3 3>actual.3 >actual.1 <<-EOF &&
1780        cat-blob $blob
1781        EOF
1782        test_cmp expect actual.3 &&
1783        test_cmp empty actual.1 &&
1784        git fast-import 3>actual.3 >actual.1 <<-EOF &&
1785        option cat-blob-fd=3
1786        cat-blob $blob
1787        EOF
1788        test_cmp empty actual.3 &&
1789        test_cmp expect actual.1
1790'
1791
1792test_expect_success 'R: print new blob' '
1793        blob=$(echo "yep yep yep" | git hash-object --stdin) &&
1794        cat >expect <<-EOF &&
1795        ${blob} blob 12
1796        yep yep yep
1797
1798        EOF
1799        git fast-import --cat-blob-fd=6 6>actual <<-\EOF &&
1800        blob
1801        mark :1
1802        data <<BLOB_END
1803        yep yep yep
1804        BLOB_END
1805        cat-blob :1
1806        EOF
1807        test_cmp expect actual
1808'
1809
1810test_expect_success 'R: print new blob by sha1' '
1811        blob=$(echo "a new blob named by sha1" | git hash-object --stdin) &&
1812        cat >expect <<-EOF &&
1813        ${blob} blob 25
1814        a new blob named by sha1
1815
1816        EOF
1817        git fast-import --cat-blob-fd=6 6>actual <<-EOF &&
1818        blob
1819        data <<BLOB_END
1820        a new blob named by sha1
1821        BLOB_END
1822        cat-blob $blob
1823        EOF
1824        test_cmp expect actual
1825'
1826
1827test_expect_success 'setup: big file' '
1828        (
1829                echo "the quick brown fox jumps over the lazy dog" >big &&
1830                for i in 1 2 3
1831                do
1832                        cat big big big big >bigger &&
1833                        cat bigger bigger bigger bigger >big ||
1834                        exit
1835                done
1836        )
1837'
1838
1839test_expect_success 'R: print two blobs to stdout' '
1840        blob1=$(git hash-object big) &&
1841        blob1_len=$(wc -c <big) &&
1842        blob2=$(echo hello | git hash-object --stdin) &&
1843        {
1844                echo ${blob1} blob $blob1_len &&
1845                cat big &&
1846                cat <<-EOF
1847
1848                ${blob2} blob 6
1849                hello
1850
1851                EOF
1852        } >expect &&
1853        {
1854                cat <<-\END_PART1 &&
1855                        blob
1856                        mark :1
1857                        data <<data_end
1858                END_PART1
1859                cat big &&
1860                cat <<-\EOF
1861                        data_end
1862                        blob
1863                        mark :2
1864                        data <<data_end
1865                        hello
1866                        data_end
1867                        cat-blob :1
1868                        cat-blob :2
1869                EOF
1870        } |
1871        git fast-import >actual &&
1872        test_cmp expect actual
1873'
1874
1875test_expect_success 'setup: have pipes?' '
1876        rm -f frob &&
1877        if mkfifo frob
1878        then
1879                test_set_prereq PIPE
1880        fi
1881'
1882
1883test_expect_success PIPE 'R: copy using cat-file' '
1884        expect_id=$(git hash-object big) &&
1885        expect_len=$(wc -c <big) &&
1886        echo $expect_id blob $expect_len >expect.response &&
1887
1888        rm -f blobs &&
1889        cat >frontend <<-\FRONTEND_END &&
1890        #!/bin/sh
1891        cat <<EOF &&
1892        feature cat-blob
1893        blob
1894        mark :1
1895        data <<BLOB
1896        EOF
1897        cat big
1898        cat <<EOF
1899        BLOB
1900        cat-blob :1
1901        EOF
1902
1903        read blob_id type size <&3 &&
1904        echo "$blob_id $type $size" >response &&
1905        dd of=blob bs=1 count=$size <&3 &&
1906        read newline <&3 &&
1907
1908        cat <<EOF &&
1909        commit refs/heads/copied
1910        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1911        data <<COMMIT
1912        copy big file as file3
1913        COMMIT
1914        M 644 inline file3
1915        data <<BLOB
1916        EOF
1917        cat blob &&
1918        cat <<EOF
1919        BLOB
1920        EOF
1921        FRONTEND_END
1922
1923        mkfifo blobs &&
1924        (
1925                export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_COMMITTER_DATE &&
1926                sh frontend 3<blobs |
1927                git fast-import --cat-blob-fd=3 3>blobs
1928        ) &&
1929        git show copied:file3 >actual &&
1930        test_cmp expect.response response &&
1931        test_cmp big actual
1932'
1933
1934test_expect_success PIPE 'R: print blob mid-commit' '
1935        rm -f blobs &&
1936        echo "A blob from _before_ the commit." >expect &&
1937        mkfifo blobs &&
1938        (
1939                exec 3<blobs &&
1940                cat <<-EOF &&
1941                feature cat-blob
1942                blob
1943                mark :1
1944                data <<BLOB
1945                A blob from _before_ the commit.
1946                BLOB
1947                commit refs/heads/temporary
1948                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1949                data <<COMMIT
1950                Empty commit
1951                COMMIT
1952                cat-blob :1
1953                EOF
1954
1955                read blob_id type size <&3 &&
1956                dd of=actual bs=1 count=$size <&3 &&
1957                read newline <&3 &&
1958
1959                echo
1960        ) |
1961        git fast-import --cat-blob-fd=3 3>blobs &&
1962        test_cmp expect actual
1963'
1964
1965test_expect_success PIPE 'R: print staged blob within commit' '
1966        rm -f blobs &&
1967        echo "A blob from _within_ the commit." >expect &&
1968        mkfifo blobs &&
1969        (
1970                exec 3<blobs &&
1971                cat <<-EOF &&
1972                feature cat-blob
1973                commit refs/heads/within
1974                committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
1975                data <<COMMIT
1976                Empty commit
1977                COMMIT
1978                M 644 inline within
1979                data <<BLOB
1980                A blob from _within_ the commit.
1981                BLOB
1982                EOF
1983
1984                to_get=$(
1985                        echo "A blob from _within_ the commit." |
1986                        git hash-object --stdin
1987                ) &&
1988                echo "cat-blob $to_get" &&
1989
1990                read blob_id type size <&3 &&
1991                dd of=actual bs=1 count=$size <&3 &&
1992                read newline <&3 &&
1993
1994                echo deleteall
1995        ) |
1996        git fast-import --cat-blob-fd=3 3>blobs &&
1997        test_cmp expect actual
1998'
1999
2000cat >input << EOF
2001option git quiet
2002blob
2003data 3
2004hi
2005
2006EOF
2007
2008test_expect_success 'R: quiet option results in no stats being output' '
2009    cat input | git fast-import 2> output &&
2010    test_cmp empty output
2011'
2012
2013cat >input <<EOF
2014option git non-existing-option
2015EOF
2016
2017test_expect_success 'R: die on unknown option' '
2018    test_must_fail git fast-import <input
2019'
2020
2021test_expect_success 'R: unknown commandline options are rejected' '\
2022    test_must_fail git fast-import --non-existing-option < /dev/null
2023'
2024
2025test_expect_success 'R: die on invalid option argument' '
2026        echo "option git active-branches=-5" |
2027        test_must_fail git fast-import &&
2028        echo "option git depth=" |
2029        test_must_fail git fast-import &&
2030        test_must_fail git fast-import --depth="5 elephants" </dev/null
2031'
2032
2033cat >input <<EOF
2034option non-existing-vcs non-existing-option
2035EOF
2036
2037test_expect_success 'R: ignore non-git options' '
2038    git fast-import <input
2039'
2040
2041##
2042## R: very large blobs
2043##
2044blobsize=$((2*1024*1024 + 53))
2045test-genrandom bar $blobsize >expect
2046cat >input <<INPUT_END
2047commit refs/heads/big-file
2048committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2049data <<COMMIT
2050R - big file
2051COMMIT
2052
2053M 644 inline big1
2054data $blobsize
2055INPUT_END
2056cat expect >>input
2057cat >>input <<INPUT_END
2058M 644 inline big2
2059data $blobsize
2060INPUT_END
2061cat expect >>input
2062echo >>input
2063
2064test_expect_success \
2065        'R: blob bigger than threshold' \
2066        'test_create_repo R &&
2067         git --git-dir=R/.git fast-import --big-file-threshold=1 <input'
2068test_expect_success \
2069        'R: verify created pack' \
2070        ': >verify &&
2071         for p in R/.git/objects/pack/*.pack;
2072         do
2073           git verify-pack -v $p >>verify || exit;
2074         done'
2075test_expect_success \
2076        'R: verify written objects' \
2077        'git --git-dir=R/.git cat-file blob big-file:big1 >actual &&
2078         test_cmp expect actual &&
2079         a=$(git --git-dir=R/.git rev-parse big-file:big1) &&
2080         b=$(git --git-dir=R/.git rev-parse big-file:big2) &&
2081         test $a = $b'
2082test_expect_success \
2083        'R: blob appears only once' \
2084        'n=$(grep $a verify | wc -l) &&
2085         test 1 = $n'
2086
2087test_done