vcs-svn: drop string_pool
[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=${2:+test_$2} &&
22
23         {
24                 $maybe_fail test-svn-fe "$input" >stream 3<backflow &
25         } &&
26         git fast-import --cat-blob-fd=3 <stream 3>backflow &&
27         wait $!
28 }
29
30 properties () {
31         while test "$#" -ne 0
32         do
33                 property="$1" &&
34                 value="$2" &&
35                 printf "%s\n" "K ${#property}" &&
36                 printf "%s\n" "$property" &&
37                 printf "%s\n" "V ${#value}" &&
38                 printf "%s\n" "$value" &&
39                 shift 2 ||
40                 return 1
41         done
42 }
43
44 text_no_props () {
45         text="$1
46 " &&
47         printf "%s\n" "Prop-content-length: 10" &&
48         printf "%s\n" "Text-content-length: ${#text}" &&
49         printf "%s\n" "Content-length: $((${#text} + 10))" &&
50         printf "%s\n" "" "PROPS-END" &&
51         printf "%s\n" "$text"
52 }
53
54 >empty
55
56 test_expect_success 'setup: have pipes?' '
57         rm -f frob &&
58         if mkfifo frob
59         then
60                 test_set_prereq PIPE
61         fi
62 '
63
64 test_expect_success PIPE 'empty dump' '
65         reinit_git &&
66         echo "SVN-fs-dump-format-version: 2" >input &&
67         try_dump input
68 '
69
70 test_expect_success PIPE 'v4 dumps not supported' '
71         reinit_git &&
72         echo "SVN-fs-dump-format-version: 4" >v4.dump &&
73         try_dump v4.dump must_fail
74 '
75
76 test_expect_failure PIPE 'empty revision' '
77         reinit_git &&
78         printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
79         cat >emptyrev.dump <<-\EOF &&
80         SVN-fs-dump-format-version: 3
81
82         Revision-number: 1
83         Prop-content-length: 0
84         Content-length: 0
85
86         Revision-number: 2
87         Prop-content-length: 0
88         Content-length: 0
89
90         EOF
91         try_dump emptyrev.dump &&
92         git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
93         test_cmp expect actual
94 '
95
96 test_expect_success PIPE 'empty properties' '
97         reinit_git &&
98         printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
99         cat >emptyprop.dump <<-\EOF &&
100         SVN-fs-dump-format-version: 3
101
102         Revision-number: 1
103         Prop-content-length: 10
104         Content-length: 10
105
106         PROPS-END
107
108         Revision-number: 2
109         Prop-content-length: 10
110         Content-length: 10
111
112         PROPS-END
113         EOF
114         try_dump emptyprop.dump &&
115         git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
116         test_cmp expect actual
117 '
118
119 test_expect_success PIPE 'author name and commit message' '
120         reinit_git &&
121         echo "<author@example.com, author@example.com@local>" >expect.author &&
122         cat >message <<-\EOF &&
123         A concise summary of the change
124
125         A detailed description of the change, why it is needed, what
126         was broken and why applying this is the best course of action.
127
128         * file.c
129             Details pertaining to an individual file.
130         EOF
131         {
132                 properties \
133                         svn:author author@example.com \
134                         svn:log "$(cat message)" &&
135                 echo PROPS-END
136         } >props &&
137         {
138                 echo "SVN-fs-dump-format-version: 3" &&
139                 echo &&
140                 echo "Revision-number: 1" &&
141                 echo Prop-content-length: $(wc -c <props) &&
142                 echo Content-length: $(wc -c <props) &&
143                 echo &&
144                 cat props
145         } >log.dump &&
146         try_dump log.dump &&
147         git log -p --format="%B" HEAD >actual.log &&
148         git log --format="<%an, %ae>" >actual.author &&
149         test_cmp message actual.log &&
150         test_cmp expect.author actual.author
151 '
152
153 test_expect_success PIPE 'unsupported properties are ignored' '
154         reinit_git &&
155         echo author >expect &&
156         cat >extraprop.dump <<-\EOF &&
157         SVN-fs-dump-format-version: 3
158
159         Revision-number: 1
160         Prop-content-length: 56
161         Content-length: 56
162
163         K 8
164         nonsense
165         V 1
166         y
167         K 10
168         svn:author
169         V 6
170         author
171         PROPS-END
172         EOF
173         try_dump extraprop.dump &&
174         git log -p --format=%an HEAD >actual &&
175         test_cmp expect actual
176 '
177
178 test_expect_failure PIPE 'timestamp and empty file' '
179         echo author@example.com >expect.author &&
180         echo 1999-01-01 >expect.date &&
181         echo file >expect.files &&
182         reinit_git &&
183         {
184                 properties \
185                         svn:author author@example.com \
186                         svn:date "1999-01-01T00:01:002.000000Z" \
187                         svn:log "add empty file" &&
188                 echo PROPS-END
189         } >props &&
190         {
191                 cat <<-EOF &&
192                 SVN-fs-dump-format-version: 3
193
194                 Revision-number: 1
195                 EOF
196                 echo Prop-content-length: $(wc -c <props) &&
197                 echo Content-length: $(wc -c <props) &&
198                 echo &&
199                 cat props &&
200                 cat <<-\EOF
201
202                 Node-path: empty-file
203                 Node-kind: file
204                 Node-action: add
205                 Content-length: 0
206
207                 EOF
208         } >emptyfile.dump &&
209         try_dump emptyfile.dump &&
210         git log --format=%an HEAD >actual.author &&
211         git log --date=short --format=%ad HEAD >actual.date &&
212         git ls-tree -r --name-only HEAD >actual.files &&
213         test_cmp expect.author actual.author &&
214         test_cmp expect.date actual.date &&
215         test_cmp expect.files actual.files &&
216         git checkout HEAD empty-file &&
217         test_cmp empty file
218 '
219
220 test_expect_success PIPE 'directory with files' '
221         reinit_git &&
222         printf "%s\n" directory/file1 directory/file2 >expect.files &&
223         echo hi >hi &&
224         echo hello >hello &&
225         {
226                 properties \
227                         svn:author author@example.com \
228                         svn:date "1999-02-01T00:01:002.000000Z" \
229                         svn:log "add directory with some files in it" &&
230                 echo PROPS-END
231         } >props &&
232         {
233                 cat <<-EOF &&
234                 SVN-fs-dump-format-version: 3
235
236                 Revision-number: 1
237                 EOF
238                 echo Prop-content-length: $(wc -c <props) &&
239                 echo Content-length: $(wc -c <props) &&
240                 echo &&
241                 cat props &&
242                 cat <<-\EOF &&
243
244                 Node-path: directory
245                 Node-kind: dir
246                 Node-action: add
247                 Prop-content-length: 10
248                 Content-length: 10
249
250                 PROPS-END
251
252                 Node-path: directory/file1
253                 Node-kind: file
254                 Node-action: add
255                 EOF
256                 text_no_props hello &&
257                 cat <<-\EOF &&
258                 Node-path: directory/file2
259                 Node-kind: file
260                 Node-action: add
261                 EOF
262                 text_no_props hi
263         } >directory.dump &&
264         try_dump directory.dump &&
265
266         git ls-tree -r --name-only HEAD >actual.files &&
267         git checkout HEAD directory &&
268         test_cmp expect.files actual.files &&
269         test_cmp hello directory/file1 &&
270         test_cmp hi directory/file2
271 '
272
273 test_expect_success PIPE 'branch name with backslash' '
274         reinit_git &&
275         sort <<-\EOF >expect.branch-files &&
276         trunk/file1
277         trunk/file2
278         "branches/UpdateFOPto094\\/file1"
279         "branches/UpdateFOPto094\\/file2"
280         EOF
281
282         echo hi >hi &&
283         echo hello >hello &&
284         {
285                 properties \
286                         svn:author author@example.com \
287                         svn:date "1999-02-02T00:01:02.000000Z" \
288                         svn:log "add directory with some files in it" &&
289                 echo PROPS-END
290         } >props.setup &&
291         {
292                 properties \
293                         svn:author brancher@example.com \
294                         svn:date "2007-12-06T21:38:34.000000Z" \
295                         svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
296                 echo PROPS-END
297         } >props.branch &&
298         {
299                 cat <<-EOF &&
300                 SVN-fs-dump-format-version: 3
301
302                 Revision-number: 1
303                 EOF
304                 echo Prop-content-length: $(wc -c <props.setup) &&
305                 echo Content-length: $(wc -c <props.setup) &&
306                 echo &&
307                 cat props.setup &&
308                 cat <<-\EOF &&
309
310                 Node-path: trunk
311                 Node-kind: dir
312                 Node-action: add
313                 Prop-content-length: 10
314                 Content-length: 10
315
316                 PROPS-END
317
318                 Node-path: branches
319                 Node-kind: dir
320                 Node-action: add
321                 Prop-content-length: 10
322                 Content-length: 10
323
324                 PROPS-END
325
326                 Node-path: trunk/file1
327                 Node-kind: file
328                 Node-action: add
329                 EOF
330                 text_no_props hello &&
331                 cat <<-\EOF &&
332                 Node-path: trunk/file2
333                 Node-kind: file
334                 Node-action: add
335                 EOF
336                 text_no_props hi &&
337                 cat <<-\EOF &&
338
339                 Revision-number: 2
340                 EOF
341                 echo Prop-content-length: $(wc -c <props.branch) &&
342                 echo Content-length: $(wc -c <props.branch) &&
343                 echo &&
344                 cat props.branch &&
345                 cat <<-\EOF
346
347                 Node-path: branches/UpdateFOPto094\
348                 Node-kind: dir
349                 Node-action: add
350                 Node-copyfrom-rev: 1
351                 Node-copyfrom-path: trunk
352
353                 Node-kind: dir
354                 Node-action: add
355                 Prop-content-length: 34
356                 Content-length: 34
357
358                 K 13
359                 svn:mergeinfo
360                 V 0
361
362                 PROPS-END
363                 EOF
364         } >branch.dump &&
365         try_dump branch.dump &&
366
367         git ls-tree -r --name-only HEAD |
368         sort >actual.branch-files &&
369         test_cmp expect.branch-files actual.branch-files
370 '
371
372 test_expect_success PIPE 'node without action' '
373         reinit_git &&
374         cat >inaction.dump <<-\EOF &&
375         SVN-fs-dump-format-version: 3
376
377         Revision-number: 1
378         Prop-content-length: 10
379         Content-length: 10
380
381         PROPS-END
382
383         Node-path: directory
384         Node-kind: dir
385         Prop-content-length: 10
386         Content-length: 10
387
388         PROPS-END
389         EOF
390         try_dump inaction.dump must_fail
391 '
392
393 test_expect_success PIPE 'action: add node without text' '
394         reinit_git &&
395         cat >textless.dump <<-\EOF &&
396         SVN-fs-dump-format-version: 3
397
398         Revision-number: 1
399         Prop-content-length: 10
400         Content-length: 10
401
402         PROPS-END
403
404         Node-path: textless
405         Node-kind: file
406         Node-action: add
407         Prop-content-length: 10
408         Content-length: 10
409
410         PROPS-END
411         EOF
412         try_dump textless.dump must_fail
413 '
414
415 test_expect_failure PIPE 'change file mode but keep old content' '
416         reinit_git &&
417         cat >expect <<-\EOF &&
418         OBJID
419         :120000 100644 OBJID OBJID T    greeting
420         OBJID
421         :100644 120000 OBJID OBJID T    greeting
422         OBJID
423         :000000 100644 OBJID OBJID A    greeting
424         EOF
425         echo "link hello" >expect.blob &&
426         echo hello >hello &&
427         cat >filemode.dump <<-\EOF &&
428         SVN-fs-dump-format-version: 3
429
430         Revision-number: 1
431         Prop-content-length: 10
432         Content-length: 10
433
434         PROPS-END
435
436         Node-path: greeting
437         Node-kind: file
438         Node-action: add
439         Prop-content-length: 10
440         Text-content-length: 11
441         Content-length: 21
442
443         PROPS-END
444         link hello
445
446         Revision-number: 2
447         Prop-content-length: 10
448         Content-length: 10
449
450         PROPS-END
451
452         Node-path: greeting
453         Node-kind: file
454         Node-action: change
455         Prop-content-length: 33
456         Content-length: 33
457
458         K 11
459         svn:special
460         V 1
461         *
462         PROPS-END
463
464         Revision-number: 3
465         Prop-content-length: 10
466         Content-length: 10
467
468         PROPS-END
469
470         Node-path: greeting
471         Node-kind: file
472         Node-action: change
473         Prop-content-length: 10
474         Content-length: 10
475
476         PROPS-END
477         EOF
478         try_dump filemode.dump &&
479         {
480                 git rev-list HEAD |
481                 git diff-tree --root --stdin |
482                 sed "s/$_x40/OBJID/g"
483         } >actual &&
484         git show HEAD:greeting >actual.blob &&
485         git show HEAD^:greeting >actual.target &&
486         test_cmp expect actual &&
487         test_cmp expect.blob actual.blob &&
488         test_cmp hello actual.target
489 '
490
491 test_expect_success PIPE 'change file mode and reiterate content' '
492         reinit_git &&
493         cat >expect <<-\EOF &&
494         OBJID
495         :120000 100644 OBJID OBJID T    greeting
496         OBJID
497         :100644 120000 OBJID OBJID T    greeting
498         OBJID
499         :000000 100644 OBJID OBJID A    greeting
500         EOF
501         echo "link hello" >expect.blob &&
502         echo hello >hello &&
503         cat >filemode2.dump <<-\EOF &&
504         SVN-fs-dump-format-version: 3
505
506         Revision-number: 1
507         Prop-content-length: 10
508         Content-length: 10
509
510         PROPS-END
511
512         Node-path: greeting
513         Node-kind: file
514         Node-action: add
515         Prop-content-length: 10
516         Text-content-length: 11
517         Content-length: 21
518
519         PROPS-END
520         link hello
521
522         Revision-number: 2
523         Prop-content-length: 10
524         Content-length: 10
525
526         PROPS-END
527
528         Node-path: greeting
529         Node-kind: file
530         Node-action: change
531         Prop-content-length: 33
532         Text-content-length: 11
533         Content-length: 44
534
535         K 11
536         svn:special
537         V 1
538         *
539         PROPS-END
540         link hello
541
542         Revision-number: 3
543         Prop-content-length: 10
544         Content-length: 10
545
546         PROPS-END
547
548         Node-path: greeting
549         Node-kind: file
550         Node-action: change
551         Prop-content-length: 10
552         Text-content-length: 11
553         Content-length: 21
554
555         PROPS-END
556         link hello
557         EOF
558         try_dump filemode2.dump &&
559         {
560                 git rev-list HEAD |
561                 git diff-tree --root --stdin |
562                 sed "s/$_x40/OBJID/g"
563         } >actual &&
564         git show HEAD:greeting >actual.blob &&
565         git show HEAD^:greeting >actual.target &&
566         test_cmp expect actual &&
567         test_cmp expect.blob actual.blob &&
568         test_cmp hello actual.target
569 '
570
571 test_expect_success PIPE 'deltas not supported' '
572         reinit_git &&
573         {
574                 # (old) h + (inline) ello + (old) \n
575                 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
576                 q_to_nul
577         } >delta &&
578         {
579                 properties \
580                         svn:author author@example.com \
581                         svn:date "1999-01-05T00:01:002.000000Z" \
582                         svn:log "add greeting" &&
583                 echo PROPS-END
584         } >props &&
585         {
586                 properties \
587                         svn:author author@example.com \
588                         svn:date "1999-01-06T00:01:002.000000Z" \
589                         svn:log "change it" &&
590                 echo PROPS-END
591         } >props2 &&
592         {
593                 echo SVN-fs-dump-format-version: 3 &&
594                 echo &&
595                 echo Revision-number: 1 &&
596                 echo Prop-content-length: $(wc -c <props) &&
597                 echo Content-length: $(wc -c <props) &&
598                 echo &&
599                 cat props &&
600                 cat <<-\EOF &&
601
602                 Node-path: hello
603                 Node-kind: file
604                 Node-action: add
605                 Prop-content-length: 10
606                 Text-content-length: 3
607                 Content-length: 13
608
609                 PROPS-END
610                 hi
611
612                 EOF
613                 echo Revision-number: 2 &&
614                 echo Prop-content-length: $(wc -c <props2) &&
615                 echo Content-length: $(wc -c <props2) &&
616                 echo &&
617                 cat props2 &&
618                 cat <<-\EOF &&
619
620                 Node-path: hello
621                 Node-kind: file
622                 Node-action: change
623                 Text-delta: true
624                 Prop-content-length: 10
625                 EOF
626                 echo Text-content-length: $(wc -c <delta) &&
627                 echo Content-length: $((10 + $(wc -c <delta))) &&
628                 echo &&
629                 echo PROPS-END &&
630                 cat delta
631         } >delta.dump &&
632         test_must_fail try_dump delta.dump
633 '
634
635 test_expect_success PIPE 'property deltas supported' '
636         reinit_git &&
637         cat >expect <<-\EOF &&
638         OBJID
639         :100755 100644 OBJID OBJID M    script.sh
640         EOF
641         {
642                 properties \
643                         svn:author author@example.com \
644                         svn:date "1999-03-06T00:01:002.000000Z" \
645                         svn:log "make an executable, or chmod -x it" &&
646                 echo PROPS-END
647         } >revprops &&
648         {
649                 echo SVN-fs-dump-format-version: 3 &&
650                 echo &&
651                 echo Revision-number: 1 &&
652                 echo Prop-content-length: $(wc -c <revprops) &&
653                 echo Content-length: $(wc -c <revprops) &&
654                 echo &&
655                 cat revprops &&
656                 echo &&
657                 cat <<-\EOF &&
658                 Node-path: script.sh
659                 Node-kind: file
660                 Node-action: add
661                 Text-content-length: 0
662                 Prop-content-length: 39
663                 Content-length: 39
664
665                 K 14
666                 svn:executable
667                 V 4
668                 true
669                 PROPS-END
670
671                 EOF
672                 echo Revision-number: 2 &&
673                 echo Prop-content-length: $(wc -c <revprops) &&
674                 echo Content-length: $(wc -c <revprops) &&
675                 echo &&
676                 cat revprops &&
677                 echo &&
678                 cat <<-\EOF
679                 Node-path: script.sh
680                 Node-kind: file
681                 Node-action: change
682                 Prop-delta: true
683                 Prop-content-length: 30
684                 Content-length: 30
685
686                 D 14
687                 svn:executable
688                 PROPS-END
689                 EOF
690         } >propdelta.dump &&
691         try_dump propdelta.dump &&
692         {
693                 git rev-list HEAD |
694                 git diff-tree --stdin |
695                 sed "s/$_x40/OBJID/g"
696         } >actual &&
697         test_cmp expect actual
698 '
699
700 test_expect_success PIPE 'properties on /' '
701         reinit_git &&
702         cat <<-\EOF >expect &&
703         OBJID
704         OBJID
705         :000000 100644 OBJID OBJID A    greeting
706         EOF
707         sed -e "s/X$//" <<-\EOF >changeroot.dump &&
708         SVN-fs-dump-format-version: 3
709
710         Revision-number: 1
711         Prop-content-length: 10
712         Content-length: 10
713
714         PROPS-END
715
716         Node-path: greeting
717         Node-kind: file
718         Node-action: add
719         Text-content-length: 0
720         Prop-content-length: 10
721         Content-length: 10
722
723         PROPS-END
724
725         Revision-number: 2
726         Prop-content-length: 10
727         Content-length: 10
728
729         PROPS-END
730
731         Node-path: X
732         Node-kind: dir
733         Node-action: change
734         Prop-delta: true
735         Prop-content-length: 43
736         Content-length: 43
737
738         K 10
739         svn:ignore
740         V 11
741         build-area
742
743         PROPS-END
744         EOF
745         try_dump changeroot.dump &&
746         {
747                 git rev-list HEAD |
748                 git diff-tree --root --always --stdin |
749                 sed "s/$_x40/OBJID/g"
750         } >actual &&
751         test_cmp expect actual
752 '
753
754 test_expect_success PIPE 'deltas for typechange' '
755         reinit_git &&
756         cat >expect <<-\EOF &&
757         OBJID
758         :120000 100644 OBJID OBJID T    test-file
759         OBJID
760         :100755 120000 OBJID OBJID T    test-file
761         OBJID
762         :000000 100755 OBJID OBJID A    test-file
763         EOF
764         cat >deleteprop.dump <<-\EOF &&
765         SVN-fs-dump-format-version: 3
766
767         Revision-number: 1
768         Prop-content-length: 10
769         Content-length: 10
770
771         PROPS-END
772
773         Node-path: test-file
774         Node-kind: file
775         Node-action: add
776         Prop-delta: true
777         Prop-content-length: 35
778         Text-content-length: 17
779         Content-length: 52
780
781         K 14
782         svn:executable
783         V 0
784
785         PROPS-END
786         link testing 123
787
788         Revision-number: 2
789         Prop-content-length: 10
790         Content-length: 10
791
792         PROPS-END
793
794         Node-path: test-file
795         Node-kind: file
796         Node-action: change
797         Prop-delta: true
798         Prop-content-length: 53
799         Text-content-length: 17
800         Content-length: 70
801
802         K 11
803         svn:special
804         V 1
805         *
806         D 14
807         svn:executable
808         PROPS-END
809         link testing 231
810
811         Revision-number: 3
812         Prop-content-length: 10
813         Content-length: 10
814
815         PROPS-END
816
817         Node-path: test-file
818         Node-kind: file
819         Node-action: change
820         Prop-delta: true
821         Prop-content-length: 27
822         Text-content-length: 17
823         Content-length: 44
824
825         D 11
826         svn:special
827         PROPS-END
828         link testing 321
829         EOF
830         try_dump deleteprop.dump &&
831         {
832                 git rev-list HEAD |
833                 git diff-tree --root --stdin |
834                 sed "s/$_x40/OBJID/g"
835         } >actual &&
836         test_cmp expect actual
837 '
838
839
840 test_expect_success 'set up svn repo' '
841         svnconf=$PWD/svnconf &&
842         mkdir -p "$svnconf" &&
843
844         if
845                 svnadmin -h >/dev/null 2>&1 &&
846                 svnadmin create simple-svn &&
847                 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
848                 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
849         then
850                 test_set_prereq SVNREPO
851         fi
852 '
853
854 test_expect_success SVNREPO,PIPE 't9135/svn.dump' '
855         mkdir -p simple-git &&
856         (
857                 cd simple-git &&
858                 reinit_git &&
859                 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
860         ) &&
861         (
862                 cd simple-svnco &&
863                 git init &&
864                 git add . &&
865                 git fetch ../simple-git master &&
866                 git diff --exit-code FETCH_HEAD
867         )
868 '
869
870 test_done