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