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