* Re: [PATCH 2/2] fetch/push: readd rsync support
From: Shawn O. Pearce @ 2007-09-28 5:20 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: gitster, Daniel Barkalow, git
In-Reply-To: <Pine.LNX.4.64.0709280606530.28395@racer.site>
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> +static int disconnect_rsync(struct transport *transport)
> +{
> + return 0;
> +}
>
> /* Generic functions for using commit walkers */
>
> @@ -402,7 +730,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
> ret->url = url;
>
> if (!prefixcmp(url, "rsync://")) {
> - /* not supported; don't populate any ops */
> + ret->get_refs_list = get_refs_via_rsync;
> + ret->fetch = fetch_objs_via_rsync;
> + ret->push = rsync_transport_push;
> + ret->disconnect = disconnect_rsync;
>
> } else if (!prefixcmp(url, "http://")
> || !prefixcmp(url, "https://")
For what it's worth disconnect is an optional operation. You did
not need to implement it if you don't allocate a data member in
the struct transport. So removing disconnect_rsync() could save
you 6 lines or so.
I see push is now supported again. Didn't we remove rsync push
support a long time ago? Like say in:
commit c485104741ccdf32dd0c96fcb886c38a0b5badbd
Author: c.shoemaker@cox.net <c.shoemaker@cox.net>
Date: Sat Oct 29 00:16:33 2005 -0400
Add usage help to git-push.sh
Also clarify failure to push to read-only remote. Especially,
state why rsync:// is not used for pushing.
[jc: ideally rsync should not be used for anything]
Signed-off-by: Chris Shoemaker <c.shoemaker at cox.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
I guess it is nice to see that you can't kill rsync. Like Windows
it always finds it way back into your life.
--
Shawn.
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Peter Baumann @ 2007-09-28 5:15 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: git, Russ Brown, Kelvie Wong
In-Reply-To: <20070927222825.GG12427@artemis.corp>
On Fri, Sep 28, 2007 at 12:28:25AM +0200, Pierre Habouzit wrote:
> On Thu, Sep 27, 2007 at 10:23:26PM +0000, Theodore Tso wrote:
> > On Thu, Sep 27, 2007 at 09:11:25PM +0200, Pierre Habouzit wrote:
> > > > > And as none of the other merge tool that are supported are able to
> > > > > either do 3way merges, or have a decent UI (that definitely seems to be
> > > > > exclusive features) I've given up on git-mergetool (and to be fair, it
> > > > > sucks, because it could be _sooo_ useful sometimes).
> > > > >
> > > >
> > > > What about meld? That does 3-way merge, and the UI is fine.
> > >
> > > Indeed, it seems that since the last time I tested it, it now does
> > > diff3 merging. I should reevaluate it :)
> >
> > Pierre,
> >
> > FYI, kdiff3, meld, xxdiff, opendiff (on MacOSX), and emerge all
> > support 3-way merge.
>
> I know, but:
> * kdiff3 often take decisions behind your back, and results in broken
> merges, so it's a no-go ;
> * xxdiff has (IMHO) a very bad and non-intuitive UI, I never get to
> make it work ;
> * I don't use macos (opendiff) ;
> * emerge is emacs right ? :)
>
> Though I gave meld another chance, and it works really better than it
> used to, so I may give it a try :) Let's hope I won't be disappointed by
> meld :)
>
FWIW, xxdiff has support to handle halfway merged files, so that if git
could merge some hunks already for you (e.g. rerere kicked in), you
don't have to redo the _whole_ merge by hand, just call
xxdiff -U file/with/mergemarkers/inside
and it will do the right thing. Not sure if the other tools could handle
it, but any pointers appreciated, because it often happens to me that
only one hunk out of several wasn't merged automatically by git. And
mergetool wants to always redo the whole merge, which isn't the best it
can do.
-Peter
^ permalink raw reply
* Re: [PATCH] Merge non-first refs that match first refspec
From: Daniel Barkalow @ 2007-09-28 5:12 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20070928044824.GV3099@spearce.org>
On Fri, 28 Sep 2007, Shawn O. Pearce wrote:
> Daniel Barkalow <barkalow@iabervon.org> wrote:
> > Beats me; Junio, what's your test case?
>
> If I understood him correctly it is this:
>
> mkdir foo; cd foo; git init
> git config remote.origin.url git://repo.or.cz/alt-git.git
> git config remote.origin.fetch refs/heads/master:refs/remotes/origin/master
> git config --add remote.origin.fetch refs/heads/maint:refs/remotes/origin/maint
> git pull
>
> We should see "master" listed in .git/FETCH_HEAD as a "for-merge"
> and "maint" listed as a "not-for-merge"...
>
> But if that remote.origin.fetch was a wildcard spec this shouldn't
> happen as the results are unpredictable. But above the user
> explicitly put master first, so it should be defaulted to.
But after that sequence, the right thing does happen. So I'm guessing that
he has some different sequence that triggers a bug.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* [PATCH 2/2] fetch/push: readd rsync support
From: Johannes Schindelin @ 2007-09-28 5:07 UTC (permalink / raw)
To: gitster, Daniel Barkalow, git
In-Reply-To: <Pine.LNX.4.64.0709280602580.28395@racer.site>
We lost rsync support when transitioning from shell to C. Support it
again (even if the transport is technically deprecated, some people just
do not have any chance to use anything else).
Also, add a test to t5510. Since rsync transport is not configured by
default on most machines, and especially not such that you can
write to rsync://127.0.0.1$(pwd)/, it is disabled by default; you can
enable it by setting the environment variable TEST_RSYNC.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Maybe this should be moved into transport-rsync.c...
t/t5510-fetch.sh | 35 ++++++
transport.c | 333 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 367 insertions(+), 1 deletions(-)
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 439430f..73a4e3c 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -153,4 +153,39 @@ test_expect_success 'bundle should be able to create a full history' '
'
+test "$TEST_RSYNC" && {
+test_expect_success 'fetch via rsync' '
+ git pack-refs &&
+ mkdir rsynced &&
+ cd rsynced &&
+ git init &&
+ git fetch rsync://127.0.0.1$(pwd)/../.git master:refs/heads/master &&
+ git gc --prune &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full
+'
+
+test_expect_success 'push via rsync' '
+ mkdir ../rsynced2 &&
+ (cd ../rsynced2 &&
+ git init) &&
+ git push rsync://127.0.0.1$(pwd)/../rsynced2/.git master &&
+ cd ../rsynced2 &&
+ git gc --prune &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full
+'
+
+test_expect_success 'push via rsync' '
+ cd .. &&
+ mkdir rsynced3 &&
+ (cd rsynced3 &&
+ git init) &&
+ git push --all rsync://127.0.0.1$(pwd)/rsynced3/.git &&
+ cd rsynced3 &&
+ test $(git rev-parse master) = $(cd .. && git rev-parse master) &&
+ git fsck --full
+'
+}
+
test_done
diff --git a/transport.c b/transport.c
index 4f9cddc..d50a311 100644
--- a/transport.c
+++ b/transport.c
@@ -6,6 +6,334 @@
#include "fetch-pack.h"
#include "walker.h"
#include "bundle.h"
+#include "dir.h"
+#include "refs.h"
+
+/* rsync support */
+
+/*
+ * We copy packed-refs and refs/ into a temporary file, then read the
+ * loose refs recursively (sorting whenever possible), and then inserting
+ * those packed refs that are not yet in the list (not validating, but
+ * assuming that the file is sorted).
+ *
+ * Appears refactoring this from refs.c is too cumbersome.
+ */
+
+static int direntry_cmp(const void *a, const void *b)
+{
+ const struct dirent *d1 = a;
+ const struct dirent *d2 = b;
+
+ return strcmp(d1->d_name, d2->d_name);
+}
+
+/*
+ * path is assumed to point to a buffer of PATH_MAX bytes, and
+ * path + name_offset is expected to point to "refs/".
+ */
+
+static int read_loose_refs(char *path, int name_offset, struct ref **tail)
+{
+ DIR *dir = opendir(path);
+ struct dirent *de;
+ struct {
+ struct dirent *entries;
+ int nr, alloc;
+ } list;
+ int i, pathlen;
+
+ if (!dir)
+ return -1;
+
+ memset (&list, 0, sizeof(list));
+
+ while ((de = readdir(dir))) {
+ if (de->d_name[0] == '.' && (de->d_name[1] == '\0' ||
+ (de->d_name[1] == '.' &&
+ de->d_name[2] == '\0')))
+ continue;
+ if (list.nr >= list.alloc) {
+ list.alloc = alloc_nr(list.nr);
+ list.entries = xrealloc(list.entries,
+ list.alloc * sizeof(*de));
+ }
+ list.entries[list.nr++] = *de;
+ }
+ closedir(dir);
+
+ /* sort the list */
+
+ qsort(list.entries, list.nr, sizeof(*de), direntry_cmp);
+
+ pathlen = strlen(path);
+ path[pathlen] = '/';
+
+ for (i = 0; i < list.nr; i++) {
+ strlcpy(path + pathlen + 1, list.entries[i].d_name,
+ PATH_MAX - pathlen - 1);
+ if (read_loose_refs(path, name_offset, tail)) {
+ int fd = open(path, O_RDONLY);
+ char buffer[40];
+ struct ref *next;
+
+ if (fd < 0)
+ continue;
+ next = alloc_ref(strlen(path + name_offset));
+ if (read_in_full(fd, buffer, 40) != 40 ||
+ get_sha1_hex(buffer, next->old_sha1)) {
+ free(next);
+ continue;
+ }
+ close(fd);
+ strcpy(next->name, path + name_offset);
+ (*tail)->next = next;
+ *tail = next;
+ }
+ }
+
+ path[pathlen] = '\0';
+
+ free(list.entries);
+ return 0;
+}
+
+/* insert the packed refs for which no loose refs were found */
+
+static void insert_packed_refs(const char *packed_refs, struct ref **list)
+{
+ FILE *f = fopen(packed_refs, "r");
+ static char buffer[PATH_MAX];
+
+ if (!f)
+ return;
+
+ for (;;) {
+ int cmp, len;
+
+ if (!fgets(buffer, sizeof(buffer), f)) {
+ fclose(f);
+ return;
+ }
+
+ if (hexval(buffer[0]) & 0x10)
+ continue;
+ len = strlen(buffer);
+ if (buffer[len - 1] == '\n')
+ buffer[--len] = '\0';
+ if (len < 41)
+ continue;
+ while ((*list)->next &&
+ (cmp = strcmp(buffer + 41,
+ (*list)->next->name)) > 0)
+ list = &(*list)->next;
+ if (!(*list)->next || cmp < 0) {
+ struct ref *next = alloc_ref(len - 40);
+ buffer[40] = '\0';
+ if (get_sha1_hex(buffer, next->old_sha1)) {
+ warning ("invalid SHA-1: %s", buffer);
+ free(next);
+ continue;
+ }
+ strcpy(next->name, buffer + 41);
+ next->next = (*list)->next;
+ (*list)->next = next;
+ list = &(*list)->next;
+ }
+ }
+}
+
+static struct ref *get_refs_via_rsync(const struct transport *transport)
+{
+ char buffer[PATH_MAX];
+ struct strbuf buf = STRBUF_INIT;
+ struct ref dummy, *result = &dummy;
+ struct child_process rsync;
+ const char *args[5];
+ char *temp_dir;
+
+ /* copy the refs to the temporary directory */
+
+ temp_dir = mkdtemp(git_path("rsync-refs-XXXXXX"));
+ if (temp_dir == NULL)
+ die ("Could not make temporary directory");
+ temp_dir = strcpy(buffer, temp_dir);
+
+ strbuf_addstr(&buf, transport->url);
+ strbuf_addstr(&buf, "/refs");
+
+ memset(&rsync, 0, sizeof(rsync));
+ rsync.argv = args;
+ rsync.stdout_to_stderr = 1;
+ args[0] = "rsync";
+ args[1] = transport->verbose ? "-rv" : "-r";
+ args[2] = buf.buf;
+ args[3] = temp_dir;
+ args[4] = NULL;
+
+ if (run_command(&rsync))
+ die ("Could not run rsync to get refs");
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, transport->url);
+ strbuf_addstr(&buf, "/packed-refs");
+
+ args[2] = buf.buf;
+
+ if (run_command(&rsync))
+ die ("Could not run rsync to get refs");
+
+ /* read the copied refs */
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, temp_dir);
+ strbuf_addstr(&buf, "/refs");
+ read_loose_refs(buf.buf, strlen(buf.buf) - 4, &result);
+
+ result = &dummy;
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, temp_dir);
+ strbuf_addstr(&buf, "/packed-refs");
+ insert_packed_refs(buf.buf, &result);
+
+ if (remove_dir_recursively(temp_dir, strlen(temp_dir), 0))
+ warning ("Could not remove temporary directory %s.", temp_dir);
+
+ return dummy.next;
+}
+
+static int fetch_objs_via_rsync(struct transport *transport,
+ int nr_objs, struct ref **to_fetch)
+{
+ struct strbuf buf = STRBUF_INIT;
+ struct child_process rsync;
+ const char *args[8];
+
+ strbuf_addstr(&buf, transport->url);
+ strbuf_addstr(&buf, "/objects/");
+
+ memset(&rsync, 0, sizeof(rsync));
+ rsync.argv = args;
+ rsync.stdout_to_stderr = 1;
+ args[0] = "rsync";
+ args[1] = transport->verbose ? "-rv" : "-r";
+ args[2] = "--ignore-existing";
+ args[3] = "--exclude";
+ args[4] = "info";
+ args[5] = buf.buf;
+ args[6] = get_object_directory();
+ args[7] = NULL;
+
+ /* NEEDSWORK: handle one level of alternates */
+ return run_command(&rsync);
+}
+
+static int write_one_ref(const char *name, const unsigned char *sha1,
+ int flags, void *data)
+{
+ struct strbuf *buf = data;
+ int len = buf->len;
+ FILE *f;
+
+ if (flags && prefixcmp(name, "refs/heads/") &&
+ prefixcmp(name, "refs/tags/"))
+ return 0;
+
+ strbuf_addstr(buf, name);
+ if (safe_create_leading_directories(buf->buf) ||
+ !(f = fopen(buf->buf, "w")) ||
+ !fwrite(sha1_to_hex(sha1), 40, 1, f) ||
+ fputc('\n', f) == EOF ||
+ fclose(f))
+ return error("problems writing temporary file %s", buf->buf);
+ strbuf_setlen(buf, len);
+ return 0;
+}
+
+static int write_refs_to_temp_dir(struct strbuf *temp_dir,
+ int refspec_nr, const char **refspec)
+{
+ int i;
+
+ for (i = 0; i < refspec_nr; i++) {
+ unsigned char sha1[20];
+ char *ref;
+
+ if (dwim_ref(refspec[i], strlen(refspec[i]), sha1, &ref) != 1)
+ return error("Could not get ref %s", refspec[i]);
+
+ if (write_one_ref(ref, sha1, 0, temp_dir)) {
+ free(ref);
+ return -1;
+ }
+ free(ref);
+ }
+ return 0;
+}
+
+static int rsync_transport_push(struct transport *transport,
+ int refspec_nr, const char **refspec, int flags) {
+ char buffer[PATH_MAX];
+ struct strbuf buf = STRBUF_INIT;
+ int result = 0, i;
+ struct child_process rsync;
+ const char *args[8];
+ char *temp_dir;
+
+ /* first push the objects */
+
+ strbuf_addstr(&buf, transport->url);
+ strbuf_addch(&buf, '/');
+
+ memset(&rsync, 0, sizeof(rsync));
+ rsync.argv = args;
+ rsync.stdout_to_stderr = 1;
+ args[0] = "rsync";
+ args[1] = transport->verbose ? "-av" : "-a";
+ args[2] = "--ignore-existing";
+ args[3] = "--exclude";
+ args[4] = "info";
+ args[5] = get_object_directory();;
+ args[6] = buf.buf;
+ args[7] = NULL;
+
+ if (run_command(&rsync))
+ return error("Could not push objects to %s", transport->url);
+
+ /* copy the refs to the temporary directory; they could be packed. */
+
+ temp_dir = mkdtemp(git_path("rsync-refs-XXXXXX"));
+ if (temp_dir == NULL)
+ die ("Could not make temporary directory");
+ temp_dir = strcpy(buffer, temp_dir);
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, temp_dir);
+ strbuf_addch(&buf, '/');
+
+ if (flags & TRANSPORT_PUSH_ALL) {
+ if (for_each_ref(write_one_ref, &buf))
+ return -1;
+ } else if (write_refs_to_temp_dir(&buf, refspec_nr, refspec))
+ return -1;
+
+ i = (flags & TRANSPORT_PUSH_FORCE) ? 2 : 3;
+ args[i++] = buf.buf;
+ args[i++] = transport->url;
+ args[i++] = NULL;
+ if (run_command(&rsync))
+ result = error("Could not push to %s", transport->url);
+
+ if (remove_dir_recursively(temp_dir, strlen(temp_dir), 0))
+ warning ("Could not remove temporary directory %s.", temp_dir);
+
+ return result;
+}
+
+static int disconnect_rsync(struct transport *transport)
+{
+ return 0;
+}
/* Generic functions for using commit walkers */
@@ -402,7 +730,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
ret->url = url;
if (!prefixcmp(url, "rsync://")) {
- /* not supported; don't populate any ops */
+ ret->get_refs_list = get_refs_via_rsync;
+ ret->fetch = fetch_objs_via_rsync;
+ ret->push = rsync_transport_push;
+ ret->disconnect = disconnect_rsync;
} else if (!prefixcmp(url, "http://")
|| !prefixcmp(url, "https://")
--
1.5.3.2.1102.g9487
^ permalink raw reply related
* [PATCH 1/2] Introduce remove_dir_recursively()
From: Johannes Schindelin @ 2007-09-28 5:06 UTC (permalink / raw)
To: gitster, Daniel Barkalow, git
In-Reply-To: <Pine.LNX.4.64.0709280602580.28395@racer.site>
There was a function called remove_empty_dir_recursive() buried
in refs.c. Expose a slightly enhanced version in dir.h: it can now
optionally remove a non-empty directory.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
dir.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
dir.h | 2 ++
refs.c | 36 ++----------------------------------
3 files changed, 49 insertions(+), 34 deletions(-)
diff --git a/dir.c b/dir.c
index eb6c3ab..0fae400 100644
--- a/dir.c
+++ b/dir.c
@@ -685,3 +685,48 @@ int is_inside_dir(const char *dir)
char buffer[PATH_MAX];
return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
}
+
+int remove_dir_recursively(char *path, int len, int only_empty)
+{
+ DIR *dir = opendir(path);
+ struct dirent *e;
+ int ret = 0;
+
+ if (!dir)
+ return -1;
+ if (path[len-1] != '/')
+ path[len++] = '/';
+ while ((e = readdir(dir)) != NULL) {
+ struct stat st;
+ int namlen;
+ if ((e->d_name[0] == '.') &&
+ ((e->d_name[1] == 0) ||
+ ((e->d_name[1] == '.') && e->d_name[2] == 0)))
+ continue; /* "." and ".." */
+
+ namlen = strlen(e->d_name);
+ if (len + namlen > PATH_MAX ||
+ !memcpy(path + len, e->d_name, namlen) ||
+ (path[len + namlen] = '\0') ||
+ lstat(path, &st))
+ ; /* fall thru */
+ else if (S_ISDIR(st.st_mode)) {
+ if (!remove_dir_recursively(path, len + namlen,
+ only_empty))
+ continue; /* happy */
+ } else if (!only_empty &&
+ len + namlen + 1 < PATH_MAX &&
+ !unlink(path))
+ continue; /* happy, too */
+
+ /* path too long, stat fails, or non-directory still exists */
+ ret = -1;
+ break;
+ }
+ closedir(dir);
+ if (!ret) {
+ path[len] = 0;
+ ret = rmdir(path);
+ }
+ return ret;
+}
diff --git a/dir.h b/dir.h
index f55a87b..f52eea8 100644
--- a/dir.h
+++ b/dir.h
@@ -64,4 +64,6 @@ extern struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna
extern char *get_relative_cwd(char *buffer, int size, const char *dir);
extern int is_inside_dir(const char *dir);
+extern int remove_dir_recursively(char *dir, int len, int only_empty);
+
#endif
diff --git a/refs.c b/refs.c
index 07e260c..f0336ee 100644
--- a/refs.c
+++ b/refs.c
@@ -2,6 +2,7 @@
#include "refs.h"
#include "object.h"
#include "tag.h"
+#include "dir.h"
/* ISSYMREF=01 and ISPACKED=02 are public interfaces */
#define REF_KNOWS_PEELED 04
@@ -673,40 +674,7 @@ static struct ref_lock *verify_lock(struct ref_lock *lock,
static int remove_empty_dir_recursive(char *path, int len)
{
- DIR *dir = opendir(path);
- struct dirent *e;
- int ret = 0;
-
- if (!dir)
- return -1;
- if (path[len-1] != '/')
- path[len++] = '/';
- while ((e = readdir(dir)) != NULL) {
- struct stat st;
- int namlen;
- if ((e->d_name[0] == '.') &&
- ((e->d_name[1] == 0) ||
- ((e->d_name[1] == '.') && e->d_name[2] == 0)))
- continue; /* "." and ".." */
-
- namlen = strlen(e->d_name);
- if ((len + namlen < PATH_MAX) &&
- strcpy(path + len, e->d_name) &&
- !lstat(path, &st) &&
- S_ISDIR(st.st_mode) &&
- !remove_empty_dir_recursive(path, len + namlen))
- continue; /* happy */
-
- /* path too long, stat fails, or non-directory still exists */
- ret = -1;
- break;
- }
- closedir(dir);
- if (!ret) {
- path[len] = 0;
- ret = rmdir(path);
- }
- return ret;
+ return remove_dir_recursively(path, len, 1);
}
static int remove_empty_directories(char *file)
--
1.5.3.2.1102.g9487
^ permalink raw reply related
* [PATCH 0/2] rsync support
From: Johannes Schindelin @ 2007-09-28 5:06 UTC (permalink / raw)
To: gitster, Daniel Barkalow, git
Hi,
I worked too long on this... So here it is, a 2-patch series to readd the
rsync support.
One thing I did not do: fetch alternates. My rationale is this: just as
with HTTP, the rsync protocol does allow for having a different root than
the file system root. So, just as with HTTP, the alternates are likely to
break.
But hey, if somebody feels like it, there is a NEEDSWORK pointer from
which to start.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] alloc_ref(): allow for trailing NUL
From: Daniel Barkalow @ 2007-09-28 5:03 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: gitster, git
In-Reply-To: <Pine.LNX.4.64.0709280356550.28395@racer.site>
On Fri, 28 Sep 2007, Johannes Schindelin wrote:
> The parameter name "namelen" suggests that you pass the equivalent of
> strlen() to the function alloc_ref(). However, this function did not
> allocate enough space to put a NUL after the name.
>
> Since struct ref does not have any member to describe the length of the
> string, this just does not make sense.
>
> So make space for the NUL.
Good point, but shouldn't you then fix call sites that use strlen(name) +
1?
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* Re: [PATCH] Merge non-first refs that match first refspec
From: Shawn O. Pearce @ 2007-09-28 4:48 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0709280026240.5926@iabervon.org>
Daniel Barkalow <barkalow@iabervon.org> wrote:
> Beats me; Junio, what's your test case?
If I understood him correctly it is this:
mkdir foo; cd foo; git init
git config remote.origin.url git://repo.or.cz/alt-git.git
git config remote.origin.fetch refs/heads/master:refs/remotes/origin/master
git config --add remote.origin.fetch refs/heads/maint:refs/remotes/origin/maint
git pull
We should see "master" listed in .git/FETCH_HEAD as a "for-merge"
and "maint" listed as a "not-for-merge"...
But if that remote.origin.fetch was a wildcard spec this shouldn't
happen as the results are unpredictable. But above the user
explicitly put master first, so it should be defaulted to.
--
Shawn.
^ permalink raw reply
* Re: [PATCH] Merge non-first refs that match first refspec
From: Daniel Barkalow @ 2007-09-28 4:40 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Junio C Hamano, git
In-Reply-To: <20070928041509.GU3099@spearce.org>
On Fri, 28 Sep 2007, Shawn O. Pearce wrote:
> My understanding of the old code was that it should do what Junio
> was reporting as broken:
Agreed; that's why I thought there must be something wrong with it.
> - when i == 0 this is the first remote.$foo.fetch;
> - when has_merge == 0 we have no branch.$name.merge;
> - when ref_map != NULL we have at least one ref from this fetch spec;
> - when fetch[0].src == ref_map->name it wasn't a wildcard spec;
>
> The if conditional above was ordered the way it is so we can skip
> the more expensive operation (the strcmp) most of them time through
> the loop iteration.
>
> The only way I can see the old code was failing was if ref_map
> as returned by get_fetch_map() pointed to more than one refspec.
> But for that to be true then fetch[1].src must have been a wildcard,
> in which case the strcmp() would fail. So we should only ever
> get one entry, it should be the first entry, and dammit it should
> have matched.
That is the analysis that the original code is based on, yes. But it's not
the easiest thing to follow, and I misunderstood it earlier this evening
(prompted by the claim that it wasn't working, mostly). It's probably
worth checking remote->fetch[0].pattern instead of the strcmp, anyway,
since that's clearer and cheaper anyway.
> How/why are we getting cases where fetch[0].src isn't in the first
> entry in ref_map? What are those other entries? Are they possibly
> going to also match fetch[0].src and cause more than one branch
> to merge?
Beats me; Junio, what's your test case?
> BTW, thanks for looking at this. I didn't have time to get to it
> this week and now I'm really unlikely to be able to do so until
> after I get back from San Jose. I have too many things crammed
> into this next week. :-\
No problem. You fixed plenty of my other bugs in this code, and it's
getting so close to done.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* [EGIT PATCH] Won't append '/' to an empty repo relative path.
From: Jing Xue @ 2007-09-28 4:39 UTC (permalink / raw)
To: git
When the repo relative path is empty, the extra "/" causes all subsequent
"startsWith" tests to fail.
Signed-off-by: Jing Xue <jingxue@digizenstudio.com>
---
.../egit/ui/internal/actions/CommitAction.java | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java
index 82cad58..7d638c7 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/actions/CommitAction.java
@@ -358,7 +358,11 @@ public class CommitAction implements IObjectActionDelegate {
}
private void includeList(IProject project, HashSet<String> added, ArrayList<IFile> category) {
- String repoRelativePath = RepositoryMapping.getMapping(project).getRepoRelativePath(project) + "/";
+ String repoRelativePath = RepositoryMapping.getMapping(project).getRepoRelativePath(project);
+ if (repoRelativePath.length() > 0) {
+ repoRelativePath += "/";
+ }
+
for (String filename : added) {
try {
if (!filename.startsWith(repoRelativePath))
--
1.5.3.2.116.ge36bb5
^ permalink raw reply related
* Re: Mergetool generating blank files (1.5.3)
From: Kelvie Wong @ 2007-09-28 4:17 UTC (permalink / raw)
To: Theodore Tso; +Cc: Junio C Hamano, git
In-Reply-To: <20070927225218.GD8688@thunk.org>
On 9/27/07, Theodore Tso <tytso@mit.edu> wrote:
> It's not that emacs sets $PWD via its first argument, but the output
> file is passed from emerge-files*-command to stashed in the per-buffer
> variable emerge-file-out, which in turn gets passed to the emacs lisp
> file write-file, which is what gets run when you run C-x C-w --- and
> write-file interprets a relative pathname based on the containing
> directory of the existing buffer.
> - Ted
>
Ah yes, I just started reading up on elisp a little while ago :)
I'd always assumed that emacs kept an internal "pwd" variable (i.e.
what's displayed with M-x pwd), but I guess my way of thinking is
archaic and deprecated :(
--
Kelvie
^ permalink raw reply
* Re: [PATCH] Merge non-first refs that match first refspec
From: Shawn O. Pearce @ 2007-09-28 4:15 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0709272351010.5926@iabervon.org>
Daniel Barkalow <barkalow@iabervon.org> wrote:
> The code only looked at the first ref in the map of refs when looking
> for matches for the first refspec in the case where there is not
> per-branch configuration of ref to merge. This is often sufficient,
> but not always. Make the logic clearer and test everything in the map.
>
> Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
> ---
> I ran all the usual tests with this, and it seems like it should fix a bug
> you saw, but I don't have the test case to make sure.
>
> builtin-fetch.c | 7 ++++---
> 1 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/builtin-fetch.c b/builtin-fetch.c
> index 2f639cc..47811c9 100644
> --- a/builtin-fetch.c
> +++ b/builtin-fetch.c
> @@ -101,12 +101,13 @@ static struct ref *get_ref_map(struct transport *transport,
> if (remote->fetch[i].dst &&
> remote->fetch[i].dst[0])
> *autotags = 1;
> - if (!i && !has_merge && ref_map &&
> - !strcmp(remote->fetch[0].src, ref_map->name))
> - ref_map->merge = 1;
> }
> if (has_merge)
> add_merge_config(&ref_map, remote_refs, branch, &tail);
> + else
> + for (rm = ref_map; rm; rm = rm->next)
> + if (!strcmp(remote->fetch[0].src, rm->name))
> + rm->merge = 1;
> } else {
> ref_map = get_remote_ref(remote_refs, "HEAD");
> ref_map->merge = 1;
Hmmph. I'm not seeing how this fixes the bug. But if it fixes it,
it fixes it.
My understanding of the old code was that it should do what Junio
was reporting as broken:
- when i == 0 this is the first remote.$foo.fetch;
- when has_merge == 0 we have no branch.$name.merge;
- when ref_map != NULL we have at least one ref from this fetch spec;
- when fetch[0].src == ref_map->name it wasn't a wildcard spec;
The if conditional above was ordered the way it is so we can skip
the more expensive operation (the strcmp) most of them time through
the loop iteration.
The only way I can see the old code was failing was if ref_map
as returned by get_fetch_map() pointed to more than one refspec.
But for that to be true then fetch[1].src must have been a wildcard,
in which case the strcmp() would fail. So we should only ever
get one entry, it should be the first entry, and dammit it should
have matched.
How/why are we getting cases where fetch[0].src isn't in the first
entry in ref_map? What are those other entries? Are they possibly
going to also match fetch[0].src and cause more than one branch
to merge?
BTW, thanks for looking at this. I didn't have time to get to it
this week and now I'm really unlikely to be able to do so until
after I get back from San Jose. I have too many things crammed
into this next week. :-\
--
Shawn.
^ permalink raw reply
* [PATCH] Merge non-first refs that match first refspec
From: Daniel Barkalow @ 2007-09-28 3:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
The code only looked at the first ref in the map of refs when looking
for matches for the first refspec in the case where there is not
per-branch configuration of ref to merge. This is often sufficient,
but not always. Make the logic clearer and test everything in the map.
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
I ran all the usual tests with this, and it seems like it should fix a bug
you saw, but I don't have the test case to make sure.
builtin-fetch.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/builtin-fetch.c b/builtin-fetch.c
index 2f639cc..47811c9 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -101,12 +101,13 @@ static struct ref *get_ref_map(struct transport *transport,
if (remote->fetch[i].dst &&
remote->fetch[i].dst[0])
*autotags = 1;
- if (!i && !has_merge && ref_map &&
- !strcmp(remote->fetch[0].src, ref_map->name))
- ref_map->merge = 1;
}
if (has_merge)
add_merge_config(&ref_map, remote_refs, branch, &tail);
+ else
+ for (rm = ref_map; rm; rm = rm->next)
+ if (!strcmp(remote->fetch[0].src, rm->name))
+ rm->merge = 1;
} else {
ref_map = get_remote_ref(remote_refs, "HEAD");
ref_map->merge = 1;
--
1.5.3.2.1041.g2df10
^ permalink raw reply related
* Re: What's cooking in git.git (topics)
From: Daniel Barkalow @ 2007-09-28 3:24 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vfy11yyxk.fsf@gitster.siamese.dyndns.org>
On Wed, 26 Sep 2007, Junio C Hamano wrote:
> * db/fetch-pack (Tue Sep 25 00:13:25 2007 -0400) 45 commits
> + Prevent send-pack from segfaulting when a branch doesn't match
> + Cleanup unnecessary break in remote.c
> + Cleanup style nit of 'x == NULL' in remote.c
> + Fix memory leaks when disconnecting transport instances
> + Ensure builtin-fetch honors {fetch,transfer}.unpackLimit
> + ...
>
> Two issues known to me are:
>
> - "rsync" transport is not supported yet;
>
> - regresses "git pull <name>" using .git/remotes/<name>; does
> not merge the first refspec when branch.<name>.merge is not
> set.
Actually, I think it's only that it doesn't merge anything if the first
refspec doesn't match the first fetched ref from the server. I'm running
tests on a patch that should fix it, but I'm not sure how to write a test
for this particular case; I think the fetch tests try to test this, but
pass by chance.
-Daniel
*This .sig left intentionally blank*
^ permalink raw reply
* [PATCH] alloc_ref(): allow for trailing NUL
From: Johannes Schindelin @ 2007-09-28 2:57 UTC (permalink / raw)
To: gitster, git
The parameter name "namelen" suggests that you pass the equivalent of
strlen() to the function alloc_ref(). However, this function did not
allocate enough space to put a NUL after the name.
Since struct ref does not have any member to describe the length of the
string, this just does not make sense.
So make space for the NUL.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
remote.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/remote.c b/remote.c
index e7d735b..7531c92 100644
--- a/remote.c
+++ b/remote.c
@@ -453,7 +453,7 @@ int remote_find_tracking(struct remote *remote, struct refspec *refspec)
struct ref *alloc_ref(unsigned namelen)
{
- struct ref *ret = xmalloc(sizeof(struct ref) + namelen);
+ struct ref *ret = xmalloc(sizeof(struct ref) + namelen + 1);
memset(ret, 0, sizeof(struct ref) + namelen);
return ret;
}
--
1.5.3.2.1102.g9487
^ permalink raw reply related
* Re: backup or mirror a repository
From: Dan Farina @ 2007-09-28 2:37 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0709280253150.28395@racer.site>
On Fri, 2007-09-28 at 02:56 +0100, Johannes Schindelin wrote:
> Hi,
>
> On Thu, 27 Sep 2007, Dan Farina wrote:
> git remote rm is about removing the remote nick, not a remote branch.
Ah, I thought for some reason there'd be a "remove" (since the other
operations have long names) and, much like "ls-remote" there'd be some
"rm-remote." An insane presupposition of mine from having too little
information.
> What you should have done is "git fetch backup".
>
> Or use "origin" instead of "backup" right from the start, and then use
> "git fetch".
>
> But no pull.
I did use "pull backup" (my error for being sloppy and omitting it from
my mail) and it does work provided I do the dirty thing of doing a
subsequent reset --hard (I thought perhaps things were not yet
fully-there). Fetch does it perfectly, as you say, thanks!
> You want to remove branches from the local repo which are no longer there
> on the remote side?
>
> Then "git remote prune" is for you. For details, please see the man page.
>
I did look at prune and update, but my problem is the opposite: I want
something that will remove branches from the remote repo when they no
longer exist locally. As-is over time I will proliferate little local
branches unless I occasionally sit down and delete branches by operating
directly on the bare backup repository. (and then use prune on the
remote nodes)
Thanks,
fdr
^ permalink raw reply
* Re: [PATCH] git-gui: fix typo in lib/blame.tcl
From: Shawn O. Pearce @ 2007-09-28 2:14 UTC (permalink / raw)
To: Michele Ballabio; +Cc: git
In-Reply-To: <200709271453.25772.barra_cuda@katamail.com>
Michele Ballabio <barra_cuda@katamail.com> wrote:
> diff --git a/lib/blame.tcl b/lib/blame.tcl
> index a911c3c..00ecf21 100644
> --- a/lib/blame.tcl
> +++ b/lib/blame.tcl
> @@ -905,7 +905,7 @@ method _open_tooltip {cur_w} {
> set author_time {}
> catch {set author_name $header($cmit,author)}
> catch {set summary $header($cmit,summary)}
> - catch {set author_time [foramt_date $header($cmit,author-time)]}
> + catch {set author_time [format_date $header($cmit,author-time)]}
Shame on me. Thanks for the fix. :-)
--
Shawn.
^ permalink raw reply
* Re: backup or mirror a repository
From: Johannes Schindelin @ 2007-09-28 1:56 UTC (permalink / raw)
To: Dan Farina; +Cc: git
In-Reply-To: <1190940704.2263.32.camel@Tenacity>
Hi,
On Thu, 27 Sep 2007, Dan Farina wrote:
> On Thu, 2007-09-27 at 22:56 +0100, Johannes Schindelin wrote:
> > I guess you're looking for "git remote add --mirror origin <url>".
> > AFAIK this is not in any released version yet, though.
>
> I just tried a bleeding edge git with --mirror.
>
> It's close, except (unless there is some other provision to take care of
> this) remote branch deletes. (Which, after more gmane trolling, seemed
> to be "git remote rm", which doesn't seem present just yet).
git remote rm is about removing the remote nick, not a remote branch.
> Of course, it is completely possible I'm using it incorrectly. In brief,
> I did "git init" "git remote add --mirror backup <url>" "git pull"
"git pull" without further parameters accesses the remote "origin", not
"backup", and it merges _one_ branch into the current branch.
What you should have done is "git fetch backup".
Or use "origin" instead of "backup" right from the start, and then use
"git fetch".
But no pull.
> (perhaps I should have used "git remote update"?) And the behavior of
> this is more or less what I wanted, as far as sending branches.
> Convenient removal of branches and propagating that removal still stumps
> me. Is there a preferred way to do this yet?
You want to remove branches from the local repo which are no longer there
on the remote side?
Then "git remote prune" is for you. For details, please see the man page.
Ciao,
Dscho
^ permalink raw reply
* Re: backup or mirror a repository
From: Dan Farina @ 2007-09-28 0:51 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0709272255360.28395@racer.site>
On Thu, 2007-09-27 at 22:56 +0100, Johannes Schindelin wrote:
> I guess you're looking for "git remote add --mirror origin <url>". AFAIK
> this is not in any released version yet, though.
I just tried a bleeding edge git with --mirror.
It's close, except (unless there is some other provision to take care of
this) remote branch deletes. (Which, after more gmane trolling, seemed
to be "git remote rm", which doesn't seem present just yet).
Of course, it is completely possible I'm using it incorrectly. In brief,
I did "git init" "git remote add --mirror backup <url>" "git
pull" (perhaps I should have used "git remote update"?) And the behavior
of this is more or less what I wanted, as far as sending branches.
Convenient removal of branches and propagating that removal still stumps
me. Is there a preferred way to do this yet?
Thanks,
fdr
^ permalink raw reply
* Re: return void expressions in C (Was: [PATCH 3/6] Rework pretty_print_commit ...)
From: Linus Torvalds @ 2007-09-27 22:56 UTC (permalink / raw)
To: Pierre Habouzit; +Cc: Junio C Hamano, git
In-Reply-To: <20070910183256.GD32442@artemis.corp>
On Mon, 10 Sep 2007, Pierre Habouzit wrote:
>
> Okay, I stand corrected, but as I'm curious, I've now the Truth about
> this, for those who still care at that point (as the patch has been
> fixed in the next round anyways ;p)
The
void fn1(void);
void fn2(void)
{
return fn1();
}
thing is a gcc extension. It happens to be one we use in the kernel too,
since it makes for nicer-looking source code in some circumstances, but
it's definitely nonstandard.
Linus
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Theodore Tso @ 2007-09-27 22:52 UTC (permalink / raw)
To: Kelvie Wong; +Cc: Junio C Hamano, git
In-Reply-To: <94ccbe710709271523s7e4c7a1dh53e34bd460c31d1f@mail.gmail.com>
On Thu, Sep 27, 2007 at 03:23:44PM -0700, Kelvie Wong wrote:
> Finally got it to work. emacs (at least the version I'm using,
> 22.1.1) seems to set the $PWD via its first argument, that is,
> $LOCAL's directory, and when it goes to save, it tries to save $path
> on top of that.
It's not that emacs sets $PWD via its first argument, but the output
file is passed from emerge-files*-command to stashed in the per-buffer
variable emerge-file-out, which in turn gets passed to the emacs lisp
file write-file, which is what gets run when you run C-x C-w --- and
write-file interprets a relative pathname based on the containing
directory of the existing buffer.
> The updated patch above would be just to use the basename, that is, if
> it is certain that $LOCAL and $path will always reside in the same
> directory -- and I believe, but am not certain, that this is the case.
> Also, I am not sure if this is specific to my version of Emacs, so
> perhaps some further testing is required.
Yep, I've checked both emacs21 and emacs23-snapshot, and they both use
write-file, so this seems to be a long-standing bug (and I would call
it that) in emerge.el. So a patch like what you suggested is probably
going to be needed.
- Ted
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Theodore Tso @ 2007-09-27 22:35 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Kelvie Wong
In-Reply-To: <7vir5vss58.fsf@gitster.siamese.dyndns.org>
On Thu, Sep 27, 2007 at 02:41:23PM -0700, Junio C Hamano wrote:
> When mergetool is run from a subdirectory, "ls-files -u" nicely
> limits the output to conflicted files in that directory, but
> we need to give the full path to cat-file plumbing to grab the
> contents of stages.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Acked-by: "Theodore Ts'o" <tytso@mit.edu>
- Ted
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Pierre Habouzit @ 2007-09-27 22:28 UTC (permalink / raw)
To: Theodore Tso; +Cc: Russ Brown, Kelvie Wong, git
In-Reply-To: <20070927222326.GB8688@thunk.org>
[-- Attachment #1: Type: text/plain, Size: 1371 bytes --]
On Thu, Sep 27, 2007 at 10:23:26PM +0000, Theodore Tso wrote:
> On Thu, Sep 27, 2007 at 09:11:25PM +0200, Pierre Habouzit wrote:
> > > > And as none of the other merge tool that are supported are able to
> > > > either do 3way merges, or have a decent UI (that definitely seems to be
> > > > exclusive features) I've given up on git-mergetool (and to be fair, it
> > > > sucks, because it could be _sooo_ useful sometimes).
> > > >
> > >
> > > What about meld? That does 3-way merge, and the UI is fine.
> >
> > Indeed, it seems that since the last time I tested it, it now does
> > diff3 merging. I should reevaluate it :)
>
> Pierre,
>
> FYI, kdiff3, meld, xxdiff, opendiff (on MacOSX), and emerge all
> support 3-way merge.
I know, but:
* kdiff3 often take decisions behind your back, and results in broken
merges, so it's a no-go ;
* xxdiff has (IMHO) a very bad and non-intuitive UI, I never get to
make it work ;
* I don't use macos (opendiff) ;
* emerge is emacs right ? :)
Though I gave meld another chance, and it works really better than it
used to, so I may give it a try :) Let's hope I won't be disappointed by
meld :)
--
·O· Pierre Habouzit
··O madcoder@debian.org
OOO http://www.madism.org
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Kelvie Wong @ 2007-09-27 22:23 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Theodore Ts'o, git
In-Reply-To: <7vir5vss58.fsf@gitster.siamese.dyndns.org>
On 9/27/07, Junio C Hamano <gitster@pobox.com> wrote:
> When mergetool is run from a subdirectory, "ls-files -u" nicely
> limits the output to conflicted files in that directory, but
> we need to give the full path to cat-file plumbing to grab the
> contents of stages.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>
> * I earlier sent one with cd_to_toplevel but I think the
> approach in this patch is nicer.
>
> git-mergetool.sh | 7 ++++---
> 1 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/git-mergetool.sh b/git-mergetool.sh
> index a0e44f7..3b1ec13 100755
> --- a/git-mergetool.sh
> +++ b/git-mergetool.sh
> @@ -12,6 +12,7 @@ USAGE='[--tool=tool] [file to merge] ...'
> SUBDIRECTORY_OK=Yes
> . git-sh-setup
> require_work_tree
> +prefix=$(git rev-parse --show-prefix)
>
> # Returns true if the mode reflects a symlink
> is_symlink () {
> @@ -162,9 +163,9 @@ merge_file () {
> local_mode=`git ls-files -u -- "$path" | awk '{if ($3==2) print $1;}'`
> remote_mode=`git ls-files -u -- "$path" | awk '{if ($3==3) print $1;}'`
>
> - base_present && git cat-file blob ":1:$path" > "$BASE" 2>/dev/null
> - local_present && git cat-file blob ":2:$path" > "$LOCAL" 2>/dev/null
> - remote_present && git cat-file blob ":3:$path" > "$REMOTE" 2>/dev/null
> + base_present && git cat-file blob ":1:$prefix$path" >"$BASE" 2>/dev/null
> + local_present && git cat-file blob ":2:$prefix$path" >"$LOCAL" 2>/dev/null
> + remote_present && git cat-file blob ":3:$prefix$path" >"$REMOTE" 2>/dev/null
>
> if test -z "$local_mode" -o -z "$remote_mode"; then
> echo "Deleted merge conflict for '$path':"
>
--- a/git-mergetool 2007-09-24 09:08:23.000000000 -0700
+++ b/git-mergetool 2007-09-27 15:04:15.000000000 -0700
@@ -12,6 +12,7 @@
SUBDIRECTORY_OK=Yes
. git-sh-setup
require_work_tree
+prefix=$(git rev-parse --show-prefix)
# Returns true if the mode reflects a symlink
is_symlink () {
@@ -162,9 +163,9 @@
local_mode=`git ls-files -u -- "$path" | awk '{if ($3==2) print $1;}'`
remote_mode=`git ls-files -u -- "$path" | awk '{if ($3==3) print $1;}'`
- base_present && git cat-file blob ":1:$path" > "$BASE" 2>/dev/null
- local_present && git cat-file blob ":2:$path" > "$LOCAL" 2>/dev/null
- remote_present && git cat-file blob ":3:$path" > "$REMOTE" 2>/dev/null
+ base_present && git cat-file blob ":1:$prefix$path" > "$BASE" 2>/dev/null
+ local_present && git cat-file blob ":2:$prefix$path" > "$LOCAL"
2>/dev/null
+ remote_present && git cat-file blob ":3:$prefix$path" > "$REMOTE"
2>/dev/null
if test -z "$local_mode" -o -z "$remote_mode"; then
echo "Deleted merge conflict for '$path':"
@@ -251,7 +252,7 @@
;;
emerge)
if base_present ; then
- emacs -f emerge-files-with-ancestor-command "$LOCAL"
"$REMOTE" "$BASE" "$path"
+ emacs -f emerge-files-with-ancestor-command "$LOCAL"
"$REMOTE" "$BASE" "$(basename "$path")"
else
emacs -f emerge-files-command "$LOCAL" "$REMOTE"
"$(basename "$path")"
fi
Finally got it to work. emacs (at least the version I'm using,
22.1.1) seems to set the $PWD via its first argument, that is,
$LOCAL's directory, and when it goes to save, it tries to save $path
on top of that.
The updated patch above would be just to use the basename, that is, if
it is certain that $LOCAL and $path will always reside in the same
directory -- and I believe, but am not certain, that this is the case.
Also, I am not sure if this is specific to my version of Emacs, so
perhaps some further testing is required.
--
Kelvie
^ permalink raw reply
* Re: Mergetool generating blank files (1.5.3)
From: Theodore Tso @ 2007-09-27 22:23 UTC (permalink / raw)
To: Pierre Habouzit, Russ Brown, Kelvie Wong, git
In-Reply-To: <20070927191125.GD12427@artemis.corp>
On Thu, Sep 27, 2007 at 09:11:25PM +0200, Pierre Habouzit wrote:
> > > And as none of the other merge tool that are supported are able to
> > > either do 3way merges, or have a decent UI (that definitely seems to be
> > > exclusive features) I've given up on git-mergetool (and to be fair, it
> > > sucks, because it could be _sooo_ useful sometimes).
> > >
> >
> > What about meld? That does 3-way merge, and the UI is fine.
>
> Indeed, it seems that since the last time I tested it, it now does
> diff3 merging. I should reevaluate it :)
Pierre,
FYI, kdiff3, meld, xxdiff, opendiff (on MacOSX), and emerge all
support 3-way merge.
- Ted
^ 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