Merge tag 'v2.8.6' into maint-2.9
[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 test_expect_success 'R: corrupt lines do not mess marks file' '
2654         rm -f io.marks &&
2655         blob=$(echo hi | git hash-object --stdin) &&
2656         cat >expect <<-EOF &&
2657         :3 0000000000000000000000000000000000000000
2658         :1 $blob
2659         :2 $blob
2660         EOF
2661         cp expect io.marks &&
2662         test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
2663
2664         EOF
2665         test_cmp expect io.marks
2666 '
2667
2668 ##
2669 ## R: very large blobs
2670 ##
2671 test_expect_success 'R: blob bigger than threshold' '
2672         blobsize=$((2*1024*1024 + 53)) &&
2673         test-genrandom bar $blobsize >expect &&
2674         cat >input <<-INPUT_END &&
2675         commit refs/heads/big-file
2676         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2677         data <<COMMIT
2678         R - big file
2679         COMMIT
2680
2681         M 644 inline big1
2682         data $blobsize
2683         INPUT_END
2684         cat expect >>input &&
2685         cat >>input <<-INPUT_END &&
2686         M 644 inline big2
2687         data $blobsize
2688         INPUT_END
2689         cat expect >>input &&
2690         echo >>input &&
2691
2692         test_create_repo R &&
2693         git --git-dir=R/.git fast-import --big-file-threshold=1 <input
2694 '
2695
2696 test_expect_success 'R: verify created pack' '
2697         (
2698                 cd R &&
2699                 verify_packs -v > ../verify
2700         )
2701 '
2702
2703 test_expect_success 'R: verify written objects' '
2704         git --git-dir=R/.git cat-file blob big-file:big1 >actual &&
2705         test_cmp_bin expect actual &&
2706         a=$(git --git-dir=R/.git rev-parse big-file:big1) &&
2707         b=$(git --git-dir=R/.git rev-parse big-file:big2) &&
2708         test $a = $b
2709 '
2710
2711 test_expect_success 'R: blob appears only once' '
2712         n=$(grep $a verify | wc -l) &&
2713         test 1 = $n
2714 '
2715
2716 ###
2717 ### series S
2718 ###
2719 #
2720 # Make sure missing spaces and EOLs after mark references
2721 # cause errors.
2722 #
2723 # Setup:
2724 #
2725 #   1--2--4
2726 #    \   /
2727 #     -3-
2728 #
2729 #   commit marks:  301, 302, 303, 304
2730 #   blob marks:              403, 404, resp.
2731 #   note mark:          202
2732 #
2733 # The error message when a space is missing not at the
2734 # end of the line is:
2735 #
2736 #   Missing space after ..
2737 #
2738 # or when extra characters come after the mark at the end
2739 # of the line:
2740 #
2741 #   Garbage after ..
2742 #
2743 # or when the dataref is neither "inline " or a known SHA1,
2744 #
2745 #   Invalid dataref ..
2746 #
2747 test_expect_success 'S: initialize for S tests' '
2748         test_tick &&
2749
2750         cat >input <<-INPUT_END &&
2751         commit refs/heads/S
2752         mark :301
2753         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2754         data <<COMMIT
2755         commit 1
2756         COMMIT
2757         M 100644 inline hello.c
2758         data <<BLOB
2759         blob 1
2760         BLOB
2761
2762         commit refs/heads/S
2763         mark :302
2764         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2765         data <<COMMIT
2766         commit 2
2767         COMMIT
2768         from :301
2769         M 100644 inline hello.c
2770         data <<BLOB
2771         blob 2
2772         BLOB
2773
2774         blob
2775         mark :403
2776         data <<BLOB
2777         blob 3
2778         BLOB
2779
2780         blob
2781         mark :202
2782         data <<BLOB
2783         note 2
2784         BLOB
2785         INPUT_END
2786
2787         git fast-import --export-marks=marks <input
2788 '
2789
2790 #
2791 # filemodify, three datarefs
2792 #
2793 test_expect_success 'S: filemodify with garbage after mark must fail' '
2794         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2795         commit refs/heads/S
2796         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2797         data <<COMMIT
2798         commit N
2799         COMMIT
2800         M 100644 :403x hello.c
2801         EOF
2802         cat err &&
2803         test_i18ngrep "space after mark" err
2804 '
2805
2806 # inline is misspelled; fast-import thinks it is some unknown dataref
2807 test_expect_success 'S: filemodify with garbage after inline must fail' '
2808         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2809         commit refs/heads/S
2810         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2811         data <<COMMIT
2812         commit N
2813         COMMIT
2814         M 100644 inlineX hello.c
2815         data <<BLOB
2816         inline
2817         BLOB
2818         EOF
2819         cat err &&
2820         test_i18ngrep "nvalid dataref" err
2821 '
2822
2823 test_expect_success 'S: filemodify with garbage after sha1 must fail' '
2824         sha1=$(grep :403 marks | cut -d\  -f2) &&
2825         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2826         commit refs/heads/S
2827         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2828         data <<COMMIT
2829         commit N
2830         COMMIT
2831         M 100644 ${sha1}x hello.c
2832         EOF
2833         cat err &&
2834         test_i18ngrep "space after SHA1" err
2835 '
2836
2837 #
2838 # notemodify, three ways to say dataref
2839 #
2840 test_expect_success 'S: notemodify with garabge after mark dataref must fail' '
2841         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2842         commit refs/heads/S
2843         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2844         data <<COMMIT
2845         commit S note dataref markref
2846         COMMIT
2847         N :202x :302
2848         EOF
2849         cat err &&
2850         test_i18ngrep "space after mark" err
2851 '
2852
2853 test_expect_success 'S: notemodify with garbage after inline dataref must fail' '
2854         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2855         commit refs/heads/S
2856         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2857         data <<COMMIT
2858         commit S note dataref inline
2859         COMMIT
2860         N inlineX :302
2861         data <<BLOB
2862         note blob
2863         BLOB
2864         EOF
2865         cat err &&
2866         test_i18ngrep "nvalid dataref" err
2867 '
2868
2869 test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' '
2870         sha1=$(grep :202 marks | cut -d\  -f2) &&
2871         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2872         commit refs/heads/S
2873         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2874         data <<COMMIT
2875         commit S note dataref sha1
2876         COMMIT
2877         N ${sha1}x :302
2878         EOF
2879         cat err &&
2880         test_i18ngrep "space after SHA1" err
2881 '
2882
2883 #
2884 # notemodify, mark in commit-ish
2885 #
2886 test_expect_success 'S: notemodify with garbage after mark commit-ish must fail' '
2887         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2888         commit refs/heads/Snotes
2889         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2890         data <<COMMIT
2891         commit S note commit-ish
2892         COMMIT
2893         N :202 :302x
2894         EOF
2895         cat err &&
2896         test_i18ngrep "after mark" err
2897 '
2898
2899 #
2900 # from
2901 #
2902 test_expect_success 'S: from with garbage after mark must fail' '
2903         test_must_fail \
2904         git fast-import --import-marks=marks --export-marks=marks <<-EOF 2>err &&
2905         commit refs/heads/S2
2906         mark :303
2907         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2908         data <<COMMIT
2909         commit 3
2910         COMMIT
2911         from :301x
2912         M 100644 :403 hello.c
2913         EOF
2914
2915
2916         # go create the commit, need it for merge test
2917         git fast-import --import-marks=marks --export-marks=marks <<-EOF &&
2918         commit refs/heads/S2
2919         mark :303
2920         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2921         data <<COMMIT
2922         commit 3
2923         COMMIT
2924         from :301
2925         M 100644 :403 hello.c
2926         EOF
2927
2928         # now evaluate the error
2929         cat err &&
2930         test_i18ngrep "after mark" err
2931 '
2932
2933
2934 #
2935 # merge
2936 #
2937 test_expect_success 'S: merge with garbage after mark must fail' '
2938         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2939         commit refs/heads/S
2940         mark :304
2941         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2942         data <<COMMIT
2943         merge 4
2944         COMMIT
2945         from :302
2946         merge :303x
2947         M 100644 :403 hello.c
2948         EOF
2949         cat err &&
2950         test_i18ngrep "after mark" err
2951 '
2952
2953 #
2954 # tag, from markref
2955 #
2956 test_expect_success 'S: tag with garbage after mark must fail' '
2957         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2958         tag refs/tags/Stag
2959         from :302x
2960         tagger $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
2961         data <<TAG
2962         tag S
2963         TAG
2964         EOF
2965         cat err &&
2966         test_i18ngrep "after mark" err
2967 '
2968
2969 #
2970 # cat-blob markref
2971 #
2972 test_expect_success 'S: cat-blob with garbage after mark must fail' '
2973         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2974         cat-blob :403x
2975         EOF
2976         cat err &&
2977         test_i18ngrep "after mark" err
2978 '
2979
2980 #
2981 # ls markref
2982 #
2983 test_expect_success 'S: ls with garbage after mark must fail' '
2984         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2985         ls :302x hello.c
2986         EOF
2987         cat err &&
2988         test_i18ngrep "space after mark" err
2989 '
2990
2991 test_expect_success 'S: ls with garbage after sha1 must fail' '
2992         sha1=$(grep :302 marks | cut -d\  -f2) &&
2993         test_must_fail git fast-import --import-marks=marks <<-EOF 2>err &&
2994         ls ${sha1}x hello.c
2995         EOF
2996         cat err &&
2997         test_i18ngrep "space after tree-ish" err
2998 '
2999
3000 ###
3001 ### series T (ls)
3002 ###
3003 # Setup is carried over from series S.
3004
3005 test_expect_success 'T: ls root tree' '
3006         sed -e "s/Z\$//" >expect <<-EOF &&
3007         040000 tree $(git rev-parse S^{tree})   Z
3008         EOF
3009         sha1=$(git rev-parse --verify S) &&
3010         git fast-import --import-marks=marks <<-EOF >actual &&
3011         ls $sha1 ""
3012         EOF
3013         test_cmp expect actual
3014 '
3015
3016 test_expect_success 'T: delete branch' '
3017         git branch to-delete &&
3018         git fast-import <<-EOF &&
3019         reset refs/heads/to-delete
3020         from 0000000000000000000000000000000000000000
3021         EOF
3022         test_must_fail git rev-parse --verify refs/heads/to-delete
3023 '
3024
3025 test_expect_success 'T: empty reset doesnt delete branch' '
3026         git branch not-to-delete &&
3027         git fast-import <<-EOF &&
3028         reset refs/heads/not-to-delete
3029         EOF
3030         git show-ref &&
3031         git rev-parse --verify refs/heads/not-to-delete
3032 '
3033
3034 ###
3035 ### series U (filedelete)
3036 ###
3037
3038 test_expect_success 'U: initialize for U tests' '
3039         cat >input <<-INPUT_END &&
3040         commit refs/heads/U
3041         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3042         data <<COMMIT
3043         test setup
3044         COMMIT
3045         M 100644 inline hello.c
3046         data <<BLOB
3047         blob 1
3048         BLOB
3049         M 100644 inline good/night.txt
3050         data <<BLOB
3051         sleep well
3052         BLOB
3053         M 100644 inline good/bye.txt
3054         data <<BLOB
3055         au revoir
3056         BLOB
3057
3058         INPUT_END
3059
3060         git fast-import <input
3061 '
3062
3063 test_expect_success 'U: filedelete file succeeds' '
3064         cat >input <<-INPUT_END &&
3065         commit refs/heads/U
3066         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3067         data <<COMMIT
3068         delete good/night.txt
3069         COMMIT
3070         from refs/heads/U^0
3071         D good/night.txt
3072
3073         INPUT_END
3074
3075         git fast-import <input
3076 '
3077
3078 test_expect_success 'U: validate file delete result' '
3079         cat >expect <<-EOF &&
3080         :100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D      good/night.txt
3081         EOF
3082
3083         git diff-tree -M -r U^1 U >actual &&
3084
3085         compare_diff_raw expect actual
3086 '
3087
3088 test_expect_success 'U: filedelete directory succeeds' '
3089         cat >input <<-INPUT_END &&
3090         commit refs/heads/U
3091         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3092         data <<COMMIT
3093         delete good dir
3094         COMMIT
3095         from refs/heads/U^0
3096         D good
3097
3098         INPUT_END
3099
3100         git fast-import <input
3101 '
3102
3103 test_expect_success 'U: validate directory delete result' '
3104         cat >expect <<-EOF &&
3105         :100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D      good/bye.txt
3106         EOF
3107
3108         git diff-tree -M -r U^1 U >actual &&
3109
3110         compare_diff_raw expect actual
3111 '
3112
3113 test_expect_success 'U: filedelete root succeeds' '
3114         cat >input <<-INPUT_END &&
3115         commit refs/heads/U
3116         committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
3117         data <<COMMIT
3118         must succeed
3119         COMMIT
3120         from refs/heads/U^0
3121         D ""
3122
3123         INPUT_END
3124
3125         git fast-import <input
3126 '
3127
3128 test_expect_success 'U: validate root delete result' '
3129         cat >expect <<-EOF &&
3130         :100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D      hello.c
3131         EOF
3132
3133         git diff-tree -M -r U^1 U >actual &&
3134
3135         compare_diff_raw expect actual
3136 '
3137
3138 test_done