Merge branch 'db/vcs-svn-incremental' into svn-fe
[git/jnareb-git.git] / t / t9010-svn-fe.sh
blob003395c5f6f05bf7afe2aef35146518a3323af02
1 #!/bin/sh
3 test_description='check svn dumpfile importer'
5 . ./test-lib.sh
7 reinit_git () {
8 if ! test_declared_prereq PIPE
9 then
10 echo >&4 "reinit_git: need to declare PIPE prerequisite"
11 return 127
13 rm -fr .git &&
14 rm -f stream backflow &&
15 git init &&
16 mkfifo stream backflow
19 try_dump () {
20 input=$1 &&
21 maybe_fail=${2:+test_$2} &&
24 $maybe_fail test-svn-fe "$input" >stream 3<backflow &
25 } &&
26 git fast-import --cat-blob-fd=3 <stream 3>backflow &&
27 wait $!
30 properties () {
31 while test "$#" -ne 0
33 property="$1" &&
34 value="$2" &&
35 printf "%s\n" "K ${#property}" &&
36 printf "%s\n" "$property" &&
37 printf "%s\n" "V ${#value}" &&
38 printf "%s\n" "$value" &&
39 shift 2 ||
40 return 1
41 done
44 text_no_props () {
45 text="$1
46 " &&
47 printf "%s\n" "Prop-content-length: 10" &&
48 printf "%s\n" "Text-content-length: ${#text}" &&
49 printf "%s\n" "Content-length: $((${#text} + 10))" &&
50 printf "%s\n" "" "PROPS-END" &&
51 printf "%s\n" "$text"
54 >empty
56 test_expect_success 'setup: have pipes?' '
57 rm -f frob &&
58 if mkfifo frob
59 then
60 test_set_prereq PIPE
64 test_expect_success PIPE 'empty dump' '
65 reinit_git &&
66 echo "SVN-fs-dump-format-version: 2" >input &&
67 try_dump input
70 test_expect_success PIPE 'v4 dumps not supported' '
71 reinit_git &&
72 echo "SVN-fs-dump-format-version: 4" >v4.dump &&
73 try_dump v4.dump must_fail
76 test_expect_failure PIPE 'empty revision' '
77 reinit_git &&
78 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
79 cat >emptyrev.dump <<-\EOF &&
80 SVN-fs-dump-format-version: 3
82 Revision-number: 1
83 Prop-content-length: 0
84 Content-length: 0
86 Revision-number: 2
87 Prop-content-length: 0
88 Content-length: 0
90 EOF
91 try_dump emptyrev.dump &&
92 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
93 test_cmp expect actual
96 test_expect_success PIPE 'empty properties' '
97 reinit_git &&
98 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
99 cat >emptyprop.dump <<-\EOF &&
100 SVN-fs-dump-format-version: 3
102 Revision-number: 1
103 Prop-content-length: 10
104 Content-length: 10
106 PROPS-END
108 Revision-number: 2
109 Prop-content-length: 10
110 Content-length: 10
112 PROPS-END
114 try_dump emptyprop.dump &&
115 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
116 test_cmp expect actual
119 test_expect_success PIPE 'author name and commit message' '
120 reinit_git &&
121 echo "<author@example.com, author@example.com@local>" >expect.author &&
122 cat >message <<-\EOF &&
123 A concise summary of the change
125 A detailed description of the change, why it is needed, what
126 was broken and why applying this is the best course of action.
128 * file.c
129 Details pertaining to an individual file.
132 properties \
133 svn:author author@example.com \
134 svn:log "$(cat message)" &&
135 echo PROPS-END
136 } >props &&
138 echo "SVN-fs-dump-format-version: 3" &&
139 echo &&
140 echo "Revision-number: 1" &&
141 echo Prop-content-length: $(wc -c <props) &&
142 echo Content-length: $(wc -c <props) &&
143 echo &&
144 cat props
145 } >log.dump &&
146 try_dump log.dump &&
147 git log -p --format="%B" HEAD >actual.log &&
148 git log --format="<%an, %ae>" >actual.author &&
149 test_cmp message actual.log &&
150 test_cmp expect.author actual.author
153 test_expect_success PIPE 'unsupported properties are ignored' '
154 reinit_git &&
155 echo author >expect &&
156 cat >extraprop.dump <<-\EOF &&
157 SVN-fs-dump-format-version: 3
159 Revision-number: 1
160 Prop-content-length: 56
161 Content-length: 56
164 nonsense
167 K 10
168 svn:author
170 author
171 PROPS-END
173 try_dump extraprop.dump &&
174 git log -p --format=%an HEAD >actual &&
175 test_cmp expect actual
178 test_expect_failure PIPE 'timestamp and empty file' '
179 echo author@example.com >expect.author &&
180 echo 1999-01-01 >expect.date &&
181 echo file >expect.files &&
182 reinit_git &&
184 properties \
185 svn:author author@example.com \
186 svn:date "1999-01-01T00:01:002.000000Z" \
187 svn:log "add empty file" &&
188 echo PROPS-END
189 } >props &&
191 cat <<-EOF &&
192 SVN-fs-dump-format-version: 3
194 Revision-number: 1
196 echo Prop-content-length: $(wc -c <props) &&
197 echo Content-length: $(wc -c <props) &&
198 echo &&
199 cat props &&
200 cat <<-\EOF
202 Node-path: empty-file
203 Node-kind: file
204 Node-action: add
205 Content-length: 0
208 } >emptyfile.dump &&
209 try_dump emptyfile.dump &&
210 git log --format=%an HEAD >actual.author &&
211 git log --date=short --format=%ad HEAD >actual.date &&
212 git ls-tree -r --name-only HEAD >actual.files &&
213 test_cmp expect.author actual.author &&
214 test_cmp expect.date actual.date &&
215 test_cmp expect.files actual.files &&
216 git checkout HEAD empty-file &&
217 test_cmp empty file
220 test_expect_success PIPE 'directory with files' '
221 reinit_git &&
222 printf "%s\n" directory/file1 directory/file2 >expect.files &&
223 echo hi >hi &&
224 echo hello >hello &&
226 properties \
227 svn:author author@example.com \
228 svn:date "1999-02-01T00:01:002.000000Z" \
229 svn:log "add directory with some files in it" &&
230 echo PROPS-END
231 } >props &&
233 cat <<-EOF &&
234 SVN-fs-dump-format-version: 3
236 Revision-number: 1
238 echo Prop-content-length: $(wc -c <props) &&
239 echo Content-length: $(wc -c <props) &&
240 echo &&
241 cat props &&
242 cat <<-\EOF &&
244 Node-path: directory
245 Node-kind: dir
246 Node-action: add
247 Prop-content-length: 10
248 Content-length: 10
250 PROPS-END
252 Node-path: directory/file1
253 Node-kind: file
254 Node-action: add
256 text_no_props hello &&
257 cat <<-\EOF &&
258 Node-path: directory/file2
259 Node-kind: file
260 Node-action: add
262 text_no_props hi
263 } >directory.dump &&
264 try_dump directory.dump &&
266 git ls-tree -r --name-only HEAD >actual.files &&
267 git checkout HEAD directory &&
268 test_cmp expect.files actual.files &&
269 test_cmp hello directory/file1 &&
270 test_cmp hi directory/file2
273 test_expect_success PIPE 'branch name with backslash' '
274 reinit_git &&
275 sort <<-\EOF >expect.branch-files &&
276 trunk/file1
277 trunk/file2
278 "branches/UpdateFOPto094\\/file1"
279 "branches/UpdateFOPto094\\/file2"
282 echo hi >hi &&
283 echo hello >hello &&
285 properties \
286 svn:author author@example.com \
287 svn:date "1999-02-02T00:01:02.000000Z" \
288 svn:log "add directory with some files in it" &&
289 echo PROPS-END
290 } >props.setup &&
292 properties \
293 svn:author brancher@example.com \
294 svn:date "2007-12-06T21:38:34.000000Z" \
295 svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
296 echo PROPS-END
297 } >props.branch &&
299 cat <<-EOF &&
300 SVN-fs-dump-format-version: 3
302 Revision-number: 1
304 echo Prop-content-length: $(wc -c <props.setup) &&
305 echo Content-length: $(wc -c <props.setup) &&
306 echo &&
307 cat props.setup &&
308 cat <<-\EOF &&
310 Node-path: trunk
311 Node-kind: dir
312 Node-action: add
313 Prop-content-length: 10
314 Content-length: 10
316 PROPS-END
318 Node-path: branches
319 Node-kind: dir
320 Node-action: add
321 Prop-content-length: 10
322 Content-length: 10
324 PROPS-END
326 Node-path: trunk/file1
327 Node-kind: file
328 Node-action: add
330 text_no_props hello &&
331 cat <<-\EOF &&
332 Node-path: trunk/file2
333 Node-kind: file
334 Node-action: add
336 text_no_props hi &&
337 cat <<-\EOF &&
339 Revision-number: 2
341 echo Prop-content-length: $(wc -c <props.branch) &&
342 echo Content-length: $(wc -c <props.branch) &&
343 echo &&
344 cat props.branch &&
345 cat <<-\EOF
347 Node-path: branches/UpdateFOPto094\
348 Node-kind: dir
349 Node-action: add
350 Node-copyfrom-rev: 1
351 Node-copyfrom-path: trunk
353 Node-kind: dir
354 Node-action: add
355 Prop-content-length: 34
356 Content-length: 34
358 K 13
359 svn:mergeinfo
362 PROPS-END
364 } >branch.dump &&
365 try_dump branch.dump &&
367 git ls-tree -r --name-only HEAD |
368 sort >actual.branch-files &&
369 test_cmp expect.branch-files actual.branch-files
372 test_expect_success PIPE 'node without action' '
373 reinit_git &&
374 cat >inaction.dump <<-\EOF &&
375 SVN-fs-dump-format-version: 3
377 Revision-number: 1
378 Prop-content-length: 10
379 Content-length: 10
381 PROPS-END
383 Node-path: directory
384 Node-kind: dir
385 Prop-content-length: 10
386 Content-length: 10
388 PROPS-END
390 try_dump inaction.dump must_fail
393 test_expect_success PIPE 'action: add node without text' '
394 reinit_git &&
395 cat >textless.dump <<-\EOF &&
396 SVN-fs-dump-format-version: 3
398 Revision-number: 1
399 Prop-content-length: 10
400 Content-length: 10
402 PROPS-END
404 Node-path: textless
405 Node-kind: file
406 Node-action: add
407 Prop-content-length: 10
408 Content-length: 10
410 PROPS-END
412 try_dump textless.dump must_fail
415 test_expect_failure PIPE 'change file mode but keep old content' '
416 reinit_git &&
417 cat >expect <<-\EOF &&
418 OBJID
419 :120000 100644 OBJID OBJID T greeting
420 OBJID
421 :100644 120000 OBJID OBJID T greeting
422 OBJID
423 :000000 100644 OBJID OBJID A greeting
425 echo "link hello" >expect.blob &&
426 echo hello >hello &&
427 cat >filemode.dump <<-\EOF &&
428 SVN-fs-dump-format-version: 3
430 Revision-number: 1
431 Prop-content-length: 10
432 Content-length: 10
434 PROPS-END
436 Node-path: greeting
437 Node-kind: file
438 Node-action: add
439 Prop-content-length: 10
440 Text-content-length: 11
441 Content-length: 21
443 PROPS-END
444 link hello
446 Revision-number: 2
447 Prop-content-length: 10
448 Content-length: 10
450 PROPS-END
452 Node-path: greeting
453 Node-kind: file
454 Node-action: change
455 Prop-content-length: 33
456 Content-length: 33
458 K 11
459 svn:special
462 PROPS-END
464 Revision-number: 3
465 Prop-content-length: 10
466 Content-length: 10
468 PROPS-END
470 Node-path: greeting
471 Node-kind: file
472 Node-action: change
473 Prop-content-length: 10
474 Content-length: 10
476 PROPS-END
478 try_dump filemode.dump &&
480 git rev-list HEAD |
481 git diff-tree --root --stdin |
482 sed "s/$_x40/OBJID/g"
483 } >actual &&
484 git show HEAD:greeting >actual.blob &&
485 git show HEAD^:greeting >actual.target &&
486 test_cmp expect actual &&
487 test_cmp expect.blob actual.blob &&
488 test_cmp hello actual.target
491 test_expect_success PIPE 'NUL in property value' '
492 reinit_git &&
493 echo "commit message" >expect.message &&
495 properties \
496 unimportant "something with a NUL (Q)" \
497 svn:log "commit message"&&
498 echo PROPS-END
500 q_to_nul >props &&
502 cat <<-\EOF &&
503 SVN-fs-dump-format-version: 3
505 Revision-number: 1
507 echo Prop-content-length: $(wc -c <props) &&
508 echo Content-length: $(wc -c <props) &&
509 echo &&
510 cat props
511 } >nulprop.dump &&
512 try_dump nulprop.dump &&
513 git diff-tree --always -s --format=%s HEAD >actual.message &&
514 test_cmp expect.message actual.message
517 test_expect_success PIPE 'NUL in log message, file content, and property name' '
518 # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the
519 # svn:specialQnotreally example.
520 reinit_git &&
521 cat >expect <<-\EOF &&
522 OBJID
523 :100644 100644 OBJID OBJID M greeting
524 OBJID
525 :000000 100644 OBJID OBJID A greeting
527 printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message &&
528 printf "%s\n" "helQo" >expect.hello1 &&
529 printf "%s\n" "link hello" >expect.hello2 &&
531 properties svn:log "something with an ASCII NUL (Q)" &&
532 echo PROPS-END
534 q_to_nul >props &&
536 q_to_nul <<-\EOF &&
537 SVN-fs-dump-format-version: 3
539 Revision-number: 1
540 Prop-content-length: 10
541 Content-length: 10
543 PROPS-END
545 Node-path: greeting
546 Node-kind: file
547 Node-action: add
548 Prop-content-length: 10
549 Text-content-length: 6
550 Content-length: 16
552 PROPS-END
553 helQo
555 Revision-number: 2
557 echo Prop-content-length: $(wc -c <props) &&
558 echo Content-length: $(wc -c <props) &&
559 echo &&
560 cat props &&
561 q_to_nul <<-\EOF
563 Node-path: greeting
564 Node-kind: file
565 Node-action: change
566 Prop-content-length: 43
567 Text-content-length: 11
568 Content-length: 54
570 K 21
571 svn:specialQnotreally
574 PROPS-END
575 link hello
577 } >8bitclean.dump &&
578 try_dump 8bitclean.dump &&
580 git rev-list HEAD |
581 git diff-tree --root --stdin |
582 sed "s/$_x40/OBJID/g"
583 } >actual &&
585 git cat-file commit HEAD | nul_to_q &&
586 echo
588 sed -ne "/^\$/,\$ p" >actual.message &&
589 git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 &&
590 git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 &&
591 test_cmp expect actual &&
592 test_cmp expect.message actual.message &&
593 test_cmp expect.hello1 actual.hello1 &&
594 test_cmp expect.hello2 actual.hello2
597 test_expect_success PIPE 'change file mode and reiterate content' '
598 reinit_git &&
599 cat >expect <<-\EOF &&
600 OBJID
601 :120000 100644 OBJID OBJID T greeting
602 OBJID
603 :100644 120000 OBJID OBJID T greeting
604 OBJID
605 :000000 100644 OBJID OBJID A greeting
607 echo "link hello" >expect.blob &&
608 echo hello >hello &&
609 cat >filemode2.dump <<-\EOF &&
610 SVN-fs-dump-format-version: 3
612 Revision-number: 1
613 Prop-content-length: 10
614 Content-length: 10
616 PROPS-END
618 Node-path: greeting
619 Node-kind: file
620 Node-action: add
621 Prop-content-length: 10
622 Text-content-length: 11
623 Content-length: 21
625 PROPS-END
626 link hello
628 Revision-number: 2
629 Prop-content-length: 10
630 Content-length: 10
632 PROPS-END
634 Node-path: greeting
635 Node-kind: file
636 Node-action: change
637 Prop-content-length: 33
638 Text-content-length: 11
639 Content-length: 44
641 K 11
642 svn:special
645 PROPS-END
646 link hello
648 Revision-number: 3
649 Prop-content-length: 10
650 Content-length: 10
652 PROPS-END
654 Node-path: greeting
655 Node-kind: file
656 Node-action: change
657 Prop-content-length: 10
658 Text-content-length: 11
659 Content-length: 21
661 PROPS-END
662 link hello
664 try_dump filemode2.dump &&
666 git rev-list HEAD |
667 git diff-tree --root --stdin |
668 sed "s/$_x40/OBJID/g"
669 } >actual &&
670 git show HEAD:greeting >actual.blob &&
671 git show HEAD^:greeting >actual.target &&
672 test_cmp expect actual &&
673 test_cmp expect.blob actual.blob &&
674 test_cmp hello actual.target
677 test_expect_success PIPE 'deltas not supported' '
678 reinit_git &&
680 # (old) h + (inline) ello + (old) \n
681 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
682 q_to_nul
683 } >delta &&
685 properties \
686 svn:author author@example.com \
687 svn:date "1999-01-05T00:01:002.000000Z" \
688 svn:log "add greeting" &&
689 echo PROPS-END
690 } >props &&
692 properties \
693 svn:author author@example.com \
694 svn:date "1999-01-06T00:01:002.000000Z" \
695 svn:log "change it" &&
696 echo PROPS-END
697 } >props2 &&
699 echo SVN-fs-dump-format-version: 3 &&
700 echo &&
701 echo Revision-number: 1 &&
702 echo Prop-content-length: $(wc -c <props) &&
703 echo Content-length: $(wc -c <props) &&
704 echo &&
705 cat props &&
706 cat <<-\EOF &&
708 Node-path: hello
709 Node-kind: file
710 Node-action: add
711 Prop-content-length: 10
712 Text-content-length: 3
713 Content-length: 13
715 PROPS-END
719 echo Revision-number: 2 &&
720 echo Prop-content-length: $(wc -c <props2) &&
721 echo Content-length: $(wc -c <props2) &&
722 echo &&
723 cat props2 &&
724 cat <<-\EOF &&
726 Node-path: hello
727 Node-kind: file
728 Node-action: change
729 Text-delta: true
730 Prop-content-length: 10
732 echo Text-content-length: $(wc -c <delta) &&
733 echo Content-length: $((10 + $(wc -c <delta))) &&
734 echo &&
735 echo PROPS-END &&
736 cat delta
737 } >delta.dump &&
738 test_must_fail try_dump delta.dump
741 test_expect_success PIPE 'property deltas supported' '
742 reinit_git &&
743 cat >expect <<-\EOF &&
744 OBJID
745 :100755 100644 OBJID OBJID M script.sh
748 properties \
749 svn:author author@example.com \
750 svn:date "1999-03-06T00:01:002.000000Z" \
751 svn:log "make an executable, or chmod -x it" &&
752 echo PROPS-END
753 } >revprops &&
755 echo SVN-fs-dump-format-version: 3 &&
756 echo &&
757 echo Revision-number: 1 &&
758 echo Prop-content-length: $(wc -c <revprops) &&
759 echo Content-length: $(wc -c <revprops) &&
760 echo &&
761 cat revprops &&
762 echo &&
763 cat <<-\EOF &&
764 Node-path: script.sh
765 Node-kind: file
766 Node-action: add
767 Text-content-length: 0
768 Prop-content-length: 39
769 Content-length: 39
771 K 14
772 svn:executable
774 true
775 PROPS-END
778 echo Revision-number: 2 &&
779 echo Prop-content-length: $(wc -c <revprops) &&
780 echo Content-length: $(wc -c <revprops) &&
781 echo &&
782 cat revprops &&
783 echo &&
784 cat <<-\EOF
785 Node-path: script.sh
786 Node-kind: file
787 Node-action: change
788 Prop-delta: true
789 Prop-content-length: 30
790 Content-length: 30
792 D 14
793 svn:executable
794 PROPS-END
796 } >propdelta.dump &&
797 try_dump propdelta.dump &&
799 git rev-list HEAD |
800 git diff-tree --stdin |
801 sed "s/$_x40/OBJID/g"
802 } >actual &&
803 test_cmp expect actual
806 test_expect_success PIPE 'properties on /' '
807 reinit_git &&
808 cat <<-\EOF >expect &&
809 OBJID
810 OBJID
811 :000000 100644 OBJID OBJID A greeting
813 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
814 SVN-fs-dump-format-version: 3
816 Revision-number: 1
817 Prop-content-length: 10
818 Content-length: 10
820 PROPS-END
822 Node-path: greeting
823 Node-kind: file
824 Node-action: add
825 Text-content-length: 0
826 Prop-content-length: 10
827 Content-length: 10
829 PROPS-END
831 Revision-number: 2
832 Prop-content-length: 10
833 Content-length: 10
835 PROPS-END
837 Node-path: X
838 Node-kind: dir
839 Node-action: change
840 Prop-delta: true
841 Prop-content-length: 43
842 Content-length: 43
844 K 10
845 svn:ignore
846 V 11
847 build-area
849 PROPS-END
851 try_dump changeroot.dump &&
853 git rev-list HEAD |
854 git diff-tree --root --always --stdin |
855 sed "s/$_x40/OBJID/g"
856 } >actual &&
857 test_cmp expect actual
860 test_expect_success PIPE 'deltas for typechange' '
861 reinit_git &&
862 cat >expect <<-\EOF &&
863 OBJID
864 :120000 100644 OBJID OBJID T test-file
865 OBJID
866 :100755 120000 OBJID OBJID T test-file
867 OBJID
868 :000000 100755 OBJID OBJID A test-file
870 cat >deleteprop.dump <<-\EOF &&
871 SVN-fs-dump-format-version: 3
873 Revision-number: 1
874 Prop-content-length: 10
875 Content-length: 10
877 PROPS-END
879 Node-path: test-file
880 Node-kind: file
881 Node-action: add
882 Prop-delta: true
883 Prop-content-length: 35
884 Text-content-length: 17
885 Content-length: 52
887 K 14
888 svn:executable
891 PROPS-END
892 link testing 123
894 Revision-number: 2
895 Prop-content-length: 10
896 Content-length: 10
898 PROPS-END
900 Node-path: test-file
901 Node-kind: file
902 Node-action: change
903 Prop-delta: true
904 Prop-content-length: 53
905 Text-content-length: 17
906 Content-length: 70
908 K 11
909 svn:special
912 D 14
913 svn:executable
914 PROPS-END
915 link testing 231
917 Revision-number: 3
918 Prop-content-length: 10
919 Content-length: 10
921 PROPS-END
923 Node-path: test-file
924 Node-kind: file
925 Node-action: change
926 Prop-delta: true
927 Prop-content-length: 27
928 Text-content-length: 17
929 Content-length: 44
931 D 11
932 svn:special
933 PROPS-END
934 link testing 321
936 try_dump deleteprop.dump &&
938 git rev-list HEAD |
939 git diff-tree --root --stdin |
940 sed "s/$_x40/OBJID/g"
941 } >actual &&
942 test_cmp expect actual
946 test_expect_success 'set up svn repo' '
947 svnconf=$PWD/svnconf &&
948 mkdir -p "$svnconf" &&
951 svnadmin -h >/dev/null 2>&1 &&
952 svnadmin create simple-svn &&
953 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
954 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
955 then
956 test_set_prereq SVNREPO
960 test_expect_success SVNREPO,PIPE 't9135/svn.dump' '
961 mkdir -p simple-git &&
963 cd simple-git &&
964 reinit_git &&
965 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
966 ) &&
968 cd simple-svnco &&
969 git init &&
970 git add . &&
971 git fetch ../simple-git master &&
972 git diff --exit-code FETCH_HEAD
976 test_done