Skip to content

Commit

Permalink
vcs-svn: pass paths through to fast-import
Browse files Browse the repository at this point in the history
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 <david.barr@cordelta.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
  • Loading branch information
David Barr authored and Jonathan Nieder committed Mar 22, 2011
1 parent fa6c4bc commit 0308797
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 62 deletions.
48 changes: 24 additions & 24 deletions vcs-svn/fast_export.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
9 changes: 4 additions & 5 deletions vcs-svn/fast_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ 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);
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
20 changes: 10 additions & 10 deletions vcs-svn/repo_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand All @@ -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);
}
13 changes: 5 additions & 8 deletions vcs-svn/repo_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
34 changes: 19 additions & 15 deletions vcs-svn/svndump.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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);
Expand All @@ -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))
Expand Down

0 comments on commit 0308797

Please sign in to comment.