vcs-svn: Replace = Delete + Add
[git] / t / t9010-svn-fe.sh
1 #!/bin/sh
2
3 test_description='check svn dumpfile importer'
4
5 . ./lib-git-svn.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_failure 'change file mode but keep old content' '
256         reinit_git &&
257         cat >expect <<-\EOF &&
258         OBJID
259         :120000 100644 OBJID OBJID T    greeting
260         OBJID
261         :100644 120000 OBJID OBJID T    greeting
262         OBJID
263         :000000 100644 OBJID OBJID A    greeting
264         EOF
265         echo "link hello" >expect.blob &&
266         echo hello >hello &&
267         cat >filemode.dump <<-\EOF &&
268         SVN-fs-dump-format-version: 3
269
270         Revision-number: 1
271         Prop-content-length: 10
272         Content-length: 10
273
274         PROPS-END
275
276         Node-path: greeting
277         Node-kind: file
278         Node-action: add
279         Prop-content-length: 10
280         Text-content-length: 11
281         Content-length: 21
282
283         PROPS-END
284         link hello
285
286         Revision-number: 2
287         Prop-content-length: 10
288         Content-length: 10
289
290         PROPS-END
291
292         Node-path: greeting
293         Node-kind: file
294         Node-action: change
295         Prop-content-length: 33
296         Content-length: 33
297
298         K 11
299         svn:special
300         V 1
301         *
302         PROPS-END
303
304         Revision-number: 3
305         Prop-content-length: 10
306         Content-length: 10
307
308         PROPS-END
309
310         Node-path: greeting
311         Node-kind: file
312         Node-action: change
313         Prop-content-length: 10
314         Content-length: 10
315
316         PROPS-END
317         EOF
318         test-svn-fe filemode.dump >stream &&
319         git fast-import <stream &&
320         {
321                 git rev-list HEAD |
322                 git diff-tree --root --stdin |
323                 sed "s/$_x40/OBJID/g"
324         } >actual &&
325         git show HEAD:greeting >actual.blob &&
326         git show HEAD^:greeting >actual.target &&
327         test_cmp expect actual &&
328         test_cmp expect.blob actual.blob &&
329         test_cmp hello actual.target
330 '
331
332 test_expect_success 'change file mode and reiterate content' '
333         reinit_git &&
334         cat >expect <<-\EOF &&
335         OBJID
336         :120000 100644 OBJID OBJID T    greeting
337         OBJID
338         :100644 120000 OBJID OBJID T    greeting
339         OBJID
340         :000000 100644 OBJID OBJID A    greeting
341         EOF
342         echo "link hello" >expect.blob &&
343         echo hello >hello &&
344         cat >filemode.dump <<-\EOF &&
345         SVN-fs-dump-format-version: 3
346
347         Revision-number: 1
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: add
356         Prop-content-length: 10
357         Text-content-length: 11
358         Content-length: 21
359
360         PROPS-END
361         link hello
362
363         Revision-number: 2
364         Prop-content-length: 10
365         Content-length: 10
366
367         PROPS-END
368
369         Node-path: greeting
370         Node-kind: file
371         Node-action: change
372         Prop-content-length: 33
373         Text-content-length: 11
374         Content-length: 44
375
376         K 11
377         svn:special
378         V 1
379         *
380         PROPS-END
381         link hello
382
383         Revision-number: 3
384         Prop-content-length: 10
385         Content-length: 10
386
387         PROPS-END
388
389         Node-path: greeting
390         Node-kind: file
391         Node-action: change
392         Prop-content-length: 10
393         Text-content-length: 11
394         Content-length: 21
395
396         PROPS-END
397         link hello
398         EOF
399         test-svn-fe filemode.dump >stream &&
400         git fast-import <stream &&
401         {
402                 git rev-list HEAD |
403                 git diff-tree --root --stdin |
404                 sed "s/$_x40/OBJID/g"
405         } >actual &&
406         git show HEAD:greeting >actual.blob &&
407         git show HEAD^:greeting >actual.target &&
408         test_cmp expect actual &&
409         test_cmp expect.blob actual.blob &&
410         test_cmp hello actual.target
411 '
412
413 test_expect_success 'deltas not supported' '
414         {
415                 # (old) h + (inline) ello + (old) \n
416                 printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
417                 q_to_nul
418         } >delta &&
419         {
420                 properties \
421                         svn:author author@example.com \
422                         svn:date "1999-01-05T00:01:002.000000Z" \
423                         svn:log "add greeting" &&
424                 echo PROPS-END
425         } >props &&
426         {
427                 properties \
428                         svn:author author@example.com \
429                         svn:date "1999-01-06T00:01:002.000000Z" \
430                         svn:log "change it" &&
431                 echo PROPS-END
432         } >props2 &&
433         {
434                 echo SVN-fs-dump-format-version: 3 &&
435                 echo &&
436                 echo Revision-number: 1 &&
437                 echo Prop-content-length: $(wc -c <props) &&
438                 echo Content-length: $(wc -c <props) &&
439                 echo &&
440                 cat props &&
441                 cat <<-\EOF &&
442
443                 Node-path: hello
444                 Node-kind: file
445                 Node-action: add
446                 Prop-content-length: 10
447                 Text-content-length: 3
448                 Content-length: 13
449
450                 PROPS-END
451                 hi
452
453                 EOF
454                 echo Revision-number: 2 &&
455                 echo Prop-content-length: $(wc -c <props2) &&
456                 echo Content-length: $(wc -c <props2) &&
457                 echo &&
458                 cat props2 &&
459                 cat <<-\EOF &&
460
461                 Node-path: hello
462                 Node-kind: file
463                 Node-action: change
464                 Text-delta: true
465                 Prop-content-length: 10
466                 EOF
467                 echo Text-content-length: $(wc -c <delta) &&
468                 echo Content-length: $((10 + $(wc -c <delta))) &&
469                 echo &&
470                 echo PROPS-END &&
471                 cat delta
472         } >delta.dump &&
473         test_must_fail test-svn-fe delta.dump
474 '
475
476 test_expect_success 'property deltas not supported' '
477         {
478                 properties \
479                         svn:author author@example.com \
480                         svn:date "1999-03-06T00:01:002.000000Z" \
481                         svn:log "make an executable, or chmod -x it" &&
482                 echo PROPS-END
483         } >revprops &&
484         {
485                 echo SVN-fs-dump-format-version: 3 &&
486                 echo &&
487                 echo Revision-number: 1 &&
488                 echo Prop-content-length: $(wc -c <revprops) &&
489                 echo Content-length: $(wc -c <revprops) &&
490                 echo &&
491                 cat revprops &&
492                 echo &&
493                 cat <<-\EOF &&
494                 Node-path: script.sh
495                 Node-kind: file
496                 Node-action: add
497                 Text-content-length: 0
498                 Prop-content-length: 39
499                 Content-length: 39
500
501                 K 14
502                 svn:executable
503                 V 4
504                 true
505                 PROPS-END
506
507                 EOF
508                 echo Revision-number: 2 &&
509                 echo Prop-content-length: $(wc -c <revprops) &&
510                 echo Content-length: $(wc -c <revprops) &&
511                 echo &&
512                 cat revprops &&
513                 echo &&
514                 cat <<-\EOF
515                 Node-path: script.sh
516                 Node-kind: file
517                 Node-action: change
518                 Prop-delta: true
519                 Prop-content-length: 30
520                 Content-length: 30
521
522                 D 14
523                 svn:executable
524                 PROPS-END
525                 EOF
526         } >propdelta.dump &&
527         test_must_fail test-svn-fe propdelta.dump
528 '
529
530 test_expect_success 't9135/svn.dump' '
531         svnadmin create simple-svn &&
532         svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
533         svn_cmd export "file://$PWD/simple-svn" simple-svnco &&
534         git init simple-git &&
535         test-svn-fe "$TEST_DIRECTORY/t9135/svn.dump" >simple.fe &&
536         (
537                 cd simple-git &&
538                 git fast-import <../simple.fe
539         ) &&
540         (
541                 cd simple-svnco &&
542                 git init &&
543                 git add . &&
544                 git fetch ../simple-git master &&
545                 git diff --exit-code FETCH_HEAD
546         )
547 '
548
549 test_done