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" &&
58 test_expect_success 'empty dump' '
60 echo "SVN-fs-dump-format-version: 2" >input &&
64 test_expect_success 'v4 dumps not supported' '
66 echo "SVN-fs-dump-format-version: 4" >v4.dump &&
67 try_dump v4.dump must_fail
70 test_expect_failure 'empty revision' '
72 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
73 cat >emptyrev.dump <<-\EOF &&
74 SVN-fs-dump-format-version: 3
77 Prop-content-length: 0
81 Prop-content-length: 0
85 try_dump emptyrev.dump &&
86 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
87 test_cmp expect actual
90 test_expect_success 'empty properties' '
92 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
93 cat >emptyprop.dump <<-\EOF &&
94 SVN-fs-dump-format-version: 3
97 Prop-content-length: 10
103 Prop-content-length: 10
108 try_dump emptyprop.dump &&
109 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
110 test_cmp expect actual
113 test_expect_success 'author name and commit message' '
115 echo "<author@example.com, author@example.com@local>" >expect.author &&
116 cat >message <<-\EOF &&
117 A concise summary of the change
119 A detailed description of the change, why it is needed, what
120 was broken and why applying this is the best course of action.
123 Details pertaining to an individual file.
127 svn:author author@example.com \
128 svn:log "$(cat message)" &&
132 echo "SVN-fs-dump-format-version: 3" &&
134 echo "Revision-number: 1" &&
135 echo Prop-content-length: $(wc -c <props) &&
136 echo Content-length: $(wc -c <props) &&
141 git log -p --format="%B" HEAD >actual.log &&
142 git log --format="<%an, %ae>" >actual.author &&
143 test_cmp message actual.log &&
144 test_cmp expect.author actual.author
147 test_expect_success 'unsupported properties are ignored' '
149 echo author >expect &&
150 cat >extraprop.dump <<-\EOF &&
151 SVN-fs-dump-format-version: 3
154 Prop-content-length: 56
167 try_dump extraprop.dump &&
168 git log -p --format=%an HEAD >actual &&
169 test_cmp expect actual
172 test_expect_failure 'timestamp and empty file' '
173 echo author@example.com >expect.author &&
174 echo 1999-01-01 >expect.date &&
175 echo file >expect.files &&
179 svn:author author@example.com \
180 svn:date "1999-01-01T00:01:002.000000Z" \
181 svn:log "add empty file" &&
186 SVN-fs-dump-format-version: 3
190 echo Prop-content-length: $(wc -c <props) &&
191 echo Content-length: $(wc -c <props) &&
196 Node-path: empty-file
203 try_dump emptyfile.dump &&
204 git log --format=%an HEAD >actual.author &&
205 git log --date=short --format=%ad HEAD >actual.date &&
206 git ls-tree -r --name-only HEAD >actual.files &&
207 test_cmp expect.author actual.author &&
208 test_cmp expect.date actual.date &&
209 test_cmp expect.files actual.files &&
210 git checkout HEAD empty-file &&
214 test_expect_success 'directory with files' '
216 printf "%s\n" directory/file1 directory/file2 >expect.files &&
221 svn:author author@example.com \
222 svn:date "1999-02-01T00:01:002.000000Z" \
223 svn:log "add directory with some files in it" &&
228 SVN-fs-dump-format-version: 3
232 echo Prop-content-length: $(wc -c <props) &&
233 echo Content-length: $(wc -c <props) &&
241 Prop-content-length: 10
246 Node-path: directory/file1
250 text_no_props hello &&
252 Node-path: directory/file2
258 try_dump directory.dump &&
260 git ls-tree -r --name-only HEAD >actual.files &&
261 git checkout HEAD directory &&
262 test_cmp expect.files actual.files &&
263 test_cmp hello directory/file1 &&
264 test_cmp hi directory/file2
267 test_expect_success 'branch name with backslash' '
269 sort <<-\EOF >expect.branch-files &&
272 "branches/UpdateFOPto094\\/file1"
273 "branches/UpdateFOPto094\\/file2"
280 svn:author author@example.com \
281 svn:date "1999-02-02T00:01:02.000000Z" \
282 svn:log "add directory with some files in it" &&
287 svn:author brancher@example.com \
288 svn:date "2007-12-06T21:38:34.000000Z" \
289 svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
294 SVN-fs-dump-format-version: 3
298 echo Prop-content-length: $(wc -c <props.setup) &&
299 echo Content-length: $(wc -c <props.setup) &&
307 Prop-content-length: 10
315 Prop-content-length: 10
320 Node-path: trunk/file1
324 text_no_props hello &&
326 Node-path: trunk/file2
335 echo Prop-content-length: $(wc -c <props.branch) &&
336 echo Content-length: $(wc -c <props.branch) &&
341 Node-path: branches/UpdateFOPto094\
345 Node-copyfrom-path: trunk
349 Prop-content-length: 34
359 try_dump branch.dump &&
361 git ls-tree -r --name-only HEAD |
362 sort >actual.branch-files &&
363 test_cmp expect.branch-files actual.branch-files
366 test_expect_success 'node without action' '
368 cat >inaction.dump <<-\EOF &&
369 SVN-fs-dump-format-version: 3
372 Prop-content-length: 10
379 Prop-content-length: 10
384 try_dump inaction.dump must_fail
387 test_expect_success 'action: add node without text' '
389 cat >textless.dump <<-\EOF &&
390 SVN-fs-dump-format-version: 3
393 Prop-content-length: 10
401 Prop-content-length: 10
406 try_dump textless.dump must_fail
409 test_expect_failure 'change file mode but keep old content' '
411 cat >expect <<-\EOF &&
413 :120000 100644 OBJID OBJID T greeting
415 :100644 120000 OBJID OBJID T greeting
417 :000000 100644 OBJID OBJID A greeting
419 echo "link hello" >expect.blob &&
421 cat >filemode.dump <<-\EOF &&
422 SVN-fs-dump-format-version: 3
425 Prop-content-length: 10
433 Prop-content-length: 10
434 Text-content-length: 11
441 Prop-content-length: 10
449 Prop-content-length: 33
459 Prop-content-length: 10
467 Prop-content-length: 10
472 try_dump filemode.dump &&
475 git diff-tree --root --stdin |
476 sed "s/$OID_REGEX/OBJID/g"
478 git show HEAD:greeting >actual.blob &&
479 git show HEAD^:greeting >actual.target &&
480 test_cmp expect actual &&
481 test_cmp expect.blob actual.blob &&
482 test_cmp hello actual.target
485 test_expect_success 'NUL in property value' '
487 echo "commit message" >expect.message &&
490 unimportant "something with a NUL (Q)" \
491 svn:log "commit message"&&
497 SVN-fs-dump-format-version: 3
501 echo Prop-content-length: $(wc -c <props) &&
502 echo Content-length: $(wc -c <props) &&
506 try_dump nulprop.dump &&
507 git diff-tree --always -s --format=%s HEAD >actual.message &&
508 test_cmp expect.message actual.message
511 test_expect_success 'NUL in log message, file content, and property name' '
512 # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the
513 # svn:specialQnotreally example.
515 cat >expect <<-\EOF &&
517 :100644 100644 OBJID OBJID M greeting
519 :000000 100644 OBJID OBJID A greeting
521 printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message &&
522 printf "%s\n" "helQo" >expect.hello1 &&
523 printf "%s\n" "link hello" >expect.hello2 &&
525 properties svn:log "something with an ASCII NUL (Q)" &&
531 SVN-fs-dump-format-version: 3
534 Prop-content-length: 10
542 Prop-content-length: 10
543 Text-content-length: 6
551 echo Prop-content-length: $(wc -c <props) &&
552 echo Content-length: $(wc -c <props) &&
560 Prop-content-length: 43
561 Text-content-length: 11
565 svn:specialQnotreally
572 try_dump 8bitclean.dump &&
575 git diff-tree --root --stdin |
576 sed "s/$OID_REGEX/OBJID/g"
579 git cat-file commit HEAD | nul_to_q &&
582 sed -ne "/^\$/,\$ p" >actual.message &&
583 git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 &&
584 git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 &&
585 test_cmp expect actual &&
586 test_cmp expect.message actual.message &&
587 test_cmp expect.hello1 actual.hello1 &&
588 test_cmp expect.hello2 actual.hello2
591 test_expect_success 'change file mode and reiterate content' '
593 cat >expect <<-\EOF &&
595 :120000 100644 OBJID OBJID T greeting
597 :100644 120000 OBJID OBJID T greeting
599 :000000 100644 OBJID OBJID A greeting
601 echo "link hello" >expect.blob &&
603 cat >filemode2.dump <<-\EOF &&
604 SVN-fs-dump-format-version: 3
607 Prop-content-length: 10
615 Prop-content-length: 10
616 Text-content-length: 11
623 Prop-content-length: 10
631 Prop-content-length: 33
632 Text-content-length: 11
643 Prop-content-length: 10
651 Prop-content-length: 10
652 Text-content-length: 11
658 try_dump filemode2.dump &&
661 git diff-tree --root --stdin |
662 sed "s/$OID_REGEX/OBJID/g"
664 git show HEAD:greeting >actual.blob &&
665 git show HEAD^:greeting >actual.target &&
666 test_cmp expect actual &&
667 test_cmp expect.blob actual.blob &&
668 test_cmp hello actual.target
671 test_expect_success 'deltas supported' '
674 # (old) h + (inline) ello + (old) \n
675 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
680 svn:author author@example.com \
681 svn:date "1999-01-05T00:01:002.000000Z" \
682 svn:log "add greeting" &&
687 svn:author author@example.com \
688 svn:date "1999-01-06T00:01:002.000000Z" \
689 svn:log "change it" &&
693 echo SVN-fs-dump-format-version: 3 &&
695 echo Revision-number: 1 &&
696 echo Prop-content-length: $(wc -c <props) &&
697 echo Content-length: $(wc -c <props) &&
705 Prop-content-length: 10
706 Text-content-length: 3
713 echo Revision-number: 2 &&
714 echo Prop-content-length: $(wc -c <props2) &&
715 echo Content-length: $(wc -c <props2) &&
724 Prop-content-length: 10
726 echo Text-content-length: $(wc -c <delta) &&
727 echo Content-length: $((10 + $(wc -c <delta))) &&
735 test_expect_success 'property deltas supported' '
737 cat >expect <<-\EOF &&
739 :100755 100644 OBJID OBJID M script.sh
743 svn:author author@example.com \
744 svn:date "1999-03-06T00:01:002.000000Z" \
745 svn:log "make an executable, or chmod -x it" &&
749 echo SVN-fs-dump-format-version: 3 &&
751 echo Revision-number: 1 &&
752 echo Prop-content-length: $(wc -c <revprops) &&
753 echo Content-length: $(wc -c <revprops) &&
761 Text-content-length: 0
762 Prop-content-length: 39
772 echo Revision-number: 2 &&
773 echo Prop-content-length: $(wc -c <revprops) &&
774 echo Content-length: $(wc -c <revprops) &&
783 Prop-content-length: 30
791 try_dump propdelta.dump &&
794 git diff-tree --stdin |
795 sed "s/$OID_REGEX/OBJID/g"
797 test_cmp expect actual
800 test_expect_success 'properties on /' '
802 cat <<-\EOF >expect &&
805 :000000 100644 OBJID OBJID A greeting
807 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
808 SVN-fs-dump-format-version: 3
811 Prop-content-length: 10
819 Text-content-length: 0
820 Prop-content-length: 10
826 Prop-content-length: 10
835 Prop-content-length: 43
845 try_dump changeroot.dump &&
848 git diff-tree --root --always --stdin |
849 sed "s/$OID_REGEX/OBJID/g"
851 test_cmp expect actual
854 test_expect_success 'deltas for typechange' '
856 cat >expect <<-\EOF &&
858 :120000 100644 OBJID OBJID T test-file
860 :100755 120000 OBJID OBJID T test-file
862 :000000 100755 OBJID OBJID A test-file
864 cat >deleteprop.dump <<-\EOF &&
865 SVN-fs-dump-format-version: 3
868 Prop-content-length: 10
877 Prop-content-length: 35
878 Text-content-length: 17
889 Prop-content-length: 10
898 Prop-content-length: 53
899 Text-content-length: 17
912 Prop-content-length: 10
921 Prop-content-length: 27
922 Text-content-length: 17
930 try_dump deleteprop.dump &&
933 git diff-tree --root --stdin |
934 sed "s/$OID_REGEX/OBJID/g"
936 test_cmp expect actual
939 test_expect_success 'deltas need not consume the whole preimage' '
941 cat >expect <<-\EOF &&
943 :120000 100644 OBJID OBJID T postimage
945 :100644 120000 OBJID OBJID T postimage
947 :000000 100644 OBJID OBJID A postimage
949 echo "first preimage" >expect.1 &&
950 printf target >expect.2 &&
951 printf lnk >expect.3 &&
953 printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
957 properties svn:special "*" &&
961 printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
965 printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
970 SVN-fs-dump-format-version: 3
973 Prop-content-length: 10
982 Prop-content-length: 10
984 echo Text-content-length: $(wc -c <delta.1) &&
985 echo Content-length: $((10 + $(wc -c <delta.1))) &&
992 Prop-content-length: 10
1002 echo Prop-content-length: $(wc -c <symlink.props) &&
1003 echo Text-content-length: $(wc -c <delta.2) &&
1004 echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
1006 cat symlink.props &&
1011 Prop-content-length: 10
1016 Node-path: postimage
1020 Prop-content-length: 10
1022 echo Text-content-length: $(wc -c <delta.3) &&
1023 echo Content-length: $((10 + $(wc -c <delta.3))) &&
1028 } >deltapartial.dump &&
1029 try_dump deltapartial.dump &&
1032 git diff-tree --root --stdin |
1033 sed "s/$OID_REGEX/OBJID/g"
1035 test_cmp expect actual &&
1036 git show HEAD:postimage >actual.3 &&
1037 git show HEAD^:postimage >actual.2 &&
1038 git show HEAD^^:postimage >actual.1 &&
1039 test_cmp expect.1 actual.1 &&
1040 test_cmp expect.2 actual.2 &&
1041 test_cmp expect.3 actual.3
1044 test_expect_success 'no hang for delta trying to read past end of preimage' '
1048 printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" |
1053 SVN-fs-dump-format-version: 3
1056 Prop-content-length: 10
1061 Node-path: bootstrap
1065 Prop-content-length: 10
1067 echo Text-content-length: $(wc -c <greedy.delta) &&
1068 echo Content-length: $((10 + $(wc -c <greedy.delta))) &&
1073 } >greedydelta.dump &&
1074 try_dump greedydelta.dump must_fail might_fail
1077 test_expect_success 'set up svn repo' '
1078 svnconf=$PWD/svnconf &&
1079 mkdir -p "$svnconf" &&
1082 svnadmin -h >/dev/null 2>&1 &&
1083 svnadmin create simple-svn &&
1084 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
1085 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
1087 test_set_prereq SVNREPO
1091 test_expect_success SVNREPO 't9135/svn.dump' '
1092 mkdir -p simple-git &&
1096 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1102 git fetch ../simple-git master &&
1103 git diff --exit-code FETCH_HEAD