transport: die if server options are unsupported
[git] / t / t9010-svn-fe.sh
1 #!/bin/sh
2
3 test_description='check svn dumpfile importer'
4
5 . ./test-lib.sh
6
7 if test_have_prereq !PIPE
8 then
9         skip_all="svn dumpfile importer testing requires the PIPE prerequisite"
10         test_done
11 fi
12
13 reinit_git () {
14         rm -fr .git &&
15         rm -f stream backflow &&
16         git init &&
17         mkfifo stream backflow
18 }
19
20 try_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
32 properties () {
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
46 text_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
58 test_expect_success 'empty dump' '
59         reinit_git &&
60         echo "SVN-fs-dump-format-version: 2" >input &&
61         try_dump input
62 '
63
64 test_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
70 test_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
90 test_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
113 test_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
147 test_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
172 test_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
214 test_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
267 test_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
366 test_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
387 test_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
409 test_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/$OID_REGEX/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
485 test_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
511 test_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/$OID_REGEX/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
591 test_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/$OID_REGEX/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
671 test_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
735 test_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/$OID_REGEX/OBJID/g"
796         } >actual &&
797         test_cmp expect actual
798 '
799
800 test_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/$OID_REGEX/OBJID/g"
850         } >actual &&
851         test_cmp expect actual
852 '
853
854 test_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/$OID_REGEX/OBJID/g"
935         } >actual &&
936         test_cmp expect actual
937 '
938
939 test_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/$OID_REGEX/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
1044 test_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
1077 test_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
1091 test_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
1107 test_done