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