3 test_description='check svn dumpfile importer'
7 if test_have_prereq !PIPE
9 skip_all="svn dumpfile importer testing requires the PIPE prerequisite"
15 rm -f stream backflow &&
17 mkfifo stream backflow
22 maybe_fail_svnfe=${2:+test_$2} &&
23 maybe_fail_fi=${3:+test_$3} &&
26 $maybe_fail_svnfe test-svn-fe "$input" >stream 3<backflow &
28 $maybe_fail_fi git fast-import --cat-blob-fd=3 <stream 3>backflow &&
37 printf "%s\n" "K ${#property}" &&
38 printf "%s\n" "$property" &&
39 printf "%s\n" "V ${#value}" &&
40 printf "%s\n" "$value" &&
49 printf "%s\n" "Prop-content-length: 10" &&
50 printf "%s\n" "Text-content-length: ${#text}" &&
51 printf "%s\n" "Content-length: $((${#text} + 10))" &&
52 printf "%s\n" "" "PROPS-END" &&
56 test_expect_success 'empty dump' '
58 echo "SVN-fs-dump-format-version: 2" >input &&
62 test_expect_success 'v4 dumps not supported' '
64 echo "SVN-fs-dump-format-version: 4" >v4.dump &&
65 try_dump v4.dump must_fail
68 test_expect_failure 'empty revision' '
70 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
71 cat >emptyrev.dump <<-\EOF &&
72 SVN-fs-dump-format-version: 3
75 Prop-content-length: 0
79 Prop-content-length: 0
83 try_dump emptyrev.dump &&
84 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
85 test_cmp expect actual
88 test_expect_success 'empty properties' '
90 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
91 cat >emptyprop.dump <<-\EOF &&
92 SVN-fs-dump-format-version: 3
95 Prop-content-length: 10
101 Prop-content-length: 10
106 try_dump emptyprop.dump &&
107 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
108 test_cmp expect actual
111 test_expect_success 'author name and commit message' '
113 echo "<author@example.com, author@example.com@local>" >expect.author &&
114 cat >message <<-\EOF &&
115 A concise summary of the change
117 A detailed description of the change, why it is needed, what
118 was broken and why applying this is the best course of action.
121 Details pertaining to an individual file.
125 svn:author author@example.com \
126 svn:log "$(cat message)" &&
130 echo "SVN-fs-dump-format-version: 3" &&
132 echo "Revision-number: 1" &&
133 echo Prop-content-length: $(wc -c <props) &&
134 echo Content-length: $(wc -c <props) &&
139 git log -p --format="%B" HEAD >actual.log &&
140 git log --format="<%an, %ae>" >actual.author &&
141 test_cmp message actual.log &&
142 test_cmp expect.author actual.author
145 test_expect_success 'unsupported properties are ignored' '
147 echo author >expect &&
148 cat >extraprop.dump <<-\EOF &&
149 SVN-fs-dump-format-version: 3
152 Prop-content-length: 56
165 try_dump extraprop.dump &&
166 git log -p --format=%an HEAD >actual &&
167 test_cmp expect actual
170 test_expect_failure 'timestamp and empty file' '
171 echo author@example.com >expect.author &&
172 echo 1999-01-01 >expect.date &&
173 echo file >expect.files &&
177 svn:author author@example.com \
178 svn:date "1999-01-01T00:01:002.000000Z" \
179 svn:log "add empty file" &&
184 SVN-fs-dump-format-version: 3
188 echo Prop-content-length: $(wc -c <props) &&
189 echo Content-length: $(wc -c <props) &&
194 Node-path: empty-file
201 try_dump emptyfile.dump &&
202 git log --format=%an HEAD >actual.author &&
203 git log --date=short --format=%ad HEAD >actual.date &&
204 git ls-tree -r --name-only HEAD >actual.files &&
205 test_cmp expect.author actual.author &&
206 test_cmp expect.date actual.date &&
207 test_cmp expect.files actual.files &&
208 git checkout HEAD empty-file &&
209 test_must_be_empty file
212 test_expect_success 'directory with files' '
214 printf "%s\n" directory/file1 directory/file2 >expect.files &&
219 svn:author author@example.com \
220 svn:date "1999-02-01T00:01:002.000000Z" \
221 svn:log "add directory with some files in it" &&
226 SVN-fs-dump-format-version: 3
230 echo Prop-content-length: $(wc -c <props) &&
231 echo Content-length: $(wc -c <props) &&
239 Prop-content-length: 10
244 Node-path: directory/file1
248 text_no_props hello &&
250 Node-path: directory/file2
256 try_dump directory.dump &&
258 git ls-tree -r --name-only HEAD >actual.files &&
259 git checkout HEAD directory &&
260 test_cmp expect.files actual.files &&
261 test_cmp hello directory/file1 &&
262 test_cmp hi directory/file2
265 test_expect_success 'branch name with backslash' '
267 sort <<-\EOF >expect.branch-files &&
270 "branches/UpdateFOPto094\\/file1"
271 "branches/UpdateFOPto094\\/file2"
278 svn:author author@example.com \
279 svn:date "1999-02-02T00:01:02.000000Z" \
280 svn:log "add directory with some files in it" &&
285 svn:author brancher@example.com \
286 svn:date "2007-12-06T21:38:34.000000Z" \
287 svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
292 SVN-fs-dump-format-version: 3
296 echo Prop-content-length: $(wc -c <props.setup) &&
297 echo Content-length: $(wc -c <props.setup) &&
305 Prop-content-length: 10
313 Prop-content-length: 10
318 Node-path: trunk/file1
322 text_no_props hello &&
324 Node-path: trunk/file2
333 echo Prop-content-length: $(wc -c <props.branch) &&
334 echo Content-length: $(wc -c <props.branch) &&
339 Node-path: branches/UpdateFOPto094\
343 Node-copyfrom-path: trunk
347 Prop-content-length: 34
357 try_dump branch.dump &&
359 git ls-tree -r --name-only HEAD |
360 sort >actual.branch-files &&
361 test_cmp expect.branch-files actual.branch-files
364 test_expect_success 'node without action' '
366 cat >inaction.dump <<-\EOF &&
367 SVN-fs-dump-format-version: 3
370 Prop-content-length: 10
377 Prop-content-length: 10
382 try_dump inaction.dump must_fail
385 test_expect_success 'action: add node without text' '
387 cat >textless.dump <<-\EOF &&
388 SVN-fs-dump-format-version: 3
391 Prop-content-length: 10
399 Prop-content-length: 10
404 try_dump textless.dump must_fail
407 test_expect_failure 'change file mode but keep old content' '
409 cat >expect <<-\EOF &&
411 :120000 100644 OBJID OBJID T greeting
413 :100644 120000 OBJID OBJID T greeting
415 :000000 100644 OBJID OBJID A greeting
417 echo "link hello" >expect.blob &&
419 cat >filemode.dump <<-\EOF &&
420 SVN-fs-dump-format-version: 3
423 Prop-content-length: 10
431 Prop-content-length: 10
432 Text-content-length: 11
439 Prop-content-length: 10
447 Prop-content-length: 33
457 Prop-content-length: 10
465 Prop-content-length: 10
470 try_dump filemode.dump &&
473 git diff-tree --root --stdin |
474 sed "s/$OID_REGEX/OBJID/g"
476 git show HEAD:greeting >actual.blob &&
477 git show HEAD^:greeting >actual.target &&
478 test_cmp expect actual &&
479 test_cmp expect.blob actual.blob &&
480 test_cmp hello actual.target
483 test_expect_success 'NUL in property value' '
485 echo "commit message" >expect.message &&
488 unimportant "something with a NUL (Q)" \
489 svn:log "commit message"&&
495 SVN-fs-dump-format-version: 3
499 echo Prop-content-length: $(wc -c <props) &&
500 echo Content-length: $(wc -c <props) &&
504 try_dump nulprop.dump &&
505 git diff-tree --always -s --format=%s HEAD >actual.message &&
506 test_cmp expect.message actual.message
509 test_expect_success 'NUL in log message, file content, and property name' '
510 # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the
511 # svn:specialQnotreally example.
513 cat >expect <<-\EOF &&
515 :100644 100644 OBJID OBJID M greeting
517 :000000 100644 OBJID OBJID A greeting
519 printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message &&
520 printf "%s\n" "helQo" >expect.hello1 &&
521 printf "%s\n" "link hello" >expect.hello2 &&
523 properties svn:log "something with an ASCII NUL (Q)" &&
529 SVN-fs-dump-format-version: 3
532 Prop-content-length: 10
540 Prop-content-length: 10
541 Text-content-length: 6
549 echo Prop-content-length: $(wc -c <props) &&
550 echo Content-length: $(wc -c <props) &&
558 Prop-content-length: 43
559 Text-content-length: 11
563 svn:specialQnotreally
570 try_dump 8bitclean.dump &&
573 git diff-tree --root --stdin |
574 sed "s/$OID_REGEX/OBJID/g"
577 git cat-file commit HEAD | nul_to_q &&
580 sed -ne "/^\$/,\$ p" >actual.message &&
581 git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 &&
582 git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 &&
583 test_cmp expect actual &&
584 test_cmp expect.message actual.message &&
585 test_cmp expect.hello1 actual.hello1 &&
586 test_cmp expect.hello2 actual.hello2
589 test_expect_success 'change file mode and reiterate content' '
591 cat >expect <<-\EOF &&
593 :120000 100644 OBJID OBJID T greeting
595 :100644 120000 OBJID OBJID T greeting
597 :000000 100644 OBJID OBJID A greeting
599 echo "link hello" >expect.blob &&
601 cat >filemode2.dump <<-\EOF &&
602 SVN-fs-dump-format-version: 3
605 Prop-content-length: 10
613 Prop-content-length: 10
614 Text-content-length: 11
621 Prop-content-length: 10
629 Prop-content-length: 33
630 Text-content-length: 11
641 Prop-content-length: 10
649 Prop-content-length: 10
650 Text-content-length: 11
656 try_dump filemode2.dump &&
659 git diff-tree --root --stdin |
660 sed "s/$OID_REGEX/OBJID/g"
662 git show HEAD:greeting >actual.blob &&
663 git show HEAD^:greeting >actual.target &&
664 test_cmp expect actual &&
665 test_cmp expect.blob actual.blob &&
666 test_cmp hello actual.target
669 test_expect_success 'deltas supported' '
672 # (old) h + (inline) ello + (old) \n
673 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
678 svn:author author@example.com \
679 svn:date "1999-01-05T00:01:002.000000Z" \
680 svn:log "add greeting" &&
685 svn:author author@example.com \
686 svn:date "1999-01-06T00:01:002.000000Z" \
687 svn:log "change it" &&
691 echo SVN-fs-dump-format-version: 3 &&
693 echo Revision-number: 1 &&
694 echo Prop-content-length: $(wc -c <props) &&
695 echo Content-length: $(wc -c <props) &&
703 Prop-content-length: 10
704 Text-content-length: 3
711 echo Revision-number: 2 &&
712 echo Prop-content-length: $(wc -c <props2) &&
713 echo Content-length: $(wc -c <props2) &&
722 Prop-content-length: 10
724 echo Text-content-length: $(wc -c <delta) &&
725 echo Content-length: $((10 + $(wc -c <delta))) &&
733 test_expect_success 'property deltas supported' '
735 cat >expect <<-\EOF &&
737 :100755 100644 OBJID OBJID M script.sh
741 svn:author author@example.com \
742 svn:date "1999-03-06T00:01:002.000000Z" \
743 svn:log "make an executable, or chmod -x it" &&
747 echo SVN-fs-dump-format-version: 3 &&
749 echo Revision-number: 1 &&
750 echo Prop-content-length: $(wc -c <revprops) &&
751 echo Content-length: $(wc -c <revprops) &&
759 Text-content-length: 0
760 Prop-content-length: 39
770 echo Revision-number: 2 &&
771 echo Prop-content-length: $(wc -c <revprops) &&
772 echo Content-length: $(wc -c <revprops) &&
781 Prop-content-length: 30
789 try_dump propdelta.dump &&
792 git diff-tree --stdin |
793 sed "s/$OID_REGEX/OBJID/g"
795 test_cmp expect actual
798 test_expect_success 'properties on /' '
800 cat <<-\EOF >expect &&
803 :000000 100644 OBJID OBJID A greeting
805 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
806 SVN-fs-dump-format-version: 3
809 Prop-content-length: 10
817 Text-content-length: 0
818 Prop-content-length: 10
824 Prop-content-length: 10
833 Prop-content-length: 43
843 try_dump changeroot.dump &&
846 git diff-tree --root --always --stdin |
847 sed "s/$OID_REGEX/OBJID/g"
849 test_cmp expect actual
852 test_expect_success 'deltas for typechange' '
854 cat >expect <<-\EOF &&
856 :120000 100644 OBJID OBJID T test-file
858 :100755 120000 OBJID OBJID T test-file
860 :000000 100755 OBJID OBJID A test-file
862 cat >deleteprop.dump <<-\EOF &&
863 SVN-fs-dump-format-version: 3
866 Prop-content-length: 10
875 Prop-content-length: 35
876 Text-content-length: 17
887 Prop-content-length: 10
896 Prop-content-length: 53
897 Text-content-length: 17
910 Prop-content-length: 10
919 Prop-content-length: 27
920 Text-content-length: 17
928 try_dump deleteprop.dump &&
931 git diff-tree --root --stdin |
932 sed "s/$OID_REGEX/OBJID/g"
934 test_cmp expect actual
937 test_expect_success 'deltas need not consume the whole preimage' '
939 cat >expect <<-\EOF &&
941 :120000 100644 OBJID OBJID T postimage
943 :100644 120000 OBJID OBJID T postimage
945 :000000 100644 OBJID OBJID A postimage
947 echo "first preimage" >expect.1 &&
948 printf target >expect.2 &&
949 printf lnk >expect.3 &&
951 printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
955 properties svn:special "*" &&
959 printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
963 printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
968 SVN-fs-dump-format-version: 3
971 Prop-content-length: 10
980 Prop-content-length: 10
982 echo Text-content-length: $(wc -c <delta.1) &&
983 echo Content-length: $((10 + $(wc -c <delta.1))) &&
990 Prop-content-length: 10
1000 echo Prop-content-length: $(wc -c <symlink.props) &&
1001 echo Text-content-length: $(wc -c <delta.2) &&
1002 echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
1004 cat symlink.props &&
1009 Prop-content-length: 10
1014 Node-path: postimage
1018 Prop-content-length: 10
1020 echo Text-content-length: $(wc -c <delta.3) &&
1021 echo Content-length: $((10 + $(wc -c <delta.3))) &&
1026 } >deltapartial.dump &&
1027 try_dump deltapartial.dump &&
1030 git diff-tree --root --stdin |
1031 sed "s/$OID_REGEX/OBJID/g"
1033 test_cmp expect actual &&
1034 git show HEAD:postimage >actual.3 &&
1035 git show HEAD^:postimage >actual.2 &&
1036 git show HEAD^^:postimage >actual.1 &&
1037 test_cmp expect.1 actual.1 &&
1038 test_cmp expect.2 actual.2 &&
1039 test_cmp expect.3 actual.3
1042 test_expect_success 'no hang for delta trying to read past end of preimage' '
1046 printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" |
1051 SVN-fs-dump-format-version: 3
1054 Prop-content-length: 10
1059 Node-path: bootstrap
1063 Prop-content-length: 10
1065 echo Text-content-length: $(wc -c <greedy.delta) &&
1066 echo Content-length: $((10 + $(wc -c <greedy.delta))) &&
1071 } >greedydelta.dump &&
1072 try_dump greedydelta.dump must_fail might_fail
1075 test_expect_success 'set up svn repo' '
1076 svnconf=$PWD/svnconf &&
1077 mkdir -p "$svnconf" &&
1080 svnadmin -h >/dev/null 2>&1 &&
1081 svnadmin create simple-svn &&
1082 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
1083 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
1085 test_set_prereq SVNREPO
1089 test_expect_success SVNREPO 't9135/svn.dump' '
1090 mkdir -p simple-git &&
1094 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1100 git fetch ../simple-git master &&
1101 git diff --exit-code FETCH_HEAD