All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ramkumar Ramachandra <artagnon@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: Jonathan Nieder <jrnieder@gmail.com>,
	David Barr <david.barr@cordelta.com>,
	Sverre Rabbelier <srabbelier@gmail.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 1/3] vcs-svn: Introduce svnload, a dumpfile producer
Date: Tue,  1 Feb 2011 19:56:41 +0530	[thread overview]
Message-ID: <1296570403-9082-2-git-send-email-artagnon@gmail.com> (raw)
In-Reply-To: <1296570403-9082-1-git-send-email-artagnon@gmail.com>

Design-wise, svnload resembles svndump. Include a Makefile rule to
build it into vcs-svn/lib.a.

Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 Makefile              |    4 +-
 vcs-svn/dir_cache.c   |   40 ++++++
 vcs-svn/dir_cache.h   |   12 ++
 vcs-svn/dump_export.c |  149 +++++++++++++++++++++++
 vcs-svn/dump_export.h |   33 +++++
 vcs-svn/svnload.c     |  322 +++++++++++++++++++++++++++++++++++++++++++++++++
 vcs-svn/svnload.h     |   10 ++
 7 files changed, 568 insertions(+), 2 deletions(-)
 create mode 100644 vcs-svn/dir_cache.c
 create mode 100644 vcs-svn/dir_cache.h
 create mode 100644 vcs-svn/dump_export.c
 create mode 100644 vcs-svn/dump_export.h
 create mode 100644 vcs-svn/svnload.c
 create mode 100644 vcs-svn/svnload.h

diff --git a/Makefile b/Makefile
index 1345c38..d9c2442 100644
--- a/Makefile
+++ b/Makefile
@@ -1834,9 +1834,9 @@ ifndef NO_CURL
 endif
 XDIFF_OBJS = xdiff/xdiffi.o xdiff/xprepare.o xdiff/xutils.o xdiff/xemit.o \
 	xdiff/xmerge.o xdiff/xpatience.o
-VCSSVN_OBJS = vcs-svn/line_buffer.o \
+VCSSVN_OBJS = vcs-svn/line_buffer.o vcs-svn/svnload.o vcs-svn/dump_export.o \
 	vcs-svn/repo_tree.o vcs-svn/fast_export.o vcs-svn/sliding_window.o \
-	vcs-svn/svndiff.o vcs-svn/svndump.o
+	vcs-svn/svndiff.o vcs-svn/svndump.o vcs-svn/dir_cache.o
 VCSSVN_TEST_OBJS = test-obj-pool.o \
 	test-line-buffer.o test-treap.o test-svn-fe.o
 OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
