Code

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