t / t9010-svn-fe.shon commit remote: add a macro for "refs/tags/*:refs/tags/*" (750d0da)
   1#!/bin/sh
   2
   3test_description='check svn dumpfile importer'
   4
   5. ./test-lib.sh
   6
   7if test_have_prereq !PIPE
   8then
   9        skip_all="svn dumpfile importer testing requires the PIPE prerequisite"
  10        test_done
  11fi
  12
  13reinit_git () {
  14        rm -fr .git &&
  15        rm -f stream backflow &&
  16        git init &&
  17        mkfifo stream backflow
  18}
  19
  20try_dump () {
  21        input=$1 &&
  22        maybe_fail_svnfe=${2:+test_$2} &&
  23        maybe_fail_fi=${3:+test_$3} &&
  24
  25        {
  26                $maybe_fail_svnfe test-svn-fe "$input" >stream 3<backflow &
  27        } &&
  28        $maybe_fail_fi git fast-import --cat-blob-fd=3 <stream 3>backflow &&
  29        wait $!
  30}
  31
  32properties () {
  33        while test "$#" -ne 0
  34        do
  35                property="$1" &&
  36                value="$2" &&
  37                printf "%s\n" "K ${#property}" &&
  38                printf "%s\n" "$property" &&
  39                printf "%s\n" "V ${#value}" &&
  40                printf "%s\n" "$value" &&
  41                shift 2 ||
  42                return 1
  43        done
  44}
  45
  46text_no_props () {
  47        text="$1
  48" &&
  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" &&
  53        printf "%s\n" "$text"
  54}
  55
  56>empty
  57
  58test_expect_success 'empty dump' '
  59        reinit_git &&
  60        echo "SVN-fs-dump-format-version: 2" >input &&
  61        try_dump input
  62'
  63
  64test_expect_success 'v4 dumps not supported' '
  65        reinit_git &&
  66        echo "SVN-fs-dump-format-version: 4" >v4.dump &&
  67        try_dump v4.dump must_fail
  68'
  69
  70test_expect_failure 'empty revision' '
  71        reinit_git &&
  72        printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
  73        cat >emptyrev.dump <<-\EOF &&
  74        SVN-fs-dump-format-version: 3
  75
  76        Revision-number: 1
  77        Prop-content-length: 0
  78        Content-length: 0
  79
  80        Revision-number: 2
  81        Prop-content-length: 0
  82        Content-length: 0
  83
  84        EOF
  85        try_dump emptyrev.dump &&
  86        git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
  87        test_cmp expect actual
  88'
  89
  90test_expect_success 'empty properties' '
  91        reinit_git &&
  92        printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
  93        cat >emptyprop.dump <<-\EOF &&
  94        SVN-fs-dump-format-version: 3
  95
  96        Revision-number: 1
  97        Prop-content-length: 10
  98        Content-length: 10
  99
 100        PROPS-END
 101
 102        Revision-number: 2
 103        Prop-content-length: 10
 104        Content-length: 10
 105
 106        PROPS-END
 107        EOF
 108        try_dump emptyprop.dump &&
 109        git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
 110        test_cmp expect actual
 111'
 112
 113test_expect_success 'author name and commit message' '
 114        reinit_git &&
 115        echo "<author@example.com, author@example.com@local>" >expect.author &&
 116        cat >message <<-\EOF &&
 117        A concise summary of the change
 118
 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.
 121
 122        * file.c
 123            Details pertaining to an individual file.
 124        EOF
 125        {
 126                properties \
 127                        svn:author author@example.com \
 128                        svn:log "$(cat message)" &&
 129                echo PROPS-END
 130        } >props &&
 131        {
 132                echo "SVN-fs-dump-format-version: 3" &&
 133                echo &&
 134                echo "Revision-number: 1" &&
 135                echo Prop-content-length: $(wc -c <props) &&
 136                echo Content-length: $(wc -c <props) &&
 137                echo &&
 138                cat props
 139        } >log.dump &&
 140        try_dump log.dump &&
 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
 145'
 146
 147test_expect_success 'unsupported properties are ignored' '
 148        reinit_git &&
 149        echo author >expect &&
 150        cat >extraprop.dump <<-\EOF &&
 151        SVN-fs-dump-format-version: 3
 152
 153        Revision-number: 1
 154        Prop-content-length: 56
 155        Content-length: 56
 156
 157        K 8
 158        nonsense
 159        V 1
 160        y
 161        K 10
 162        svn:author
 163        V 6
 164        author
 165        PROPS-END
 166        EOF
 167        try_dump extraprop.dump &&
 168        git log -p --format=%an HEAD >actual &&
 169        test_cmp expect actual
 170'
 171
 172test_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 &&
 176        reinit_git &&
 177        {
 178                properties \
 179                        svn:author author@example.com \
 180                        svn:date "1999-01-01T00:01:002.000000Z" \
 181                        svn:log "add empty file" &&
 182                echo PROPS-END
 183        } >props &&
 184        {
 185                cat <<-EOF &&
 186                SVN-fs-dump-format-version: 3
 187
 188                Revision-number: 1
 189                EOF
 190                echo Prop-content-length: $(wc -c <props) &&
 191                echo Content-length: $(wc -c <props) &&
 192                echo &&
 193                cat props &&
 194                cat <<-\EOF
 195
 196                Node-path: empty-file
 197                Node-kind: file
 198                Node-action: add
 199                Content-length: 0
 200
 201                EOF
 202        } >emptyfile.dump &&
 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 &&
 211        test_cmp empty file
 212'
 213
 214test_expect_success 'directory with files' '
 215        reinit_git &&
 216        printf "%s\n" directory/file1 directory/file2 >expect.files &&
 217        echo hi >hi &&
 218        echo hello >hello &&
 219        {
 220                properties \
 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" &&
 224                echo PROPS-END
 225        } >props &&
 226        {
 227                cat <<-EOF &&
 228                SVN-fs-dump-format-version: 3
 229
 230                Revision-number: 1
 231                EOF
 232                echo Prop-content-length: $(wc -c <props) &&
 233                echo Content-length: $(wc -c <props) &&
 234                echo &&
 235                cat props &&
 236                cat <<-\EOF &&
 237
 238                Node-path: directory
 239                Node-kind: dir
 240                Node-action: add
 241                Prop-content-length: 10
 242                Content-length: 10
 243
 244                PROPS-END
 245
 246                Node-path: directory/file1
 247                Node-kind: file
 248                Node-action: add
 249                EOF
 250                text_no_props hello &&
 251                cat <<-\EOF &&
 252                Node-path: directory/file2
 253                Node-kind: file
 254                Node-action: add
 255                EOF
 256                text_no_props hi
 257        } >directory.dump &&
 258        try_dump directory.dump &&
 259
 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
 265'
 266
 267test_expect_success 'branch name with backslash' '
 268        reinit_git &&
 269        sort <<-\EOF >expect.branch-files &&
 270        trunk/file1
 271        trunk/file2
 272        "branches/UpdateFOPto094\\/file1"
 273        "branches/UpdateFOPto094\\/file2"
 274        EOF
 275
 276        echo hi >hi &&
 277        echo hello >hello &&
 278        {
 279                properties \
 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" &&
 283                echo PROPS-END
 284        } >props.setup &&
 285        {
 286                properties \
 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" &&
 290                echo PROPS-END
 291        } >props.branch &&
 292        {
 293                cat <<-EOF &&
 294                SVN-fs-dump-format-version: 3
 295
 296                Revision-number: 1
 297                EOF
 298                echo Prop-content-length: $(wc -c <props.setup) &&
 299                echo Content-length: $(wc -c <props.setup) &&
 300                echo &&
 301                cat props.setup &&
 302                cat <<-\EOF &&
 303
 304                Node-path: trunk
 305                Node-kind: dir
 306                Node-action: add
 307                Prop-content-length: 10
 308                Content-length: 10
 309
 310                PROPS-END
 311
 312                Node-path: branches
 313                Node-kind: dir
 314                Node-action: add
 315                Prop-content-length: 10
 316                Content-length: 10
 317
 318                PROPS-END
 319
 320                Node-path: trunk/file1
 321                Node-kind: file
 322                Node-action: add
 323                EOF
 324                text_no_props hello &&
 325                cat <<-\EOF &&
 326                Node-path: trunk/file2
 327                Node-kind: file
 328                Node-action: add
 329                EOF
 330                text_no_props hi &&
 331                cat <<-\EOF &&
 332
 333                Revision-number: 2
 334                EOF
 335                echo Prop-content-length: $(wc -c <props.branch) &&
 336                echo Content-length: $(wc -c <props.branch) &&
 337                echo &&
 338                cat props.branch &&
 339                cat <<-\EOF
 340
 341                Node-path: branches/UpdateFOPto094\
 342                Node-kind: dir
 343                Node-action: add
 344                Node-copyfrom-rev: 1
 345                Node-copyfrom-path: trunk
 346
 347                Node-kind: dir
 348                Node-action: add
 349                Prop-content-length: 34
 350                Content-length: 34
 351
 352                K 13
 353                svn:mergeinfo
 354                V 0
 355
 356                PROPS-END
 357                EOF
 358        } >branch.dump &&
 359        try_dump branch.dump &&
 360
 361        git ls-tree -r --name-only HEAD |
 362        sort >actual.branch-files &&
 363        test_cmp expect.branch-files actual.branch-files
 364'
 365
 366test_expect_success 'node without action' '
 367        reinit_git &&
 368        cat >inaction.dump <<-\EOF &&
 369        SVN-fs-dump-format-version: 3
 370
 371        Revision-number: 1
 372        Prop-content-length: 10
 373        Content-length: 10
 374
 375        PROPS-END
 376
 377        Node-path: directory
 378        Node-kind: dir
 379        Prop-content-length: 10
 380        Content-length: 10
 381
 382        PROPS-END
 383        EOF
 384        try_dump inaction.dump must_fail
 385'
 386
 387test_expect_success 'action: add node without text' '
 388        reinit_git &&
 389        cat >textless.dump <<-\EOF &&
 390        SVN-fs-dump-format-version: 3
 391
 392        Revision-number: 1
 393        Prop-content-length: 10
 394        Content-length: 10
 395
 396        PROPS-END
 397
 398        Node-path: textless
 399        Node-kind: file
 400        Node-action: add
 401        Prop-content-length: 10
 402        Content-length: 10
 403
 404        PROPS-END
 405        EOF
 406        try_dump textless.dump must_fail
 407'
 408
 409test_expect_failure 'change file mode but keep old content' '
 410        reinit_git &&
 411        cat >expect <<-\EOF &&
 412        OBJID
 413        :120000 100644 OBJID OBJID T    greeting
 414        OBJID
 415        :100644 120000 OBJID OBJID T    greeting
 416        OBJID
 417        :000000 100644 OBJID OBJID A    greeting
 418        EOF
 419        echo "link hello" >expect.blob &&
 420        echo hello >hello &&
 421        cat >filemode.dump <<-\EOF &&
 422        SVN-fs-dump-format-version: 3
 423
 424        Revision-number: 1
 425        Prop-content-length: 10
 426        Content-length: 10
 427
 428        PROPS-END
 429
 430        Node-path: greeting
 431        Node-kind: file
 432        Node-action: add
 433        Prop-content-length: 10
 434        Text-content-length: 11
 435        Content-length: 21
 436
 437        PROPS-END
 438        link hello
 439
 440        Revision-number: 2
 441        Prop-content-length: 10
 442        Content-length: 10
 443
 444        PROPS-END
 445
 446        Node-path: greeting
 447        Node-kind: file
 448        Node-action: change
 449        Prop-content-length: 33
 450        Content-length: 33
 451
 452        K 11
 453        svn:special
 454        V 1
 455        *
 456        PROPS-END
 457
 458        Revision-number: 3
 459        Prop-content-length: 10
 460        Content-length: 10
 461
 462        PROPS-END
 463
 464        Node-path: greeting
 465        Node-kind: file
 466        Node-action: change
 467        Prop-content-length: 10
 468        Content-length: 10
 469
 470        PROPS-END
 471        EOF
 472        try_dump filemode.dump &&
 473        {
 474                git rev-list HEAD |
 475                git diff-tree --root --stdin |
 476                sed "s/$_x40/OBJID/g"
 477        } >actual &&
 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
 483'
 484
 485test_expect_success 'NUL in property value' '
 486        reinit_git &&
 487        echo "commit message" >expect.message &&
 488        {
 489                properties \
 490                        unimportant "something with a NUL (Q)" \
 491                        svn:log "commit message"&&
 492                echo PROPS-END
 493        } |
 494        q_to_nul >props &&
 495        {
 496                cat <<-\EOF &&
 497                SVN-fs-dump-format-version: 3
 498
 499                Revision-number: 1
 500                EOF
 501                echo Prop-content-length: $(wc -c <props) &&
 502                echo Content-length: $(wc -c <props) &&
 503                echo &&
 504                cat props
 505        } >nulprop.dump &&
 506        try_dump nulprop.dump &&
 507        git diff-tree --always -s --format=%s HEAD >actual.message &&
 508        test_cmp expect.message actual.message
 509'
 510
 511test_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.
 514        reinit_git &&
 515        cat >expect <<-\EOF &&
 516        OBJID
 517        :100644 100644 OBJID OBJID M    greeting
 518        OBJID
 519        :000000 100644 OBJID OBJID A    greeting
 520        EOF
 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 &&
 524        {
 525                properties svn:log "something with an ASCII NUL (Q)" &&
 526                echo PROPS-END
 527        } |
 528        q_to_nul >props &&
 529        {
 530                q_to_nul <<-\EOF &&
 531                SVN-fs-dump-format-version: 3
 532
 533                Revision-number: 1
 534                Prop-content-length: 10
 535                Content-length: 10
 536
 537                PROPS-END
 538
 539                Node-path: greeting
 540                Node-kind: file
 541                Node-action: add
 542                Prop-content-length: 10
 543                Text-content-length: 6
 544                Content-length: 16
 545
 546                PROPS-END
 547                helQo
 548
 549                Revision-number: 2
 550                EOF
 551                echo Prop-content-length: $(wc -c <props) &&
 552                echo Content-length: $(wc -c <props) &&
 553                echo &&
 554                cat props &&
 555                q_to_nul <<-\EOF
 556
 557                Node-path: greeting
 558                Node-kind: file
 559                Node-action: change
 560                Prop-content-length: 43
 561                Text-content-length: 11
 562                Content-length: 54
 563
 564                K 21
 565                svn:specialQnotreally
 566                V 1
 567                *
 568                PROPS-END
 569                link hello
 570                EOF
 571        } >8bitclean.dump &&
 572        try_dump 8bitclean.dump &&
 573        {
 574                git rev-list HEAD |
 575                git diff-tree --root --stdin |
 576                sed "s/$_x40/OBJID/g"
 577        } >actual &&
 578        {
 579                git cat-file commit HEAD | nul_to_q &&
 580                echo
 581        } |
 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
 589'
 590
 591test_expect_success 'change file mode and reiterate content' '
 592        reinit_git &&
 593        cat >expect <<-\EOF &&
 594        OBJID
 595        :120000 100644 OBJID OBJID T    greeting
 596        OBJID
 597        :100644 120000 OBJID OBJID T    greeting
 598        OBJID
 599        :000000 100644 OBJID OBJID A    greeting
 600        EOF
 601        echo "link hello" >expect.blob &&
 602        echo hello >hello &&
 603        cat >filemode2.dump <<-\EOF &&
 604        SVN-fs-dump-format-version: 3
 605
 606        Revision-number: 1
 607        Prop-content-length: 10
 608        Content-length: 10
 609
 610        PROPS-END
 611
 612        Node-path: greeting
 613        Node-kind: file
 614        Node-action: add
 615        Prop-content-length: 10
 616        Text-content-length: 11
 617        Content-length: 21
 618
 619        PROPS-END
 620        link hello
 621
 622        Revision-number: 2
 623        Prop-content-length: 10
 624        Content-length: 10
 625
 626        PROPS-END
 627
 628        Node-path: greeting
 629        Node-kind: file
 630        Node-action: change
 631        Prop-content-length: 33
 632        Text-content-length: 11
 633        Content-length: 44
 634
 635        K 11
 636        svn:special
 637        V 1
 638        *
 639        PROPS-END
 640        link hello
 641
 642        Revision-number: 3
 643        Prop-content-length: 10
 644        Content-length: 10
 645
 646        PROPS-END
 647
 648        Node-path: greeting
 649        Node-kind: file
 650        Node-action: change
 651        Prop-content-length: 10
 652        Text-content-length: 11
 653        Content-length: 21
 654
 655        PROPS-END
 656        link hello
 657        EOF
 658        try_dump filemode2.dump &&
 659        {
 660                git rev-list HEAD |
 661                git diff-tree --root --stdin |
 662                sed "s/$_x40/OBJID/g"
 663        } >actual &&
 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
 669'
 670
 671test_expect_success 'deltas supported' '
 672        reinit_git &&
 673        {
 674                # (old) h + (inline) ello + (old) \n
 675                printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
 676                q_to_nul
 677        } >delta &&
 678        {
 679                properties \
 680                        svn:author author@example.com \
 681                        svn:date "1999-01-05T00:01:002.000000Z" \
 682                        svn:log "add greeting" &&
 683                echo PROPS-END
 684        } >props &&
 685        {
 686                properties \
 687                        svn:author author@example.com \
 688                        svn:date "1999-01-06T00:01:002.000000Z" \
 689                        svn:log "change it" &&
 690                echo PROPS-END
 691        } >props2 &&
 692        {
 693                echo SVN-fs-dump-format-version: 3 &&
 694                echo &&
 695                echo Revision-number: 1 &&
 696                echo Prop-content-length: $(wc -c <props) &&
 697                echo Content-length: $(wc -c <props) &&
 698                echo &&
 699                cat props &&
 700                cat <<-\EOF &&
 701
 702                Node-path: hello
 703                Node-kind: file
 704                Node-action: add
 705                Prop-content-length: 10
 706                Text-content-length: 3
 707                Content-length: 13
 708
 709                PROPS-END
 710                hi
 711
 712                EOF
 713                echo Revision-number: 2 &&
 714                echo Prop-content-length: $(wc -c <props2) &&
 715                echo Content-length: $(wc -c <props2) &&
 716                echo &&
 717                cat props2 &&
 718                cat <<-\EOF &&
 719
 720                Node-path: hello
 721                Node-kind: file
 722                Node-action: change
 723                Text-delta: true
 724                Prop-content-length: 10
 725                EOF
 726                echo Text-content-length: $(wc -c <delta) &&
 727                echo Content-length: $((10 + $(wc -c <delta))) &&
 728                echo &&
 729                echo PROPS-END &&
 730                cat delta
 731        } >delta.dump &&
 732        try_dump delta.dump
 733'
 734
 735test_expect_success 'property deltas supported' '
 736        reinit_git &&
 737        cat >expect <<-\EOF &&
 738        OBJID
 739        :100755 100644 OBJID OBJID M    script.sh
 740        EOF
 741        {
 742                properties \
 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" &&
 746                echo PROPS-END
 747        } >revprops &&
 748        {
 749                echo SVN-fs-dump-format-version: 3 &&
 750                echo &&
 751                echo Revision-number: 1 &&
 752                echo Prop-content-length: $(wc -c <revprops) &&
 753                echo Content-length: $(wc -c <revprops) &&
 754                echo &&
 755                cat revprops &&
 756                echo &&
 757                cat <<-\EOF &&
 758                Node-path: script.sh
 759                Node-kind: file
 760                Node-action: add
 761                Text-content-length: 0
 762                Prop-content-length: 39
 763                Content-length: 39
 764
 765                K 14
 766                svn:executable
 767                V 4
 768                true
 769                PROPS-END
 770
 771                EOF
 772                echo Revision-number: 2 &&
 773                echo Prop-content-length: $(wc -c <revprops) &&
 774                echo Content-length: $(wc -c <revprops) &&
 775                echo &&
 776                cat revprops &&
 777                echo &&
 778                cat <<-\EOF
 779                Node-path: script.sh
 780                Node-kind: file
 781                Node-action: change
 782                Prop-delta: true
 783                Prop-content-length: 30
 784                Content-length: 30
 785
 786                D 14
 787                svn:executable
 788                PROPS-END
 789                EOF
 790        } >propdelta.dump &&
 791        try_dump propdelta.dump &&
 792        {
 793                git rev-list HEAD |
 794                git diff-tree --stdin |
 795                sed "s/$_x40/OBJID/g"
 796        } >actual &&
 797        test_cmp expect actual
 798'
 799
 800test_expect_success 'properties on /' '
 801        reinit_git &&
 802        cat <<-\EOF >expect &&
 803        OBJID
 804        OBJID
 805        :000000 100644 OBJID OBJID A    greeting
 806        EOF
 807        sed -e "s/X$//" <<-\EOF >changeroot.dump &&
 808        SVN-fs-dump-format-version: 3
 809
 810        Revision-number: 1
 811        Prop-content-length: 10
 812        Content-length: 10
 813
 814        PROPS-END
 815
 816        Node-path: greeting
 817        Node-kind: file
 818        Node-action: add
 819        Text-content-length: 0
 820        Prop-content-length: 10
 821        Content-length: 10
 822
 823        PROPS-END
 824
 825        Revision-number: 2
 826        Prop-content-length: 10
 827        Content-length: 10
 828
 829        PROPS-END
 830
 831        Node-path: X
 832        Node-kind: dir
 833        Node-action: change
 834        Prop-delta: true
 835        Prop-content-length: 43
 836        Content-length: 43
 837
 838        K 10
 839        svn:ignore
 840        V 11
 841        build-area
 842
 843        PROPS-END
 844        EOF
 845        try_dump changeroot.dump &&
 846        {
 847                git rev-list HEAD |
 848                git diff-tree --root --always --stdin |
 849                sed "s/$_x40/OBJID/g"
 850        } >actual &&
 851        test_cmp expect actual
 852'
 853
 854test_expect_success 'deltas for typechange' '
 855        reinit_git &&
 856        cat >expect <<-\EOF &&
 857        OBJID
 858        :120000 100644 OBJID OBJID T    test-file
 859        OBJID
 860        :100755 120000 OBJID OBJID T    test-file
 861        OBJID
 862        :000000 100755 OBJID OBJID A    test-file
 863        EOF
 864        cat >deleteprop.dump <<-\EOF &&
 865        SVN-fs-dump-format-version: 3
 866
 867        Revision-number: 1
 868        Prop-content-length: 10
 869        Content-length: 10
 870
 871        PROPS-END
 872
 873        Node-path: test-file
 874        Node-kind: file
 875        Node-action: add
 876        Prop-delta: true
 877        Prop-content-length: 35
 878        Text-content-length: 17
 879        Content-length: 52
 880
 881        K 14
 882        svn:executable
 883        V 0
 884
 885        PROPS-END
 886        link testing 123
 887
 888        Revision-number: 2
 889        Prop-content-length: 10
 890        Content-length: 10
 891
 892        PROPS-END
 893
 894        Node-path: test-file
 895        Node-kind: file
 896        Node-action: change
 897        Prop-delta: true
 898        Prop-content-length: 53
 899        Text-content-length: 17
 900        Content-length: 70
 901
 902        K 11
 903        svn:special
 904        V 1
 905        *
 906        D 14
 907        svn:executable
 908        PROPS-END
 909        link testing 231
 910
 911        Revision-number: 3
 912        Prop-content-length: 10
 913        Content-length: 10
 914
 915        PROPS-END
 916
 917        Node-path: test-file
 918        Node-kind: file
 919        Node-action: change
 920        Prop-delta: true
 921        Prop-content-length: 27
 922        Text-content-length: 17
 923        Content-length: 44
 924
 925        D 11
 926        svn:special
 927        PROPS-END
 928        link testing 321
 929        EOF
 930        try_dump deleteprop.dump &&
 931        {
 932                git rev-list HEAD |
 933                git diff-tree --root --stdin |
 934                sed "s/$_x40/OBJID/g"
 935        } >actual &&
 936        test_cmp expect actual
 937'
 938
 939test_expect_success 'deltas need not consume the whole preimage' '
 940        reinit_git &&
 941        cat >expect <<-\EOF &&
 942        OBJID
 943        :120000 100644 OBJID OBJID T    postimage
 944        OBJID
 945        :100644 120000 OBJID OBJID T    postimage
 946        OBJID
 947        :000000 100644 OBJID OBJID A    postimage
 948        EOF
 949        echo "first preimage" >expect.1 &&
 950        printf target >expect.2 &&
 951        printf lnk >expect.3 &&
 952        {
 953                printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
 954                q_to_nul
 955        } >delta.1 &&
 956        {
 957                properties svn:special "*" &&
 958                echo PROPS-END
 959        } >symlink.props &&
 960        {
 961                printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
 962                q_to_nul
 963        } >delta.2 &&
 964        {
 965                printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
 966                q_to_nul
 967        } >delta.3 &&
 968        {
 969                cat <<-\EOF &&
 970                SVN-fs-dump-format-version: 3
 971
 972                Revision-number: 1
 973                Prop-content-length: 10
 974                Content-length: 10
 975
 976                PROPS-END
 977
 978                Node-path: postimage
 979                Node-kind: file
 980                Node-action: add
 981                Text-delta: true
 982                Prop-content-length: 10
 983                EOF
 984                echo Text-content-length: $(wc -c <delta.1) &&
 985                echo Content-length: $((10 + $(wc -c <delta.1))) &&
 986                echo &&
 987                echo PROPS-END &&
 988                cat delta.1 &&
 989                cat <<-\EOF &&
 990
 991                Revision-number: 2
 992                Prop-content-length: 10
 993                Content-length: 10
 994
 995                PROPS-END
 996
 997                Node-path: postimage
 998                Node-kind: file
 999                Node-action: change
1000                Text-delta: true
1001                EOF
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))) &&
1005                echo &&
1006                cat symlink.props &&
1007                cat delta.2 &&
1008                cat <<-\EOF &&
1009
1010                Revision-number: 3
1011                Prop-content-length: 10
1012                Content-length: 10
1013
1014                PROPS-END
1015
1016                Node-path: postimage
1017                Node-kind: file
1018                Node-action: change
1019                Text-delta: true
1020                Prop-content-length: 10
1021                EOF
1022                echo Text-content-length: $(wc -c <delta.3) &&
1023                echo Content-length: $((10 + $(wc -c <delta.3))) &&
1024                echo &&
1025                echo PROPS-END &&
1026                cat delta.3 &&
1027                echo
1028        } >deltapartial.dump &&
1029        try_dump deltapartial.dump &&
1030        {
1031                git rev-list HEAD |
1032                git diff-tree --root --stdin |
1033                sed "s/$_x40/OBJID/g"
1034        } >actual &&
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
1042'
1043
1044test_expect_success 'no hang for delta trying to read past end of preimage' '
1045        reinit_git &&
1046        {
1047                # COPY 1
1048                printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" |
1049                q_to_nul
1050        } >greedy.delta &&
1051        {
1052                cat <<-\EOF &&
1053                SVN-fs-dump-format-version: 3
1054
1055                Revision-number: 1
1056                Prop-content-length: 10
1057                Content-length: 10
1058
1059                PROPS-END
1060
1061                Node-path: bootstrap
1062                Node-kind: file
1063                Node-action: add
1064                Text-delta: true
1065                Prop-content-length: 10
1066                EOF
1067                echo Text-content-length: $(wc -c <greedy.delta) &&
1068                echo Content-length: $((10 + $(wc -c <greedy.delta))) &&
1069                echo &&
1070                echo PROPS-END &&
1071                cat greedy.delta &&
1072                echo
1073        } >greedydelta.dump &&
1074        try_dump greedydelta.dump must_fail might_fail
1075'
1076
1077test_expect_success 'set up svn repo' '
1078        svnconf=$PWD/svnconf &&
1079        mkdir -p "$svnconf" &&
1080
1081        if
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
1086        then
1087                test_set_prereq SVNREPO
1088        fi
1089'
1090
1091test_expect_success SVNREPO 't9135/svn.dump' '
1092        mkdir -p simple-git &&
1093        (
1094                cd simple-git &&
1095                reinit_git &&
1096                try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1097        ) &&
1098        (
1099                cd simple-svnco &&
1100                git init &&
1101                git add . &&
1102                git fetch ../simple-git master &&
1103                git diff --exit-code FETCH_HEAD
1104        )
1105'
1106
1107test_done