Merge branch 'maint'
[git.git] / t / t9010-svn-fe.sh
1 #!/bin/sh
2
3 test_description='check svn dumpfile importer'
4
5 . ./test-lib.sh
6
7 reinit_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
19 try_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
31 properties () {
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
45 text_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
57 test_expect_success 'setup: have pipes?' '
58         rm -f frob &&
59         if mkfifo frob
60         then
61                 test_set_prereq PIPE
62         fi
63 '
64
65 test_expect_success PIPE 'empty dump' '
66         reinit_git &&
67         echo "SVN-fs-dump-format-version: 2" >input &&
68         try_dump input
69 '
70
71 test_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
77 test_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
97 test_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
120 test_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
154 test_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
179 test_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
221 test_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
274 test_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
373 test_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
394 test_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
416 test_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
492 test_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
518 test_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
598 test_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
678 test_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
742 test_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
807 test_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
861 test_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
946 test_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
1051 test_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
1084 test_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
1098 test_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
1114 test_done