@matheusbsbs / matheus-bagliano / commits / 1f05d07c45
Fork 0

vcs-svn: Allow simple v3 dumps (no deltas yet)

Since the dumpfile version 1 days, the Subversion dump format gained some new fields: - a unique identifier for the repository (version 2 format) - whether the text and properties for a node should be interpreted as deltas - checksums for a delta's preimage - SHA-1 sums as alternatives to the existing MD5 checksums for copy source and the payload (delta). For now what is relevant to us is the Text-delta and Prop-delta fields, since not noticing these causes a dump file to be misinterpreted (see the previous commit). [jn: with tests] Signed-off-by: David Barr <david.barr@cordelta.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

David Barr committed Nov 17, 2010 at 23:03 UTC 1f05d07c456e23c0827efbbb3e738afc9f3152e7
2 files changed +365 -6
t/t9010-svn-fe.sh
+347 -3
@@ -9,6 +9,30 @@ reinit_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' '
@@ -18,13 +42,333 @@ test_expect_success 'empty dump' '
42 git fast-import <stream
43 '
44
21 -test_expect_success 'v3 dumps not supported' '
45 +test_expect_success 'v4 dumps not supported' '
46 reinit_git &&
23 - echo "SVN-fs-dump-format-version: 3" >input &&
24 - test_must_fail test-svn-fe input >stream &&
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 'deltas not supported' '
256 + {
257 + # (old) h + (inline) ello + (old) \n
258 + printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
259 + q_to_nul
260 + } >delta &&
261 + {
262 + properties \
263 + svn:author author@example.com \
264 + svn:date "1999-01-05T00:01:002.000000Z" \
265 + svn:log "add greeting" &&
266 + echo PROPS-END
267 + } >props &&
268 + {
269 + properties \
270 + svn:author author@example.com \
271 + svn:date "1999-01-06T00:01:002.000000Z" \
272 + svn:log "change it" &&
273 + echo PROPS-END
274 + } >props2 &&
275 + {
276 + echo SVN-fs-dump-format-version: 3 &&
277 + echo &&
278 + echo Revision-number: 1 &&
279 + echo Prop-content-length: $(wc -c <props) &&
280 + echo Content-length: $(wc -c <props) &&
281 + echo &&
282 + cat props &&
283 + cat <<-\EOF &&
284 +
285 + Node-path: hello
286 + Node-kind: file
287 + Node-action: add
288 + Prop-content-length: 10
289 + Text-content-length: 3
290 + Content-length: 13
291 +
292 + PROPS-END
293 + hi
294 +
295 + EOF
296 + echo Revision-number: 2 &&
297 + echo Prop-content-length: $(wc -c <props2) &&
298 + echo Content-length: $(wc -c <props2) &&
299 + echo &&
300 + cat props2 &&
301 + cat <<-\EOF &&
302 +
303 + Node-path: hello
304 + Node-kind: file
305 + Node-action: change
306 + Text-delta: true
307 + Prop-content-length: 10
308 + EOF
309 + echo Text-content-length: $(wc -c <delta) &&
310 + echo Content-length: $((10 + $(wc -c <delta))) &&
311 + echo &&
312 + echo PROPS-END &&
313 + cat delta
314 + } >delta.dump &&
315 + test_must_fail test-svn-fe delta.dump
316 +'
317 +
318 +test_expect_success 'property deltas not supported' '
319 + {
320 + properties \
321 + svn:author author@example.com \
322 + svn:date "1999-03-06T00:01:002.000000Z" \
323 + svn:log "make an executable, or chmod -x it" &&
324 + echo PROPS-END
325 + } >revprops &&
326 + {
327 + echo SVN-fs-dump-format-version: 3 &&
328 + echo &&
329 + echo Revision-number: 1 &&
330 + echo Prop-content-length: $(wc -c <revprops) &&
331 + echo Content-length: $(wc -c <revprops) &&
332 + echo &&
333 + cat revprops &&
334 + echo &&
335 + cat <<-\EOF &&
336 + Node-path: script.sh
337 + Node-kind: file
338 + Node-action: add
339 + Text-content-length: 0
340 + Prop-content-length: 39
341 + Content-length: 39
342 +
343 + K 14
344 + svn:executable
345 + V 4
346 + true
347 + PROPS-END
348 +
349 + EOF
350 + echo Revision-number: 2 &&
351 + echo Prop-content-length: $(wc -c <revprops) &&
352 + echo Content-length: $(wc -c <revprops) &&
353 + echo &&
354 + cat revprops &&
355 + echo &&
356 + cat <<-\EOF
357 + Node-path: script.sh
358 + Node-kind: file
359 + Node-action: change
360 + Prop-delta: true
361 + Prop-content-length: 30
362 + Content-length: 30
363 +
364 + D 14
365 + svn:executable
366 + PROPS-END
367 + EOF
368 + } >propdelta.dump &&
369 + test_must_fail test-svn-fe propdelta.dump
370 +'
371 +
372 test_expect_success 't9135/svn.dump' '
373 svnadmin create simple-svn &&
374 svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
vcs-svn/svndump.c
+18 -3
@@ -42,6 +42,7 @@ static char* log_copy(uint32_t length, char *log)
42 static struct {
43 uint32_t action, propLength, textLength, srcRev, srcMode, mark, type;
44 uint32_t src[REPO_MAX_PATH_DEPTH], dst[REPO_MAX_PATH_DEPTH];
45 + uint32_t text_delta, prop_delta;
46 } node_ctx;
47
48 static struct {
@@ -58,7 +59,9 @@ static struct {
59 uint32_t svn_log, svn_author, svn_date, svn_executable, svn_special, uuid,
60 revision_number, node_path, node_kind, node_action,
61 node_copyfrom_path, node_copyfrom_rev, text_content_length,
61 - prop_content_length, content_length, svn_fs_dump_format_version;
62 + prop_content_length, content_length, svn_fs_dump_format_version,
63 + /* version 3 format */
64 + text_delta, prop_delta;
65 } keys;
66
67 static void reset_node_ctx(char *fname)
@@ -72,6 +75,8 @@ static void reset_node_ctx(char *fname)
75 node_ctx.srcMode = 0;
76 pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.dst, "/", fname);
77 node_ctx.mark = 0;
78 + node_ctx.text_delta = 0;
79 + node_ctx.prop_delta = 0;
80 }
81
82 static void reset_rev_ctx(uint32_t revision)
@@ -107,6 +112,9 @@ static void init_keys(void)
112 keys.prop_content_length = pool_intern("Prop-content-length");
113 keys.content_length = pool_intern("Content-length");
114 keys.svn_fs_dump_format_version = pool_intern("SVN-fs-dump-format-version");
115 + /* version 3 format (Subversion 1.1.0) */
116 + keys.text_delta = pool_intern("Text-delta");
117 + keys.prop_delta = pool_intern("Prop-delta");
118 }
119
120 static void read_props(void)
@@ -144,6 +152,9 @@ static void read_props(void)
152
153 static void handle_node(void)
154 {
155 + if (node_ctx.text_delta || node_ctx.prop_delta)
156 + die("text and property deltas not supported");
157 +
158 if (node_ctx.propLength != LENGTH_UNKNOWN && node_ctx.propLength)
159 read_props();
160
@@ -210,8 +221,8 @@ void svndump_read(const char *url)
221
222 if (key == keys.svn_fs_dump_format_version) {
223 dump_ctx.version = atoi(val);
213 - if (dump_ctx.version > 2)
214 - die("expected svn dump format version <= 2, found %d",
224 + if (dump_ctx.version > 3)
225 + die("expected svn dump format version <= 3, found %d",
226 dump_ctx.version);
227 } else if (key == keys.uuid) {
228 dump_ctx.uuid = pool_intern(val);
@@ -255,6 +266,10 @@ void svndump_read(const char *url)
266 node_ctx.textLength = atoi(val);
267 } else if (key == keys.prop_content_length) {
268 node_ctx.propLength = atoi(val);
269 + } else if (key == keys.text_delta) {
270 + node_ctx.text_delta = !strcmp(val, "true");
271 + } else if (key == keys.prop_delta) {
272 + node_ctx.prop_delta = !strcmp(val, "true");
273 } else if (key == keys.content_length) {
274 len = atoi(val);
275 buffer_read_line();