1 /******************************************************************************
3 * Copyright (C) 2005 Stefan Hegny, hydrografix Consulting GmbH,
4 * Frankfurt/Main, Germany
5 * and others, see http://svn2cc.sarovar.org
7 * Copyright (C) 2010 David Barr <david.barr@cordelta.com>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice(s), this list of conditions and the following disclaimer
15 * unmodified other than the allowable addition of one or more
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice(s), this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 ******************************************************************************/
37 * Parse and rearrange a svnadmin dump.
38 * Create the dump with:
39 * svnadmin dump --incremental -r<startrev>:<endrev> <repository> >outfile
48 #include "repo_tree.h"
49 #include "line_buffer.h"
54 #define NODEACT_REPLACE 3
59 #define NODEACT_DELETE 2
62 * node was added or copied from other location
69 #define NODEACT_CHANGE 0
74 #define NODEACT_UNKNOWN -1
76 static uint32_t next_blob_mark(void)
78 static int32_t mark
= 1000000000;
83 * read a modified file (node) within a revision
85 static void svnnode_read(char *fname
)
88 int action
= NODEACT_UNKNOWN
;
94 char *dst
= strdup(fname
);
101 fprintf(stderr
, "Node path: %s\n", fname
);
103 for (t
= buffer_read_line();
105 t
= buffer_read_line()) {
106 if (!strncmp(t
, "Node-kind:", 10)) {
108 if (!strncasecmp(val
, "dir", 3)) {
109 type
= REPO_MODE_DIR
;
110 } else if (!strncasecmp(val
, "file", 4)) {
111 type
= REPO_MODE_BLB
;
113 fprintf(stderr
, "Unknown node-kind: %s\n", val
);
115 } else if (!strncmp(t
, "Node-action", 11)) {
117 if (!strncasecmp(val
, "delete", 6))
118 action
= NODEACT_DELETE
;
120 else if (!strncasecmp(val
, "add", 3))
121 action
= NODEACT_ADD
;
123 else if (!strncasecmp(val
, "change", 6))
124 action
= NODEACT_CHANGE
;
126 else if (!strncasecmp(val
, "replace", 6))
127 action
= NODEACT_REPLACE
;
130 action
= NODEACT_UNKNOWN
;
131 } else if (!strncmp(t
, "Node-copyfrom-path", 18)) {
132 src
= strdup(&t
[20]);
133 fprintf(stderr
, "Node copy path: %s\n", src
);
134 } else if (!strncmp(t
, "Node-copyfrom-rev", 17)) {
137 fprintf(stderr
, "Node copy revision: %d\n", srcRev
);
138 } else if (!strncmp(t
, "Text-content-length:", 20)) {
140 textLength
= atoi(val
);
141 fprintf(stderr
, "Text content length: %d\n", textLength
);
142 } else if (!strncmp(t
, "Prop-content-length:", 20)) {
144 propLength
= atoi(val
);
145 fprintf(stderr
, "Prop content length: %d\n", propLength
);
149 if (propLength
> 0) {
150 for (t
= buffer_read_line();
151 t
&& strncasecmp(t
, "PROPS-END", 9);
152 t
= buffer_read_line()) {
153 if (!strncmp(t
, "K ", 2)) {
155 key
= buffer_read_string(len
);
157 } else if (!strncmp(t
, "V ", 2)) {
159 val
= buffer_read_string(len
);
160 if (!strcmp(key
, "svn:executable")) {
161 if (type
== REPO_MODE_BLB
) {
162 type
= REPO_MODE_EXE
;
164 fprintf(stderr
, "Executable: %s\n", val
);
165 } else if (!strcmp(key
, "svn:special")) {
166 if (type
== REPO_MODE_BLB
) {
167 type
= REPO_MODE_LNK
;
169 fprintf(stderr
, "Special: %s\n", val
);
178 srcMode
= repo_copy(srcRev
, src
, dst
);
181 if (textLength
>= 0 && type
!= REPO_MODE_DIR
) {
182 mark
= next_blob_mark();
185 if (action
== NODEACT_DELETE
) {
187 } else if (action
== NODEACT_CHANGE
||
188 action
== NODEACT_REPLACE
) {
189 if (propLength
>= 0 && textLength
>= 0) {
190 repo_modify(dst
, type
, mark
);
191 } else if (textLength
>= 0) {
192 srcMode
= repo_replace(dst
, mark
);
194 } else if (action
== NODEACT_ADD
) {
195 if (src
&& srcRev
&& propLength
< 0 && textLength
>= 0) {
196 srcMode
= repo_replace(dst
, mark
);
197 } else if(type
== REPO_MODE_DIR
|| textLength
>= 0){
198 repo_add(dst
, type
, mark
);
202 if (propLength
< 0 && srcMode
) {
206 if(textLength
== -1) textLength
= 0;
209 if (type
== REPO_MODE_LNK
) {
210 /* svn symlink blobs start with "link " */
211 buffer_skip_bytes(5);
214 printf("blob\nmark :%d\ndata %d\n", mark
, textLength
);
215 buffer_copy_bytes(textLength
);
218 buffer_skip_bytes(textLength
);
222 static char *uuid
= NULL
;
223 static char *url
= NULL
;
227 * create revision reading from stdin
228 * param number revision number
230 static void svnrev_read(uint32_t number
)
233 time_t timestamp
= 0;
235 char *author
= "nobody";
242 fprintf(stderr
, "Revision: %d\n", number
);
244 for (t
= buffer_read_line();
245 t
&& strncasecmp(t
, "PROPS-END", 9);
246 t
= buffer_read_line()) {
247 if (!strncmp(t
, "K ", 2)) {
249 key
= buffer_read_string(len
);
251 } else if (!strncmp(t
, "V ", 2)) {
253 val
= buffer_read_string(len
);
254 if (!strcmp(key
, "svn:log")) {
256 fprintf(stderr
, "Log: %s\n", descr
);
257 } else if (!strcmp(key
, "svn:author")) {
259 fprintf(stderr
, "Author: %s\n", author
);
260 } else if (!strcmp(key
, "svn:date")) {
262 fprintf(stderr
, "Date: %s\n", date
);
263 strptime(date
, "%FT%T", &tm
);
266 timestamp
= mktime(&tm
);
274 t
&& strncmp(t
, "Revision-number:", 16);
275 t
= buffer_read_line()) {
276 if (!strncmp(t
, "Node-path:", 10)) {
277 svnnode_read(&t
[11]);
283 repo_commit(number
, author
, descr
, uuid
, url
, timestamp
);
287 * create dump representation by importing dump file
289 static void svndump_read(void)
293 for (t
= buffer_read_line(); t
; t
= buffer_read_line()) {
294 if (!strncmp(t
, "Revision-number:", 16)) {
295 revision
= atoi(&t
[17]);
296 svnrev_read(revision
);
297 } else if(!strncmp(t
, "UUID:", 5)) {
298 uuid
= strdup(&t
[6]);
303 int main(int argc
, char **argv
)
305 if (argc
> 1) url
= argv
[1];