3 test_description='check svn dumpfile importer'
8 if ! test_declared_prereq PIPE
10 echo >&4 "reinit_git: need to declare PIPE prerequisite"
14 rm -f stream backflow &&
16 mkfifo stream backflow
21 maybe_fail_svnfe=${2:+test_$2} &&
22 maybe_fail_fi=${3:+test_$3} &&
25 $maybe_fail_svnfe test-svn-fe "$input" >stream 3<backflow &
27 $maybe_fail_fi git fast-import --cat-blob-fd=3 <stream 3>backflow &&
36 printf "%s\n" "K ${#property}" &&
37 printf "%s\n" "$property" &&
38 printf "%s\n" "V ${#value}" &&
39 printf "%s\n" "$value" &&
48 printf "%s\n" "Prop-content-length: 10" &&
49 printf "%s\n" "Text-content-length: ${#text}" &&
50 printf "%s\n" "Content-length: $((${#text} + 10))" &&
51 printf "%s\n" "" "PROPS-END" &&
57 test_expect_success 'setup: have pipes?' '
65 test_expect_success PIPE 'empty dump' '
67 echo "SVN-fs-dump-format-version: 2" >input &&
71 test_expect_success PIPE 'v4 dumps not supported' '
73 echo "SVN-fs-dump-format-version: 4" >v4.dump &&
74 try_dump v4.dump must_fail
77 test_expect_failure PIPE 'empty revision' '
79 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
80 cat >emptyrev.dump <<-\EOF &&
81 SVN-fs-dump-format-version: 3
84 Prop-content-length: 0
88 Prop-content-length: 0
92 try_dump emptyrev.dump &&
93 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
94 test_cmp expect actual
97 test_expect_success PIPE 'empty properties' '
99 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
100 cat >emptyprop.dump <<-\EOF &&
101 SVN-fs-dump-format-version: 3
104 Prop-content-length: 10
110 Prop-content-length: 10
115 try_dump emptyprop.dump &&
116 git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
117 test_cmp expect actual
120 test_expect_success PIPE 'author name and commit message' '
122 echo "<author@example.com, author@example.com@local>" >expect.author &&
123 cat >message <<-\EOF &&
124 A concise summary of the change
126 A detailed description of the change, why it is needed, what
127 was broken and why applying this is the best course of action.
130 Details pertaining to an individual file.
134 svn:author author@example.com \
135 svn:log "$(cat message)" &&
139 echo "SVN-fs-dump-format-version: 3" &&
141 echo "Revision-number: 1" &&
142 echo Prop-content-length: $(wc -c <props) &&
143 echo Content-length: $(wc -c <props) &&
148 git log -p --format="%B" HEAD >actual.log &&
149 git log --format="<%an, %ae>" >actual.author &&
150 test_cmp message actual.log &&
151 test_cmp expect.author actual.author
154 test_expect_success PIPE 'unsupported properties are ignored' '
156 echo author >expect &&
157 cat >extraprop.dump <<-\EOF &&
158 SVN-fs-dump-format-version: 3
161 Prop-content-length: 56
174 try_dump extraprop.dump &&
175 git log -p --format=%an HEAD >actual &&
176 test_cmp expect actual
179 test_expect_failure PIPE 'timestamp and empty file' '
180 echo author@example.com >expect.author &&
181 echo 1999-01-01 >expect.date &&
182 echo file >expect.files &&
186 svn:author author@example.com \
187 svn:date "1999-01-01T00:01:002.000000Z" \
188 svn:log "add empty file" &&
193 SVN-fs-dump-format-version: 3
197 echo Prop-content-length: $(wc -c <props) &&
198 echo Content-length: $(wc -c <props) &&
203 Node-path: empty-file
210 try_dump emptyfile.dump &&
211 git log --format=%an HEAD >actual.author &&
212 git log --date=short --format=%ad HEAD >actual.date &&
213 git ls-tree -r --name-only HEAD >actual.files &&
214 test_cmp expect.author actual.author &&
215 test_cmp expect.date actual.date &&
216 test_cmp expect.files actual.files &&
217 git checkout HEAD empty-file &&
221 test_expect_success PIPE 'directory with files' '
223 printf "%s\n" directory/file1 directory/file2 >expect.files &&
228 svn:author author@example.com \
229 svn:date "1999-02-01T00:01:002.000000Z" \
230 svn:log "add directory with some files in it" &&
235 SVN-fs-dump-format-version: 3
239 echo Prop-content-length: $(wc -c <props) &&
240 echo Content-length: $(wc -c <props) &&
248 Prop-content-length: 10
253 Node-path: directory/file1
257 text_no_props hello &&
259 Node-path: directory/file2
265 try_dump directory.dump &&
267 git ls-tree -r --name-only HEAD >actual.files &&
268 git checkout HEAD directory &&
269 test_cmp expect.files actual.files &&
270 test_cmp hello directory/file1 &&
271 test_cmp hi directory/file2
274 test_expect_success PIPE 'branch name with backslash' '
276 sort <<-\EOF >expect.branch-files &&
279 "branches/UpdateFOPto094\\/file1"
280 "branches/UpdateFOPto094\\/file2"
287 svn:author author@example.com \
288 svn:date "1999-02-02T00:01:02.000000Z" \
289 svn:log "add directory with some files in it" &&
294 svn:author brancher@example.com \
295 svn:date "2007-12-06T21:38:34.000000Z" \
296 svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
301 SVN-fs-dump-format-version: 3
305 echo Prop-content-length: $(wc -c <props.setup) &&
306 echo Content-length: $(wc -c <props.setup) &&
314 Prop-content-length: 10
322 Prop-content-length: 10
327 Node-path: trunk/file1
331 text_no_props hello &&
333 Node-path: trunk/file2
342 echo Prop-content-length: $(wc -c <props.branch) &&
343 echo Content-length: $(wc -c <props.branch) &&
348 Node-path: branches/UpdateFOPto094\
352 Node-copyfrom-path: trunk
356 Prop-content-length: 34
366 try_dump branch.dump &&
368 git ls-tree -r --name-only HEAD |
369 sort >actual.branch-files &&
370 test_cmp expect.branch-files actual.branch-files
373 test_expect_success PIPE 'node without action' '
375 cat >inaction.dump <<-\EOF &&
376 SVN-fs-dump-format-version: 3
379 Prop-content-length: 10
386 Prop-content-length: 10
391 try_dump inaction.dump must_fail
394 test_expect_success PIPE 'action: add node without text' '
396 cat >textless.dump <<-\EOF &&
397 SVN-fs-dump-format-version: 3
400 Prop-content-length: 10
408 Prop-content-length: 10
413 try_dump textless.dump must_fail
416 test_expect_failure PIPE 'change file mode but keep old content' '
418 cat >expect <<-\EOF &&
420 :120000 100644 OBJID OBJID T greeting
422 :100644 120000 OBJID OBJID T greeting
424 :000000 100644 OBJID OBJID A greeting
426 echo "link hello" >expect.blob &&
428 cat >filemode.dump <<-\EOF &&
429 SVN-fs-dump-format-version: 3
432 Prop-content-length: 10
440 Prop-content-length: 10
441 Text-content-length: 11
448 Prop-content-length: 10
456 Prop-content-length: 33
466 Prop-content-length: 10
474 Prop-content-length: 10
479 try_dump filemode.dump &&
482 git diff-tree --root --stdin |
483 sed "s/$_x40/OBJID/g"
485 git show HEAD:greeting >actual.blob &&
486 git show HEAD^:greeting >actual.target &&
487 test_cmp expect actual &&
488 test_cmp expect.blob actual.blob &&
489 test_cmp hello actual.target
492 test_expect_success PIPE 'NUL in property value' '
494 echo "commit message" >expect.message &&
497 unimportant "something with a NUL (Q)" \
498 svn:log "commit message"&&
504 SVN-fs-dump-format-version: 3
508 echo Prop-content-length: $(wc -c <props) &&
509 echo Content-length: $(wc -c <props) &&
513 try_dump nulprop.dump &&
514 git diff-tree --always -s --format=%s HEAD >actual.message &&
515 test_cmp expect.message actual.message
518 test_expect_success PIPE 'NUL in log message, file content, and property name' '
519 # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the
520 # svn:specialQnotreally example.
522 cat >expect <<-\EOF &&
524 :100644 100644 OBJID OBJID M greeting
526 :000000 100644 OBJID OBJID A greeting
528 printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message &&
529 printf "%s\n" "helQo" >expect.hello1 &&
530 printf "%s\n" "link hello" >expect.hello2 &&
532 properties svn:log "something with an ASCII NUL (Q)" &&
538 SVN-fs-dump-format-version: 3
541 Prop-content-length: 10
549 Prop-content-length: 10
550 Text-content-length: 6
558 echo Prop-content-length: $(wc -c <props) &&
559 echo Content-length: $(wc -c <props) &&
567 Prop-content-length: 43
568 Text-content-length: 11
572 svn:specialQnotreally
579 try_dump 8bitclean.dump &&
582 git diff-tree --root --stdin |
583 sed "s/$_x40/OBJID/g"
586 git cat-file commit HEAD | nul_to_q &&
589 sed -ne "/^\$/,\$ p" >actual.message &&
590 git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 &&
591 git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 &&
592 test_cmp expect actual &&
593 test_cmp expect.message actual.message &&
594 test_cmp expect.hello1 actual.hello1 &&
595 test_cmp expect.hello2 actual.hello2
598 test_expect_success PIPE 'change file mode and reiterate content' '
600 cat >expect <<-\EOF &&
602 :120000 100644 OBJID OBJID T greeting
604 :100644 120000 OBJID OBJID T greeting
606 :000000 100644 OBJID OBJID A greeting
608 echo "link hello" >expect.blob &&
610 cat >filemode2.dump <<-\EOF &&
611 SVN-fs-dump-format-version: 3
614 Prop-content-length: 10
622 Prop-content-length: 10
623 Text-content-length: 11
630 Prop-content-length: 10
638 Prop-content-length: 33
639 Text-content-length: 11
650 Prop-content-length: 10
658 Prop-content-length: 10
659 Text-content-length: 11
665 try_dump filemode2.dump &&
668 git diff-tree --root --stdin |
669 sed "s/$_x40/OBJID/g"
671 git show HEAD:greeting >actual.blob &&
672 git show HEAD^:greeting >actual.target &&
673 test_cmp expect actual &&
674 test_cmp expect.blob actual.blob &&
675 test_cmp hello actual.target
678 test_expect_success PIPE 'deltas supported' '
681 # (old) h + (inline) ello + (old) \n
682 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
687 svn:author author@example.com \
688 svn:date "1999-01-05T00:01:002.000000Z" \
689 svn:log "add greeting" &&
694 svn:author author@example.com \
695 svn:date "1999-01-06T00:01:002.000000Z" \
696 svn:log "change it" &&
700 echo SVN-fs-dump-format-version: 3 &&
702 echo Revision-number: 1 &&
703 echo Prop-content-length: $(wc -c <props) &&
704 echo Content-length: $(wc -c <props) &&
712 Prop-content-length: 10
713 Text-content-length: 3
720 echo Revision-number: 2 &&
721 echo Prop-content-length: $(wc -c <props2) &&
722 echo Content-length: $(wc -c <props2) &&
731 Prop-content-length: 10
733 echo Text-content-length: $(wc -c <delta) &&
734 echo Content-length: $((10 + $(wc -c <delta))) &&
742 test_expect_success PIPE 'property deltas supported' '
744 cat >expect <<-\EOF &&
746 :100755 100644 OBJID OBJID M script.sh
750 svn:author author@example.com \
751 svn:date "1999-03-06T00:01:002.000000Z" \
752 svn:log "make an executable, or chmod -x it" &&
756 echo SVN-fs-dump-format-version: 3 &&
758 echo Revision-number: 1 &&
759 echo Prop-content-length: $(wc -c <revprops) &&
760 echo Content-length: $(wc -c <revprops) &&
768 Text-content-length: 0
769 Prop-content-length: 39
779 echo Revision-number: 2 &&
780 echo Prop-content-length: $(wc -c <revprops) &&
781 echo Content-length: $(wc -c <revprops) &&
790 Prop-content-length: 30
798 try_dump propdelta.dump &&
801 git diff-tree --stdin |
802 sed "s/$_x40/OBJID/g"
804 test_cmp expect actual
807 test_expect_success PIPE 'properties on /' '
809 cat <<-\EOF >expect &&
812 :000000 100644 OBJID OBJID A greeting
814 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
815 SVN-fs-dump-format-version: 3
818 Prop-content-length: 10
826 Text-content-length: 0
827 Prop-content-length: 10
833 Prop-content-length: 10
842 Prop-content-length: 43
852 try_dump changeroot.dump &&
855 git diff-tree --root --always --stdin |
856 sed "s/$_x40/OBJID/g"
858 test_cmp expect actual
861 test_expect_success PIPE 'deltas for typechange' '
863 cat >expect <<-\EOF &&
865 :120000 100644 OBJID OBJID T test-file
867 :100755 120000 OBJID OBJID T test-file
869 :000000 100755 OBJID OBJID A test-file
871 cat >deleteprop.dump <<-\EOF &&
872 SVN-fs-dump-format-version: 3
875 Prop-content-length: 10
884 Prop-content-length: 35
885 Text-content-length: 17
896 Prop-content-length: 10
905 Prop-content-length: 53
906 Text-content-length: 17
919 Prop-content-length: 10
928 Prop-content-length: 27
929 Text-content-length: 17
937 try_dump deleteprop.dump &&
940 git diff-tree --root --stdin |
941 sed "s/$_x40/OBJID/g"
943 test_cmp expect actual
946 test_expect_success PIPE 'deltas need not consume the whole preimage' '
948 cat >expect <<-\EOF &&
950 :120000 100644 OBJID OBJID T postimage
952 :100644 120000 OBJID OBJID T postimage
954 :000000 100644 OBJID OBJID A postimage
956 echo "first preimage" >expect.1 &&
957 printf target >expect.2 &&
958 printf lnk >expect.3 &&
960 printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
964 properties svn:special "*" &&
968 printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
972 printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
977 SVN-fs-dump-format-version: 3
980 Prop-content-length: 10
989 Prop-content-length: 10
991 echo Text-content-length: $(wc -c <delta.1) &&
992 echo Content-length: $((10 + $(wc -c <delta.1))) &&
999 Prop-content-length: 10
1004 Node-path: postimage
1009 echo Prop-content-length: $(wc -c <symlink.props) &&
1010 echo Text-content-length: $(wc -c <delta.2) &&
1011 echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
1013 cat symlink.props &&
1018 Prop-content-length: 10
1023 Node-path: postimage
1027 Prop-content-length: 10
1029 echo Text-content-length: $(wc -c <delta.3) &&
1030 echo Content-length: $((10 + $(wc -c <delta.3))) &&
1035 } >deltapartial.dump &&
1036 try_dump deltapartial.dump &&
1039 git diff-tree --root --stdin |
1040 sed "s/$_x40/OBJID/g"
1042 test_cmp expect actual &&
1043 git show HEAD:postimage >actual.3 &&
1044 git show HEAD^:postimage >actual.2 &&
1045 git show HEAD^^:postimage >actual.1 &&
1046 test_cmp expect.1 actual.1 &&
1047 test_cmp expect.2 actual.2 &&
1048 test_cmp expect.3 actual.3
1051 test_expect_success PIPE 'no hang for delta trying to read past end of preimage' '
1055 printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" |
1060 SVN-fs-dump-format-version: 3
1063 Prop-content-length: 10
1068 Node-path: bootstrap
1072 Prop-content-length: 10
1074 echo Text-content-length: $(wc -c <greedy.delta) &&
1075 echo Content-length: $((10 + $(wc -c <greedy.delta))) &&
1080 } >greedydelta.dump &&
1081 try_dump greedydelta.dump must_fail might_fail
1084 test_expect_success 'set up svn repo' '
1085 svnconf=$PWD/svnconf &&
1086 mkdir -p "$svnconf" &&
1089 svnadmin -h >/dev/null 2>&1 &&
1090 svnadmin create simple-svn &&
1091 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
1092 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
1094 test_set_prereq SVNREPO
1098 test_expect_success SVNREPO,PIPE 't9135/svn.dump' '
1099 mkdir -p simple-git &&
1103 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1109 git fetch ../simple-git master &&
1110 git diff --exit-code FETCH_HEAD