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