* [PATCH 3/3] Build an svn-fi target in contrib/svn-fe
From: Ramkumar Ramachandra @ 2011-01-15 6:51 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier
In-Reply-To: <1295074272-19559-1-git-send-email-artagnon@gmail.com>
Build an svn-fi target for testing the dumpfile producer in vcs-svn/.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
contrib/svn-fe/Makefile | 23 +++++++++++++++++++++--
contrib/svn-fe/svn-fi.c | 16 ++++++++++++++++
contrib/svn-fe/svn-fi.txt | 28 ++++++++++++++++++++++++++++
3 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 contrib/svn-fe/svn-fi.c
create mode 100644 contrib/svn-fe/svn-fi.txt
diff --git a/contrib/svn-fe/Makefile b/contrib/svn-fe/Makefile
index 360d8da..555a8ff 100644
--- a/contrib/svn-fe/Makefile
+++ b/contrib/svn-fe/Makefile
@@ -37,7 +37,7 @@ svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(GIT_LIB)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ svn-fe.o \
$(ALL_LDFLAGS) $(LIBS)
-svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h
+svn-fe.o: svn-fe.c ../../vcs-svn/svnload.h
$(QUIET_CC)$(CC) -I../../vcs-svn -o $*.o -c $(ALL_CFLAGS) $<
svn-fe.html: svn-fe.txt
@@ -51,6 +51,24 @@ svn-fe.1: svn-fe.txt
../contrib/svn-fe/$@
$(MV) ../../Documentation/svn-fe.1 .
+svn-fi$X: svn-fi.o $(VCSSVN_LIB) $(GIT_LIB)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ svn-fi.o \
+ $(ALL_LDFLAGS) $(LIBS)
+
+svn-fi.o: svn-fi.c ../../vcs-svn/svnload.h
+ $(QUIET_CC)$(CC) -I../../vcs-svn -o $*.o -c $(ALL_CFLAGS) $<
+
+svn-fi.html: svn-fi.txt
+ $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
+ MAN_TXT=../contrib/svn-fe/svn-fi.txt \
+ ../contrib/svn-fe/$@
+
+svn-fi.1: svn-fi.txt
+ $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
+ MAN_TXT=../contrib/svn-fe/svn-fi.txt \
+ ../contrib/svn-fe/$@
+ $(MV) ../../Documentation/svn-fi.1 .
+
../../vcs-svn/lib.a: FORCE
$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) vcs-svn/lib.a
@@ -58,6 +76,7 @@ svn-fe.1: svn-fe.txt
$(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) libgit.a
clean:
- $(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1
+ $(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1 \
+ svn-fi$X svn-fi.o svn-fi.html svn-fi.xml svn-fi.1
.PHONY: all clean FORCE
diff --git a/contrib/svn-fe/svn-fi.c b/contrib/svn-fe/svn-fi.c
new file mode 100644
index 0000000..81347b0
--- /dev/null
+++ b/contrib/svn-fe/svn-fi.c
@@ -0,0 +1,16 @@
+/*
+ * This file is in the public domain.
+ * You may freely use, modify, distribute, and relicense it.
+ */
+
+#include <stdlib.h>
+#include "svnload.h"
+
+int main(int argc, char **argv)
+{
+ if (svnload_init(NULL))
+ return 1;
+ svnload_read();
+ svnload_deinit();
+ return 0;
+}
diff --git a/contrib/svn-fe/svn-fi.txt b/contrib/svn-fe/svn-fi.txt
new file mode 100644
index 0000000..996a175
--- /dev/null
+++ b/contrib/svn-fe/svn-fi.txt
@@ -0,0 +1,28 @@
+svn-fe(1)
+=========
+
+NAME
+----
+svn-fi - convert fast-import stream to an SVN "dumpfile"
+
+SYNOPSIS
+--------
+[verse]
+svn-fi
+
+DESCRIPTION
+-----------
+
+Converts a git-fast-import(1) stream into a Subversion dumpfile.
+
+INPUT FORMAT
+-------------
+The fast-import format is documented by the git-fast-import(1)
+manual page.
+
+OUTPUT FORMAT
+------------
+Subversion's repository dump format is documented in full in
+`notes/dump-load-format.txt` from the Subversion source tree.
+Files in this format can be generated using the 'svnadmin dump' or
+'svk admin dump' command.
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply related
* [PATCH 2/3] vcs-svn: Start working on the dumpfile producer
From: Ramkumar Ramachandra @ 2011-01-15 6:51 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier
In-Reply-To: <1295074272-19559-1-git-send-email-artagnon@gmail.com>
Start off with some broad design sketches. Compile succeeds, but
parser is incorrect. Include a Makefile rule to build it into
vcs-svn/lib.a.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
Makefile | 2 +-
vcs-svn/dump_export.c | 73 ++++++++++++
vcs-svn/svnload.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 368 insertions(+), 1 deletions(-)
create mode 100644 vcs-svn/dump_export.c
create mode 100644 vcs-svn/svnload.c
diff --git a/Makefile b/Makefile
index 1345c38..40f6691 100644
--- a/Makefile
+++ b/Makefile
@@ -1834,7 +1834,7 @@ 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
VCSSVN_TEST_OBJS = test-obj-pool.o \
diff --git a/vcs-svn/dump_export.c b/vcs-svn/dump_export.c
new file mode 100644
index 0000000..04ede06
--- /dev/null
+++ b/vcs-svn/dump_export.c
@@ -0,0 +1,73 @@
+/*
+ * 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"
+
+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) {
+ printf("Node-path: %s\n", path);
+ printf("Node-kind: ");
+ switch (action) {
+ case NODE_KIND_NORMAL:
+ printf("file\n");
+ break;
+ case NODE_KIND_EXECUTABLE:
+ printf("file\n");
+ break;
+ case NODE_KIND_SYMLINK:
+ printf("file\n");
+ break;
+ case NODE_KIND_GITLINK:
+ printf("file\n");
+ break;
+ case NODE_KIND_SUBDIR:
+ die("Unsupported: subdirectory");
+ default:
+ break;
+ }
+ printf("Node-action: ");
+ switch (action) {
+ case NODE_ACTION_CHANGE:
+ printf("change\n");
+ break;
+ case NODE_ACTION_ADD:
+ printf("add\n");
+ break;
+ case NODE_ACTION_REPLACE:
+ printf("replace\n");
+ break;
+ case NODE_ACTION_DELETE:
+ printf("delete\n");
+ 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);
+ }
+ printf("Prop-delta: false\n");
+ printf("Prop-content-length: 10\n"); /* Constant 10 for "PROPS-END" */
+ printf("Text-delta: false\n");
+ printf("Text-content-length: %lu\n", text_len);
+ printf("Content-length: %lu\n\n", text_len + 10);
+ printf("PROPS-END\n\n");
+}
+
+void dump_export_text(struct line_buffer *data, off_t len) {
+ buffer_copy_bytes(data, len);
+}
diff --git a/vcs-svn/svnload.c b/vcs-svn/svnload.c
new file mode 100644
index 0000000..7043ae7
--- /dev/null
+++ b/vcs-svn/svnload.c
@@ -0,0 +1,294 @@
+/*
+ * 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 "strbuf.h"
+
+#define SVN_DATE_FORMAT "%Y-%m-%dT%H:%M:%S.000000Z"
+#define SVN_DATE_LEN 28
+#define LENGTH_UNKNOWN (~0)
+
+static struct line_buffer input = LINE_BUFFER_INIT;
+static struct strbuf blobs[100];
+
+static struct {
+ unsigned long prop_len, text_len, copyfrom_rev, mark;
+ int text_delta, prop_delta; /* Boolean */
+ 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 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.mark = 0;
+ node_ctx.copyfrom_rev = 0;
+ node_ctx.text_delta = -1;
+ node_ctx.prop_delta = -1;
+ strbuf_reset(&node_ctx.copyfrom_path);
+ strbuf_reset(&node_ctx.path);
+}
+
+static void populate_props(struct strbuf *props, const char *author,
+ const char *log, const char *date) {
+ strbuf_reset(props);
+ strbuf_addf(props, "K\nsvn:author\nV\n%s\n", author);
+ strbuf_addf(props, "K\nsvn:log\nV\n%s", log);
+ strbuf_addf(props, "K\nsvn:date\nV\n%s\n", 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];
+ const struct tm *tm_time;
+
+ /* Simon Hausmann <shausman@trolltech.com> 1170199019 +0100 */
+ strbuf_reset(name);
+ strbuf_reset(email);
+ strbuf_reset(date);
+ tz_off = strrchr(val, ' ');
+ *tz_off++ = '\0';
+ t = strrchr(val, ' ');
+ *(t - 1) = '\0'; /* Ignore '>' from email */
+ t ++;
+ tm_time = time_to_tm(strtoul(t, NULL, 10), atoi(tz_off));
+ strftime(time_buf, SVN_DATE_LEN, SVN_DATE_FORMAT, tm_time);
+ strbuf_add(date, time_buf, SVN_DATE_LEN);
+ t = strchr(val, '<');
+ *(t - 1) = '\0'; /* Ignore ' <' from email */
+ t ++;
+ strbuf_add(email, t, strlen(t));
+ strbuf_add(name, val, strlen(val));
+}
+
+void svnload_read(void) {
+ char *t, *val;
+ int mode_incr;
+ struct strbuf *to_dump;
+
+ while ((t = buffer_read_line(&input))) {
+ val = strchr(t, ' ');
+ if (!val) {
+ if (!memcmp(t, "blob", 4))
+ active_ctx = BLOB_CTX;
+ else if (!memcmp(t, "deleteall", 9))
+ ;
+ continue;
+ }
+ *val++ = '\0';
+
+ /* strlen(key) */
+ switch (val - t - 1) {
+ 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)) {
+ node_ctx.action = NODE_ACTION_CHANGE;
+ mode_incr = 7;
+ 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 {
+ if (!memcmp(val, "755", 3))
+ node_ctx.kind = NODE_KIND_EXECUTABLE;
+ else if(!memcmp(val, "644", 3))
+ node_ctx.kind = NODE_KIND_NORMAL;
+ else
+ die("Unrecognized mode: %s", val);
+ mode_incr = 4;
+ }
+ val += mode_incr;
+ t = strchr(val, ' ');
+ *t++ = '\0';
+ strbuf_reset(&node_ctx.path);
+ strbuf_add(&node_ctx.path, t, strlen(t));
+ if (!memcmp(val + 1, "inline", 6))
+ die("Unsupported dataref: inline");
+ else if (*val == ':')
+ to_dump = &blobs[strtoul(val + 1, NULL, 10)];
+ else
+ die("Unsupported dataref: sha1");
+ dump_export_node(node_ctx.path.buf, node_ctx.kind,
+ node_ctx.action, to_dump->len,
+ 0, NULL);
+ printf("%s", to_dump->buf);
+ }
+ break;
+ case 3:
+ if (!memcmp(t, "tag", 3))
+ continue;
+ break;
+ case 4:
+ if (!memcmp(t, "mark", 4))
+ switch(active_ctx) {
+ case COMMIT_CTX:
+ /* What do we do with commit marks? */
+ continue;
+ case BLOB_CTX:
+ node_ctx.mark = strtoul(val + 1, NULL, 10);
+ break;
+ default:
+ break;
+ }
+ 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_props(&rev_ctx.props,
+ rev_ctx.svn_author.buf,
+ rev_ctx.log.buf,
+ 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);
+ buffer_read_binary(&input,
+ &blobs[node_ctx.mark],
+ 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 */
+ t = strchr(rev_ctx.author_email.buf, '@');
+ strbuf_reset(&rev_ctx.svn_author);
+ strbuf_add(&rev_ctx.svn_author,
+ rev_ctx.author_email.buf,
+ t - rev_ctx.author_email.buf);
+
+ }
+ else if (!memcmp(t, "commit", 6)) {
+ rev_ctx.rev ++;
+ active_ctx = COMMIT_CTX;
+ }
+ break;
+ case 9:
+ if (!memcmp(t, "committer", 9))
+ parse_author_line(val, &rev_ctx.committer,
+ &rev_ctx.committer_email,
+ &rev_ctx.committer_date);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+int svnload_init(const char *filename)
+{
+ int i;
+ 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.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);
+ for (i = 0; i < 100; i ++)
+ strbuf_init(&blobs[i], 10000);
+ return 0;
+}
+
+void svnload_deinit(void)
+{
+ int i;
+ 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.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);
+ for (i = 0; i < 100; i ++)
+ strbuf_release(&blobs[i]);
+ if (buffer_deinit(&input))
+ fprintf(stderr, "Input error\n");
+ if (ferror(stdout))
+ fprintf(stderr, "Output error\n");
+}
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply related
* [PATCH 1/3] date: Expose the time_to_tm function
From: Ramkumar Ramachandra @ 2011-01-15 6:51 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier
In-Reply-To: <1295074272-19559-1-git-send-email-artagnon@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
cache.h | 1 +
date.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/cache.h b/cache.h
index d83d68c..95fea31 100644
--- a/cache.h
+++ b/cache.h
@@ -816,6 +816,7 @@ enum date_mode {
DATE_RAW
};
+struct tm *time_to_tm(unsigned long time, int tz);
const char *show_date(unsigned long time, int timezone, enum date_mode mode);
const char *show_date_relative(unsigned long time, int tz,
const struct timeval *now,
diff --git a/date.c b/date.c
index 00f9eb5..e601a50 100644
--- a/date.c
+++ b/date.c
@@ -54,7 +54,7 @@ static time_t gm_time_t(unsigned long time, int tz)
* thing, which means that tz -0100 is passed in as the integer -100,
* even though it means "sixty minutes off"
*/
-static struct tm *time_to_tm(unsigned long time, int tz)
+struct tm *time_to_tm(unsigned long time, int tz)
{
time_t t = gm_time_t(time, tz);
return gmtime(&t);
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply related
* [RFC PATCH 0/3] Towards a Git-to-SVN bridge
From: Ramkumar Ramachandra @ 2011-01-15 6:51 UTC (permalink / raw)
To: Git List; +Cc: Jonathan Nieder, David Barr, Sverre Rabbelier
Hi,
Over the last couple of days, I've been working on a parser that
converts a fast-import stream into a SVN dumpfile. So far, it's very
rough and works minimally for some common fast-import
commands. However, the major roadblock is persisting blobs: in this
implementation, they're persisted as an array of strbufs. This is very
memory-intensive and not scalable at all. With some valuable insight
from Jonathan on IRC, I've decided to try re-implementing fast-export
to eliminate blob marks and produce them inline instead [1].
Comments are much appreciated.
[1]: http://colabti.org/irclogger/irclogger_log/git-devel?date=2011-01-14
Ramkumar Ramachandra (3):
date: Expose the time_to_tm function
vcs-svn: Start working on the dumpfile producer
Build an svn-fi target in contrib/svn-fe
Makefile | 2 +-
cache.h | 1 +
contrib/svn-fe/Makefile | 23 ++++-
contrib/svn-fe/svn-fi.c | 16 +++
contrib/svn-fe/svn-fi.txt | 28 +++++
date.c | 2 +-
vcs-svn/dump_export.c | 73 +++++++++++
vcs-svn/svnload.c | 294 +++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 435 insertions(+), 4 deletions(-)
create mode 100644 contrib/svn-fe/svn-fi.c
create mode 100644 contrib/svn-fe/svn-fi.txt
create mode 100644 vcs-svn/dump_export.c
create mode 100644 vcs-svn/svnload.c
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply
* [PATCH] fast-import: Introduce --import-marks-if-exists
From: Ramkumar Ramachandra @ 2011-01-15 6:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, Git List
In-Reply-To: <20110111175102.GB15133@burratino>
The --import-marks option errors out when the specified marks file
doesn't exist. If a frontend is just using a marks file to ensure its
state persists between runs, it would be simpler if missing marks
files were tolerated. In some cases, the frontend cannot even check
for the existence of the marks file because with --relative-marks, the
location of the marks file is backend-dependent. This can be solved by
changing the meaning of --import-marks, but will result in trading off
functionality that some frontends might desire. So, add new
command-line option --import-marks-if-exists that's like
--import-marks, except that it tolerates missing marks files.
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
Changes since last time: Junio suggested making this an optional
feature, and Jonathan wrote a fixup patch for the same.
Documentation/git-fast-import.txt | 4 +++
fast-import.c | 16 +++++++++--
t/t9300-fast-import.sh | 55 +++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index f56dfca..32a062c 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -78,6 +78,10 @@ OPTIONS
set of marks. If a mark is defined to different values,
the last file wins.
+--import-marks-if-exists=<file>::
+ Like --import-marks but instead of erroring out, silently
+ skips the file if it does not exist.
+
--relative-marks::
After specifying --relative-marks= the paths specified
with --import-marks= and --export-marks= are relative
diff --git a/fast-import.c b/fast-import.c
index 7857760..c525fda 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -329,6 +329,7 @@ static struct mark_set *marks;
static const char *export_marks_file;
static const char *import_marks_file;
static int import_marks_file_from_stream;
+static int import_marks_file_ignore_missing;
static int relative_marks_paths;
/* Our last blob */
@@ -1795,7 +1796,11 @@ static void read_marks(void)
{
char line[512];
FILE *f = fopen(import_marks_file, "r");
- if (!f)
+ if (f)
+ ;
+ else if (import_marks_file_ignore_missing && errno == ENOENT)
+ return; /* Marks file does not exist */
+ else
die_errno("cannot read '%s'", import_marks_file);
while (fgets(line, sizeof(line), f)) {
uintmax_t mark;
@@ -2861,7 +2866,8 @@ static char* make_fast_import_path(const char *path)
return strbuf_detach(&abs_path, NULL);
}
-static void option_import_marks(const char *marks, int from_stream)
+static void option_import_marks(const char *marks,
+ int from_stream, int ignore_missing)
{
if (import_marks_file) {
if (from_stream)
@@ -2875,6 +2881,7 @@ static void option_import_marks(const char *marks, int from_stream)
import_marks_file = make_fast_import_path(marks);
safe_create_leading_directories_const(import_marks_file);
import_marks_file_from_stream = from_stream;
+ import_marks_file_ignore_missing = ignore_missing;
}
static void option_date_format(const char *fmt)
@@ -2974,7 +2981,10 @@ static int parse_one_feature(const char *feature, int from_stream)
if (!prefixcmp(feature, "date-format=")) {
option_date_format(feature + 12);
} else if (!prefixcmp(feature, "import-marks=")) {
- option_import_marks(feature + 13, from_stream);
+ option_import_marks(feature + 13, from_stream, 0);
+ } else if (!prefixcmp(feature, "import-marks-if-exists=")) {
+ option_import_marks(feature + strlen("import-marks-if-exists="),
+ from_stream, 1);
} else if (!prefixcmp(feature, "export-marks=")) {
option_export_marks(feature + 13);
} else if (!strcmp(feature, "cat-blob")) {
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 222d105..870e55b 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1706,6 +1706,61 @@ test_expect_success \
'cat input | git fast-import --export-marks=other.marks &&
grep :1 other.marks'
+test_expect_success 'R: catch typo in marks file name' '
+ test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null &&
+ echo "feature import-marks=nonexistent.marks" |
+ test_must_fail git fast-import
+'
+
+test_expect_success 'R: import and output marks can be the same file' '
+ rm -f io.marks &&
+ blob=$(echo hi | git hash-object --stdin) &&
+ cat >expect <<-EOF &&
+ :1 $blob
+ :2 $blob
+ EOF
+ git fast-import --export-marks=io.marks <<-\EOF &&
+ blob
+ mark :1
+ data 3
+ hi
+
+ EOF
+ git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF &&
+ blob
+ mark :2
+ data 3
+ hi
+
+ EOF
+ test_cmp expect io.marks
+'
+
+test_expect_success 'R: --import-marks=foo --output-marks=foo to create foo fails' '
+ rm -f io.marks &&
+ test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF
+ blob
+ mark :1
+ data 3
+ hi
+
+ EOF
+'
+
+test_expect_success 'R: --import-marks-if-exists' '
+ rm -f io.marks &&
+ blob=$(echo hi | git hash-object --stdin) &&
+ echo ":1 $blob" >expect &&
+ git fast-import --import-marks-if-exists=io.marks --export-marks=io.marks <<-\EOF &&
+ blob
+ mark :1
+ data 3
+ hi
+
+ EOF
+ test_cmp expect io.marks
+'
+
cat >input << EOF
feature import-marks=marks.out
feature export-marks=marks.new
--
1.7.4.rc1.7.g2cf08.dirty
^ permalink raw reply related
* Re: small downloads and immutable history (Re: clone breaks replace)
From: Phillip Susi @ 2011-01-15 5:27 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Johannes Sixt, Jeff King, git, Christian Couder, Stephen Bash
In-Reply-To: <20110114205308.GA15286@burratino>
On 01/14/2011 03:53 PM, Jonathan Nieder wrote:
> Ah, I forgot the use case. If you are using this to at long last get
> past the limitations (e.g., inability to push) of "fetch --depth",
> then yes, rewriting existing history is bad.
I'm not really talking about using --depth, but more of the project
deciding to truncate the history in the central repository.
> So what's left is some way to make the "have" part of transport
> negotiation make sense in this context. I'll be happy if it happens.
Good point. Whether local history is short because of --depth or
replace records, the same problem arises; the negotiation needs to be
able to exclude older objects that are not present locally, rather than
assuming that the client has the entire history if it has any at all.
It seems like this should just require sending the server and end point
in addition to a start point. In other words, not just send ID of the
most recent commit, but also the oldest that it has on hand, so that the
server can be sure that it does not deltafy against objects prior to
that commit.
^ permalink raw reply
* multiple group access to update repo
From: Neal Kreitzinger @ 2011-01-15 4:53 UTC (permalink / raw)
To: git
How do I allow users from different linux group to cd to a common bare
mirror repo and also to a common non-bare cloned repo and perform
git-fetch and git pull --ff-only? Currently, the non-owner group gets
this error:
error: cannot open FETCH_HEAD: Permission denied
v/r,
Neal
^ permalink raw reply
* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
From: Maaartin-1 @ 2011-01-15 0:04 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Jonathan Nieder, git, Aleksey Shumkin
In-Reply-To: <201101142348.31647.jnareb@gmail.com>
On 11-01-14 23:48, Jakub Narebski wrote:
> On Fri, 14 Jan 2011, Maaartin-1 wrote:
>> On 11-01-14 09:49, Jonathan Nieder wrote:
>>> Some tweaks suggested by Maaartin:
>>> [side note: please do not prune the cc list; I only stumbled on this
>>> message in the online archive by luck]
>>
>> What could I have done about it? I didn't received it by email and
>> answered using post.gmane.org. There's no way to add CC there. If I'd
>> wrote an email instead, it wouldn't be placed in the thread.
>
> In a good newsreader, like e.g. Gnus from GNU Emacs, you have option
> to do 'reply all via email', which includes also git@vger.kernel.org,
> i.e. mailing list from which gmane newsgroup is created. That's what
> I do nowadays (usually).
I hate using Emacs for too many things. However, I'm starting to use
Thunderbird as newsreader, and it's quite OK.
>> I'd go the other way round and use "-i" so I'd need only one file. Using
>> a shell variable instead would be even better, s. below.
>
> No, using shell variable for storing commit object is *not* a good idea.
> Either save it to temporary file, where you can edit it using editor of
> your choice, or use pipeline.
I see that the line-breaks get (for whatever reason) replaced by blanks,
sorry for the noise.
>>> +$ sed "/^tree / a \\
>>> +parent $(git rev-parse v2.4)" <tmp >new <4>
>>
>> $ first_commit = $($ echo $first_commit |
>> sed "/^tree / a \\
>> parent $(git rev-parse v2.4)") <4>
>>
>> Unfortunately, the line got too long. For sed unaware people like me it
>> may not be obvious that a line break is required.
>
> No, it is not required, I think.
You're right, sorry again.
> If you don't use temporary file, which you can edit, you can use pipeline
> instead:
>
> $ new_commit=$(git cat-file commit $first_commit |
> sed -e "/^tree / a\\parent $(git rev-parse v2.4)" |
> git hash-object -t commit -w --stdin
>
> $ git replace $first_commit $new_commit
I know, I just thought, using such a pipe is not very enlightening, but
it's actually quite easy to follow.
^ permalink raw reply
* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
From: Jakub Narebski @ 2011-01-14 22:48 UTC (permalink / raw)
To: Maaartin-1; +Cc: Jonathan Nieder, git, Aleksey Shumkin
In-Reply-To: <4D308B69.1050003@seznam.cz>
On Fri, 14 Jan 2011, Maaartin-1 wrote:
> On 11-01-14 09:49, Jonathan Nieder wrote:
> > Some tweaks suggested by Maaartin:
>
> [snip]
>
>> [side note: please do not prune the cc list; I only stumbled on this
>> message in the online archive by luck]
>
> What could I have done about it? I didn't received it by email and
> answered using post.gmane.org. There's no way to add CC there. If I'd
> wrote an email instead, it wouldn't be placed in the thread.
In a good newsreader, like e.g. Gnus from GNU Emacs, you have option
to do 'reply all via email', which includes also git@vger.kernel.org,
i.e. mailing list from which gmane newsgroup is created. That's what
I do nowadays (usually).
> [snip]
>
>>>> +<1> Find all parentless commits in the 'master' branch;
>>>> +for 'master' read the branch holding v2.5 history.
>>>
>>> Aren't you later calling it "FIRST" and assuming there's only one?
>>
>> Hmm. I want to say that there _could_ be multiple parentless commits
>> in the v2.5 history and we are treating one of them as its root (just
>> like git master has multiple parentless ancestors but e83c5163 is
>> conventionally considered its beginning). Not sure how to write that
>> clearly.
>
> Maybe just something like "Let's assume there's only one and let's call
> it FIRST". For the example, this is enough.
That might be good enough, as I don't think that at beginning (where you
are creating current and archive repository) one would have multiple roots
from joining separate projects.
>>> Isn't the combination of "-i" (=in-place edit) with redirection wrong?
>>
>> Good catch (the "-i" is a typo).
>
> I'd go the other way round and use "-i" so I'd need only one file. Using
> a shell variable instead would be even better, s. below.
No, using shell variable for storing commit object is *not* a good idea.
Either save it to temporary file, where you can edit it using editor of
your choice, or use pipeline.
> [snip]
>
> I tried to use the vars instead of files below, but never tested it. I
> used "first_commit" instead of both "tmp" and "new", which is not really
> nice.
>
>> +$ git rev-list master --parents | grep -v ' '
>> +$ first=$(git rev-list master --parents | grep -v ' ') <1>
Or using always the oldest commit:
+$ first=$(git rev-list master --date-order --parents | grep -v ' ' | tail -1) <1>
>> +$ git rev-parse v2.4 <2>
Let's save it to a variable too
+$ join=$(git rev-parse v2.4) <2>
>> +$ git cat-file commit $first >tmp <3>
We can use COMMIT, or even FIRST as a file name here.
> $ first_commit = $(git cat-file commit FIRST) <3>
No. Just... no.
> > +$ sed "/^tree / a \\
> > +parent $(git rev-parse v2.4)" <tmp >new <4>
>
> $ first_commit = $($ echo $first_commit |
> sed "/^tree / a \\
> parent $(git rev-parse v2.4)") <4>
>
> Unfortunately, the line got too long. For sed unaware people like me it
> may not be obvious that a line break is required.
No, it is not required, I think.
> I'd use perl, anyway.
>
> $ first_commit = $($ echo $first_commit |
> perl -p
> "s/^tree .*/$&\nparent $(git rev-parse v2.4)/") <4>
>
> > +$ new_commit=$(git hash-object -t commit -w new) <5>
>
> $ new_commit=$(echo $first_commit |
> git hash-object -t commit -w --stdin) <5>
If you don't use temporary file, which you can edit, you can use pipeline
instead:
$ new_commit=$(git cat-file commit $first_commit |
sed -e "/^tree / a\\parent $(git rev-parse v2.4)" |
git hash-object -t commit -w --stdin
$ git replace $first_commit $new_commit
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] git-p4: Fixed handling of file names with spaces
From: Jerzy Kozera @ 2011-01-14 22:45 UTC (permalink / raw)
To: Andreas Schwab; +Cc: git, gitster, msclrhd
In-Reply-To: <m28vyncffu.fsf@igel.home>
On 14 Jan 2011, at 22:01, Andreas Schwab wrote:
> Can those file names also include a double quote or a backquote or a
> dollar sign?
Double quote and backquote get escaped by git so they are not a problem:
$ git diff-tree -r HEAD^ HEAD
:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A "\" \\ $"
But as you can see above, the dollar sign remains intact, so it needs to be handled as well - patch below takes it into account.
Thanks,
Jerzy
---
contrib/fast-import/git-p4 | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index 04ce7e3..d930908 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -47,7 +47,7 @@ def p4_build_cmd(cmd):
real_cmd += "%s" % (cmd)
if verbose:
print real_cmd
- return real_cmd
+ return real_cmd.replace('$', '\\$')
def chdir(dir):
if os.name == 'nt':
@@ -139,12 +139,12 @@ def setP4ExecBit(file, mode):
if p4Type[-1] == "+":
p4Type = p4Type[0:-1]
- p4_system("reopen -t %s %s" % (p4Type, file))
+ p4_system("reopen -t %s \"%s\"" % (p4Type, file))
def getP4OpenedType(file):
# Returns the perforce file type for the given file.
- result = p4_read_pipe("opened %s" % file)
+ result = p4_read_pipe("opened \"%s\"" % file)
match = re.match(".*\((.+)\)\r?$", result)
if match:
return match.group(1)
@@ -666,7 +666,7 @@ class P4Submit(Command):
for f in editedFiles:
p4_system("revert \"%s\"" % f);
for f in filesToAdd:
- system("rm %s" %f)
+ system("rm \"%s\"" % f.replace('$', '\\$'))
return
elif response == "a":
os.system(applyPatchCmd)
--
1.7.1
^ permalink raw reply related
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Junio C Hamano @ 2011-01-14 22:30 UTC (permalink / raw)
To: Jeff King; +Cc: Erik Faye-Lund, Linus Torvalds, Tor Arntsen, JT Olds, git
In-Reply-To: <20110114200705.GA3316@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> More or less. You would still have some lossiness when emailing your
> patch. Do we want to warn about that?
Probably not.
There will only be less than hundred people with a single letter name in
the world (I was tempted to say 26 but decided to be generous ;-) like
that, and you will much more likely to see an overly short "name" part
from a misconfiguration or misparsing than from receiving a real patch
from people with such a name.
But I haven't thought the issues, possible improvements and pros-and-cons
through.
^ permalink raw reply
* Re: [PATCH] git-p4: Fixed handling of file names with spaces
From: Andreas Schwab @ 2011-01-14 22:01 UTC (permalink / raw)
To: Jerzy Kozera; +Cc: git, gitster, msclrhd
In-Reply-To: <1294944715-5647-1-git-send-email-jerzy.kozera@gmail.com>
Jerzy Kozera <jerzy.kozera@gmail.com> writes:
> I've noticed the same issue in reopen and rm calls - not saying these three are all occurences of this problem, but I guess fixing them is a good start.
Can those file names also include a double quote or a backquote or a
dollar sign?
Andreas.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* Re: cvsimport still not working with cvsnt
From: Junio C Hamano @ 2011-01-14 21:49 UTC (permalink / raw)
To: Jonathan Nieder
Cc: Guy Rouillier, Martin Langhoff, Emil Medve, git, Pascal Obry,
Clemens Buchacher
In-Reply-To: <20110114074449.GA11175@burratino>
Jonathan Nieder <jrnieder@gmail.com> writes:
> and recommended erroring out if both files exist to make this easier
> to diagnose.
>
> Emil's advice: if this is an important use case to you, maybe it would
> be served better by looking at both files?
Thanks for summarizing two-year's worth of discussion ;-)
Trying both, one after another, in the order that likely favors newer one
over the older one, is a very valid option but is appropriate only under a
very narrow condition. Picking a wrong one must reliably, silently _and_
quickly fail, and fail without any side effect. The one in .cvspass may
identify you as a different user from the user .cvs/cvspass identifies you
as, and the two users may have different capabilities or default server
side preferences--in such a case, both may succeed, but in a different and
unexpected way [*1*].
As the general principle, in a "we see two, and we cannot tell which one
the user wants to use" situation like this, I tend to prefer erroring out
to _force_ the user to fix the configuration once and for all.
Unless the "try both" approach is reasonable, we could implement "we read
from one and when we find one we stop, otherwise we read from the other"
and document the order, but it is probably less friendly than the above
two options.
[Footnote]
*1* I know .cvspass is a bad example for this, as it records the password
for the <pserver you are trying to connect to, your user on the server>
tuple. Once you get in, what you can do is exactly the same because you
are authenticating as the same user, but think of a case like .ssh/config
that is indexed by "Host" and allows you to use "User" to
^ permalink raw reply
* Re: noob question
From: Harry Johnson @ 2011-01-14 21:32 UTC (permalink / raw)
To: Thomas Rast; +Cc: git
In-Reply-To: <201101141210.25523.trast@student.ethz.ch>
>> I have used git-svn to create a git repo from our subversion repo. I
>> have done this as user foo which is just an account that is used for
>> doing central builds. I have then cloned this as repo as myself,
>> harry. My thought is that the repo owned by foo would be a central
>> repo that all of the developers, including myself, could clone and to
>> which we could then 'git push' our changes.
> [...]
>> when checking the git log is that while the changes I made and checked
>> into my repo clearly showed me as the author, the same changes after
>> being pushed to foo's repo showed a different author.
>>
>> So two things.. First should the author have been preserved? How can I
>> make sure that it is?
>
> Yes, absolutely, and since the author is encoded in the commit objects
> it's impossible to change it without also changing the commit sha1s.
>
> Can you spell your experiments in actual commands and output snippets
> so we can see what happened?
>
> Did you ever run 'git svn dcommit', 'git rebase', 'git commit --amend'
> or similar in foo's repo? All of these rewrite commits. As part of
> their rewriting they set the *committer* to the identity of the
> current user. 'git svn dcommit' sets author&committer to the identity
> coming back from SVN.
Ah that does sound like the issue then. I did in fact do a git svn
dcommit to commit the changes from the foo repo to our subversion
repo. If dcommit rewrites the commit changing the author then that
would explain it.
So I did a new test. I made a change and committed it to my local
repo. I then did a git pull to bring my repo in sync with the foo
repo, then did a push to the foo repo. Before doing anything else I
checked the author of my changes in the foo repo and sure enough I am
the author! Yay for that.
Now I try to git svn dcommit and I receive the following error:
Merge conflict during commit: File or directory 'bar' is out of date.
Try updating ...
So I do a git svn rebase, followed by git svn dcommit which works. Now
looking at git log I see that my changes are 'authored' by some else.
All that to say that you seem to hit the nail on the head and the git
svn rebase and git svn dcommit are rewriting the commits and changing
the author.
If we do indeed adopt git as our version control system then we would
freeze the subversion repo and not worry about git svn any further so
I think this is ultimately a non-issue and just something we will deal
with during this hybrid testing period.
Thanks!!
-Harry
>
> --
> Thomas Rast
> trast@{inf,student}.ethz.ch
>
^ permalink raw reply
* how multiple roots happen (Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for)
From: Jonathan Nieder @ 2011-01-14 21:09 UTC (permalink / raw)
To: Maaartin-1; +Cc: git, Jakub Narebski, Aleksey Shumkin
In-Reply-To: <20110114193023.GA14294@burratino>
Jonathan Nieder wrote:
> Maaartin wrote:
>> Maybe just something like "Let's assume there's only one and let's call
>> it FIRST". For the example, this is enough.
>
> True enough. Even better would be to give a reference to the "coolest merge
> ever" (is that documented anywhere?) so the interested reader can discover
> how there could be more than one.
Apparently it was not clear what I was talking about (who knew?). So
here you go:
http://thread.gmane.org/gmane.comp.version-control.git/5126
For a more modern take on it:
http://thread.gmane.org/gmane.comp.version-control.git/144302/focus=144323
^ permalink raw reply
* Re: Forcing re-reading files with unchanged stats
From: Maaartin-1 @ 2011-01-14 21:03 UTC (permalink / raw)
To: Jeff King; +Cc: Tomas Carnecky, git
In-Reply-To: <20110113033217.GA32661@sigill.intra.peff.net>
On 11-01-13 04:32, Jeff King wrote:
> On Thu, Jan 13, 2011 at 04:12:25AM +0100, Tomas Carnecky wrote:
>
>> On 1/12/11 3:07 PM, Maaartin wrote:
>>> There are files in my working tree which changes, but their size and mtime
>>> remains the same (I know it's strange, but it's useful). Can I make git to re-
>>
>> When can this be useful?
Well, not really. I was asked to place a line containing a version
number and a fingerprint in each file (of course the fingerprint must
ignore this line), so I did. This gets done using a script, and I didn't
like always saying "yes" to Emacs complaining about editing a file
changed on the disk, so I reset the mtime. I really don't think it was
the brightest idea ever.
>>> read them all, so it recognizes the change? Ideally, using a configuration
>>> variable. The repo is fairly small, so speed is no issue here.
>>
>> Try git update-index --refresh. I'm not aware of any config option,
>> but you might want to look through man git-config.
>
> That won't work, as it respects the stat information. So does
> --really-refresh. AFAIK, there isn't a way to tell update-index to
> ignore start information, short of blowing away the index entirely, and
> doing a read-tree to repopulate it.
Blowing away the index could work for me. I had to check if it's clean
(equal to the HEAD or working tree) first, so I loose no work. But this
is a bit too much work for making my mtime hack work.
> I'm curious what this use case is, and whether it would be acceptable to
> update something like ctime on the files to make them stat-dirty to git.
I'd suppose, Emacs does the same checks.
^ permalink raw reply
* small downloads and immutable history (Re: clone breaks replace)
From: Jonathan Nieder @ 2011-01-14 20:53 UTC (permalink / raw)
To: Phillip Susi
Cc: Johannes Sixt, Jeff King, git, Christian Couder, Stephen Bash
In-Reply-To: <4D2CFD0A.1060901@cfl.rr.com>
Phillip Susi wrote:
> On 01/11/2011 03:50 PM, Jonathan Nieder wrote:
>> Yes, except for "Using filter-branch is bad". Using filter-branch is
>> not bad.
>
> It is bad because it breaks people tracking your branch, and
> violates the immutability of history.
Ah, I forgot the use case. If you are using this to at long last get
past the limitations (e.g., inability to push) of "fetch --depth",
then yes, rewriting existing history is bad.
So what's left is some way to make the "have" part of transport
negotiation make sense in this context. I'll be happy if it happens.
Thanks for clarifying.
Jonathan
[note: if you occasionally use
git commit; # new commit
git tag tmp
git checkout --orphan newroot
git replace newroot tmp
git tag -d tmp
so the history without replacement refs is short, no rewriting of
history has to take place. Some testing and tweaking might be
required to make "git pull" continue to fast-forward.]
^ permalink raw reply
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Jeff King @ 2011-01-14 20:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Erik Faye-Lund, Linus Torvalds, Tor Arntsen, JT Olds, git
In-Reply-To: <7vhbdbnxud.fsf@alter.siamese.dyndns.org>
On Fri, Jan 14, 2011 at 10:28:58AM -0800, Junio C Hamano wrote:
> Jeff King <peff@peff.net> writes:
>
> > So we should probably do one or both of:
> >
> > 1. Make an --allow-any-name option to mailinfo, and use it when we
> > invoke mailinfo internally for rebasing. That still doesn't solve
> > the emailed patch problem, but at least keeps purely internal
> > operations sane.
> >
> > 2. Bump the check up to git-commit time, which is the best place to
> > catch and tell somebody that their name is too short, because they
> > can actually fix it.
> >
> > Even if we dropped the check now, option (2) is still useful, because
> > you have no idea which version of git the other end will use to apply
> > your patch.
>
> I am perfectly Ok with making the check looser in "am" when $rebasing is
> in effect. Wouldn't that solve the issue?
More or less. You would still have some lossiness when emailing your
patch. Do we want to warn about that?
-Peff
^ permalink raw reply
* Re: [PATCH] fix git-parse-remote.sh for remotes that contain slashes
From: Junio C Hamano @ 2011-01-14 19:55 UTC (permalink / raw)
To: Stefan Naewe; +Cc: git
In-Reply-To: <1295005000-11562-1-git-send-email-stefan.naewe@gmail.com>
Stefan Naewe <stefan.naewe@gmail.com> writes:
> Signed-off-by: Stefan Naewe <stefan.naewe@gmail.com>
> ---
Thanks, but no explanation?
Imagine somebody who weren't reading this thread (especially the article
you responded to with this patch) sees this in "git log" output stream.
For that matter, imagine yourself doing that in 2012 when the motivation
of this change you all forgot already.
Do you think it is obvious what the problem the patch tried to fix was?
I don't. "fix" on the subject line gives you 0-bit information for that
purpose.
> diff --git a/git-parse-remote.sh b/git-parse-remote.sh
> index 5f47b18..7cf204e 100644
> --- a/git-parse-remote.sh
> +++ b/git-parse-remote.sh
> @@ -7,8 +7,12 @@ GIT_DIR=$(git rev-parse -q --git-dir) || :;
> get_data_source () {
> case "$1" in
> */*)
> - echo ''
> - ;;
> + if test "$(git config --get "remote.$1.url")"
> + then
> + echo config
> + else
> + echo ''
> + fi ;;
I suspect that making this case arm trigger not on */* but only on /* and
../* would be a lot more sensible solution. Otherwise you would still
have the same issue in repositories that use remotes/ and branches/
mechanism.
git-parse-remote.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/git-parse-remote.sh b/git-parse-remote.sh
index 1cc2ba6..8ec33e3 100644
--- a/git-parse-remote.sh
+++ b/git-parse-remote.sh
@@ -6,7 +6,7 @@ GIT_DIR=$(git rev-parse -q --git-dir) || :;
get_data_source () {
case "$1" in
- */*)
+ ../* | /*)
echo ''
;;
.)
^ permalink raw reply related
* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
From: Jonathan Nieder @ 2011-01-14 19:30 UTC (permalink / raw)
To: Maaartin-1; +Cc: git, Jakub Narebski, Aleksey Shumkin
In-Reply-To: <4D308B69.1050003@seznam.cz>
Maaartin wrote:
> On 11-01-14 09:49, Jonathan Nieder wrote:
>> [side note: please do not prune the cc list; I only stumbled on this
>> message in the online archive by luck]
>
> What could I have done about it?
See [1].
> Maybe just something like "Let's assume there's only one and let's call
> it FIRST". For the example, this is enough.
True enough. Even better would be to give a reference to the "coolest merge
ever" (is that documented anywhere?) so the interested reader can discover
how there could be more than one.
> I'd go the other way round and use "-i" so I'd need only one file.
"sed -i" is not portable (not sure how important that is for documentation).
But perl -i is. :)
> $ first_commit = $($ echo $first_commit |
> perl -p
> "s/^tree .*/$&\nparent $(git rev-parse v2.4)/") <4>
So:
perl -pi -e "s/^tree .*$/\$&\nparent $(git rev-parse v2.4)/" new
Unfortunately "echo" and process substitution destroy some formatting
in the commit message --- in particular, trailing whitespace.
Thanks for the suggestions. Please feel free to pick up the patch and
run with it (I trust you for this more than I would trust myself).
Regards,
Jonathan
[1] My current method: [2] Yes, I agree that this is cumbersome.
I'm also told that Thunderbird when used as a newsreader can reply-to-all
easily, though I haven't tried it.
[2] http://thread.gmane.org/gmane.comp.version-control.git/154490
^ permalink raw reply
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Junio C Hamano @ 2011-01-14 18:28 UTC (permalink / raw)
To: Jeff King; +Cc: Erik Faye-Lund, Linus Torvalds, Tor Arntsen, JT Olds, git
In-Reply-To: <20110114162144.GA867@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> So we should probably do one or both of:
>
> 1. Make an --allow-any-name option to mailinfo, and use it when we
> invoke mailinfo internally for rebasing. That still doesn't solve
> the emailed patch problem, but at least keeps purely internal
> operations sane.
>
> 2. Bump the check up to git-commit time, which is the best place to
> catch and tell somebody that their name is too short, because they
> can actually fix it.
>
> Even if we dropped the check now, option (2) is still useful, because
> you have no idea which version of git the other end will use to apply
> your patch.
I am perfectly Ok with making the check looser in "am" when $rebasing is
in effect. Wouldn't that solve the issue?
^ permalink raw reply
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Jay Soffian @ 2011-01-14 18:02 UTC (permalink / raw)
To: Jeff King; +Cc: Erik Faye-Lund, Linus Torvalds, Tor Arntsen, JT Olds, git
In-Reply-To: <20110114163333.GA1230@sigill.intra.peff.net>
On Fri, Jan 14, 2011 at 11:33 AM, Jeff King <peff@peff.net> wrote:
> Even if we remove the check, it may still be worthwhile to say "Just so
> you know, older versions of git may mangle the name you have chosen".
I knew this conversation sounded familiar. It came up before in a
different context:
http://thread.gmane.org/gmane.comp.version-control.git/150871/focus=150902
j.
^ permalink raw reply
* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
From: Maaartin-1 @ 2011-01-14 17:44 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git, Jakub Narebski, Aleksey Shumkin
In-Reply-To: <20110114084903.GD11343@burratino>
On 11-01-14 09:49, Jonathan Nieder wrote:
> Some tweaks suggested by Maaartin:
[snip]
> [side note: please do not prune the cc list; I only stumbled on this
> message in the online archive by luck]
What could I have done about it? I didn't received it by email and
answered using post.gmane.org. There's no way to add CC there. If I'd
wrote an email instead, it wouldn't be placed in the thread.
[snip]
>>> +<1> Find all parentless commits in the 'master' branch;
>>> +for 'master' read the branch holding v2.5 history.
>>
>> Aren't you later calling it "FIRST" and assuming there's only one?
>
> Hmm. I want to say that there _could_ be multiple parentless commits
> in the v2.5 history and we are treating one of them as its root (just
> like git master has multiple parentless ancestors but e83c5163 is
> conventionally considered its beginning). Not sure how to write that
> clearly.
Maybe just something like "Let's assume there's only one and let's call
it FIRST". For the example, this is enough.
>> Isn't the combination of "-i" (=in-place edit) with redirection wrong?
>
> Good catch (the "-i" is a typo).
I'd go the other way round and use "-i" so I'd need only one file. Using
a shell variable instead would be even better, s. below.
[snip]
I tried to use the vars instead of files below, but never tested it. I
used "first_commit" instead of both "tmp" and "new", which is not really
nice.
> +$ git rev-list master --parents | grep -v ' '
> +$ first=$(git rev-list master --parents | grep -v ' ') <1>
> +$ git rev-parse v2.4 <2>
> +$ git cat-file commit $first >tmp <3>
$ first_commit = $(git cat-file commit FIRST) <3>
> +$ sed "/^tree / a \\
> +parent $(git rev-parse v2.4)" <tmp >new <4>
$ first_commit = $($ echo $first_commit |
sed "/^tree / a \\
parent $(git rev-parse v2.4)") <4>
Unfortunately, the line got too long. For sed unaware people like me it
may not be obvious that a line break is required. I'd use perl, anyway.
$ first_commit = $($ echo $first_commit |
perl -p
"s/^tree .*/$&\nparent $(git rev-parse v2.4)/") <4>
> +$ new_commit=$(git hash-object -t commit -w new) <5>
$ new_commit=$(echo $first_commit |
git hash-object -t commit -w --stdin) <5>
[snip]
^ permalink raw reply
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Linus Torvalds @ 2011-01-14 17:18 UTC (permalink / raw)
To: Tor Arntsen; +Cc: kusmabite, JT Olds, Jeff King, git
In-Reply-To: <4D3077FE.9090407@spacetec.no>
On Fri, Jan 14, 2011 at 8:21 AM, Tor Arntsen <tor@spacetec.no> wrote:
> On 14/01/2011 17:13, Erik Faye-Lund wrote:
>
>> I think Tor pointed out that he knew a swede with his full legal name
>> to be only one letter long. I would suppose that meant that he didn't
>> have a surename?
>
> Exactly. He didn't. Bank printouts etc. would only have that single
> letter, he didn't use a nickname - that letter was his legal name.
>
> As for the rest of the world - I don't think the first name/last name combo
> (almost) everyone in the west use is necessarily a universal rule.
Quite frankly, I'd suggest that person then use "The letter 'G'" as
his/her git name.
git names aren't "legal names". They are for informational purposes.
And a single letter just isn't informational.
Linus
^ permalink raw reply
* Re: Git Rebase blows away GIT_AUTHOR_NAME
From: Jeff King @ 2011-01-14 16:33 UTC (permalink / raw)
To: Erik Faye-Lund; +Cc: Linus Torvalds, Tor Arntsen, JT Olds, git
In-Reply-To: <AANLkTimcQq++CLv66AyTve+PiXBhYdUPk2epCyOXX1c0@mail.gmail.com>
On Fri, Jan 14, 2011 at 05:30:51PM +0100, Erik Faye-Lund wrote:
> > 2. Bump the check up to git-commit time, which is the best place to
> > catch and tell somebody that their name is too short, because they
> > can actually fix it.
> >
>
> The problem with (2) is that git-am uses git-commit-tree rather than
> git-commit. But I do think that adding the same checks to git-commit
> would make sense. Unless we decide to remove the checks, that is...
Yeah, I didn't say it very clearly, but I meant to factor the check out
and use it also in git-commit (probably as a warning, the same way we do
with other ident verification in print_summary().
Even if we remove the check, it may still be worthwhile to say "Just so
you know, older versions of git may mangle the name you have chosen".
-Peff
^ 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