fast_export.c had logic to set up commit ref, author name, email, parent commit, import mark and git-svn-id: line based on both it's own state (current import batch history) and the arguments passed. Do separate the layers: make fast_export focus on producing the fast-import stream, applying the deltas but not on svn-fe specific logic. svndump now is responsible for choosing commit parents, marks, ref name. Making it possible to generate incremental streams, produce stream for several branches at a time, customize progress lines generation and adding new logic becomes easier. fast_export API changes: - make fast_export_begin_commit to be more intuitive by using a set of parameters closer to what gets written to fast-import. - rename fast_export_end_commit to fast_export_progress as it does only a progress line generation. fast_export_end_commit can be reintroduced once the need will arise. - git-svn-id line is now a caller concern. If it is needed, it should be simply appended to the log message. - author_name and author_email are now generated by the caller. - ref name to be updated with the commit is now a parameter rather than a fixed "refs/heads/master". The caller now may have to setup temporary buffers for author identity, ref names, etc. This is a small additional per-commit cost to arrange and/or copy them. Though, it's only per-commit rather that per-path and might be worth the gain in readablity. Signed-off-by: Dmitry Ivankov <divanorama@xxxxxxxxx> Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- vcs-svn/fast_export.c | 47 +++++++++++++---------------------------------- vcs-svn/fast_export.h | 8 ++++---- vcs-svn/svndump.c | 44 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/vcs-svn/fast_export.c b/vcs-svn/fast_export.c index 19d7c34..3dfccd2 100644 --- a/vcs-svn/fast_export.c +++ b/vcs-svn/fast_export.c @@ -13,9 +13,6 @@ #include "sliding_window.h" #include "line_buffer.h" -#define MAX_GITSVN_LINE_LEN 4096 - -static uint32_t first_commit_done; static struct line_buffer postimage = LINE_BUFFER_INIT; static struct line_buffer report_buffer = LINE_BUFFER_INIT; @@ -31,7 +28,6 @@ static int init_postimage(void) void fast_export_init(int fd) { - first_commit_done = 0; if (buffer_fdinit(&report_buffer, fd)) die_errno("cannot read from file descriptor %d", fd); } @@ -73,40 +69,23 @@ void fast_export_modify(const char *path, uint32_t mode, const char *dataref) putchar('\n'); } -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) +void fast_export_begin_commit(const char *ref, uint32_t mark, const char *from, + const char *author_name, const char *author_email, + const struct strbuf *log, unsigned long timestamp) { - static const struct strbuf empty = STRBUF_INIT; - if (!log) - log = ∅ - if (*uuid && *url) { - snprintf(gitsvnline, MAX_GITSVN_LINE_LEN, - "\n\ngit-svn-id: %s@%"PRIu32" %s\n", - url, revision, uuid); - } else { - *gitsvnline = '\0'; - } - printf("commit refs/heads/master\n"); - printf("mark :%"PRIu32"\n", revision); - printf("committer %s <%s@%s> %ld +0000\n", - *author ? author : "nobody", - *author ? author : "nobody", - *uuid ? uuid : "local", timestamp); - printf("data %"PRIuMAX"\n", - (uintmax_t) (log->len + strlen(gitsvnline))); + printf("commit %s\n", ref); + if (mark) + printf("mark :%"PRIu32"\n", mark); + printf("committer %s <%s> %ld +0000\n", + author_name, author_email, timestamp); + printf("data %"PRIuMAX"\n", (uintmax_t) log->len); fwrite(log->buf, log->len, 1, stdout); - printf("%s\n", gitsvnline); - if (!first_commit_done) { - if (revision > 1) - printf("from :%"PRIu32"\n", revision - 1); - first_commit_done = 1; - } + putchar('\n'); + if (from && *from) + printf("from %s\n", from); } -void fast_export_end_commit(uint32_t revision) +void fast_export_progress(uint32_t revision) { printf("progress Imported commit %"PRIu32".\n\n", revision); } diff --git a/vcs-svn/fast_export.h b/vcs-svn/fast_export.h index 43d05b6..bf58880 100644 --- a/vcs-svn/fast_export.h +++ b/vcs-svn/fast_export.h @@ -10,10 +10,10 @@ 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_begin_commit(uint32_t revision, const char *author, - const struct strbuf *log, const char *uuid, - const char *url, unsigned long timestamp); -void fast_export_end_commit(uint32_t revision); +void fast_export_begin_commit(const char *ref, uint32_t mark, const char *from, + const char *author_name, const char *author_email, + const struct strbuf *log, unsigned long timestamp); +void fast_export_progress(uint32_t revision); void fast_export_data(uint32_t mode, uint32_t len, struct line_buffer *input); void fast_export_blob_delta(uint32_t mode, uint32_t old_mode, const char *old_data, diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 5cdf6b8..28d84c9 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -37,6 +37,8 @@ #define LENGTH_UNKNOWN (~0) #define DATE_RFC2822_LEN 31 +#define MAX_GITSVN_LINE_LEN 4096 + static struct line_buffer input = LINE_BUFFER_INIT; static struct { @@ -54,6 +56,7 @@ static struct { static struct { uint32_t version; struct strbuf uuid, url; + int first_commit_done; } dump_ctx; static void reset_node_ctx(char *fname) @@ -86,6 +89,7 @@ static void reset_dump_ctx(const char *url) strbuf_addstr(&dump_ctx.url, url); dump_ctx.version = 1; strbuf_reset(&dump_ctx.uuid); + dump_ctx.first_commit_done = 0; } static void handle_property(const struct strbuf *key_buf, @@ -299,19 +303,49 @@ static void handle_node(void) node_ctx.textLength, &input); } +static void add_metadata_trailer(struct strbuf *buf) +{ + if (*dump_ctx.uuid.buf && *dump_ctx.url.buf) + strbuf_addf(buf, "\n\ngit-svn-id: %s@%"PRIu32" %s\n", + dump_ctx.url.buf, rev_ctx.revision, dump_ctx.uuid.buf); +} + static void begin_revision(void) { + static struct strbuf email; + const char *author; + uint32_t prev; + char buf[32]; + 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); + prev = dump_ctx.first_commit_done ? rev_ctx.revision - 1 : 0; + if (prev) + snprintf(buf, 32, ":%"PRIu32, prev); + else + *buf = 0; + author = *rev_ctx.author.buf ? rev_ctx.author.buf : "nobody"; + + strbuf_reset(&email); + strbuf_addstr(&email, author); + strbuf_addch(&email, '@'); + if (*dump_ctx.uuid.buf) + strbuf_addstr(&email, dump_ctx.uuid.buf); + else + strbuf_addstr(&email, "local"); + + add_metadata_trailer(&rev_ctx.log); + + fast_export_begin_commit("refs/heads/master", rev_ctx.revision, buf, + author, email.buf, &rev_ctx.log, rev_ctx.timestamp); } static void end_revision(void) { - if (rev_ctx.revision) - fast_export_end_commit(rev_ctx.revision); + if (rev_ctx.revision) { + fast_export_progress(rev_ctx.revision); + dump_ctx.first_commit_done = 1; + } } void svndump_read(void) -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html