From 030879718f696b67fe1c958ab0a238971773ac96 Mon Sep 17 00:00:00 2001 From: David Barr Date: Mon, 13 Dec 2010 16:41:12 +1100 Subject: [PATCH] vcs-svn: pass paths through to fast-import Now that there is no internal representation of the repo, it is not necessary to tokenise paths. Use strbuf instead and bypass string_pool. This means svn-fe can handle arbitrarily long paths (as long as a strbuf can fit them), with arbitrarily many path components. While at it, since we now treat paths in their entirety, only quote when necessary. Signed-off-by: David Barr Signed-off-by: Jonathan Nieder --- vcs-svn/fast_export.c | 48 ++++++++++++++++++++++++------------------------ vcs-svn/fast_export.h | 9 ++++----- vcs-svn/repo_tree.c | 20 ++++++++++---------- vcs-svn/repo_tree.h | 13 +++++-------- vcs-svn/svndump.c | 34 +++++++++++++++++++--------------- 5 files changed, 62 insertions(+), 62 deletions(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index a64a3c563..ec323e9b3 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -4,10 +4,11 @@ */ #include "git-compat-util.h" +#include "strbuf.h" +#include "quote.h" #include "fast_export.h" #include "line_buffer.h" #include "repo_tree.h" -#include "string_pool.h" #include "strbuf.h" #define MAX_GITSVN_LINE_LEN 4096 @@ -32,30 +33,30 @@ void fast_export_reset(void) buffer_reset(&report_buffer); } -void fast_export_delete(uint32_t depth, const uint32_t *path) +void fast_export_delete(const char *path) { - printf("D \""); - pool_print_seq_q(depth, path, '/', stdout); - printf("\"\n"); + putchar('D'); + putchar(' '); + quote_c_style(path, NULL, stdout, 0); + putchar('\n'); } -static void fast_export_truncate(uint32_t depth, const uint32_t *path, uint32_t mode) +static void fast_export_truncate(const char *path, uint32_t mode) { - fast_export_modify(depth, path, mode, "inline"); + fast_export_modify(path, mode, "inline"); printf("data 0\n\n"); } -void fast_export_modify(uint32_t depth, const uint32_t *path, uint32_t mode, - const char *dataref) +void fast_export_modify(const char *path, uint32_t mode, const char *dataref) { /* Mode must be 100644, 100755, 120000, or 160000. */ if (!dataref) { - fast_export_truncate(depth, path, mode); + fast_export_truncate(path, mode); return; } - printf("M %06"PRIo32" %s \"", mode, dataref); - pool_print_seq_q(depth, path, '/', stdout); - printf("\"\n"); + printf("M %06"PRIo32" %s ", mode, dataref); + quote_c_style(path, NULL, stdout, 0); + putchar('\n'); } static char gitsvnline[MAX_GITSVN_LINE_LEN]; @@ -93,20 +94,20 @@ void fast_export_end_commit(uint32_t revision) printf("progress Imported commit %"PRIu32".\n\n", revision); } -static void ls_from_rev(uint32_t rev, uint32_t depth, const uint32_t *path) +static void ls_from_rev(uint32_t rev, const char *path) { /* ls :5 path/to/old/file */ - printf("ls :%"PRIu32" \"", rev); - pool_print_seq_q(depth, path, '/', stdout); - printf("\"\n"); + printf("ls :%"PRIu32" ", rev); + quote_c_style(path, NULL, stdout, 0); + putchar('\n'); fflush(stdout); } -static void ls_from_active_commit(uint32_t depth, const uint32_t *path) +static void ls_from_active_commit(const char *path) { /* ls "path/to/file" */ printf("ls \""); - pool_print_seq_q(depth, path, '/', stdout); + quote_c_style(path, NULL, stdout, 1); printf("\"\n"); fflush(stdout); } @@ -183,16 +184,15 @@ static int parse_ls_response(const char *response, uint32_t *mode, return 0; } -int fast_export_ls_rev(uint32_t rev, uint32_t depth, const uint32_t *path, +int fast_export_ls_rev(uint32_t rev, const char *path, uint32_t *mode, struct strbuf *dataref) { - ls_from_rev(rev, depth, path); + ls_from_rev(rev, path); return parse_ls_response(get_response_line(), mode, dataref); } -int fast_export_ls(uint32_t depth, const uint32_t *path, - uint32_t *mode, struct strbuf *dataref) +int fast_export_ls(const char *path, uint32_t *mode, struct strbuf *dataref) { - ls_from_active_commit(depth, path); + ls_from_active_commit(path); return parse_ls_response(get_response_line(), mode, dataref); } diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index fc1424242..12b0bbb41 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -8,9 +8,8 @@ void fast_export_init(int fd); void fast_export_deinit(void); void fast_export_reset(void); -void fast_export_delete(uint32_t depth, const uint32_t *path); -void fast_export_modify(uint32_t depth, const uint32_t *path, - uint32_t mode, const char *dataref); +void fast_export_delete(const char *path); +void fast_export_modify(const char *path, uint32_t mode, const char *dataref); void fast_export_begin_commit(uint32_t revision, const char *author, char *log, const char *uuid, const char *url, unsigned long timestamp); @@ -18,9 +17,9 @@ void fast_export_end_commit(uint32_t revision); void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input); /* If there is no such file at that rev, returns -1, errno == ENOENT. */ -int fast_export_ls_rev(uint32_t rev, uint32_t depth, const uint32_t *path, +int fast_export_ls_rev(uint32_t rev, const char *path, uint32_t *mode_out, struct strbuf *dataref_out); -int fast_export_ls(uint32_t depth, const uint32_t *path, +int fast_export_ls(const char *path, uint32_t *mode_out, struct strbuf *dataref_out); #endif diff --git a/vcs-svn/repo_tree.c b/vcs-svn/repo_tree.c index e75f58087..f2466bc63 100644 --- a/vcs-svn/repo_tree.c +++ b/vcs-svn/repo_tree.c @@ -8,14 +8,14 @@ #include "repo_tree.h" #include "fast_export.h" -const char *repo_read_path(const uint32_t *path) +const char *repo_read_path(const char *path) { int err; uint32_t dummy; static struct strbuf buf = STRBUF_INIT; strbuf_reset(&buf); - err = fast_export_ls(REPO_MAX_PATH_DEPTH, path, &dummy, &buf); + err = fast_export_ls(path, &dummy, &buf); if (err) { if (errno != ENOENT) die_errno("BUG: unexpected fast_export_ls error"); @@ -24,14 +24,14 @@ const char *repo_read_path(const uint32_t *path) return buf.buf; } -uint32_t repo_read_mode(const uint32_t *path) +uint32_t repo_read_mode(const char *path) { int err; uint32_t result; static struct strbuf dummy = STRBUF_INIT; strbuf_reset(&dummy); - err = fast_export_ls(REPO_MAX_PATH_DEPTH, path, &result, &dummy); + err = fast_export_ls(path, &result, &dummy); if (err) { if (errno != ENOENT) die_errno("BUG: unexpected fast_export_ls error"); @@ -41,24 +41,24 @@ uint32_t repo_read_mode(const uint32_t *path) return result; } -void repo_copy(uint32_t revision, const uint32_t *src, const uint32_t *dst) +void repo_copy(uint32_t revision, const char *src, const char *dst) { int err; uint32_t mode; static struct strbuf data = STRBUF_INIT; strbuf_reset(&data); - err = fast_export_ls_rev(revision, REPO_MAX_PATH_DEPTH, src, &mode, &data); + err = fast_export_ls_rev(revision, src, &mode, &data); if (err) { if (errno != ENOENT) die_errno("BUG: unexpected fast_export_ls_rev error"); - fast_export_delete(REPO_MAX_PATH_DEPTH, dst); + fast_export_delete(dst); return; } - fast_export_modify(REPO_MAX_PATH_DEPTH, dst, mode, data.buf); + fast_export_modify(dst, mode, data.buf); } -void repo_delete(uint32_t *path) +void repo_delete(const char *path) { - fast_export_delete(REPO_MAX_PATH_DEPTH, path); + fast_export_delete(path); } diff --git a/vcs-svn/repo_tree.h b/vcs-svn/repo_tree.h index 29887f976..44e6e8fab 100644 --- a/vcs-svn/repo_tree.h +++ b/vcs-svn/repo_tree.h @@ -8,15 +8,12 @@ #define REPO_MODE_EXE 0100755 #define REPO_MODE_LNK 0120000 -#define REPO_MAX_PATH_LEN 4096 -#define REPO_MAX_PATH_DEPTH 1000 - uint32_t next_blob_mark(void); -void repo_copy(uint32_t revision, const uint32_t *src, const uint32_t *dst); -void repo_add(uint32_t *path, uint32_t mode, uint32_t blob_mark); -const char *repo_read_path(const uint32_t *path); -uint32_t repo_read_mode(const uint32_t *path); -void repo_delete(uint32_t *path); +void repo_copy(uint32_t revision, const char *src, const char *dst); +void repo_add(const char *path, uint32_t mode, uint32_t blob_mark); +const char *repo_read_path(const char *path); +uint32_t repo_read_mode(const char *path); +void repo_delete(const char *path); void repo_commit(uint32_t revision, const char *author, char *log, const char *uuid, const char *url, long unsigned timestamp); diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index f5de49cbe..363503d4e 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -11,7 +11,6 @@ #include "repo_tree.h" #include "fast_export.h" #include "line_buffer.h" -#include "string_pool.h" #include "strbuf.h" #define REPORT_FILENO 3 @@ -41,7 +40,7 @@ static struct line_buffer input = LINE_BUFFER_INIT; static struct { uint32_t action, propLength, textLength, srcRev, type; - uint32_t src[REPO_MAX_PATH_DEPTH], dst[REPO_MAX_PATH_DEPTH]; + struct strbuf src, dst; uint32_t text_delta, prop_delta; } node_ctx; @@ -62,9 +61,11 @@ static void reset_node_ctx(char *fname) node_ctx.action = NODEACT_UNKNOWN; node_ctx.propLength = LENGTH_UNKNOWN; node_ctx.textLength = LENGTH_UNKNOWN; - node_ctx.src[0] = ~0; + strbuf_reset(&node_ctx.src); node_ctx.srcRev = 0; - pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.dst, "/", fname); + strbuf_reset(&node_ctx.dst); + if (fname) + strbuf_addstr(&node_ctx.dst, fname); node_ctx.text_delta = 0; node_ctx.prop_delta = 0; } @@ -228,14 +229,14 @@ static void handle_node(void) if (have_text || have_props || node_ctx.srcRev) die("invalid dump: deletion node has " "copyfrom info, text, or properties"); - return repo_delete(node_ctx.dst); + return repo_delete(node_ctx.dst.buf); } if (node_ctx.action == NODEACT_REPLACE) { - repo_delete(node_ctx.dst); + repo_delete(node_ctx.dst.buf); node_ctx.action = NODEACT_ADD; } if (node_ctx.srcRev) { - repo_copy(node_ctx.srcRev, node_ctx.src, node_ctx.dst); + repo_copy(node_ctx.srcRev, node_ctx.src.buf, node_ctx.dst.buf); if (node_ctx.action == NODEACT_ADD) node_ctx.action = NODEACT_CHANGE; } @@ -245,14 +246,14 @@ static void handle_node(void) /* * Find old content (old_data) and decide on the new mode. */ - if (node_ctx.action == NODEACT_CHANGE && !~*node_ctx.dst) { + if (node_ctx.action == NODEACT_CHANGE && !*node_ctx.dst.buf) { if (type != REPO_MODE_DIR) die("invalid dump: root of tree is not a regular file"); old_data = NULL; } else if (node_ctx.action == NODEACT_CHANGE) { uint32_t mode; - old_data = repo_read_path(node_ctx.dst); - mode = repo_read_mode(node_ctx.dst); + old_data = repo_read_path(node_ctx.dst.buf); + mode = repo_read_mode(node_ctx.dst.buf); if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR) die("invalid dump: cannot modify a directory into a file"); if (mode != REPO_MODE_DIR && type == REPO_MODE_DIR) @@ -289,12 +290,10 @@ static void handle_node(void) /* For the fast_export_* functions, NULL means empty. */ old_data = NULL; if (!have_text) { - fast_export_modify(REPO_MAX_PATH_DEPTH, node_ctx.dst, - node_ctx.type, old_data); + fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data); return; } - fast_export_modify(REPO_MAX_PATH_DEPTH, node_ctx.dst, - node_ctx.type, "inline"); + fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline"); fast_export_data(node_ctx.type, node_ctx.textLength, &input); } @@ -395,7 +394,8 @@ void svndump_read(const char *url) case sizeof("Node-copyfrom-path"): if (constcmp(t, "Node-copyfrom-path")) continue; - pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.src, "/", val); + strbuf_reset(&node_ctx.src); + strbuf_addstr(&node_ctx.src, val); break; case sizeof("Node-copyfrom-rev"): if (constcmp(t, "Node-copyfrom-rev")) @@ -460,6 +460,8 @@ int svndump_init(const char *filename) strbuf_init(&dump_ctx.url, 4096); strbuf_init(&rev_ctx.log, 4096); strbuf_init(&rev_ctx.author, 4096); + strbuf_init(&node_ctx.src, 4096); + strbuf_init(&node_ctx.dst, 4096); reset_dump_ctx(NULL); reset_rev_ctx(0); reset_node_ctx(NULL); @@ -473,6 +475,8 @@ void svndump_deinit(void) reset_rev_ctx(0); reset_node_ctx(NULL); strbuf_release(&rev_ctx.log); + strbuf_release(&node_ctx.src); + strbuf_release(&node_ctx.dst); if (buffer_deinit(&input)) fprintf(stderr, "Input error\n"); if (ferror(stdout)) -- 2.11.0