diff --git a/vcs-svn/dir_cache.c b/vcs-svn/dir_cache.c
new file mode 100644
index 0000000..9a608ce
--- /dev/null
+++ b/vcs-svn/dir_cache.c
@@ -0,0 +1,40 @@
+/*
+ * Licensed under a two-clause BSD-style license.
+ * See LICENSE for details.
+ */
+
+#include "git-compat-util.h"
+#include "string-list.h"
+#include "line_buffer.h"
+#include "dump_export.h"
+
+static struct string_list dirents = STRING_LIST_INIT_DUP;
+static struct string_list_item *dir = NULL;
+
+void dir_cache_add(const char *path, enum node_kind kind) {
+	dir = string_list_insert(&dirents, path);
+	dir->util = malloc(sizeof(enum node_kind));
+	*((enum node_kind *)(dir->util)) = kind;
+}
+
+void dir_cache_remove(const char *path) {
+	dir = string_list_lookup(&dirents, path);
+	if (dir)
+		*((enum node_kind *)(dir->util)) = NODE_KIND_UNKNOWN;
+}
+
+enum node_kind dir_cache_lookup(const char *path) {
+	dir = string_list_lookup(&dirents, path);
+	if (dir)
+		return *((enum node_kind *)(dir->util));
+	else
+		return NODE_KIND_UNKNOWN;
+}
+
+void dir_cache_init() {
+	return;
+}
+
+void dir_cache_deinit() {
+	string_list_clear(&dirents, 1);
+}
diff --git a/vcs-svn/dir_cache.h b/vcs-svn/dir_cache.h
new file mode 100644
index 0000000..43c3797
--- /dev/null
+++ b/vcs-svn/dir_cache.h
@@ -0,0 +1,12 @@
+#ifndef DIR_CACHE_H_
+#define DIR_CACHE_H_
+
+#include "dump_export.h"
+
+void dir_cache_add(const char *path, enum node_kind kind);
+void dir_cache_remove(const char *path);
+enum node_kind dir_cache_lookup(const char *path);
+void dir_cache_init();
+void dir_cache_deinit();
+
+#endif
diff --git a/vcs-svn/dump_export.c b/vcs-svn/dump_export.c
new file mode 100644
index 0000000..2b23f77
--- /dev/null
+++ b/vcs-svn/dump_export.c
@@ -0,0 +1,149 @@
+/*
+ * Licensed under a two-clause BSD-style license.
+ * See LICENSE for details.
+ */
+
+#include "git-compat-util.h"
+#include "strbuf.h"
+#include "line_buffer.h"
+#include "dump_export.h"
+#include "dir_cache.h"
+
+static struct strbuf props;
+
+void dump_export_begin_rev(int revision, const char *revprops,
+			int prop_len)
+{
+	printf("Revision-number: %d\n", revision);
+	printf("Prop-content-length: %d\n", prop_len);
+	printf("Content-length: %d\n\n", prop_len);
+	printf("%s\n", revprops);
+}
+
+void dump_export_node(const char *path, enum node_kind kind,
+		enum node_action action, unsigned long text_len,
+		unsigned long copyfrom_rev, const char *copyfrom_path)
+{
+	int dump_props = 1; /* Boolean */
+	strbuf_reset(&props);
+	printf("Node-path: %s\n", path);
+	switch (kind) {
+	case NODE_KIND_NORMAL:
+		printf("Node-kind: file\n");
+		break;
+	case NODE_KIND_EXECUTABLE:
+		printf("Node-kind: file\n");
+		strbuf_addf(&props, "K 14\nsvn:executable\nV 1\n*\n");
+		break;
+	case NODE_KIND_SYMLINK:
+		printf("Node-kind: file\n");
+		strbuf_addf(&props, "K 11\nsvn:special\nV 1\n*\n");
+		break;
+	case NODE_KIND_GITLINK:
+		printf("Node-kind: file\n");
+		break;
+	case NODE_KIND_DIR:
+		printf("Node-kind: dir\n");
+		break;
+	case NODE_KIND_SUBDIR:
+		die("Unsupported: subdirectory");
+	default:
+		break;
+	}
+	strbuf_add(&props, "PROPS-END\n", 10);
+
+	switch (action) {
+	case NODE_ACTION_CHANGE:
+		printf("Node-action: change\n");
+		break;
+	case NODE_ACTION_ADD:
+		printf("Node-action: add\n");
+		break;
+	case NODE_ACTION_REPLACE:
+		printf("Node-action: replace\n");
+		break;
+	case NODE_ACTION_DELETE:
+		printf("Node-action: delete\n");
+		dump_props = 0;
+		break;
+	default:
+		break;
+	}
+	if (copyfrom_rev != SVN_INVALID_REV) {
+		printf("Node-copyfrom-rev: %lu\n", copyfrom_rev);
+		printf("Node-copyfrom-path: %s\n", copyfrom_path);
+	}
+	if (dump_props) {
+		printf("Prop-delta: false\n");
+		printf("Prop-content-length: %lu\n", props.len);
+	}
+	if (text_len) {
+		printf("Text-delta: false\n");		
+		printf("Text-content-length: %lu\n", text_len);
+	}
+	if (text_len || dump_props) {
+		printf("Content-length: %lu\n\n", text_len + props.len);
+		printf("%s", props.buf);
+	}
+	if (!text_len)
+		printf("\n");
+}
+
+void dump_export_node_r(const char *path, enum node_kind kind,
+			enum node_action action, unsigned long text_len,
+			unsigned long copyfrom_rev, const char *copyfrom_path)
+{
+	char *start, *t;
+	start = (char *) path;
+
+	while ((t = strchr(start, '/'))) {
+			*t = '\0';
+			if (dir_cache_lookup(path) == NODE_KIND_UNKNOWN) {
+				dir_cache_add(path, NODE_KIND_NORMAL);
+				dump_export_node(path, NODE_KIND_DIR,
+						NODE_ACTION_ADD, 0,
+						SVN_INVALID_REV, NULL);
+			}
+			*t = '/';   /* Change it back */
+			start = t + 1;
+	}
+	switch (dir_cache_lookup(path)) {
+	case NODE_KIND_UNKNOWN:
+		action = NODE_ACTION_ADD;
+		break;
+	case NODE_KIND_SYMLINK:
+		dir_cache_remove(path);
+		dump_export_node(path, NODE_KIND_UNKNOWN,
+				NODE_ACTION_DELETE,
+				0, SVN_INVALID_REV, NULL);
+		action = NODE_ACTION_ADD;
+		break;
+	case NODE_KIND_DIR:
+		die("File was previously a directory?");
+		break;
+	case NODE_KIND_SUBDIR:
+		die("Subdirectories unsupported");
+		break;
+	default:
+		action = NODE_ACTION_CHANGE;
+		break;
+	}
+	dir_cache_add(path, kind);
+	dump_export_node(path, kind, action, text_len, copyfrom_rev, copyfrom_path);
+}
+
+void dump_export_text(struct line_buffer *data, off_t len)
+{
+	buffer_copy_bytes(data, len);
+}
+
+void dump_export_init()
+{
+	strbuf_init(&props, MAX_GITSVN_LINE_LEN);
+	printf("SVN-fs-dump-format-version: 3\n\n");
+}
+
+void dump_export_deinit()
+{
+	strbuf_release(&props);
+}
diff --git a/vcs-svn/dump_export.h b/vcs-svn/dump_export.h
new file mode 100644
index 0000000..e9f51a3
--- /dev/null
+++ b/vcs-svn/dump_export.h
@@ -0,0 +1,33 @@
+#ifndef DUMP_EXPORT_H_
+#define DUMP_EXPORT_H_
+
+#define MAX_GITSVN_LINE_LEN 4096
+#define SVN_INVALID_REV 0
+
+enum node_action {
+	NODE_ACTION_UNKNOWN,
+	NODE_ACTION_CHANGE,
+	NODE_ACTION_ADD,
+	NODE_ACTION_DELETE,
+	NODE_ACTION_REPLACE
+};
+
+enum node_kind {
+	NODE_KIND_UNKNOWN,       /* Missing node */
+	NODE_KIND_NORMAL,
+	NODE_KIND_EXECUTABLE,
+	NODE_KIND_SYMLINK,
+	NODE_KIND_GITLINK,
+	NODE_KIND_DIR,           /* SVN-specific */
+	NODE_KIND_SUBDIR
+};
+
+void dump_export_begin_rev(int revision, const char *revprops, int prop_len);
+void dump_export_text(struct line_buffer *data, off_t len);
+void dump_export_node_r(const char *path, enum node_kind kind,
+			enum node_action action, unsigned long text_len,
+			unsigned long copyfrom_rev, const char *copyfrom_path);
+void dump_export_init();
+void dump_export_deinit();
+
+#endif
diff --git a/vcs-svn/svnload.c b/vcs-svn/svnload.c
new file mode 100644
index 0000000..40fc1db
--- /dev/null
+++ b/vcs-svn/svnload.c
@@ -0,0 +1,322 @@
+/*
+ * Produce a dumpfile v3 from a fast-import stream.
+ * Load the dump into the SVN repository with:
+ * svnrdump load <URL> <dumpfile
+ *
+ * Licensed under a two-clause BSD-style license.
+ * See LICENSE for details.
+ */
+
+#include "cache.h"
+#include "git-compat-util.h"
+#include "line_buffer.h"
+#include "dump_export.h"
+#include "dir_cache.h"
+
+#define SVN_DATE_FORMAT "%Y-%m-%dT%H:%M:%S.000000Z"
+#define SVN_DATE_LEN 27
+#define LENGTH_UNKNOWN (~0)
+
+static struct line_buffer input = LINE_BUFFER_INIT;
+
+static struct {
+	unsigned long prop_len, text_len, copyfrom_rev;
+	int text_delta, prop_delta; /* false=0, true=1, unknown=-1 */
+	enum node_action action;
+	enum node_kind kind;
+	struct strbuf copyfrom_path, path;
+} node_ctx;
+
+static struct {
+	int rev, text_len;
+	struct strbuf props, log;
+	struct strbuf svn_author, author, committer;
+	struct strbuf author_date, committer_date;
+	struct strbuf author_email, committer_email;
+} rev_ctx;
+
+static enum {
+	UNKNOWN_CTX,
+	COMMIT_CTX,
+	BLOB_CTX
+} active_ctx;
+
+static void populate_revprops(struct strbuf *props, size_t author_len,
+			const char *author, size_t log_len, const char *log,
+			size_t date_len, const char *date)
+{
+	strbuf_reset(props);
+	strbuf_addf(props, "K 10\nsvn:author\nV %lu\n%s\n", author_len, author);
+	strbuf_addf(props, "K 7\nsvn:log\nV %lu\n%s\n", log_len, log);
+	if (date_len)
+		/* SVN doesn't like an empty svn:date value */
+		strbuf_addf(props, "K 8\nsvn:date\nV %lu\n%s\n", date_len, date);
+	strbuf_add(props, "PROPS-END\n", 10);
+}
+
+static void parse_author_line(char *val, struct strbuf *name,
+			struct strbuf *email, struct strbuf *date)
+{
+	char *t, *tz_off;
+	char time_buf[SVN_DATE_LEN + 1];
+	int tz_off_buf;
+	const struct tm *tm_time;
+
+	/* Author Name <author@email.com> 1170199019 +0530 */
+	strbuf_reset(name);
+	strbuf_reset(email);
+	strbuf_reset(date);
+	if (!val) die("Malformed author line");
+	if (!(tz_off = strrchr(val, ' '))) goto error;
+	*tz_off++ = '\0';
+	if (!(t = strrchr(val, ' '))) goto error;
+	*(t - 1) = '\0'; /* Ignore '>' from email */
+	t++;
+	tz_off_buf = atoi(tz_off);
+	if (tz_off_buf > 1200 || tz_off_buf  < -1200) goto error;
+	tm_time = time_to_tm(strtoul(t, NULL, 10), tz_off_buf);
+	strftime(time_buf, SVN_DATE_LEN + 1, SVN_DATE_FORMAT, tm_time);
+	strbuf_add(date, time_buf, SVN_DATE_LEN);
+	if (!(t = strchr(val, '<'))) goto error;
+	*(t - 1) = '\0'; /* Ignore ' <' from email */
+	t++;
+	strbuf_add(email, t, strlen(t));
+	strbuf_add(name, val, strlen(val));
+	return;
+error:
+	die("Malformed author line: %s", val);
+}
+
+void build_svn_author(struct strbuf *svn_author)
+{
+	char *t, *email;
+
+	strbuf_reset(svn_author);
+	email = rev_ctx.author_email.buf;
+	if (!(t = strchr(email, '@')))
+		goto error;
+	strbuf_add(svn_author, email, t - email);
+	return;
+error:
+	die("Malformed email: %s", email);
+}
+
+int parse_filemodify_mode(char *val)
+{
+	char *t;
+
+	if (!(t = strchr(val, ' '))) goto error;
+	switch (t - val) {
+	case 6:
+		if (!memcmp(val, "100644", 6))
+			node_ctx.kind = NODE_KIND_NORMAL;
+		else if (!memcmp(val, "100755", 6))
+			node_ctx.kind = NODE_KIND_EXECUTABLE;
+		else if (!memcmp(val, "120000", 6))
+			node_ctx.kind = NODE_KIND_SYMLINK;
+		else if (!memcmp(val, "160000", 6))
+			node_ctx.kind = NODE_KIND_GITLINK;
+		else if (!memcmp(val, "040000", 6))
+			node_ctx.kind = NODE_KIND_SUBDIR;
+		else
+			goto error;
+		break;
+	case 3:
+		if (!memcmp(val, "755", 3))
+			node_ctx.kind = NODE_KIND_EXECUTABLE;
+		else if (!memcmp(val, "644", 3))
+			node_ctx.kind = NODE_KIND_NORMAL;
+		else
+			goto error;
+		break;
+	default:
+		goto error;
+	}
+	return t - val + 1;
+error:
+	die("Unrecognized mode: %s", val);
+}
+
+void svnload_read(void)
+{
+	char *t, *val;
+	int len;
+
+	while ((t = buffer_read_line(&input))) {
+		if ((val = strchr(t, ' ')))
+			*val++ = '\0';
+		len = (val ? val - t - 1 : strlen(t));
+
+		switch (len) {
+		case 1:
+			if (!memcmp(t, "D", 1)) {
+				node_ctx.action = NODE_ACTION_DELETE;
+			} else if (!memcmp(t, "C", 1)) {
+				node_ctx.action = NODE_ACTION_ADD;
+			} else if (!memcmp(t, "R", 1)) {
+				node_ctx.action = NODE_ACTION_REPLACE;
+			} else if (!memcmp(t, "M", 1)) {
+				if (!val) goto error;
+				node_ctx.action = NODE_ACTION_CHANGE;
+				val += parse_filemodify_mode(val);
+				if (!(t = strchr(val, ' '))) goto error;
+				*t++ = '\0';
+				strbuf_reset(&node_ctx.path);
+				strbuf_add(&node_ctx.path, t, strlen(t));
+				if (!strncmp(val, "inline", 6))
+					active_ctx = BLOB_CTX;
+				else if (*val == ':')
+					die("Unsupported dataref: marks");
+				else {
+				error:
+					die("Malformed filemodify line: %s", t);
+				}
+			}
+			break;
+		case 2:
+			if (!memcmp(t, "ls", 2))
+				die("ls not supported");
+		case 3:
+			if (!memcmp(t, "tag", 3))
+				continue;
+			break;
+		case 4:
+			if (!memcmp(t, "blob", 4))
+				continue;
+			else if (!memcmp(t, "mark", 4))
+				continue;
+			else if (!memcmp(t, "from", 4))
+				continue;
+			else if (!memcmp(t, "data", 4)) {
+				switch (active_ctx) {
+				case COMMIT_CTX:
+					strbuf_reset(&rev_ctx.log);
+					buffer_read_binary(&input,
+							&rev_ctx.log,
+							strtoul(val, NULL, 10));
+					populate_revprops(&rev_ctx.props,
+							rev_ctx.svn_author.len,
+							rev_ctx.svn_author.buf,
+							rev_ctx.log.len,
+							rev_ctx.log.buf,
+							rev_ctx.author_date.len,
+							rev_ctx.author_date.buf);
+					dump_export_begin_rev(rev_ctx.rev,
+							rev_ctx.props.buf,
+							rev_ctx.props.len);
+					break;
+				case BLOB_CTX:
+					node_ctx.text_len = strtoul(val, NULL, 10);
+					dump_export_node_r(node_ctx.path.buf, node_ctx.kind,
+							node_ctx.action, node_ctx.text_len,
+							SVN_INVALID_REV, NULL);
+					buffer_copy_bytes(&input, node_ctx.text_len);
+					break;
+				default:
+					break;
+				}
+			}
+			break;
+		case 5:
+			if (!memcmp(t, "reset", 5))
+				continue;
+			if (!memcmp(t, "merge", 5))
+				continue;
+			break;
+		case 6:
+			if (!memcmp(t, "author", 6)) {
+				parse_author_line(val, &rev_ctx.author,
+						&rev_ctx.author_email,
+						&rev_ctx.author_date);
+				build_svn_author(&rev_ctx.svn_author);
+			} else if (!memcmp(t, "commit", 6)) {
+				rev_ctx.rev++;
+				active_ctx = COMMIT_CTX;
+			}
+			break;
+		case 8:
+			if (!memcmp(t, "cat-blob", 8))
+				die("cat-blob unsupported");
+			break;
+		case 9:
+			if (!memcmp(t, "deleteall", 9))
+				continue;
+			else if (!memcmp(t, "committer", 9))
+				parse_author_line(val, &rev_ctx.committer,
+						&rev_ctx.committer_email,
+						&rev_ctx.committer_date);
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+static void reset_rev_ctx(int revision)
+{
+	rev_ctx.rev = revision;
+	strbuf_reset(&rev_ctx.props);
+	strbuf_reset(&rev_ctx.log);
+	strbuf_reset(&rev_ctx.svn_author);
+	strbuf_reset(&rev_ctx.author);
+	strbuf_reset(&rev_ctx.committer);
+	strbuf_reset(&rev_ctx.author_date);
+	strbuf_reset(&rev_ctx.committer_date);
+	strbuf_reset(&rev_ctx.author_email);
+	strbuf_reset(&rev_ctx.committer_email);
+}
+
+static void reset_node_ctx(void)
+{
+	node_ctx.prop_len = LENGTH_UNKNOWN;
+	node_ctx.text_len = LENGTH_UNKNOWN;
+	node_ctx.copyfrom_rev = SVN_INVALID_REV;
+	node_ctx.text_delta = -1;
+	node_ctx.prop_delta = -1;
+	strbuf_reset(&node_ctx.copyfrom_path);
+	strbuf_reset(&node_ctx.path);
+}
+
+int svnload_init(const char *filename)
+{
+	if (buffer_init(&input, filename))
+		return error("cannot open %s: %s", filename, strerror(errno));
+	active_ctx = UNKNOWN_CTX;
+	strbuf_init(&rev_ctx.props, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.log, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.author, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.committer, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.svn_author, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.author_date, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.committer_date, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.author_email, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&rev_ctx.committer_email, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&node_ctx.path, MAX_GITSVN_LINE_LEN);
+	strbuf_init(&node_ctx.copyfrom_path, MAX_GITSVN_LINE_LEN);
+	dump_export_init();
+	dir_cache_init();
+	return 0;
+}
+
+void svnload_deinit(void)
+{
+	reset_rev_ctx(0);
+	reset_node_ctx();
+	strbuf_release(&rev_ctx.props);
+	strbuf_release(&rev_ctx.log);
+	strbuf_release(&rev_ctx.author);
+	strbuf_release(&rev_ctx.committer);
+	strbuf_release(&rev_ctx.svn_author);
+	strbuf_release(&rev_ctx.author_date);
+	strbuf_release(&rev_ctx.committer_date);
+	strbuf_release(&rev_ctx.author_email);
+	strbuf_release(&rev_ctx.committer_email);
+	strbuf_release(&node_ctx.path);
+	strbuf_release(&node_ctx.copyfrom_path);
+	dump_export_deinit();
+	dir_cache_deinit();
+	if (buffer_deinit(&input))
+		fprintf(stderr, "Input error\n");
+	if (ferror(stdout))
+		fprintf(stderr, "Output error\n");
+}
diff --git a/vcs-svn/svnload.h b/vcs-svn/svnload.h
new file mode 100644
index 0000000..0c8fe8b
--- /dev/null
+++ b/vcs-svn/svnload.h
@@ -0,0 +1,10 @@
+#ifndef SVNLOAD_H_
+#define SVNLOAD_H_
+
+#define SVN_INVALID_REV -1
+
+int svnload_init(const char *filename);
+void svnload_deinit(void);
+void svnload_read(void);
+
+#endif
-- 
1.7.4.rc1.7.g2cf08.dirty

  reply	other threads:[~2011-02-01 14:26 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-01 14:26 [PATCH v3 0/3] Towards a Git-to-SVN bridge Ramkumar Ramachandra
2011-02-01 14:26 ` Ramkumar Ramachandra [this message]
2011-02-01 14:46   ` [PATCH 1/3] vcs-svn: Introduce svnload, a dumpfile producer Erik Faye-Lund
2011-02-02  2:53     ` Ramkumar Ramachandra
2011-02-02 12:43       ` Erik Faye-Lund
2011-02-01 14:26 ` [PATCH 2/3] t9010-svn-fi: Add tests for svn-fi Ramkumar Ramachandra
2011-02-01 18:58   ` Jonathan Nieder
2011-02-02  2:49     ` Ramkumar Ramachandra
2011-02-02  3:18       ` Jonathan Nieder
2011-02-01 14:26 ` [PATCH 3/3] vcs-svn: Refactor dump_export code into dispatch table Ramkumar Ramachandra
2011-02-01 17:42   ` Jonathan Nieder
2011-02-01 21:29     ` Junio C Hamano
2011-02-02  2:56     ` Ramkumar Ramachandra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1296570403-9082-2-git-send-email-artagnon@gmail.com \
    --to=artagnon@gmail.com \
    --cc=david.barr@cordelta.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jrnieder@gmail.com \
    --cc=srabbelier@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.