Merge branch 'so/submodule-no-update-first-time'
[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         rm -fr .git &&
9         git init
10 }
11
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 }
25
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 }
35
36 >empty
37
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 '
44
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 '
51
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
57
58         Revision-number: 1
59         Prop-content-length: 0
60         Content-length: 0
61
62         Revision-number: 2
63         Prop-content-length: 0
64         Content-length: 0
65
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 '
72
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
78
79         Revision-number: 1
80         Prop-content-length: 10
81         Content-length: 10
82
83         PROPS-END
84
85         Revision-number: 2
86         Prop-content-length: 10
87         Content-length: 10
88
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 '
96
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
102
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.
105
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
130 '
131
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
137
138         Revision-number: 1
139         Prop-content-length: 56
140         Content-length: 56
141
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
156 '
157
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
173
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
181
182                 Node-path: empty-file
183                 Node-kind: file
184                 Node-action: add
185                 Content-length: 0
186
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
199 '
200
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
216
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 &&
224
225                 Node-path: directory
226                 Node-kind: dir
227                 Node-action: add
228                 Prop-content-length: 10
229                 Content-length: 10
230
231                 PROPS-END
232
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 &&
247
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
253 '
254
255 test_expect_success 'node without action' '
256         cat >inaction.dump <<-\EOF &&
257         SVN-fs-dump-format-version: 3
258
259         Revision-number: 1
260         Prop-content-length: 10
261         Content-length: 10
262
263         PROPS-END
264
265         Node-path: directory
266         Node-kind: dir
267         Prop-content-length: 10
268         Content-length: 10
269
270         PROPS-END
271         EOF
272         test_must_fail test-svn-fe inaction.dump
273 '
274
275 test_expect_success 'action: add node without text' '
276         cat >textless.dump <<-\EOF &&
277         SVN-fs-dump-format-version: 3
278
279         Revision-number: 1
280         Prop-content-length: 10
281         Content-length: 10
282
283         PROPS-END
284
285         Node-path: textless
286         Node-kind: file
287         Node-action: add
288         Prop-content-length: 10
289         Content-length: 10
290
291         PROPS-END
292         EOF
293         test_must_fail test-svn-fe textless.dump
294 '
295
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
310
311         Revision-number: 1
312         Prop-content-length: 10
313         Content-length: 10
314
315         PROPS-END
316
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
323
324         PROPS-END
325         link hello
326
327         Revision-number: 2
328         Prop-content-length: 10
329         Content-length: 10
330
331         PROPS-END
332
333         Node-path: greeting
334         Node-kind: file
335         Node-action: change
336         Prop-content-length: 33
337         Content-length: 33
338
339         K 11
340         svn:special
341         V 1
342         *
343         PROPS-END
344
345         Revision-number: 3
346         Prop-content-length: 10
347         Content-length: 10
348
349         PROPS-END
350
351         Node-path: greeting
352         Node-kind: file
353         Node-action: change
354         Prop-content-length: 10
355         Content-length: 10
356
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
371 '
372
373 test_expect_success 'change file mode and reiterate content' '
374         reinit_git &&
375         cat >expect <<-\EOF &&
376         OBJID
377         :120000 100644 OBJID OBJID T    greeting
378         OBJID
379         :100644 120000 OBJID OBJID T    greeting
380         OBJID
381         :000000 100644 OBJID OBJID A    greeting
382         EOF
383         echo "link hello" >expect.blob &&
384         echo hello >hello &&
385         cat >filemode.dump <<-\EOF &&
386         SVN-fs-dump-format-version: 3
387
388         Revision-number: 1
389         Prop-content-length: 10
390         Content-length: 10
391
392         PROPS-END
393
394         Node-path: greeting
395         Node-kind: file
396         Node-action: add
397         Prop-content-length: 10
398         Text-content-length: 11
399         Content-length: 21
400
401         PROPS-END
402         link hello
403
404         Revision-number: 2
405         Prop-content-length: 10
406         Content-length: 10
407
408         PROPS-END
409
410         Node-path: greeting
411         Node-kind: file
412         Node-action: change
413         Prop-content-length: 33
414         Text-content-length: 11
415         Content-length: 44
416
417         K 11
418         svn:special
419         V 1
420         *
421         PROPS-END
422         link hello
423
424         Revision-number: 3
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: change
433         Prop-content-length: 10
434         Text-content-length: 11
435         Content-length: 21
436
437         PROPS-END
438         link hello
439         EOF
440         test-svn-fe filemode.dump >stream &&
441         git fast-import <stream &&
442         {
443                 git rev-list HEAD |
444                 git diff-tree --root --stdin |
445                 sed "s/$_x40/OBJID/g"
446         } >actual &&
447         git show HEAD:greeting >actual.blob &&
448         git show HEAD^:greeting >actual.target &&
449         test_cmp expect actual &&
450         test_cmp expect.blob actual.blob &&
451         test_cmp hello actual.target
452 '
453
454 test_expect_success 'deltas not supported' '
455         {
456                 # (old) h + (inline) ello + (old) \n
457                 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
458                 q_to_nul
459         } >delta &&
460         {
461                 properties \
462                         svn:author author@example.com \
463                         svn:date "1999-01-05T00:01:002.000000Z" \
464                         svn:log "add greeting" &&
465                 echo PROPS-END
466         } >props &&
467         {
468                 properties \
469                         svn:author author@example.com \
470                         svn:date "1999-01-06T00:01:002.000000Z" \
471                         svn:log "change it" &&
472                 echo PROPS-END
473         } >props2 &&
474         {
475                 echo SVN-fs-dump-format-version: 3 &&
476                 echo &&
477                 echo Revision-number: 1 &&
478                 echo Prop-content-length: $(wc -c <props) &&
479                 echo Content-length: $(wc -c <props) &&
480                 echo &&
481                 cat props &&
482                 cat <<-\EOF &&
483
484                 Node-path: hello
485                 Node-kind: file
486                 Node-action: add
487                 Prop-content-length: 10
488                 Text-content-length: 3
489                 Content-length: 13
490
491                 PROPS-END
492                 hi
493
494                 EOF
495                 echo Revision-number: 2 &&
496                 echo Prop-content-length: $(wc -c <props2) &&
497                 echo Content-length: $(wc -c <props2) &&
498                 echo &&
499                 cat props2 &&
500                 cat <<-\EOF &&
501
502                 Node-path: hello
503                 Node-kind: file
504                 Node-action: change
505                 Text-delta: true
506                 Prop-content-length: 10
507                 EOF
508                 echo Text-content-length: $(wc -c <delta) &&
509                 echo Content-length: $((10 + $(wc -c <delta))) &&
510                 echo &&
511                 echo PROPS-END &&
512                 cat delta
513         } >delta.dump &&
514         test_must_fail test-svn-fe delta.dump
515 '
516
517 test_expect_success 'property deltas supported' '
518         reinit_git &&
519         cat >expect <<-\EOF &&
520         OBJID
521         :100755 100644 OBJID OBJID M    script.sh
522         EOF
523         {
524                 properties \
525                         svn:author author@example.com \
526                         svn:date "1999-03-06T00:01:002.000000Z" \
527                         svn:log "make an executable, or chmod -x it" &&
528                 echo PROPS-END
529         } >revprops &&
530         {
531                 echo SVN-fs-dump-format-version: 3 &&
532                 echo &&
533                 echo Revision-number: 1 &&
534                 echo Prop-content-length: $(wc -c <revprops) &&
535                 echo Content-length: $(wc -c <revprops) &&
536                 echo &&
537                 cat revprops &&
538                 echo &&
539                 cat <<-\EOF &&
540                 Node-path: script.sh
541                 Node-kind: file
542                 Node-action: add
543                 Text-content-length: 0
544                 Prop-content-length: 39
545                 Content-length: 39
546
547                 K 14
548                 svn:executable
549                 V 4
550                 true
551                 PROPS-END
552
553                 EOF
554                 echo Revision-number: 2 &&
555                 echo Prop-content-length: $(wc -c <revprops) &&
556                 echo Content-length: $(wc -c <revprops) &&
557                 echo &&
558                 cat revprops &&
559                 echo &&
560                 cat <<-\EOF
561                 Node-path: script.sh
562                 Node-kind: file
563                 Node-action: change
564                 Prop-delta: true
565                 Prop-content-length: 30
566                 Content-length: 30
567
568                 D 14
569                 svn:executable
570                 PROPS-END
571                 EOF
572         } >propdelta.dump &&
573         test-svn-fe propdelta.dump >stream &&
574         git fast-import <stream &&
575         {
576                 git rev-list HEAD |
577                 git diff-tree --stdin |
578                 sed "s/$_x40/OBJID/g"
579         } >actual &&
580         test_cmp expect actual
581 '
582
583 test_expect_success 'properties on /' '
584         reinit_git &&
585         cat <<-\EOF >expect &&
586         OBJID
587         OBJID
588         :000000 100644 OBJID OBJID A    greeting
589         EOF
590         sed -e "s/X$//" <<-\EOF >changeroot.dump &&
591         SVN-fs-dump-format-version: 3
592
593         Revision-number: 1
594         Prop-content-length: 10
595         Content-length: 10
596
597         PROPS-END
598
599         Node-path: greeting
600         Node-kind: file
601         Node-action: add
602         Text-content-length: 0
603         Prop-content-length: 10
604         Content-length: 10
605
606         PROPS-END
607
608         Revision-number: 2
609         Prop-content-length: 10
610         Content-length: 10
611
612         PROPS-END
613
614         Node-path: X
615         Node-kind: dir
616         Node-action: change
617         Prop-delta: true
618         Prop-content-length: 43
619         Content-length: 43
620
621         K 10
622         svn:ignore
623         V 11
624         build-area
625
626         PROPS-END
627         EOF
628         test-svn-fe changeroot.dump >stream &&
629         git fast-import <stream &&
630         {
631                 git rev-list HEAD |
632                 git diff-tree --root --always --stdin |
633                 sed "s/$_x40/OBJID/g"
634         } >actual &&
635         test_cmp expect actual
636 '
637
638 test_expect_success 'deltas for typechange' '
639         reinit_git &&
640         cat >expect <<-\EOF &&
641         OBJID
642         :120000 100644 OBJID OBJID T    test-file
643         OBJID
644         :100755 120000 OBJID OBJID T    test-file
645         OBJID
646         :000000 100755 OBJID OBJID A    test-file
647         EOF
648         cat >deleteprop.dump <<-\EOF &&
649         SVN-fs-dump-format-version: 3
650
651         Revision-number: 1
652         Prop-content-length: 10
653         Content-length: 10
654
655         PROPS-END
656
657         Node-path: test-file
658         Node-kind: file
659         Node-action: add
660         Prop-delta: true
661         Prop-content-length: 35
662         Text-content-length: 17
663         Content-length: 52
664
665         K 14
666         svn:executable
667         V 0
668
669         PROPS-END
670         link testing 123
671
672         Revision-number: 2
673         Prop-content-length: 10
674         Content-length: 10
675
676         PROPS-END
677
678         Node-path: test-file
679         Node-kind: file
680         Node-action: change
681         Prop-delta: true
682         Prop-content-length: 53
683         Text-content-length: 17
684         Content-length: 70
685
686         K 11
687         svn:special
688         V 1
689         *
690         D 14
691         svn:executable
692         PROPS-END
693         link testing 231
694
695         Revision-number: 3
696         Prop-content-length: 10
697         Content-length: 10
698
699         PROPS-END
700
701         Node-path: test-file
702         Node-kind: file
703         Node-action: change
704         Prop-delta: true
705         Prop-content-length: 27
706         Text-content-length: 17
707         Content-length: 44
708
709         D 11
710         svn:special
711         PROPS-END
712         link testing 321
713         EOF
714         test-svn-fe deleteprop.dump >stream &&
715         git fast-import <stream &&
716         {
717                 git rev-list HEAD |
718                 git diff-tree --root --stdin |
719                 sed "s/$_x40/OBJID/g"
720         } >actual &&
721         test_cmp expect actual
722 '
723
724
725 test_expect_success 'set up svn repo' '
726         svnconf=$PWD/svnconf &&
727         mkdir -p "$svnconf" &&
728
729         if
730                 svnadmin -h >/dev/null 2>&1 &&
731                 svnadmin create simple-svn &&
732                 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
733                 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
734         then
735                 test_set_prereq SVNREPO
736         fi
737 '
738
739 test_expect_success SVNREPO 't9135/svn.dump' '
740         git init simple-git &&
741         test-svn-fe "$TEST_DIRECTORY/t9135/svn.dump" >simple.fe &&
742         (
743                 cd simple-git &&
744                 git fast-import <../simple.fe
745         ) &&
746         (
747                 cd simple-svnco &&
748                 git init &&
749                 git add . &&
750                 git fetch ../simple-git master &&
751                 git diff --exit-code FETCH_HEAD
752         )
753 '
754
755 test_done