Move fast-export blob printer to repo_tree.
[svn-fe.git] / svndump.c
blobc051c8c9a2ec5cbf3ea1848baee1bdcc7d39c69d
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>.
8 * All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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
16 * copyright notices.
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
20 * distribution.
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
42 #include <stdint.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <time.h>
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 */
58 #define NODEACT_ADD 1
60 /* node was modified */
61 #define NODEACT_CHANGE 0
63 /* unknown action */
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;
72 return mark++;
75 /* read a modified file (node) within a revision */
76 static void svnnode_read(char *fname)
78 int type = 0;
79 int action = NODEACT_UNKNOWN;
80 int propLength = -1;
81 int textLength = -1;
82 char *src = NULL;
83 int srcRev = 0;
84 uint32_t srcMode;
85 char *dst = strdup(fname);
86 char *t;
87 int len;
88 char *key;
89 char *val;
90 uint32_t mark = 0;
92 fprintf(stderr, "Node path: %s\n", fname);
94 for (t = buffer_read_line();
95 t && *t;
96 t = buffer_read_line()) {
97 if (!strncmp(t, "Node-kind:", 10)) {
98 val = &t[11];
99 if (!strncasecmp(val, "dir", 3)) {
100 type = REPO_MODE_DIR;
101 } else if (!strncasecmp(val, "file", 4)) {
102 type = REPO_MODE_BLB;
103 } else {
104 fprintf(stderr, "Unknown node-kind: %s\n", val);
106 } else if (!strncmp(t, "Node-action", 11)) {
107 val = &t[13];
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;
120 else
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)) {
126 val = &t[19];
127 srcRev = atoi(val);
128 fprintf(stderr, "Node copy revision: %d\n", srcRev);
129 } else if (!strncmp(t, "Text-content-length:", 20)) {
130 val = &t[21];
131 textLength = atoi(val);
132 fprintf(stderr, "Text content length: %d\n", textLength);
133 } else if (!strncmp(t, "Prop-content-length:", 20)) {
134 val = &t[21];
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)) {
145 len = atoi(&t[2]);
146 key = buffer_read_string(len);
147 buffer_read_line();
148 } else if (!strncmp(t, "V ", 2)) {
149 len = atoi(&t[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);
162 key = "";
163 buffer_read_line();
168 if (src && srcRev) {
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) {
177 repo_delete(dst);
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) {
194 type = srcMode;
197 if(textLength == -1) textLength = 0;
199 if (mark) {
200 repo_copy_blob(type, mark, textLength);
201 } else {
202 buffer_skip_bytes(textLength);
206 /* create revision reading from stdin */
207 static void svnrev_read(uint32_t number)
209 struct tm tm;
210 time_t timestamp = 0;
211 char *descr = "";
212 char *author = "nobody";
213 char *date = "now";
214 char *t;
215 int len;
216 char *key = "";
217 char *val = "";
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)) {
225 len = atoi(&t[2]);
226 key = buffer_read_string(len);
227 buffer_read_line();
228 } else if (!strncmp(t, "V ", 2)) {
229 len = atoi(&t[2]);
230 val = buffer_read_string(len);
231 if (!strcmp(key, "svn:log")) {
232 descr = val;
233 fprintf(stderr, "Log: %s\n", descr);
234 } else if (!strcmp(key, "svn:author")) {
235 author = val;
236 fprintf(stderr, "Author: %s\n", author);
237 } else if (!strcmp(key, "svn:date")) {
238 date = val;
239 fprintf(stderr, "Date: %s\n", date);
240 strptime(date, "%FT%T", &tm);
241 timezone = 0;
242 tm.tm_isdst = 0;
243 timestamp = mktime(&tm);
245 key = "";
246 buffer_read_line();
250 for ( ;
251 t && strncmp(t, "Revision-number:", 16);
252 t = buffer_read_line()) {
253 if (!strncmp(t, "Node-path:", 10)) {
254 svnnode_read(&t[11]);
257 if (t)
258 buffer_push_line();
260 repo_commit(number, author, descr, uuid, url, timestamp);
263 /* create dump representation by importing dump file */
264 static void svndump_read(void)
266 char *t;
267 int revision;
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];
281 svndump_read();
282 return 0;