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