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