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