From: Ramkumar Ramachandra <artagnon@gmail.com>
To: "Git Mailing List" <git@vger.kernel.org>
Cc: David Michael Barr <david.barr@cordelta.com>,
Sverre Rabbelier <srabbelier@gmail.com>
Subject: [WIP PATCH] Add remote SVN helper
Date: Tue, 25 May 2010 19:00:18 +0200 [thread overview]
Message-ID: <1274806818-10904-2-git-send-email-artagnon@gmail.com> (raw)
In-Reply-To: <1274806818-10904-1-git-send-email-artagnon@gmail.com>
Add a remote helper for SVN that uses the exporter in vcs-svn/ with an
appropriate Makefile rule. For this to work, you must check out the
git-merge branch of svn-dump-fast-export [1] into vcs-svn/ and then
build git-remote-svn.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
.gitignore | 1 +
Makefile | 14 ++++-
remote-svn.c | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 205 insertions(+), 1 deletions(-)
create mode 100644 remote-svn.c
diff --git a/.gitignore b/.gitignore
index dbf1b90..6ac8a7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -112,6 +112,7 @@
/git-remote-https
/git-remote-ftp
/git-remote-ftps
+/git-remote-svn
/git-repack
/git-replace
/git-repo-config
diff --git a/Makefile b/Makefile
index 4f7224a..fde0cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -1746,6 +1746,14 @@ endif
%.s: %.c GIT-CFLAGS FORCE
$(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) $<
+vcs-svn/%.o: vcs-svn/%.c GIT-CFLAGS FORCE
+ $(QUIET_CC)$(CC) -o $@ -c $(dep_args) $(ALL_CFLAGS) \
+ -I./vcs-svn $(EXTRA_CPPFLAGS) $<
+
+remote-svn.o: remote-svn.c $(GITLIBS) GIT-CFLAGS FORCE
+ $(QUIET_CC)$(CC) -o $@ -c $(dep_args) $(ALL_CFLAGS) \
+ -I./vcs-svn $(EXTRA_CPPFLAGS) $<
+
ifdef USE_COMPUTED_HEADER_DEPENDENCIES
# Take advantage of gcc's on-the-fly dependency generation
# See <http://gcc.gnu.org/gcc-3.0/features.html>.
@@ -1824,6 +1832,10 @@ $(REMOTE_CURL_PRIMARY): remote-curl.o http.o http-walker.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
+git-remote-svn$X: remote-svn.o $(patsubst %.c,%.o,$(wildcard vcs-svn/*.c))
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
+ $(LIBS)
+
$(LIB_FILE): $(LIB_OBJS)
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
@@ -2087,7 +2099,7 @@ distclean: clean
clean:
$(RM) *.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o xdiff/*.o \
- builtin/*.o $(LIB_FILE) $(XDIFF_LIB)
+ builtin/*.o vcs-svn/*.o $(LIB_FILE) $(XDIFF_LIB)
$(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
$(RM) $(TEST_PROGRAMS)
$(RM) -r bin-wrappers
diff --git a/remote-svn.c b/remote-svn.c
new file mode 100644
index 0000000..def5b20
--- /dev/null
+++ b/remote-svn.c
@@ -0,0 +1,191 @@
+#include "cache.h"
+#include "strbuf.h"
+#include "remote.h"
+#include "strbuf.h"
+#include "exec_cmd.h"
+
+#include "svnclient.h"
+
+static struct remote *remote;
+
+struct options {
+ int verbosity;
+ unsigned long depth;
+ unsigned progress : 1,
+ dry_run : 1;
+};
+static struct options options;
+
+static int set_option(const char *name, const char *value)
+{
+ if (!strcmp(name, "verbosity")) {
+ char *end;
+ int v = strtol(value, &end, 10);
+ if (value == end || *end)
+ return -1;
+ options.verbosity = v;
+ return 0;
+ } else if (!strcmp(name, "progress")) {
+ if (!strcmp(value, "true"))
+ options.progress = 1;
+ else if (!strcmp(value, "false"))
+ options.progress = 0;
+ else
+ return -1;
+ return 0;
+ } else if (!strcmp(name, "dry-run")) {
+ if (!strcmp(value, "true"))
+ options.dry_run = 1;
+ else if (!strcmp(value, "false"))
+ options.dry_run = 0;
+ else
+ return -1;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int export_handler(int nr_spec, char **specs)
+{
+ int err = 0;
+
+ /* TODO: The real exporting */
+ /* TODO: Write an importer for SVN */
+
+ return err;
+}
+
+static int import_handler(int nr_spec, char **specs)
+{
+ int err = 0, i;
+ for (i = 0; i < nr_spec; i++)
+ FI_svn(specs[i]);
+ return err;
+}
+
+static void parse_import(struct strbuf *buf)
+{
+ char **specs = NULL;
+ int alloc_spec = 0, nr_spec = 0, i;
+
+ do {
+ if (!prefixcmp(buf->buf, "import ")) {
+ ALLOC_GROW(specs, nr_spec + 1, alloc_spec);
+ specs[nr_spec++] = xstrdup(buf->buf + 5);
+ }
+ else
+ die("remote helper does not support %s", buf->buf);
+
+ strbuf_reset(buf);
+ if (strbuf_getline(buf, stdin, '\n') == EOF)
+ return;
+ if (!*buf->buf)
+ break;
+ } while (1);
+
+ if (import_handler(nr_spec, specs))
+ exit(128); /* error already reported */
+ for (i = 0; i < nr_spec; i++)
+ free(specs[i]);
+ free(specs);
+
+ printf("\n");
+ fflush(stdout);
+}
+
+static void parse_export(struct strbuf *buf)
+{
+ char **specs = NULL;
+ int alloc_spec = 0, nr_spec = 0, i;
+
+ do {
+ if (!prefixcmp(buf->buf, "export ")) {
+ ALLOC_GROW(specs, nr_spec + 1, alloc_spec);
+ specs[nr_spec++] = xstrdup(buf->buf + 5);
+ } else
+ die("remote helper does not support %s", buf->buf);
+
+ strbuf_reset(buf);
+ if (strbuf_getline(buf, stdin, '\n') == EOF)
+ return;
+ if (!*buf->buf)
+ break;
+ } while (1);
+
+ if (export_handler(nr_spec, specs))
+ exit(128); /* error already reported */
+ for (i = 0; i < nr_spec; i++)
+ free(specs[i]);
+ free(specs);
+
+ printf("\n");
+ fflush(stdout);
+}
+
+int main(int argc, const char **argv)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int nongit;
+
+ git_extract_argv0_path(argv[0]);
+ setup_git_directory_gently(&nongit);
+ if (argc < 2) {
+ fprintf(stderr, "Remote needed\n");
+ return 1;
+ }
+
+ options.verbosity = 1;
+ options.progress = !!isatty(2);
+
+ remote = remote_get(argv[1]);
+
+ open_svn_connection(remote->url[0]);
+ do {
+ if (strbuf_getline(&buf, stdin, '\n') == EOF)
+ break;
+
+ else if (!strcmp(buf.buf, "list")) {
+ /* TODO: Code to list refs */
+ break;
+
+ } else if (!prefixcmp(buf.buf, "import ")) {
+ if (nongit)
+ die("Import attempted without a local repo");
+ parse_import(&buf);
+
+ } else if (!prefixcmp(buf.buf, "export ")) {
+ parse_export(&buf);
+
+ } else if (!prefixcmp(buf.buf, "option ")) {
+ char *name = buf.buf + strlen("option ");
+ char *value = strchr(name, ' ');
+ int result;
+ if (value)
+ *value++ = '\0';
+ else
+ value = "true";
+ result = set_option(name, value);
+ if (!result)
+ printf("ok\n");
+ else if (result < 0)
+ printf("error invalid value\n");
+ else
+ printf("unsupported\n");
+ fflush(stdout);
+
+ } else if (!strcmp(buf.buf, "capabilities")) {
+ printf("option\n");
+ printf("import\n");
+ printf("export\n");
+ printf("\n");
+ fflush(stdout);
+ } else
+ return 1;
+
+ strbuf_reset(&buf);
+ } while (1);
+
+ close_svn_connection();
+ return 0;
+}
--
1.7.1
prev parent reply other threads:[~2010-05-25 16:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-25 17:00 [WIP PATCH] Plug SVN exporter into remote helper Ramkumar Ramachandra
2010-05-25 17:00 ` Ramkumar Ramachandra [this message]
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=1274806818-10904-2-git-send-email-artagnon@gmail.com \
--to=artagnon@gmail.com \
--cc=david.barr@cordelta.com \
--cc=git@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).