diff options
Diffstat (limited to 'vcs-svn')
-rw-r--r-- | vcs-svn/fast_export.c | 47 | ||||
-rw-r--r-- | vcs-svn/fast_export.h | 9 | ||||
-rw-r--r-- | vcs-svn/line_buffer.c | 4 | ||||
-rw-r--r-- | vcs-svn/line_buffer.h | 1 | ||||
-rw-r--r-- | vcs-svn/sliding_window.c | 2 | ||||
-rw-r--r-- | vcs-svn/svndiff.c | 15 | ||||
-rw-r--r-- | vcs-svn/svndump.c | 98 | ||||
-rw-r--r-- | vcs-svn/svndump.h | 3 |
8 files changed, 117 insertions, 62 deletions
diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index b823b8519c..f2b23c81de 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -3,8 +3,7 @@ * See LICENSE for details. */ -#include "git-compat-util.h" -#include "strbuf.h" +#include "cache.h" #include "quote.h" #include "fast_export.h" #include "repo_tree.h" @@ -42,11 +41,6 @@ void fast_export_deinit(void) die_errno("error closing fast-import feedback stream"); } -void fast_export_reset(void) -{ - buffer_reset(&report_buffer); -} - void fast_export_delete(const char *path) { putchar('D'); @@ -73,11 +67,33 @@ void fast_export_modify(const char *path, uint32_t mode, const char *dataref) putchar('\n'); } +void fast_export_begin_note(uint32_t revision, const char *author, + const char *log, unsigned long timestamp, const char *note_ref) +{ + static int firstnote = 1; + size_t loglen = strlen(log); + printf("commit %s\n", note_ref); + printf("committer %s <%s@%s> %ld +0000\n", author, author, "local", timestamp); + printf("data %"PRIuMAX"\n", (uintmax_t)loglen); + fwrite(log, loglen, 1, stdout); + if (firstnote) { + if (revision > 1) + printf("from %s^0", note_ref); + firstnote = 0; + } + fputc('\n', stdout); +} + +void fast_export_note(const char *committish, const char *dataref) +{ + printf("N %s %s\n", dataref, committish); +} + static char gitsvnline[MAX_GITSVN_LINE_LEN]; void fast_export_begin_commit(uint32_t revision, const char *author, const struct strbuf *log, const char *uuid, const char *url, - unsigned long timestamp) + unsigned long timestamp, const char *local_ref) { static const struct strbuf empty = STRBUF_INIT; if (!log) @@ -89,7 +105,7 @@ void fast_export_begin_commit(uint32_t revision, const char *author, } else { *gitsvnline = '\0'; } - printf("commit refs/heads/master\n"); + printf("commit %s\n", local_ref); printf("mark :%"PRIu32"\n", revision); printf("committer %s <%s@%s> %ld +0000\n", *author ? author : "nobody", @@ -163,7 +179,7 @@ static int parse_cat_response_line(const char *header, off_t *len) if (ends_with(header, headerlen, " missing")) return error("cat-blob reports missing blob: %s", header); - type = memmem(header, headerlen, " blob ", strlen(" blob ")); + type = strstr(header, " blob "); if (!type) return error("cat-blob header has wrong object type: %s", header); n = strtoumax(type + strlen(" blob "), (char **) &end, 10); @@ -227,6 +243,13 @@ static long apply_delta(off_t len, struct line_buffer *input, return ret; } +void fast_export_buf_to_data(const struct strbuf *data) +{ + printf("data %"PRIuMAX"\n", (uintmax_t)data->len); + fwrite(data->buf, data->len, 1, stdout); + fputc('\n', stdout); +} + void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input) { assert(len >= 0); @@ -259,7 +282,7 @@ static int parse_ls_response(const char *response, uint32_t *mode, } /* Mode. */ - if (response_end - response < strlen("100644") || + if (response_end - response < (signed) strlen("100644") || response[strlen("100644")] != ' ') die("invalid ls response: missing mode: %s", response); *mode = 0; @@ -272,7 +295,7 @@ static int parse_ls_response(const char *response, uint32_t *mode, } /* ' blob ' or ' tree ' */ - if (response_end - response < strlen(" blob ") || + if (response_end - response < (signed) strlen(" blob ") || (response[1] != 'b' && response[1] != 't')) die("unexpected ls response: not a tree or blob: %s", response); response += strlen(" blob "); diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index aa629f54ff..c8b5adb811 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -6,15 +6,18 @@ struct line_buffer; void fast_export_init(int fd); void fast_export_deinit(void); -void fast_export_reset(void); void fast_export_delete(const char *path); void fast_export_modify(const char *path, uint32_t mode, const char *dataref); +void fast_export_note(const char *committish, const char *dataref); +void fast_export_begin_note(uint32_t revision, const char *author, + const char *log, unsigned long timestamp, const char *note_ref); void fast_export_begin_commit(uint32_t revision, const char *author, - const struct strbuf *log, const char *uuid, - const char *url, unsigned long timestamp); + const struct strbuf *log, const char *uuid,const char *url, + unsigned long timestamp, const char *local_ref); void fast_export_end_commit(uint32_t revision); void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input); +void fast_export_buf_to_data(const struct strbuf *data); void fast_export_blob_delta(uint32_t mode, uint32_t old_mode, const char *old_data, off_t len, struct line_buffer *input); diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 01fcb842f1..57cc1cec03 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -124,7 +124,3 @@ off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes) } return done; } - -void buffer_reset(struct line_buffer *buf) -{ -} diff --git a/vcs-svn/line_buffer.h b/vcs-svn/line_buffer.h index 8901f214ba..ee23b4f490 100644 --- a/vcs-svn/line_buffer.h +++ b/vcs-svn/line_buffer.h @@ -14,7 +14,6 @@ struct line_buffer { int buffer_init(struct line_buffer *buf, const char *filename); int buffer_fdinit(struct line_buffer *buf, int fd); int buffer_deinit(struct line_buffer *buf); -void buffer_reset(struct line_buffer *buf); int buffer_tmpfile_init(struct line_buffer *buf); FILE *buffer_tmpfile_rewind(struct line_buffer *buf); /* prepare to write. */ diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c index ec2707c9c4..f11d490995 100644 --- a/vcs-svn/sliding_window.c +++ b/vcs-svn/sliding_window.c @@ -54,7 +54,7 @@ int move_window(struct sliding_view *view, off_t off, size_t width) return -1; if (off < view->off || off + width < view->off + view->width) return error("invalid delta: window slides left"); - if (view->max_off >= 0 && view->max_off < off + width) + if (view->max_off >= 0 && view->max_off < off + (off_t) width) return error("delta preimage ends early"); file_offset = view->off + view->buf.len; diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index 1647c1a780..74c97c4543 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -77,8 +77,9 @@ static int error_short_read(struct line_buffer *input) static int read_chunk(struct line_buffer *delta, off_t *delta_len, struct strbuf *buf, size_t len) { + assert(*delta_len >= 0); strbuf_reset(buf); - if (len > *delta_len || + if (len > (uintmax_t) *delta_len || buffer_read_binary(delta, buf, len) != len) return error_short_read(delta); *delta_len -= buf->len; @@ -258,6 +259,7 @@ static int apply_window_in_core(struct window *ctx) static int apply_one_window(struct line_buffer *delta, off_t *delta_len, struct sliding_view *preimage, FILE *out) { + int rv = -1; struct window ctx = WINDOW_INIT(preimage); size_t out_len; size_t instructions_len; @@ -275,27 +277,26 @@ static int apply_one_window(struct line_buffer *delta, off_t *delta_len, if (apply_window_in_core(&ctx)) goto error_out; if (ctx.out.len != out_len) { - error("invalid delta: incorrect postimage length"); + rv = error("invalid delta: incorrect postimage length"); goto error_out; } if (write_strbuf(&ctx.out, out)) goto error_out; - window_release(&ctx); - return 0; + rv = 0; error_out: window_release(&ctx); - return -1; + return rv; } int svndiff0_apply(struct line_buffer *delta, off_t delta_len, struct sliding_view *preimage, FILE *postimage) { - assert(delta && preimage && postimage); + assert(delta && preimage && postimage && delta_len >= 0); if (read_magic(delta, &delta_len)) return -1; while (delta_len) { /* For each window: */ - off_t pre_off = pre_off; /* stupid GCC... */ + off_t pre_off = -1; size_t pre_len; if (read_offset(delta, &pre_off, &delta_len) || diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 0899790a33..31d1d83d45 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -34,14 +34,13 @@ #define NODE_CTX 2 /* node metadata */ #define INTERNODE_CTX 3 /* between nodes */ -#define LENGTH_UNKNOWN (~0) #define DATE_RFC2822_LEN 31 static struct line_buffer input = LINE_BUFFER_INIT; static struct { - uint32_t action, propLength, srcRev, type; - off_t text_length; + uint32_t action, srcRev, type; + off_t prop_length, text_length; struct strbuf src, dst; uint32_t text_delta, prop_delta; } node_ctx; @@ -49,7 +48,7 @@ static struct { static struct { uint32_t revision; unsigned long timestamp; - struct strbuf log, author; + struct strbuf log, author, note; } rev_ctx; static struct { @@ -61,7 +60,7 @@ static void reset_node_ctx(char *fname) { node_ctx.type = 0; node_ctx.action = NODEACT_UNKNOWN; - node_ctx.propLength = LENGTH_UNKNOWN; + node_ctx.prop_length = -1; node_ctx.text_length = -1; strbuf_reset(&node_ctx.src); node_ctx.srcRev = 0; @@ -78,6 +77,7 @@ static void reset_rev_ctx(uint32_t revision) rev_ctx.timestamp = 0; strbuf_reset(&rev_ctx.log); strbuf_reset(&rev_ctx.author); + strbuf_reset(&rev_ctx.note); } static void reset_dump_ctx(const char *url) @@ -209,7 +209,7 @@ static void read_props(void) static void handle_node(void) { const uint32_t type = node_ctx.type; - const int have_props = node_ctx.propLength != LENGTH_UNKNOWN; + const int have_props = node_ctx.prop_length != -1; const int have_text = node_ctx.text_length != -1; /* * Old text for this node: @@ -273,7 +273,7 @@ static void handle_node(void) if (have_props) { if (!node_ctx.prop_delta) node_ctx.type = type; - if (node_ctx.propLength) + if (node_ctx.prop_length) read_props(); } @@ -300,22 +300,29 @@ static void handle_node(void) node_ctx.text_length, &input); } -static void begin_revision(void) +static void begin_revision(const char *remote_ref) { if (!rev_ctx.revision) /* revision 0 gets no git commit. */ return; fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf, &rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf, - rev_ctx.timestamp); + rev_ctx.timestamp, remote_ref); } -static void end_revision(void) +static void end_revision(const char *note_ref) { - if (rev_ctx.revision) + struct strbuf mark = STRBUF_INIT; + if (rev_ctx.revision) { fast_export_end_commit(rev_ctx.revision); + fast_export_begin_note(rev_ctx.revision, "remote-svn", + "Note created by remote-svn.", rev_ctx.timestamp, note_ref); + strbuf_addf(&mark, ":%"PRIu32, rev_ctx.revision); + fast_export_note(mark.buf, "inline"); + fast_export_buf_to_data(&rev_ctx.note); + } } -void svndump_read(const char *url) +void svndump_read(const char *url, const char *local_ref, const char *notes_ref) { char *val; char *t; @@ -354,26 +361,29 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); if (active_ctx != DUMP_CTX) - end_revision(); + end_revision(notes_ref); active_ctx = REV_CTX; reset_rev_ctx(atoi(val)); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Node-path"): - if (prefixcmp(t, "Node-")) + if (constcmp(t, "Node-")) continue; if (!constcmp(t + strlen("Node-"), "path")) { if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); active_ctx = NODE_CTX; reset_node_ctx(val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; } if (constcmp(t + strlen("Node-"), "kind")) continue; + strbuf_addf(&rev_ctx.note, "%s\n", t); if (!strcmp(val, "dir")) node_ctx.type = REPO_MODE_DIR; else if (!strcmp(val, "file")) @@ -384,6 +394,7 @@ void svndump_read(const char *url) case sizeof("Node-action"): if (constcmp(t, "Node-action")) continue; + strbuf_addf(&rev_ctx.note, "%s\n", t); if (!strcmp(val, "delete")) { node_ctx.action = NODEACT_DELETE; } else if (!strcmp(val, "add")) { @@ -402,29 +413,35 @@ void svndump_read(const char *url) continue; strbuf_reset(&node_ctx.src); strbuf_addstr(&node_ctx.src, val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Node-copyfrom-rev"): if (constcmp(t, "Node-copyfrom-rev")) continue; node_ctx.srcRev = atoi(val); + strbuf_addf(&rev_ctx.note, "%s\n", t); break; case sizeof("Text-content-length"): - if (!constcmp(t, "Text-content-length")) { + if (constcmp(t, "Text") && constcmp(t, "Prop")) + continue; + if (constcmp(t + 4, "-content-length")) + continue; + { char *end; - uintmax_t textlen; + uintmax_t len; - textlen = strtoumax(val, &end, 10); + len = strtoumax(val, &end, 10); if (!isdigit(*val) || *end) die("invalid dump: non-numeric length %s", val); - if (textlen > maximum_signed_value_of_type(off_t)) + if (len > maximum_signed_value_of_type(off_t)) die("unrepresentable length in dump: %s", val); - node_ctx.text_length = (off_t) textlen; + + if (*t == 'T') + node_ctx.text_length = (off_t) len; + else + node_ctx.prop_length = (off_t) len; break; } - if (constcmp(t, "Prop-content-length")) - continue; - node_ctx.propLength = atoi(val); - break; case sizeof("Text-delta"): if (!constcmp(t, "Text-delta")) { node_ctx.text_delta = !strcmp(val, "true"); @@ -460,25 +477,40 @@ void svndump_read(const char *url) if (active_ctx == NODE_CTX) handle_node(); if (active_ctx == REV_CTX) - begin_revision(); + begin_revision(local_ref); if (active_ctx != DUMP_CTX) - end_revision(); + end_revision(notes_ref); } -int svndump_init(const char *filename) +static void init(int report_fd) { - if (buffer_init(&input, filename)) - return error("cannot open %s: %s", filename, strerror(errno)); - fast_export_init(REPORT_FILENO); + fast_export_init(report_fd); strbuf_init(&dump_ctx.uuid, 4096); strbuf_init(&dump_ctx.url, 4096); strbuf_init(&rev_ctx.log, 4096); strbuf_init(&rev_ctx.author, 4096); + strbuf_init(&rev_ctx.note, 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); + return; +} + +int svndump_init(const char *filename) +{ + if (buffer_init(&input, filename)) + return error("cannot open %s: %s", filename ? filename : "NULL", strerror(errno)); + init(REPORT_FILENO); + return 0; +} + +int svndump_init_fd(int in_fd, int back_fd) +{ + if(buffer_fdinit(&input, xdup(in_fd))) + return error("cannot open fd %d: %s", in_fd, strerror(errno)); + init(xdup(back_fd)); return 0; } @@ -489,6 +521,8 @@ void svndump_deinit(void) reset_rev_ctx(0); reset_node_ctx(NULL); strbuf_release(&rev_ctx.log); + strbuf_release(&rev_ctx.author); + strbuf_release(&rev_ctx.note); strbuf_release(&node_ctx.src); strbuf_release(&node_ctx.dst); if (buffer_deinit(&input)) @@ -499,8 +533,6 @@ void svndump_deinit(void) void svndump_reset(void) { - fast_export_reset(); - buffer_reset(&input); strbuf_release(&dump_ctx.uuid); strbuf_release(&dump_ctx.url); strbuf_release(&rev_ctx.log); diff --git a/vcs-svn/svndump.h b/vcs-svn/svndump.h index df9ceb0e8d..b8eb12954e 100644 --- a/vcs-svn/svndump.h +++ b/vcs-svn/svndump.h @@ -2,7 +2,8 @@ #define SVNDUMP_H_ int svndump_init(const char *filename); -void svndump_read(const char *url); +int svndump_init_fd(int in_fd, int back_fd); +void svndump_read(const char *url, const char *local_ref, const char *notes_ref); void svndump_deinit(void); void svndump_reset(void); |