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