X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=vcs-svn%2Fsvndump.c;h=4fdfcbbc0d6ac01987229c99907367fa5bf38483;hb=1c7bb316169c700df0d1711555564f86c9cb9366;hp=630eeb53b7d75f71bdf91cbdf45f428d0a14eb35;hpb=e250c5914fd151caf228cbda6c30560c266bcfef;p=git.git diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 630eeb53b..4fdfcbbc0 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -40,8 +40,9 @@ static char* log_copy(uint32_t length, char *log) } static struct { - uint32_t action, propLength, textLength, srcRev, srcMode, mark, type; + uint32_t action, propLength, textLength, srcRev, type; uint32_t src[REPO_MAX_PATH_DEPTH], dst[REPO_MAX_PATH_DEPTH]; + uint32_t text_delta, prop_delta; } node_ctx; static struct { @@ -51,14 +52,16 @@ static struct { } rev_ctx; static struct { - uint32_t uuid, url; + uint32_t version, uuid, url; } dump_ctx; static struct { uint32_t svn_log, svn_author, svn_date, svn_executable, svn_special, uuid, revision_number, node_path, node_kind, node_action, node_copyfrom_path, node_copyfrom_rev, text_content_length, - prop_content_length, content_length; + prop_content_length, content_length, svn_fs_dump_format_version, + /* version 3 format */ + text_delta, prop_delta; } keys; static void reset_node_ctx(char *fname) @@ -69,9 +72,9 @@ static void reset_node_ctx(char *fname) node_ctx.textLength = LENGTH_UNKNOWN; node_ctx.src[0] = ~0; node_ctx.srcRev = 0; - node_ctx.srcMode = 0; pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.dst, "/", fname); - node_ctx.mark = 0; + node_ctx.text_delta = 0; + node_ctx.prop_delta = 0; } static void reset_rev_ctx(uint32_t revision) @@ -85,6 +88,7 @@ static void reset_rev_ctx(uint32_t revision) static void reset_dump_ctx(uint32_t url) { dump_ctx.url = url; + dump_ctx.version = 1; dump_ctx.uuid = ~0; } @@ -105,6 +109,10 @@ static void init_keys(void) keys.text_content_length = pool_intern("Text-content-length"); keys.prop_content_length = pool_intern("Prop-content-length"); keys.content_length = pool_intern("Content-length"); + keys.svn_fs_dump_format_version = pool_intern("SVN-fs-dump-format-version"); + /* version 3 format (Subversion 1.1.0) */ + keys.text_delta = pool_intern("Text-delta"); + keys.prop_delta = pool_intern("Prop-delta"); } static void read_props(void) @@ -142,44 +150,52 @@ static void read_props(void) static void handle_node(void) { - if (node_ctx.propLength != LENGTH_UNKNOWN && node_ctx.propLength) - read_props(); + uint32_t mark = 0; + const uint32_t type = node_ctx.type; + const int have_props = node_ctx.propLength != LENGTH_UNKNOWN; - if (node_ctx.srcRev) - node_ctx.srcMode = repo_copy(node_ctx.srcRev, node_ctx.src, node_ctx.dst); + if (node_ctx.text_delta || node_ctx.prop_delta) + die("text and property deltas not supported"); - if (node_ctx.textLength != LENGTH_UNKNOWN && - node_ctx.type != REPO_MODE_DIR) - node_ctx.mark = next_blob_mark(); + if (node_ctx.textLength != LENGTH_UNKNOWN) + mark = next_blob_mark(); if (node_ctx.action == NODEACT_DELETE) { + if (mark || have_props || node_ctx.srcRev) + die("invalid dump: deletion node has " + "copyfrom info, text, or properties"); + return repo_delete(node_ctx.dst); + } + + if (node_ctx.action == NODEACT_REPLACE) { repo_delete(node_ctx.dst); - } else if (node_ctx.action == NODEACT_CHANGE || - node_ctx.action == NODEACT_REPLACE) { - if (node_ctx.action == NODEACT_REPLACE && - node_ctx.type == REPO_MODE_DIR) - repo_replace(node_ctx.dst, node_ctx.mark); - else if (node_ctx.propLength != LENGTH_UNKNOWN) - repo_modify(node_ctx.dst, node_ctx.type, node_ctx.mark); - else if (node_ctx.textLength != LENGTH_UNKNOWN) - node_ctx.srcMode = repo_replace(node_ctx.dst, node_ctx.mark); - } else if (node_ctx.action == NODEACT_ADD) { - if (node_ctx.srcRev && node_ctx.propLength != LENGTH_UNKNOWN) - repo_modify(node_ctx.dst, node_ctx.type, node_ctx.mark); - else if (node_ctx.srcRev && node_ctx.textLength != LENGTH_UNKNOWN) - node_ctx.srcMode = repo_replace(node_ctx.dst, node_ctx.mark); - else if ((node_ctx.type == REPO_MODE_DIR && !node_ctx.srcRev) || - node_ctx.textLength != LENGTH_UNKNOWN) - repo_add(node_ctx.dst, node_ctx.type, node_ctx.mark); + node_ctx.action = NODEACT_ADD; + } + + if (node_ctx.srcRev) { + repo_copy(node_ctx.srcRev, node_ctx.src, node_ctx.dst); + node_ctx.action = NODEACT_CHANGE; } - if (node_ctx.propLength == LENGTH_UNKNOWN && node_ctx.srcMode) - node_ctx.type = node_ctx.srcMode; + if (mark && type == REPO_MODE_DIR) + die("invalid dump: directories cannot have text attached"); + + if (node_ctx.action == NODEACT_CHANGE) + node_ctx.type = repo_modify_path(node_ctx.dst, 0, mark); + else /* Node-action: add */ + repo_add(node_ctx.dst, type, mark); + + if (have_props) { + const uint32_t old_mode = node_ctx.type; + node_ctx.type = type; + if (node_ctx.propLength) + read_props(); + if (node_ctx.type != old_mode) + repo_modify_path(node_ctx.dst, node_ctx.type, mark); + } - if (node_ctx.mark) - fast_export_blob(node_ctx.type, node_ctx.mark, node_ctx.textLength); - else if (node_ctx.textLength != LENGTH_UNKNOWN) - buffer_skip_bytes(node_ctx.textLength); + if (mark) + fast_export_blob(node_ctx.type, mark, node_ctx.textLength); } static void handle_revision(void) @@ -206,7 +222,12 @@ void svndump_read(const char *url) *val++ = '\0'; key = pool_intern(t); - if (key == keys.uuid) { + if (key == keys.svn_fs_dump_format_version) { + dump_ctx.version = atoi(val); + if (dump_ctx.version > 3) + die("expected svn dump format version <= 3, found %d", + dump_ctx.version); + } else if (key == keys.uuid) { dump_ctx.uuid = pool_intern(val); } else if (key == keys.revision_number) { if (active_ctx == NODE_CTX) @@ -248,6 +269,10 @@ void svndump_read(const char *url) node_ctx.textLength = atoi(val); } else if (key == keys.prop_content_length) { node_ctx.propLength = atoi(val); + } else if (key == keys.text_delta) { + node_ctx.text_delta = !strcmp(val, "true"); + } else if (key == keys.prop_delta) { + node_ctx.prop_delta = !strcmp(val, "true"); } else if (key == keys.content_length) { len = atoi(val); buffer_read_line(); @@ -257,7 +282,7 @@ void svndump_read(const char *url) handle_node(); active_ctx = REV_CTX; } else { - fprintf(stderr, "Unexpected content length header: %d\n", len); + fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len); buffer_skip_bytes(len); } } @@ -268,14 +293,16 @@ void svndump_read(const char *url) handle_revision(); } -void svndump_init(const char *filename) +int svndump_init(const char *filename) { - buffer_init(filename); + if (buffer_init(filename)) + return error("cannot open %s: %s", filename, strerror(errno)); repo_init(); reset_dump_ctx(~0); reset_rev_ctx(0); reset_node_ctx(NULL); init_keys(); + return 0; } void svndump_deinit(void)