2ae5374de38a2a618713f93fd290f74bf1dff67f
1#!/bin/sh
2
3test_description='check svn dumpfile importer'
4
5. ./test-lib.sh
6
7reinit_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
19try_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
30properties () {
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
44text_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
56test_expect_success 'setup: have pipes?' '
57 rm -f frob &&
58 if mkfifo frob
59 then
60 test_set_prereq PIPE
61 fi
62'
63
64test_expect_success PIPE 'empty dump' '
65 reinit_git &&
66 echo "SVN-fs-dump-format-version: 2" >input &&
67 try_dump input
68'
69
70test_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
76test_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
96test_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
119test_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
153test_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
178test_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
220test_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
273test_expect_success PIPE 'node without action' '
274 reinit_git &&
275 cat >inaction.dump <<-\EOF &&
276 SVN-fs-dump-format-version: 3
277
278 Revision-number: 1
279 Prop-content-length: 10
280 Content-length: 10
281
282 PROPS-END
283
284 Node-path: directory
285 Node-kind: dir
286 Prop-content-length: 10
287 Content-length: 10
288
289 PROPS-END
290 EOF
291 try_dump inaction.dump must_fail
292'
293
294test_expect_success PIPE 'action: add node without text' '
295 reinit_git &&
296 cat >textless.dump <<-\EOF &&
297 SVN-fs-dump-format-version: 3
298
299 Revision-number: 1
300 Prop-content-length: 10
301 Content-length: 10
302
303 PROPS-END
304
305 Node-path: textless
306 Node-kind: file
307 Node-action: add
308 Prop-content-length: 10
309 Content-length: 10
310
311 PROPS-END
312 EOF
313 try_dump textless.dump must_fail
314'
315
316test_expect_failure PIPE 'change file mode but keep old content' '
317 reinit_git &&
318 cat >expect <<-\EOF &&
319 OBJID
320 :120000 100644 OBJID OBJID T greeting
321 OBJID
322 :100644 120000 OBJID OBJID T greeting
323 OBJID
324 :000000 100644 OBJID OBJID A greeting
325 EOF
326 echo "link hello" >expect.blob &&
327 echo hello >hello &&
328 cat >filemode.dump <<-\EOF &&
329 SVN-fs-dump-format-version: 3
330
331 Revision-number: 1
332 Prop-content-length: 10
333 Content-length: 10
334
335 PROPS-END
336
337 Node-path: greeting
338 Node-kind: file
339 Node-action: add
340 Prop-content-length: 10
341 Text-content-length: 11
342 Content-length: 21
343
344 PROPS-END
345 link hello
346
347 Revision-number: 2
348 Prop-content-length: 10
349 Content-length: 10
350
351 PROPS-END
352
353 Node-path: greeting
354 Node-kind: file
355 Node-action: change
356 Prop-content-length: 33
357 Content-length: 33
358
359 K 11
360 svn:special
361 V 1
362 *
363 PROPS-END
364
365 Revision-number: 3
366 Prop-content-length: 10
367 Content-length: 10
368
369 PROPS-END
370
371 Node-path: greeting
372 Node-kind: file
373 Node-action: change
374 Prop-content-length: 10
375 Content-length: 10
376
377 PROPS-END
378 EOF
379 try_dump filemode.dump &&
380 {
381 git rev-list HEAD |
382 git diff-tree --root --stdin |
383 sed "s/$_x40/OBJID/g"
384 } >actual &&
385 git show HEAD:greeting >actual.blob &&
386 git show HEAD^:greeting >actual.target &&
387 test_cmp expect actual &&
388 test_cmp expect.blob actual.blob &&
389 test_cmp hello actual.target
390'
391
392test_expect_success PIPE 'change file mode and reiterate content' '
393 reinit_git &&
394 cat >expect <<-\EOF &&
395 OBJID
396 :120000 100644 OBJID OBJID T greeting
397 OBJID
398 :100644 120000 OBJID OBJID T greeting
399 OBJID
400 :000000 100644 OBJID OBJID A greeting
401 EOF
402 echo "link hello" >expect.blob &&
403 echo hello >hello &&
404 cat >filemode2.dump <<-\EOF &&
405 SVN-fs-dump-format-version: 3
406
407 Revision-number: 1
408 Prop-content-length: 10
409 Content-length: 10
410
411 PROPS-END
412
413 Node-path: greeting
414 Node-kind: file
415 Node-action: add
416 Prop-content-length: 10
417 Text-content-length: 11
418 Content-length: 21
419
420 PROPS-END
421 link hello
422
423 Revision-number: 2
424 Prop-content-length: 10
425 Content-length: 10
426
427 PROPS-END
428
429 Node-path: greeting
430 Node-kind: file
431 Node-action: change
432 Prop-content-length: 33
433 Text-content-length: 11
434 Content-length: 44
435
436 K 11
437 svn:special
438 V 1
439 *
440 PROPS-END
441 link hello
442
443 Revision-number: 3
444 Prop-content-length: 10
445 Content-length: 10
446
447 PROPS-END
448
449 Node-path: greeting
450 Node-kind: file
451 Node-action: change
452 Prop-content-length: 10
453 Text-content-length: 11
454 Content-length: 21
455
456 PROPS-END
457 link hello
458 EOF
459 try_dump filemode2.dump &&
460 {
461 git rev-list HEAD |
462 git diff-tree --root --stdin |
463 sed "s/$_x40/OBJID/g"
464 } >actual &&
465 git show HEAD:greeting >actual.blob &&
466 git show HEAD^:greeting >actual.target &&
467 test_cmp expect actual &&
468 test_cmp expect.blob actual.blob &&
469 test_cmp hello actual.target
470'
471
472test_expect_success PIPE 'deltas not supported' '
473 reinit_git &&
474 {
475 # (old) h + (inline) ello + (old) \n
476 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
477 q_to_nul
478 } >delta &&
479 {
480 properties \
481 svn:author author@example.com \
482 svn:date "1999-01-05T00:01:002.000000Z" \
483 svn:log "add greeting" &&
484 echo PROPS-END
485 } >props &&
486 {
487 properties \
488 svn:author author@example.com \
489 svn:date "1999-01-06T00:01:002.000000Z" \
490 svn:log "change it" &&
491 echo PROPS-END
492 } >props2 &&
493 {
494 echo SVN-fs-dump-format-version: 3 &&
495 echo &&
496 echo Revision-number: 1 &&
497 echo Prop-content-length: $(wc -c <props) &&
498 echo Content-length: $(wc -c <props) &&
499 echo &&
500 cat props &&
501 cat <<-\EOF &&
502
503 Node-path: hello
504 Node-kind: file
505 Node-action: add
506 Prop-content-length: 10
507 Text-content-length: 3
508 Content-length: 13
509
510 PROPS-END
511 hi
512
513 EOF
514 echo Revision-number: 2 &&
515 echo Prop-content-length: $(wc -c <props2) &&
516 echo Content-length: $(wc -c <props2) &&
517 echo &&
518 cat props2 &&
519 cat <<-\EOF &&
520
521 Node-path: hello
522 Node-kind: file
523 Node-action: change
524 Text-delta: true
525 Prop-content-length: 10
526 EOF
527 echo Text-content-length: $(wc -c <delta) &&
528 echo Content-length: $((10 + $(wc -c <delta))) &&
529 echo &&
530 echo PROPS-END &&
531 cat delta
532 } >delta.dump &&
533 test_must_fail try_dump delta.dump
534'
535
536test_expect_success PIPE 'property deltas supported' '
537 reinit_git &&
538 cat >expect <<-\EOF &&
539 OBJID
540 :100755 100644 OBJID OBJID M script.sh
541 EOF
542 {
543 properties \
544 svn:author author@example.com \
545 svn:date "1999-03-06T00:01:002.000000Z" \
546 svn:log "make an executable, or chmod -x it" &&
547 echo PROPS-END
548 } >revprops &&
549 {
550 echo SVN-fs-dump-format-version: 3 &&
551 echo &&
552 echo Revision-number: 1 &&
553 echo Prop-content-length: $(wc -c <revprops) &&
554 echo Content-length: $(wc -c <revprops) &&
555 echo &&
556 cat revprops &&
557 echo &&
558 cat <<-\EOF &&
559 Node-path: script.sh
560 Node-kind: file
561 Node-action: add
562 Text-content-length: 0
563 Prop-content-length: 39
564 Content-length: 39
565
566 K 14
567 svn:executable
568 V 4
569 true
570 PROPS-END
571
572 EOF
573 echo Revision-number: 2 &&
574 echo Prop-content-length: $(wc -c <revprops) &&
575 echo Content-length: $(wc -c <revprops) &&
576 echo &&
577 cat revprops &&
578 echo &&
579 cat <<-\EOF
580 Node-path: script.sh
581 Node-kind: file
582 Node-action: change
583 Prop-delta: true
584 Prop-content-length: 30
585 Content-length: 30
586
587 D 14
588 svn:executable
589 PROPS-END
590 EOF
591 } >propdelta.dump &&
592 try_dump propdelta.dump &&
593 {
594 git rev-list HEAD |
595 git diff-tree --stdin |
596 sed "s/$_x40/OBJID/g"
597 } >actual &&
598 test_cmp expect actual
599'
600
601test_expect_success PIPE 'properties on /' '
602 reinit_git &&
603 cat <<-\EOF >expect &&
604 OBJID
605 OBJID
606 :000000 100644 OBJID OBJID A greeting
607 EOF
608 sed -e "s/X$//" <<-\EOF >changeroot.dump &&
609 SVN-fs-dump-format-version: 3
610
611 Revision-number: 1
612 Prop-content-length: 10
613 Content-length: 10
614
615 PROPS-END
616
617 Node-path: greeting
618 Node-kind: file
619 Node-action: add
620 Text-content-length: 0
621 Prop-content-length: 10
622 Content-length: 10
623
624 PROPS-END
625
626 Revision-number: 2
627 Prop-content-length: 10
628 Content-length: 10
629
630 PROPS-END
631
632 Node-path: X
633 Node-kind: dir
634 Node-action: change
635 Prop-delta: true
636 Prop-content-length: 43
637 Content-length: 43
638
639 K 10
640 svn:ignore
641 V 11
642 build-area
643
644 PROPS-END
645 EOF
646 try_dump changeroot.dump &&
647 {
648 git rev-list HEAD |
649 git diff-tree --root --always --stdin |
650 sed "s/$_x40/OBJID/g"
651 } >actual &&
652 test_cmp expect actual
653'
654
655test_expect_success PIPE 'deltas for typechange' '
656 reinit_git &&
657 cat >expect <<-\EOF &&
658 OBJID
659 :120000 100644 OBJID OBJID T test-file
660 OBJID
661 :100755 120000 OBJID OBJID T test-file
662 OBJID
663 :000000 100755 OBJID OBJID A test-file
664 EOF
665 cat >deleteprop.dump <<-\EOF &&
666 SVN-fs-dump-format-version: 3
667
668 Revision-number: 1
669 Prop-content-length: 10
670 Content-length: 10
671
672 PROPS-END
673
674 Node-path: test-file
675 Node-kind: file
676 Node-action: add
677 Prop-delta: true
678 Prop-content-length: 35
679 Text-content-length: 17
680 Content-length: 52
681
682 K 14
683 svn:executable
684 V 0
685
686 PROPS-END
687 link testing 123
688
689 Revision-number: 2
690 Prop-content-length: 10
691 Content-length: 10
692
693 PROPS-END
694
695 Node-path: test-file
696 Node-kind: file
697 Node-action: change
698 Prop-delta: true
699 Prop-content-length: 53
700 Text-content-length: 17
701 Content-length: 70
702
703 K 11
704 svn:special
705 V 1
706 *
707 D 14
708 svn:executable
709 PROPS-END
710 link testing 231
711
712 Revision-number: 3
713 Prop-content-length: 10
714 Content-length: 10
715
716 PROPS-END
717
718 Node-path: test-file
719 Node-kind: file
720 Node-action: change
721 Prop-delta: true
722 Prop-content-length: 27
723 Text-content-length: 17
724 Content-length: 44
725
726 D 11
727 svn:special
728 PROPS-END
729 link testing 321
730 EOF
731 try_dump deleteprop.dump &&
732 {
733 git rev-list HEAD |
734 git diff-tree --root --stdin |
735 sed "s/$_x40/OBJID/g"
736 } >actual &&
737 test_cmp expect actual
738'
739
740
741test_expect_success 'set up svn repo' '
742 svnconf=$PWD/svnconf &&
743 mkdir -p "$svnconf" &&
744
745 if
746 svnadmin -h >/dev/null 2>&1 &&
747 svnadmin create simple-svn &&
748 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
749 svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
750 then
751 test_set_prereq SVNREPO
752 fi
753'
754
755test_expect_success SVNREPO,PIPE 't9135/svn.dump' '
756 mkdir -p simple-git &&
757 (
758 cd simple-git &&
759 reinit_git &&
760 try_dump "$TEST_DIRECTORY/t9135/svn.dump"
761 ) &&
762 (
763 cd simple-svnco &&
764 git init &&
765 git add . &&
766 git fetch ../simple-git master &&
767 git diff --exit-code FETCH_HEAD
768 )
769'
770
771test_done