* [PATCH 1/3] vcs-svn: Introduce svnload, a dumpfile producer
From: Ramkumar Ramachandra @ 2011-02-01 14:26 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier, Junio C Hamano
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
^ permalink raw reply related
* [PATCH 2/3] t9010-svn-fi: Add tests for svn-fi
From: Ramkumar Ramachandra @ 2011-02-01 14:26 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier, Junio C Hamano
In-Reply-To: <1296570403-9082-1-git-send-email-artagnon@gmail.com>
Create a test-svn-fi in toplevel directory, add rules to build it, and
add some basic tests.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
.gitignore | 1 +
Makefile | 5 +-
t/t9010-svn-fi.sh | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++++
test-svn-fi.c | 20 ++++
4 files changed, 328 insertions(+), 1 deletions(-)
create mode 100644 t/t9010-svn-fi.sh
create mode 100644 test-svn-fi.c
diff --git a/.gitignore b/.gitignore
index b48d1ee..c8c8a17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,6 +177,7 @@
/test-sigchain
/test-subprocess
/test-svn-fe
+/test-svn-fi
/common-cmds.h
*.tar.gz
*.dsc
diff --git a/Makefile b/Makefile
index d9c2442..cb21b78 100644
--- a/Makefile
+++ b/Makefile
@@ -431,6 +431,7 @@ TEST_PROGRAMS_NEED_X += test-sha1
TEST_PROGRAMS_NEED_X += test-sigchain
TEST_PROGRAMS_NEED_X += test-subprocess
TEST_PROGRAMS_NEED_X += test-svn-fe
+TEST_PROGRAMS_NEED_X += test-svn-fi
TEST_PROGRAMS_NEED_X += test-index-version
TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
@@ -1838,7 +1839,7 @@ 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/dir_cache.o
VCSSVN_TEST_OBJS = test-obj-pool.o \
- test-line-buffer.o test-treap.o test-svn-fe.o
+ test-line-buffer.o test-treap.o test-svn-fe.o test-svn-fi.o
OBJECTS := $(GIT_OBJS) $(XDIFF_OBJS) $(VCSSVN_OBJS)
dep_files := $(foreach f,$(OBJECTS),$(dir $f).depend/$(notdir $f).d)
@@ -2129,6 +2130,8 @@ test-parse-options$X: parse-options.o
test-svn-fe$X: vcs-svn/lib.a
+test-svn-fi$X: vcs-svn/lib.a
+
.PRECIOUS: $(TEST_OBJS)
test-%$X: test-%.o $(GITLIBS)
diff --git a/t/t9010-svn-fi.sh b/t/t9010-svn-fi.sh
new file mode 100644
index 0000000..676c7fc
--- /dev/null
+++ b/t/t9010-svn-fi.sh
@@ -0,0 +1,303 @@
+#!/bin/sh
+
+test_description='check svn dumpfile exporter'
+
+. ./test-lib.sh
+
+if ! svnadmin -h >/dev/null 2>&1
+then
+ skip_all='skipping svn-fi tests, svn not available'
+ test_done
+fi
+
+svnrepo="testsvn"
+
+reinit_svn () {
+ rm -rf "$svnrepo" &&
+ rm -f stream &&
+ svnadmin create "$svnrepo" &&
+ printf "#!/bin/sh" > "$svnrepo"/hooks/pre-revprop-change &&
+ chmod +x "$svnrepo"/hooks/pre-revprop-change &&
+ mkfifo stream
+}
+
+svn_look () {
+ subcommand=$1 &&
+ shift &&
+ svnlook "$subcommand" "$svnrepo" "$@"
+}
+
+try_load () {
+ input=$1 &&
+ maybe_fail=${2:+test_$2} &&
+
+ {
+ $maybe_fail test-svn-fi "$input" >stream &
+ } &&
+ svnadmin load "$svnrepo" <stream &&
+ wait $!
+}
+
+test_expect_success 'normal empty files' '
+ reinit_svn &&
+ cat >expect.tree <<-\EOF &&
+ /
+ foo
+ bar
+ EOF
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline foo
+ data 0
+ M 644 inline bar
+ data 0
+
+ EOF
+ try_load input &&
+ svn_look tree >actual.tree &&
+ test_cmp expect.tree actual.tree
+'
+
+# TODO: How to test date? Need to convert from local timestamp
+test_expect_success 'svn:author and svn:log' '
+ reinit_svn &&
+ echo "nothing" >expect.log &&
+ echo "nobody" >expect.author &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 100644 inline foo
+ data 0
+
+ EOF
+ try_load input &&
+ svn_look log >actual.log &&
+ svn_look author >actual.author &&
+ test_cmp expect.log actual.log &&
+ test_cmp expect.author actual.author
+'
+
+test_expect_success 'missing author line' '
+ reinit_svn &&
+ cat >expect.tree <<-\EOF &&
+ /
+ foo
+ EOF
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline foo
+ data 0
+
+ EOF
+ try_load input &&
+ svn_look tree >actual.tree &&
+ test_cmp expect.tree actual.tree
+'
+
+test_expect_success 'blob marks unsupported' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ blob
+ mark :1
+ data 0
+
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :2
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 :1 foo
+
+ EOF
+ try_load input must_fail
+'
+
+test_expect_success 'malformed fast-import stream: filemodify' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline
+
+ EOF
+ try_load input must_fail
+'
+
+test_expect_success 'malformed fast-import stream: author' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author 2d3%*s&f#k|
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline foo
+ data 0
+
+ EOF
+ try_load input must_fail
+'
+
+test_expect_success 'malformed fast-import stream: author 2' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline foo
+ data 0
+
+ EOF
+ try_load input must_fail
+'
+
+test_expect_success 'malformed fast-import stream: data length' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 0
+ M 100644 inline foo
+ data 14238
+
+ EOF
+ test_must_fail try_load input
+'
+
+test_expect_success 'recursive directory creation' '
+ reinit_svn &&
+ cat >expect.tree <<-\EOF &&
+ /
+ alpha/
+ beta/
+ gamma
+ EOF
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 100644 inline alpha/beta/gamma
+ data 12
+ some content
+
+ EOF
+ try_load input &&
+ svn_look tree >actual.tree &&
+ test_cmp expect.tree actual.tree
+'
+
+test_expect_success 'svn:special and svn:executable' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 100755 inline foo
+ data 0
+ M 755 inline moo
+ data 0
+ M 120000 inline bar
+ data 0
+
+ EOF
+ try_load input &&
+ svn_look propget svn:executable foo &&
+ svn_look propget svn:executable moo &&
+ svn_look propget svn:special bar
+'
+
+test_expect_success 'replace symlink with normal file' '
+ reinit_svn &&
+ cat >expect.tree <<-\EOF &&
+ /
+ alpha/
+ beta/
+ gamma
+ EOF
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 120000 inline alpha/beta/gamma
+ data 0
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 100644 inline alpha/beta/gamma
+ data 0
+
+ EOF
+ try_load input &&
+ svn_look tree -r1 >actual.tree1 &&
+ svn_look tree -r2 >actual.tree2 &&
+ test_cmp expect.tree actual.tree1 &&
+ test_cmp expect.tree actual.tree2
+'
+
+test_expect_success 'path includes symlink' '
+ reinit_svn &&
+ cat >input <<-\EOF &&
+ reset refs/heads/master
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 120000 inline alpha/beta/gamma
+ data 0
+ commit refs/heads/master
+ mark :1
+ author nobody <nobody@localhost> 1170199019 +0100
+ committer nobody <nobody@localhost> 1170199019 +0100
+ data 7
+ nothing
+ M 100644 inline alpha/beta/gamma/bar
+ data 0
+
+ EOF
+ test_must_fail try_load input
+'
+
+test_done
diff --git a/test-svn-fi.c b/test-svn-fi.c
new file mode 100644
index 0000000..b0605fe
--- /dev/null
+++ b/test-svn-fi.c
@@ -0,0 +1,20 @@
+/*
+ * test-svn-fe: Code to exercise the svn import lib
+ */
+
+#include "git-compat-util.h"
+#include "vcs-svn/svnload.h"
+
+int main(int argc, char *argv[])
+{
+ static const char test_svnfe_usage[] =
+ "test-svn-fe (<dumpfile>";
+ if (argc == 2) {
+ if (svnload_init(argv[1]))
+ return 1;
+ svnload_read();
+ svnload_deinit();
+ return 0;
+ }
+ usage(test_svnfe_usage);
+}
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply related
* [PATCH v3 0/3] Towards a Git-to-SVN bridge
From: Ramkumar Ramachandra @ 2011-02-01 14:26 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier, Junio C Hamano
Hi,
Here's another attempt. I've omitted 3 patches in this round:
1. The --inline-blobs patch
2. The time_to_tm patch
3. The contrib/svn-fe and test-svn-fi patch
(since those haven't changed from last time)
Changes since last time:
1. Bugfixes and testsuite. All tests pass.
2. Style fixes after Junio's review:
<7v39olok4l.fsf@alter.siamese.dyndns.org>
3. Implemented an experimetal dispatch table suggested by Jonathan:
<20110122191801.GB13023@burratino>
Thanks for reading.
Ramkumar Ramachandra (3):
vcs-svn: Introduce svnload, a dumpfile producer
t9010-svn-fi: Add tests for svn-fi
vcs-svn: Refactor dump_export code into dispatch table
.gitignore | 1 +
Makefile | 9 +-
t/t9010-svn-fi.sh | 303 ++++++++++++++++++++++++++++++++++++++++++++++
test-svn-fi.c | 20 +++
vcs-svn/dir_cache.c | 40 ++++++
vcs-svn/dir_cache.h | 12 ++
vcs-svn/dump_export.c | 150 +++++++++++++++++++++++
vcs-svn/dump_export.h | 35 ++++++
vcs-svn/svnload.c | 322 +++++++++++++++++++++++++++++++++++++++++++++++++
vcs-svn/svnload.h | 10 ++
10 files changed, 899 insertions(+), 3 deletions(-)
create mode 100644 t/t9010-svn-fi.sh
create mode 100644 test-svn-fi.c
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
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply
* Re: [1.8.0] Remote tag namespace
From: Leo Razoumov @ 2011-02-01 14:10 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: Git Mailing List, Nicolas Pitre
In-Reply-To: <AANLkTi=yFwOAQMHhvLsB1_xmYOE9HHP2YB4H4TQzwwc8@mail.gmail.com>
On Tue, Feb 1, 2011 at 05:44, Nguyen Thai Ngoc Duy <pclouds@gmail.com> wrote:
> On Tue, Feb 1, 2011 at 11:16 AM, Nicolas Pitre <nico@fluxnic.net> wrote:
>> On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
>>> Another random wish, which does not come with a proposal. How about
>>> tag namespace (ie. tags from a remote stay in remote namespace)?
>>
>> Please make this into a proper proposal. this would be indeed a huge
>> improvement.
>
> OK I'm not familiar with tag code, but I can try.
>
> Proposal:
>
Remote tag namespace is a great feature long overdue in git. Due to
git's current flat tag namespace I am forced to make my tags
artificially long like
"my_project_repo_name/v-1.2.3".
Looking forward to remote tag namespace -- sooner the better!
--Leo--
^ permalink raw reply
* Re: Features from GitSurvey 2010
From: Jakub Narebski @ 2011-02-01 13:51 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Dmitry S. Kravtsov, git
In-Reply-To: <20110129231310.GA11088@burratino>
On Sun, 30 Jan 2011, Jonathan Nieder wrote:
> Hi Dmitry,
>
> Dmitry S. Kravtsov wrote:
>
> > I want to dedicate my coursework at University to implementation of
> > some useful git feature. So I'm interesting in some kind of list of
> > development status of these features
> [...]
> > Or I'll be glad to know what features are now 'free' and what are
> > currently in active development.
>
> Interesting question. The short answer is that they are all "free".
> Generally people seem to be happy to learn of an alternative approach
> to what they have been working on.
>
> [For the following pointers, the easiest way to follow up is probably
> to search the mailing list archives.]
>
> > better support for big files (large media)
>
> For a conservative approach, you might want to get in touch with Sam
> Hocevar, Nicolas Pitre, and Miklos Vajna. The idea is to stream big
> files directly to pack and not waste time trying to compress them.
There is also, supposedly stalled, git-bigfiles project.
>
> For an alternative approach, Joey Hess's git-annex might be
> interesting.
Note that this feature would not be easy to implement; you would need
both quite good knowledge of git internals, and some realistic use case
that you can test performance of your improvements with.
> > resumable clone/fetch (and other remote operations)
>
> Jakub Narebski seems to be interested in this and Nicolas Pitre has
> given some good advice about it. You can get something usable today
> by putting up a git bundle for download over HTTP or rsync, so it is
> possible that this just involves some UI (porcelain) and documentation
> work to become standard practice.
I wouldn't say that: it is Nicolas Pitre (IIRC) who was doing the work;
I was only interested party posting comments, but no code.
Again, this feature is not very easy to implement, and would require
knowledge of git internals including "smart" git transport ("Pro Git"
book can help there).
> > GitTorrent Protocol, or git-mirror
>
> Sam Vilain and Jonas Fonseca did some good work on this, but it's
> stalled.
There was some recent discussion on this on git mailing llist, but
without any code.
One would need to know similar areas as for "resumable clone" feature.
Plus some knowledge on P2P transport in GitTorrent case.
> > lazy clone / on-demand fetching of object
>
> There's a patch. As is, it is not likely to be useful outside
> specialized circumstances imho.
>
> http://thread.gmane.org/gmane.comp.version-control.git/73117
One would need to know about how git checks for consistency, e.g. via
git-fsck for that.
> > subtree clone
>
> Nguyễn Thái Ngọc Duy and Elijah Newren have done some design and
> prototyping work.
Git mailing list archives should contain proof of concept / RFC patches
for this feature. Quite interesting.
> > support for tracking empty directories
>
> Tricky to get the UI right. I am interested in and would be glad to
> help with this one.
Also one needs to remember that this would require adding extension
to git index, because currently it tracks only files, and not
directories. Explicitly tracking directories in the index could be
useful for other purposes...
The major difficulty of this is IMHO not the UI, but tracking all those
tricky corner cases (like directory/file conflict, etc.).
[...]
> > side-by-side diffs and/or color-words diff in gitweb
> > admin and/or write features in gitweb
> > graphical history view in gitweb
>
> There may or may not have been design work on some of these for Pavan
> Kumar Sunkara's last summer of code project. John 'Warthog9' Hawley,
> Jakub Narebski, and Petr Baudis might have advice.
Pavan was to work on admin and/or write features in gitweb, while he
didn't even finish splitting gitweb (perhaps he tried to be too
ambitious in trying to split whole of gitweb at once, instead of
splitting-off well definied pieces?).
There are existing Perl modules on CPAN and/or Perl web apps that use
side-by-side diffs and/or color-words diff, so there is code to take an
example, to use in gitweb, or to borrow.
The graphical history view would be more difficult, but not very
difficult, I think. You would have to decide how to draw a graph:
should gitweb generate image on the fly, use some smart combination
of CSS and pre-made images (perhaps with transparency), use Unicode
graph characters, or use ASCII-art graph. You would also have to decide
whether to use or base on some existing algorithm to generate graph,
borrowing from tig, git-browser, gitk or git-forest (the last is in
Perl, like gitweb), or whether to make use of "git log --graph" output.
> > GUI for rebase in git-gui
> > GUI for creating repository in git-gui
> > graphical diff/merge tool integrated with git-gui
> > syntax highlighting in git-gui
>
> Pat Thoyts is probably the one to talk to.
Note that for graphical diff/merge tool you should be able to borrow
from xxdiff graphical diff/merge tool, which is also written in Tcl/Tk.
> > filename encoding (in repository vs in filesystem)
>
> This is important for the Windows port and likely to be a nuisance
> on Unix. I think there has been some work on it on the msysgit list?
That would need a good design (note also different forms of Unicode),
and overcoming inertia.
> > localization of command-line messages (i18n)
>
> Ævar Arnfjörð Bjarmason did some work which is in pu. It needs
> some polishing. I am also interested.
I don't know how much is left to do (beside actually translating
messages). But this series could use a little help.
> > union checkouts (some files from one branch, some from other)
>
> Not sure I understand the use case?
I don't know if it would be really useful, but the concept is similar to
union mounts. In union mount (unionfs, aufs,...) you can e.g. mount
CD-ROM read-only, and over it overlay on some read-write filesystem.
The idea is to have some files (some directories) in working area come
from one branch, some from other branch, persistently in some way. Not
sure if it would be actually useful.
> > advisory locking / "this file is being edited"
>
> Probably better to implement out of band (using hooks?). I don't
> know of any work or documentation in that direction.
Yes, t would probably be best as external project, only with git
integration.
> > built-in gitjour/bananajour support
>
> A good start might be to submit one or both of these to contrib?
If I remember correctly there are some third-party extensions to be
found, and perhaps even some patches in git mailing list.
Best choose something you are both interested in, and proficient with.
HTH
--
Jakub Narebski
Poland
^ permalink raw reply
* does the clone I do have the commits within them .
From: Vaishali @ 2011-02-01 13:20 UTC (permalink / raw)
To: git
hi , I am have cloned the
git://gitorious.org/~dbeck/hawkboard/dbeck-hawkboard-linux-omapl1.git
found at http://gitorious.org/~dbeck/hawkboard/dbeck-hawkboard-linux-omapl1...
Now I see there is a tab called Commit log ...The git that I have
cloned , would it include the commits in totality or will I have to do
somethng diferent to get the commits into the git that I cloned on my
PC. git checkout -f master git pull ... Is this .?
Thanks
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Nicolas Pitre @ 2011-02-01 13:08 UTC (permalink / raw)
To: Thomas Rast; +Cc: Jeff King, Junio C Hamano, git
In-Reply-To: <201102011342.06910.trast@student.ethz.ch>
On Tue, 1 Feb 2011, Thomas Rast wrote:
> Nicolas Pitre wrote:
> > What I see in the root of the Git source
> > tree is a huge clutter of source files, binary files, scripts, and
> > subdirectories all mixed together. If you know by hart where things are
> > because you've been hacking on them for the last 5 years then of course
> > you might not see the point. But since I didn't work much on Git
> > lately, things are not as obvious to me as they used to be. Looking
> > back at it now with some distance, this tree looks like a mess and it is
> > really annoying to work with.
>
> But judging by that assessment, shouldn't we strive to make it
> *easier* to find things?
>
> In particular a prospective git hacker would not care whether
> something is a source file or a script (you seem to imply the
> opposite). He would instead expect to find git-foo implemented in
> something named of that sort, so we could probably help him by mapping
>
> git-foo.sh -> git-foo.sh
> builtin/bar.c -> git-bar.c
> baz.c -> lib/baz.c
> baz.o -> build/baz.o (or whatever, just elsewhere)
> baz.gcov -> build/baz.gcov (ditto)
I'm not proposing to go that far, especially given the current
resistance to any changes. IMHO anything that unclutters the top
directory is good.
Nicolas
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Thomas Rast @ 2011-02-01 12:42 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Jeff King, Junio C Hamano, git
In-Reply-To: <alpine.LFD.2.00.1101312238170.8580@xanadu.home>
Nicolas Pitre wrote:
> What I see in the root of the Git source
> tree is a huge clutter of source files, binary files, scripts, and
> subdirectories all mixed together. If you know by hart where things are
> because you've been hacking on them for the last 5 years then of course
> you might not see the point. But since I didn't work much on Git
> lately, things are not as obvious to me as they used to be. Looking
> back at it now with some distance, this tree looks like a mess and it is
> really annoying to work with.
But judging by that assessment, shouldn't we strive to make it
*easier* to find things?
In particular a prospective git hacker would not care whether
something is a source file or a script (you seem to imply the
opposite). He would instead expect to find git-foo implemented in
something named of that sort, so we could probably help him by mapping
git-foo.sh -> git-foo.sh
builtin/bar.c -> git-bar.c
baz.c -> lib/baz.c
baz.o -> build/baz.o (or whatever, just elsewhere)
baz.gcov -> build/baz.gcov (ditto)
(I'm no huge fan of src/ either, but this should be orthogonal.)
--
Thomas Rast
trast@{inf,student}.ethz.ch
^ permalink raw reply
* [1.8.0] Remote tag namespace
From: Nguyen Thai Ngoc Duy @ 2011-02-01 10:44 UTC (permalink / raw)
To: Git Mailing List; +Cc: Nicolas Pitre
On Tue, Feb 1, 2011 at 11:16 AM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
>> Another random wish, which does not come with a proposal. How about
>> tag namespace (ie. tags from a remote stay in remote namespace)?
>
> Please make this into a proper proposal. this would be indeed a huge
> improvement.
OK I'm not familiar with tag code, but I can try.
Proposal:
Reserve refs/remote-tags namespace to store tags from remotes. Its
structure is the same as in refs/remotes. When pulling tags, put them
in refs/remote-tags/<remote> instead of refs/tags.
Tag dereference code will be taught about refs/remote-tags with
similar deref order as in remote branches.
Config branch.*.globalTags (perhaps takes a pattern?) may be defined
to create refs/tags/* in addition to refs/remote-tags/<remote>/* when
fetching tags.
Migration plan:
refs/remote-tags will be used to store new tags unconditionally, which
means there will be duplicates with the already-fetched tags in global
namespace. Perhaps we can check if they point to the same sha-1, then
choose not to annoy users with ambiguous tag messages?
I suggest to add config compatibility.remoteTagNamespace, default to
false, which retains current behavior (i.e. also create tags in global
namespace in addition to refs/remote-tags). After 1.8.0 (or a few more
cycles) the default value becomes true. Users who wish to keep old
behavior can put "false" in their ~/.gitconfig.
After a few years, remove support for the config key. Unrecognized
compatibility.* keys will abort program. Users are forced to new
behavior. I don't know, we may want to start annoy users that have the
config key set a few cycles before we drop support.
--
Duy
^ permalink raw reply
* Re: [1.8.0] Change branch --set-uptream to take an argument
From: Matthieu Moy @ 2011-02-01 9:01 UTC (permalink / raw)
To: Jay Soffian; +Cc: Junio C Hamano, git
In-Reply-To: <AANLkTinUn2SMijphe3EmPMVOOwBjPB5ffFwwqZVxQmW0@mail.gmail.com>
Jay Soffian <jaysoffian@gmail.com> writes:
> Currently it is very easy to misinvoke --set-upstream if you assume it
> takes an argument:
Your proposal sounds interesting, but I'd like to see something more
global: right now, some commands take a --track option and other take
a --set-upstream. In short, I'd like to see this --track deprecated
(since it's not actually about remote-tracking ...).
> (Though I'm not sure whether the options parser allows for both
> --set-upstream and --set-upstream=<arg>)
There are already many instances of this. When <arg> is mandatory, you
can write either --option <arg> or --option=<arg> (like "git log
--grep pattern" Vs "git log --grep=pattern"), and when <arg> is
optional, you can write either --option alone, or --option=<arg> (like
"git diff --color-words" and "git diff --color-words=.").
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Jay Soffian @ 2011-02-01 7:24 UTC (permalink / raw)
To: Jeff King; +Cc: Nicolas Pitre, Junio C Hamano, git
In-Reply-To: <20110131231210.GD14419@sigill.intra.peff.net>
On Mon, Jan 31, 2011 at 6:12 PM, Jeff King <peff@peff.net> wrote:
> And no matter what your model, renames can be annoying. On-going topics
> will have a painful rebase or merge. And people looking at history will
> have to deal with the code-base having different names at different
> points. Yeah, you can say it's all just "content", but the filenames we
> put things in are actually useful.
I have been dealing with this quite a bit lately as Chromium has been
doing mass renaming. It's no small project and sometimes those merges
are big:
[diff]
renames = copies
renameLimit = 2000
:-)
What I can say is, yes, it's annoying, but also: git does quite a
decent job of it. I've found myself having to do this occasionally,
but not too often:
git diff ...MERGE_HEAD -- /path/to/old/name | patch /path/to/new/name
(Typically when a header is renamed, a stub is left in place at the
old name which just includes the new name, and the local changes don't
come across to the new name 100% cleanly.)
Anyway, I would welcome git.git getting a little taste of that. :-) :-) :-)
j.
^ permalink raw reply
* [PATCH v4] Disallow empty section and variable names
From: Libor Pechacek @ 2011-02-01 7:13 UTC (permalink / raw)
To: git, gitster; +Cc: Johannes Sixt, Jens Lehmann
In-Reply-To: <4D46E7E7.4010805@web.de>
It is possible to break your repository config by creating an invalid key. The
config parser in turn chokes on it.
$ git init
Initialized empty Git repository in /tmp/gittest/.git/
$ git config .foo false
$ git config core.bare
fatal: bad config file line 6 in .git/config
This patch makes git-config reject keys which start or end with a dot and adds
tests for these cases.
Signed-off-by: Libor Pechacek <lpechacek@suse.cz>
---
Fix in t5526-fetch-submodules.sh was posted separately by Jens Lehmann.
Applies on top "Sanity-check config variable names".
config.c | 10 ++++++++--
t/t1300-repo-config.sh | 4 ++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/config.c b/config.c
index fde91f5..5eb89a7 100644
--- a/config.c
+++ b/config.c
@@ -1113,6 +1113,7 @@ int git_config_set(const char *key, const char *value)
int git_config_parse_key(const char *key, char **store_key, int *baselen_)
{
int i, dot, baselen;
+ int keylen = strlen(key);
const char *last_dot = strrchr(key, '.');
/*
@@ -1120,11 +1121,16 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
* key name separated by a dot, we have to know where the dot is.
*/
- if (last_dot == NULL) {
+ if (last_dot == NULL || *key == '.') {
error("key does not contain a section: %s", key);
return -2;
}
+ if (keylen && key[keylen-1] == '.') {
+ error("key does not contain variable name: %s", key);
+ return -2;
+ }
+
baselen = last_dot - key;
if (baselen_)
*baselen_ = baselen;
@@ -1132,7 +1138,7 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
/*
* Validate the key and while at it, lower case it for matching.
*/
- *store_key = xmalloc(strlen(key) + 1);
+ *store_key = xmalloc(keylen + 1);
dot = 0;
for (i = 0; key[i]; i++) {
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index c3d91d1..53fb822 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -889,6 +889,10 @@ test_expect_success 'key sanity-checking' '
test_must_fail git config foo.1bar &&
test_must_fail git config foo."ba
z".bar &&
+ test_must_fail git config . false &&
+ test_must_fail git config .foo false &&
+ test_must_fail git config foo. false &&
+ test_must_fail git config .foo. false &&
git config foo.bar true &&
git config foo."ba =z".bar false
'
--
1.7.4.rc3.11.g863f7
^ permalink raw reply related
* Re: [1.8.0] make two-argument fetch update remote branches
From: Jay Soffian @ 2011-02-01 7:04 UTC (permalink / raw)
To: Thomas Rast; +Cc: Junio C Hamano, git
In-Reply-To: <201101312244.10047.trast@student.ethz.ch>
On Mon, Jan 31, 2011 at 4:44 PM, Thomas Rast <trast@student.ethz.ch> wrote:
> Add a fetch.updateRemoteNamespace (or so) configuration variable that
> defaults to false. When enabled, it turns on the auto-updating
> behaviour.
Would it make sense to group the pre-1.8 compatibility switches
together in some way, if there will be several of them? Maybe
[compat]
fetchUpdateRemoteNamespace = false
...
(Thinking out loud.)
j.
^ permalink raw reply
* [1.8.0] Change branch --set-uptream to take an argument
From: Jay Soffian @ 2011-02-01 6:57 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Proposal:
Currently it is very easy to misinvoke --set-upstream if you assume it
takes an argument:
e.g.
(master)$ git branch --set-upstream origin/master
Branch origin/master set up to track local branch master.
In order to make its usage unambiguous, and to allow it to be used w/o
specifying the current branch, require it to take an argument like so:
(master)$ git branch --set-upstream=origin/master
(I've misinvoked it so often, I've had to train myself to always
invoke it this way: git branch master --set-upstream origin/master)
Risks:
Hands which have become trained to use it as it currently is, scripts, etc.
Migration plan:
Introduce the new syntax to the man page and git branch for 1.7.x and
emit a warning whenever the current syntax is used. In 1.8, break the
current syntax.
(Though I'm not sure whether the options parser allows for both
--set-upstream and --set-upstream=<arg>)
j.
^ permalink raw reply
* Porting JGit HistogramDiff
From: Shawn Pearce @ 2011-02-01 5:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Mon, Jan 31, 2011 at 09:05, Junio C Hamano <gitster@pobox.com> wrote:
>
> * Shawn Pearce says that the diff implementation JGit uses (histogram
> diff) performs way better than the xdiff implementation we use by
> default. It would be great if somebody can spend time taking a look at
> it and possibly port it back to C-git.
The idea that JGit's HistogramDiff is faster came from Robin Rosenburg in [1]:
> $ time jgit log -M -p >jgit.txt
>
> real 0m3.880s
> user 0m7.137s
> sys 0m0.807s
>
> $ time git log -M -p >cgit.txt
>
> real 0m16.420s
> user 0m14.936s
> sys 0m0.899s
>
> Seems JGit beats the pants off C Git. A quick scans implies both version
> produce correct diffs, but don't post this to the Git ML list just yet :)
HistogramDiff is a variation of Patience Difference[2]. Within JGit
it is implemented as two classes:
HistogramDiff[3] - the top level driver
HistogramDiffIndex[4] - the hash table used to count and match occurrences
Because its based on a hash table, the hash function for lines matters
a lot. xdiff's hash is crap, it generates too many collisions on the
linux-2.6 repository's source files. We use djb's hash function,
which you can find in our RawTextComparator class[5]. We actually
tested a number of hash functions using a test program [6].
I may try to port this myself, but it would be great if someone else
beat me to it. :-)
[1] http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg00897.html
[2] http://bramcohen.livejournal.com/73318.html
[3] http://egit.eclipse.org/w/?p=jgit.git;a=blob;f=org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiff.java;hb=HEAD
[4] http://egit.eclipse.org/w/?p=jgit.git;a=blob;f=org.eclipse.jgit/src/org/eclipse/jgit/diff/HistogramDiffIndex.java;hb=HEAD
[5] http://egit.eclipse.org/w/?p=jgit.git;a=blob;f=org.eclipse.jgit/src/org/eclipse/jgit/diff/RawTextComparator.java;hb=HEAD
[6] http://egit.eclipse.org/w/?p=jgit.git;a=blob;f=org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java;hb=HEAD
--
Shawn.
^ permalink raw reply
* Re: Planning for 1.7.5 and 1.8.0
From: Nicolas Pitre @ 2011-02-01 4:16 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: git
In-Reply-To: <AANLkTikeqsg+qJ0z4iQ6ZmKL=_HB8YX_z20L=dFFApmA@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 643 bytes --]
On Tue, 1 Feb 2011, Nguyen Thai Ngoc Duy wrote:
> On Tue, Feb 1, 2011 at 12:05 AM, Junio C Hamano <gitster@pobox.com> wrote:
> > Now the 1.7.4 release is out, I'd like people to help thinking about the
> > next cycle(s).
> >
> > As a discussion-starter, here are my random wishes. Even though this does
> > not attempt to be exhaustive, keeping the number of goals manageably small
> > may help us focus.
>
> Another random wish, which does not come with a proposal. How about
> tag namespace (ie. tags from a remote stay in remote namespace)?
Please make this into a proper proposal. this would be indeed a huge
improvement.
Nicolas
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Nicolas Pitre @ 2011-02-01 4:05 UTC (permalink / raw)
To: Jeff King; +Cc: Junio C Hamano, git
In-Reply-To: <20110201014807.GA2722@sigill.intra.peff.net>
On Mon, 31 Jan 2011, Jeff King wrote:
> On Mon, Jan 31, 2011 at 07:29:54PM -0500, Nicolas Pitre wrote:
>
> > This is no excuse not to do proper source tree reorganization.
>
> I think this is the crux of our disagreement. I don't agree that your
> proposal is any way more "proper" than what is there now. Leaving the
> rename issue aside (i.e., if we were starting a new project), I would
> still be slightly against a src/ directory. I find them annoying.
Let's agree to disagree then. What I see in the root of the Git source
tree is a huge clutter of source files, binary files, scripts, and
subdirectories all mixed together. If you know by hart where things are
because you've been hacking on them for the last 5 years then of course
you might not see the point. But since I didn't work much on Git
lately, things are not as obvious to me as they used to be. Looking
back at it now with some distance, this tree looks like a mess and it is
really annoying to work with.
> But I don't care _that_ much, and I would rather not waste either of our
> time debating it more. I would much rather you spend your time on
> pack v4. :)
I wish... I wish. But I have a plan which might involve taking some
vacation from $day_job in the Caribbeans with $wife and no kids, where
$wife is going to do scuba diving with her club mates while I'll be
alone with a laptop and no net connection and therefore nothing else to
do for a week. I've been craving for such free time for quite a while
now.
Nicolas
^ permalink raw reply
* Re: Planning for 1.7.5 and 1.8.0
From: Nguyen Thai Ngoc Duy @ 2011-02-01 3:20 UTC (permalink / raw)
To: git
In-Reply-To: <7vwrll57ha.fsf@alter.siamese.dyndns.org>
On Tue, Feb 1, 2011 at 12:05 AM, Junio C Hamano <gitster@pobox.com> wrote:
> Now the 1.7.4 release is out, I'd like people to help thinking about the
> next cycle(s).
>
> As a discussion-starter, here are my random wishes. Even though this does
> not attempt to be exhaustive, keeping the number of goals manageably small
> may help us focus.
Another random wish, which does not come with a proposal. How about
tag namespace (ie. tags from a remote stay in remote namespace)?
--
Duy
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Jeff King @ 2011-02-01 1:57 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: Nicolas Pitre, Junio C Hamano, git
In-Reply-To: <AANLkTi=boNXZbryTGFth5igZ771BbTmEKmh7LOxko+T-@mail.gmail.com>
On Tue, Feb 01, 2011 at 02:00:05AM +0100, Sverre Rabbelier wrote:
> Heya,
>
> On Tue, Feb 1, 2011 at 00:12, Jeff King <peff@peff.net> wrote:
> > [1] I'd be interested to see how much we can get around that slowness
> > using a notes-cache.
>
> Do you mean something like a refs/notes/renames namespace in which we
> stick notes on commits indicating that a rename indicated at that
> commit, with an option of the user, after-the-fact, adding this
> information manually?
Yes, without the "option of the user..." bit. Basically just cache the
list of renames for a given commit against its parent (which should be
immutable[1]), under the assumption that it is cheaper to look up the
note than it is to calculate the renames.
But I would make it purely a cache, not some place for users to stick
their own generated rename information (if people really want to do
that, I would much rather see it go into the commit itself as a
pseudo-header).
-Peff
[1] It's technically not immutable if you limit the pathspec, or if you
have non-standard rename options. But you could define some "canonical"
rename set, like all of the pairs found doing rename detection with -M90
when considering the whole set of removed files as sources and added
files as destinations. That would cover the common case of people
running "git log", and then more specialized detection would not use the
cache.
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Jeff King @ 2011-02-01 1:53 UTC (permalink / raw)
To: Erik Faye-Lund; +Cc: Nicolas Pitre, Junio C Hamano, git
In-Reply-To: <AANLkTim6YN5k+JjxYBkfpXYze1MRxFNAmSeJ_0CQpBnf@mail.gmail.com>
On Tue, Feb 01, 2011 at 01:35:16AM +0100, Erik Faye-Lund wrote:
> > It will still be _slower_ to turn it on all the time, for one[1]. And
> > that's due to fundamental design decisions of the git data structure.
>
> Does it really have to be? I mean, for whole-file rename-detection, if
> we say that we automatically enable rename-detection (by default) as
> we reach the first commit that doesn't have a given tree-entry, then
> it would only kick in as we're about to terminate the log-output. And
> since we're usually reading through a pager, it should means that it
> takes a little bit more time before the user knows he's at the end of
> the log. It shouldn't really affect the throughput of the data before
> the point that becomes an annoyance, right?
That's not quite true. You may be following not just a single file, but
some arbitrary pathspec. Any time there is a file creation event that
matches that pathspec, you will want to rename-detect any possible
sources for that created file, and add them to the list of interesting
paths.
But yeah, we don't have to do rename detection for every single case. So
the slowness may turn out to be not that bad. When I had
arbitrary-pathspec following this summer I thought I did some numbers,
but I don't remember the results and I can't find them on the list.
-Peff
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Jeff King @ 2011-02-01 1:48 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Junio C Hamano, git
In-Reply-To: <alpine.LFD.2.00.1101311903320.8580@xanadu.home>
On Mon, Jan 31, 2011 at 07:29:54PM -0500, Nicolas Pitre wrote:
> > Yes, we do suck at rename following. The problem is that it is partially
> [...]
> This is no excuse not to do proper source tree reorganization.
I think this is the crux of our disagreement. I don't agree that your
proposal is any way more "proper" than what is there now. Leaving the
rename issue aside (i.e., if we were starting a new project), I would
still be slightly against a src/ directory. I find them annoying.
But I don't care _that_ much, and I would rather not waste either of our
time debating it more. I would much rather you spend your time on
pack v4. :)
> I disagree. This is like saying: "renames are not well supported, so
> let's avoid them while using Git." People used to say that of merges
> with CVS. Are we going to follow suit de facto? Imagine the Git
> detractors taking our source tree mess to exemplify this Git flaw since
> "Git developers themselves are unwilling to move files around because
> Git sucks at it".
For the record, part of my argument was that renaming is annoying to
some degree in _all_ systems, not just git.
> > I do think it's wrong to say "renames can't be
> > done"; I just the cost needs to be considered.
>
> Instead, why not saying: "Rename tracking is not as optimal as it could
> be, so let's work it out." ?
I did also say that. :)
-Peff
^ permalink raw reply
* Re: [1.8.0] 't/' is standard name for directory with tests
From: Junio C Hamano @ 2011-02-01 1:15 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Alex Budovski, Jakub Narebski, Junio C Hamano, git
In-Reply-To: <alpine.LFD.2.00.1101311930280.8580@xanadu.home>
Nicolas Pitre <nico@fluxnic.net> writes:
> On Tue, 1 Feb 2011, Alex Budovski wrote:
> ...
>> The MySQL project (and its clones) also uses the t/ convention.
>
> OK, that makes for another one.
>
> Now what about those hundred counter-example projects _not_ using "t"
> but something more descriptive?
I am fine with "tests/", by the way.
^ permalink raw reply
* Re: [1.8.0] make two-argument fetch update remote branches
From: Junio C Hamano @ 2011-02-01 1:13 UTC (permalink / raw)
To: Eugene Sajine; +Cc: Thomas Rast, git
In-Reply-To: <AANLkTinRo5KxC9OQWyZMnqQP4WHi0sR5qqw6byr4V+3a@mail.gmail.com>
Eugene Sajine <euguess@gmail.com> writes:
> I did understand what Thomas illustrated. I'm just thinking that the
> range origin/master...FETCH_HEAD seems to be useful but in fact is
> pretty useless, because you cannot guarantee the state of the
> origin/master _before_ the fetch and therefore you cannot rely on the
> results of range selections involving it.
With the current system, origin/master is what I _used to_ have before
running this fetch, iow, what I have been looking at as a reference
material while I did my own work so far. The current "when fetching refs
explicitly, do not touch tracking branches" behaviour guarantees that.
The range above shows what I already knew about the work the other people
did, and what is new on both sides, to help me decide what I want to do
next with the fetched result. At least that is the workflow the "when
fetching refs explicitly, do not touch tracking branches" behaviour allows
us to support (I am not recommending that the workflow in particular, by
the way). The next action after seeing what they added is sane may be to
run "git pull" (no arguments), which would fast-forward my view of the
other side to whatever I reviewed this round.
^ permalink raw reply
* Re: [1.8.0] reorganize the mess that the source tree has become
From: Sverre Rabbelier @ 2011-02-01 1:00 UTC (permalink / raw)
To: Jeff King; +Cc: Nicolas Pitre, Junio C Hamano, git
In-Reply-To: <20110131231210.GD14419@sigill.intra.peff.net>
Heya,
On Tue, Feb 1, 2011 at 00:12, Jeff King <peff@peff.net> wrote:
> [1] I'd be interested to see how much we can get around that slowness
> using a notes-cache.
Do you mean something like a refs/notes/renames namespace in which we
stick notes on commits indicating that a rename indicated at that
commit, with an option of the user, after-the-fact, adding this
information manually?
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* Re: [1.8.0] 't/' is standard name for directory with tests
From: Jakub Narebski @ 2011-02-01 0:58 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Alex Budovski, Junio C Hamano, git
In-Reply-To: <alpine.LFD.2.00.1101311930280.8580@xanadu.home>
On Tue, 1 Feb 2011, Nicolas Pitre wrote:
> On Tue, 1 Feb 2011, Alex Budovski wrote:
>
> > >> Nope. 't/' is the standard name for directory with "normal" tests, at
> > >> least in Perl / CPAN land, where TAP comes from ('xt/' is for extra
> > >> tests)
> > >
> > > So what? It is not because Perl has set this horrible precedent that we
> > > have to perpetuate it. I personally never saw t used as a directory
> > > name for tests before Git, and I'm not that young anymore unfortunately.
CPAN is around 21000 distributions and 88000 modules. Most of those use
't/' for tests (default CPAN client to download and install modules runs
those tests before installing module).
> > The MySQL project (and its clones) also uses the t/ convention.
>
> OK, that makes for another one.
>
> Now what about those hundred counter-example projects _not_ using "t"
> but something more descriptive?
You mean those counter-example projects that use and include comprehensive
tests, isn't it?
Well, GCC uses 'testsuite/'. Mozilla uses 'testing/'.
--
Jakub Narebski
Poland
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox