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