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"
51 /* node was replaced */
52 #define NODEACT_REPLACE 3
54 /* node was deleted */
55 #define NODEACT_DELETE 2
57 /* node was added or copied from other location */
60 /* node was modified */
61 #define NODEACT_CHANGE 0
64 #define NODEACT_UNKNOWN -1
66 static char *uuid
= NULL
;
67 static char *url
= NULL
;
69 static uint32_t next_blob_mark(void)
71 static int32_t mark
= 1000000000;
75 /* read a modified file (node) within a revision */
76 static void svnnode_read(char *fname
)
79 int action
= NODEACT_UNKNOWN
;
85 char *dst
= strdup(fname
);
92 fprintf(stderr
, "Node path: %s\n", fname
);
94 for (t
= buffer_read_line();
96 t
= buffer_read_line()) {
97 if (!strncmp(t
, "Node-kind:", 10)) {
99 if (!strncasecmp(val
, "dir", 3)) {
100 type
= REPO_MODE_DIR
;
101 } else if (!strncasecmp(val
, "file", 4)) {
102 type
= REPO_MODE_BLB
;
104 fprintf(stderr
, "Unknown node-kind: %s\n", val
);
106 } else if (!strncmp(t
, "Node-action", 11)) {
108 if (!strncasecmp(val
, "delete", 6))
109 action
= NODEACT_DELETE
;
111 else if (!strncasecmp(val
, "add", 3))
112 action
= NODEACT_ADD
;
114 else if (!strncasecmp(val
, "change", 6))
115 action
= NODEACT_CHANGE
;
117 else if (!strncasecmp(val
, "replace", 6))
118 action
= NODEACT_REPLACE
;
121 action
= NODEACT_UNKNOWN
;
122 } else if (!strncmp(t
, "Node-copyfrom-path", 18)) {
123 src
= strdup(&t
[20]);
124 fprintf(stderr
, "Node copy path: %s\n", src
);
125 } else if (!strncmp(t
, "Node-copyfrom-rev", 17)) {
128 fprintf(stderr
, "Node copy revision: %d\n", srcRev
);
129 } else if (!strncmp(t
, "Text-content-length:", 20)) {
131 textLength
= atoi(val
);
132 fprintf(stderr
, "Text content length: %d\n", textLength
);
133 } else if (!strncmp(t
, "Prop-content-length:", 20)) {
135 propLength
= atoi(val
);
136 fprintf(stderr
, "Prop content length: %d\n", propLength
);
140 if (propLength
> 0) {
141 for (t
= buffer_read_line();
142 t
&& strncasecmp(t
, "PROPS-END", 9);
143 t
= buffer_read_line()) {
144 if (!strncmp(t
, "K ", 2)) {
146 key
= buffer_read_string(len
);
148 } else if (!strncmp(t
, "V ", 2)) {
150 val
= buffer_read_string(len
);
151 if (!strcmp(key
, "svn:executable")) {
152 if (type
== REPO_MODE_BLB
) {
153 type
= REPO_MODE_EXE
;
155 fprintf(stderr
, "Executable: %s\n", val
);
156 } else if (!strcmp(key
, "svn:special")) {
157 if (type
== REPO_MODE_BLB
) {
158 type
= REPO_MODE_LNK
;
160 fprintf(stderr
, "Special: %s\n", val
);
169 srcMode
= repo_copy(srcRev
, src
, dst
);
172 if (textLength
>= 0 && type
!= REPO_MODE_DIR
) {
173 mark
= next_blob_mark();
176 if (action
== NODEACT_DELETE
) {
178 } else if (action
== NODEACT_CHANGE
||
179 action
== NODEACT_REPLACE
) {
180 if (propLength
>= 0 && textLength
>= 0) {
181 repo_modify(dst
, type
, mark
);
182 } else if (textLength
>= 0) {
183 srcMode
= repo_replace(dst
, mark
);
185 } else if (action
== NODEACT_ADD
) {
186 if (src
&& srcRev
&& propLength
< 0 && textLength
>= 0) {
187 srcMode
= repo_replace(dst
, mark
);
188 } else if(type
== REPO_MODE_DIR
|| textLength
>= 0){
189 repo_add(dst
, type
, mark
);
193 if (propLength
< 0 && srcMode
) {
197 if(textLength
== -1) textLength
= 0;
200 repo_copy_blob(type
, mark
, textLength
);
202 buffer_skip_bytes(textLength
);
206 /* create revision reading from stdin */
207 static void svnrev_read(uint32_t number
)
210 time_t timestamp
= 0;
212 char *author
= "nobody";
219 fprintf(stderr
, "Revision: %d\n", number
);
221 for (t
= buffer_read_line();
222 t
&& strncasecmp(t
, "PROPS-END", 9);
223 t
= buffer_read_line()) {
224 if (!strncmp(t
, "K ", 2)) {
226 key
= buffer_read_string(len
);
228 } else if (!strncmp(t
, "V ", 2)) {
230 val
= buffer_read_string(len
);
231 if (!strcmp(key
, "svn:log")) {
233 fprintf(stderr
, "Log: %s\n", descr
);
234 } else if (!strcmp(key
, "svn:author")) {
236 fprintf(stderr
, "Author: %s\n", author
);
237 } else if (!strcmp(key
, "svn:date")) {
239 fprintf(stderr
, "Date: %s\n", date
);
240 strptime(date
, "%FT%T", &tm
);
243 timestamp
= mktime(&tm
);
251 t
&& strncmp(t
, "Revision-number:", 16);
252 t
= buffer_read_line()) {
253 if (!strncmp(t
, "Node-path:", 10)) {
254 svnnode_read(&t
[11]);
260 repo_commit(number
, author
, descr
, uuid
, url
, timestamp
);
263 /* create dump representation by importing dump file */
264 static void svndump_read(void)
268 for (t
= buffer_read_line(); t
; t
= buffer_read_line()) {
269 if (!strncmp(t
, "Revision-number:", 16)) {
270 revision
= atoi(&t
[17]);
271 svnrev_read(revision
);
272 } else if(!strncmp(t
, "UUID:", 5)) {
273 uuid
= strdup(&t
[6]);
278 int main(int argc
, char **argv
)
280 if (argc
> 1) url
= argv
[1];