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
=${2:+test_$2} &&
24 $maybe_fail test-svn-fe
"$input" >stream
3<backflow
&
26 git fast-import
--cat-blob-fd=3 <stream
3>backflow
&&
35 printf "%s\n" "K ${#property}" &&
36 printf "%s\n" "$property" &&
37 printf "%s\n" "V ${#value}" &&
38 printf "%s\n" "$value" &&
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" &&
56 test_expect_success
'setup: have pipes?' '
64 test_expect_success PIPE
'empty dump' '
66 echo "SVN-fs-dump-format-version: 2" >input &&
70 test_expect_success PIPE
'v4 dumps not supported' '
72 echo "SVN-fs-dump-format-version: 4" >v4.dump &&
73 try_dump v4.dump must_fail
76 test_expect_failure PIPE
'empty revision' '
78 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
79 cat >emptyrev.dump <<-\EOF &&
80 SVN-fs-dump-format-version: 3
83 Prop-content-length: 0
87 Prop-content-length: 0
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' '
98 printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
99 cat >emptyprop.dump <<-\EOF &&
100 SVN-fs-dump-format-version: 3
103 Prop-content-length: 10
109 Prop-content-length: 10
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' '
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.
129 Details pertaining to an individual file.
133 svn:author author@example.com \
134 svn:log "$(cat message)" &&
138 echo "SVN-fs-dump-format-version: 3" &&
140 echo "Revision-number: 1" &&
141 echo Prop-content-length: $(wc -c <props) &&
142 echo Content-length: $(wc -c <props) &&
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' '
155 echo author >expect &&
156 cat >extraprop.dump <<-\EOF &&
157 SVN-fs-dump-format-version: 3
160 Prop-content-length: 56
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 &&
185 svn:author author@example.com \
186 svn:date "1999-01-01T00:01:002.000000Z" \
187 svn:log "add empty file" &&
192 SVN-fs-dump-format-version: 3
196 echo Prop-content-length: $(wc -c <props) &&
197 echo Content-length: $(wc -c <props) &&
202 Node-path: empty-file
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 &&
220 test_expect_success PIPE
'directory with files' '
222 printf "%s\n" directory/file1 directory/file2 >expect.files &&
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" &&
234 SVN-fs-dump-format-version: 3
238 echo Prop-content-length: $(wc -c <props) &&
239 echo Content-length: $(wc -c <props) &&
247 Prop-content-length: 10
252 Node-path: directory/file1
256 text_no_props hello &&
258 Node-path: directory/file2
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' '
275 sort <<-\EOF >expect.branch-files &&
278 "branches/UpdateFOPto094\\/file1"
279 "branches/UpdateFOPto094\\/file2"
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" &&
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" &&
300 SVN-fs-dump-format-version: 3
304 echo Prop-content-length: $(wc -c <props.setup) &&
305 echo Content-length: $(wc -c <props.setup) &&
313 Prop-content-length: 10
321 Prop-content-length: 10
326 Node-path: trunk/file1
330 text_no_props hello &&
332 Node-path: trunk/file2
341 echo Prop-content-length: $(wc -c <props.branch) &&
342 echo Content-length: $(wc -c <props.branch) &&
347 Node-path: branches/UpdateFOPto094\
351 Node-copyfrom-path: trunk
355 Prop-content-length: 34
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' '
374 cat >inaction.dump <<-\EOF &&
375 SVN-fs-dump-format-version: 3
378 Prop-content-length: 10
385 Prop-content-length: 10
390 try_dump inaction.dump must_fail
393 test_expect_success PIPE
'action: add node without text' '
395 cat >textless.dump <<-\EOF &&
396 SVN-fs-dump-format-version: 3
399 Prop-content-length: 10
407 Prop-content-length: 10
412 try_dump textless.dump must_fail
415 test_expect_failure PIPE
'change file mode but keep old content' '
417 cat >expect <<-\EOF &&
419 :120000 100644 OBJID OBJID T greeting
421 :100644 120000 OBJID OBJID T greeting
423 :000000 100644 OBJID OBJID A greeting
425 echo "link hello" >expect.blob &&
427 cat >filemode.dump <<-\EOF &&
428 SVN-fs-dump-format-version: 3
431 Prop-content-length: 10
439 Prop-content-length: 10
440 Text-content-length: 11
447 Prop-content-length: 10
455 Prop-content-length: 33
465 Prop-content-length: 10
473 Prop-content-length: 10
478 try_dump filemode.dump &&
481 git diff-tree --root --stdin |
482 sed "s/$_x40/OBJID/g"
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' '
493 echo "commit message" >expect.message &&
496 unimportant "something with a NUL (Q)" \
497 svn:log "commit message"&&
503 SVN-fs-dump-format-version: 3
507 echo Prop-content-length: $(wc -c <props) &&
508 echo Content-length: $(wc -c <props) &&
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.
521 cat >expect <<-\EOF &&
523 :100644 100644 OBJID OBJID M greeting
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)" &&
537 SVN-fs-dump-format-version: 3
540 Prop-content-length: 10
548 Prop-content-length: 10
549 Text-content-length: 6
557 echo Prop-content-length: $(wc -c <props) &&
558 echo Content-length: $(wc -c <props) &&
566 Prop-content-length: 43
567 Text-content-length: 11
571 svn:specialQnotreally
578 try_dump 8bitclean.dump &&
581 git diff-tree --root --stdin |
582 sed "s/$_x40/OBJID/g"
585 git cat-file commit HEAD | nul_to_q &&
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' '
599 cat >expect <<-\EOF &&
601 :120000 100644 OBJID OBJID T greeting
603 :100644 120000 OBJID OBJID T greeting
605 :000000 100644 OBJID OBJID A greeting
607 echo "link hello" >expect.blob &&
609 cat >filemode2.dump <<-\EOF &&
610 SVN-fs-dump-format-version: 3
613 Prop-content-length: 10
621 Prop-content-length: 10
622 Text-content-length: 11
629 Prop-content-length: 10
637 Prop-content-length: 33
638 Text-content-length: 11
649 Prop-content-length: 10
657 Prop-content-length: 10
658 Text-content-length: 11
664 try_dump filemode2.dump &&
667 git diff-tree --root --stdin |
668 sed "s/$_x40/OBJID/g"
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 supported' '
680 # (old) h + (inline) ello + (old) \n
681 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
686 svn:author author@example.com \
687 svn:date "1999-01-05T00:01:002.000000Z" \
688 svn:log "add greeting" &&
693 svn:author author@example.com \
694 svn:date "1999-01-06T00:01:002.000000Z" \
695 svn:log "change it" &&
699 echo SVN-fs-dump-format-version: 3 &&
701 echo Revision-number: 1 &&
702 echo Prop-content-length: $(wc -c <props) &&
703 echo Content-length: $(wc -c <props) &&
711 Prop-content-length: 10
712 Text-content-length: 3
719 echo Revision-number: 2 &&
720 echo Prop-content-length: $(wc -c <props2) &&
721 echo Content-length: $(wc -c <props2) &&
730 Prop-content-length: 10
732 echo Text-content-length: $(wc -c <delta) &&
733 echo Content-length: $((10 + $(wc -c <delta))) &&
741 test_expect_success PIPE
'property deltas supported' '
743 cat >expect <<-\EOF &&
745 :100755 100644 OBJID OBJID M script.sh
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" &&
755 echo SVN-fs-dump-format-version: 3 &&
757 echo Revision-number: 1 &&
758 echo Prop-content-length: $(wc -c <revprops) &&
759 echo Content-length: $(wc -c <revprops) &&
767 Text-content-length: 0
768 Prop-content-length: 39
778 echo Revision-number: 2 &&
779 echo Prop-content-length: $(wc -c <revprops) &&
780 echo Content-length: $(wc -c <revprops) &&
789 Prop-content-length: 30
797 try_dump propdelta.dump &&
800 git diff-tree --stdin |
801 sed "s/$_x40/OBJID/g"
803 test_cmp expect actual
806 test_expect_success PIPE
'properties on /' '
808 cat <<-\EOF >expect &&
811 :000000 100644 OBJID OBJID A greeting
813 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
814 SVN-fs-dump-format-version: 3
817 Prop-content-length: 10
825 Text-content-length: 0
826 Prop-content-length: 10
832 Prop-content-length: 10
841 Prop-content-length: 43
851 try_dump changeroot.dump &&
854 git diff-tree --root --always --stdin |
855 sed "s/$_x40/OBJID/g"
857 test_cmp expect actual
860 test_expect_success PIPE
'deltas for typechange' '
862 cat >expect <<-\EOF &&
864 :120000 100644 OBJID OBJID T test-file
866 :100755 120000 OBJID OBJID T test-file
868 :000000 100755 OBJID OBJID A test-file
870 cat >deleteprop.dump <<-\EOF &&
871 SVN-fs-dump-format-version: 3
874 Prop-content-length: 10
883 Prop-content-length: 35
884 Text-content-length: 17
895 Prop-content-length: 10
904 Prop-content-length: 53
905 Text-content-length: 17
918 Prop-content-length: 10
927 Prop-content-length: 27
928 Text-content-length: 17
936 try_dump deleteprop.dump &&
939 git diff-tree --root --stdin |
940 sed "s/$_x40/OBJID/g"
942 test_cmp expect actual
945 test_expect_success PIPE
'deltas need not consume the whole preimage' '
947 cat >expect <<-\EOF &&
949 :120000 100644 OBJID OBJID T postimage
951 :100644 120000 OBJID OBJID T postimage
953 :000000 100644 OBJID OBJID A postimage
955 echo "first preimage" >expect.1 &&
956 printf target >expect.2 &&
957 printf lnk >expect.3 &&
959 printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
963 properties svn:special "*" &&
967 printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
971 printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
976 SVN-fs-dump-format-version: 3
979 Prop-content-length: 10
988 Prop-content-length: 10
990 echo Text-content-length: $(wc -c <delta.1) &&
991 echo Content-length: $((10 + $(wc -c <delta.1))) &&
998 Prop-content-length: 10
1003 Node-path: postimage
1008 echo Prop-content-length: $(wc -c <symlink.props) &&
1009 echo Text-content-length: $(wc -c <delta.2) &&
1010 echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
1012 cat symlink.props &&
1017 Prop-content-length: 10
1022 Node-path: postimage
1026 Prop-content-length: 10
1028 echo Text-content-length: $(wc -c <delta.3) &&
1029 echo Content-length: $((10 + $(wc -c <delta.3))) &&
1034 } >deltapartial.dump &&
1035 try_dump deltapartial.dump &&
1038 git diff-tree --root --stdin |
1039 sed "s/$_x40/OBJID/g"
1041 test_cmp expect actual &&
1042 git show HEAD:postimage >actual.3 &&
1043 git show HEAD^:postimage >actual.2 &&
1044 git show HEAD^^:postimage >actual.1 &&
1045 test_cmp expect.1 actual.1 &&
1046 test_cmp expect.2 actual.2 &&
1047 test_cmp expect.3 actual.3
1050 test_expect_success
'set up svn repo' '
1051 svnconf=$PWD/svnconf &&
1052 mkdir -p "$svnconf" &&
1055 svnadmin -h >/dev/null 2>&1 &&
1056 svnadmin create simple-svn &&
1057 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
1058 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
1060 test_set_prereq SVNREPO
1064 test_expect_success SVNREPO
,PIPE
't9135/svn.dump' '
1065 mkdir -p simple-git &&
1069 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1075 git fetch ../simple-git master &&
1076 git diff --exit-code FETCH_HEAD