Git development
 help / color / mirror / Atom feed
* Re: Slow fetches of tags
From: Johannes Schindelin @ 2006-07-28 10:42 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Ralf Baechle, git, Linus Torvalds
In-Reply-To: <7v4px4osjv.fsf@assigned-by-dhcp.cox.net>

Hi,

On Wed, 26 Jul 2006, Junio C Hamano wrote:

> I think the attached patch is safe in general, but somebody may
> want to give an extra set of eyeballs to double check the logic
> is sane.

The only gripe I have with it is that reachable() is relatively expensive, 
and it might be misused by a nasty client, making the server go down the 
whole history. I have no idea, though, how to prevent that.

Ciao,
Dscho

^ permalink raw reply

* [PATCH] Teach git-apply about '-R'
From: Johannes Schindelin @ 2006-07-28 10:14 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git, junkio
In-Reply-To: <20060728013038.GH13776@pasky.or.cz>


Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

---

On Fri, 28 Jul 2006, Petr Baudis wrote:

>   (i) No git-apply -R - well, it seems to me that I revert patches all
> the time, don't you?

 builtin-apply.c         |   68 ++++++++++++++++++++++++++++++++++++++++-------
 t/t4102-apply-rename.sh |   24 +++++++++++++++--
 2 files changed, 80 insertions(+), 12 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index d924ac3..eb3eda1 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -120,7 +120,7 @@ struct fragment {
 struct patch {
 	char *new_name, *old_name, *def_name;
 	unsigned int old_mode, new_mode;
-	int is_rename, is_copy, is_new, is_delete, is_binary;
+	int is_rename, is_copy, is_new, is_delete, is_binary, is_reverse;
 #define BINARY_DELTA_DEFLATED 1
 #define BINARY_LITERAL_DEFLATED 2
 	unsigned long deflate_origlen;
@@ -1119,6 +1119,37 @@ static int parse_chunk(char *buffer, uns
 	return offset + hdrsize + patchsize;
 }
 
+/* a and b may not overlap! */
+static void memswap(void *a, void *b, unsigned int len)
+{
+	char *ap = a, *bp = b;
+	int i;
+	char c;
+
+	for (i = 0; i < len; i++) {
+		c = ap[i]; ap[i] = bp[i]; bp[i] = c;
+	}
+}
+
+static void reverse_patches(struct patch *p)
+{
+	for (; p; p = p->next) {
+		struct fragment *frag = p->fragments;
+
+		memswap(p->new_name, p->old_name, sizeof(char *));
+		memswap(&p->new_mode, &p->old_mode, sizeof(unsigned int));
+		memswap(&p->is_new, &p->is_delete, sizeof(int));
+		memswap(&p->lines_added, &p->lines_deleted, sizeof(int));
+		memswap(p->old_sha1_prefix, p->new_sha1_prefix, 41);
+
+		for (; frag; frag = frag->next) {
+			memswap(&frag->newpos, &frag->oldpos, sizeof(int));
+			memswap(&frag->newlines, &frag->oldlines, sizeof(int));
+		}
+		p->is_reverse = !p->is_reverse;
+	}
+}
+
 static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
 static const char minuses[]= "----------------------------------------------------------------------";
 
@@ -1336,7 +1367,7 @@ static int apply_line(char *output, cons
 }
 
 static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
-	int inaccurate_eof)
+	int reverse, int inaccurate_eof)
 {
 	int match_beginning, match_end;
 	char *buf = desc->buffer;
@@ -1350,6 +1381,7 @@ static int apply_one_fragment(struct buf
 	int pos, lines;
 
 	while (size > 0) {
+		char first;
 		int len = linelen(patch, size);
 		int plen;
 
@@ -1366,16 +1398,23 @@ static int apply_one_fragment(struct buf
 		plen = len-1;
 		if (len < size && patch[len] == '\\')
 			plen--;
-		switch (*patch) {
+		first = *patch;
+		if (reverse) {
+			if (first == '-')
+				first = '+';
+			else if (first == '+')
+				first = '-';
+		}
+		switch (first) {
 		case ' ':
 		case '-':
 			memcpy(old + oldsize, patch + 1, plen);
 			oldsize += plen;
-			if (*patch == '-')
+			if (first == '-')
 				break;
 		/* Fall-through for ' ' */
 		case '+':
-			if (*patch != '+' || !no_add)
+			if (first != '+' || !no_add)
 				newsize += apply_line(new + newsize, patch,
 						      plen);
 			break;
@@ -1615,7 +1654,8 @@ static int apply_fragments(struct buffer
 		return apply_binary(desc, patch);
 
 	while (frag) {
-		if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
+		if (apply_one_fragment(desc, frag, patch->is_reverse,
+					patch->inaccurate_eof) < 0)
 			return error("patch failed: %s:%ld",
 				     name, frag->oldpos);
 		frag = frag->next;
@@ -2142,7 +2182,8 @@ static int use_patch(struct patch *p)
 	return 1;
 }
 
-static int apply_patch(int fd, const char *filename, int inaccurate_eof)
+static int apply_patch(int fd, const char *filename,
+		int reverse, int inaccurate_eof)
 {
 	unsigned long offset, size;
 	char *buffer = read_patch_file(fd, &size);
@@ -2162,6 +2203,8 @@ static int apply_patch(int fd, const cha
 		nr = parse_chunk(buffer + offset, size, patch);
 		if (nr < 0)
 			break;
+		if (reverse)
+			reverse_patches(patch);
 		if (use_patch(patch)) {
 			patch_stats(patch);
 			*listp = patch;
@@ -2226,6 +2269,7 @@ int cmd_apply(int argc, const char **arg
 {
 	int i;
 	int read_stdin = 1;
+	int reverse = 0;
 	int inaccurate_eof = 0;
 
 	const char *whitespace_option = NULL;
@@ -2236,7 +2280,7 @@ int cmd_apply(int argc, const char **arg
 		int fd;
 
 		if (!strcmp(arg, "-")) {
-			apply_patch(0, "<stdin>", inaccurate_eof);
+			apply_patch(0, "<stdin>", reverse, inaccurate_eof);
 			read_stdin = 0;
 			continue;
 		}
@@ -2313,6 +2357,10 @@ int cmd_apply(int argc, const char **arg
 			parse_whitespace_option(arg + 13);
 			continue;
 		}
+		if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) {
+			reverse = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--inaccurate-eof")) {
 			inaccurate_eof = 1;
 			continue;
@@ -2333,12 +2381,12 @@ int cmd_apply(int argc, const char **arg
 			usage(apply_usage);
 		read_stdin = 0;
 		set_default_whitespace_mode(whitespace_option);
-		apply_patch(fd, arg, inaccurate_eof);
+		apply_patch(fd, arg, reverse, inaccurate_eof);
 		close(fd);
 	}
 	set_default_whitespace_mode(whitespace_option);
 	if (read_stdin)
-		apply_patch(0, "<stdin>", inaccurate_eof);
+		apply_patch(0, "<stdin>", reverse, inaccurate_eof);
 	if (whitespace_error) {
 		if (squelch_whitespace_errors &&
 		    squelch_whitespace_errors < whitespace_error) {
diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh
index fbb508d..22da6a0 100755
--- a/t/t4102-apply-rename.sh
+++ b/t/t4102-apply-rename.sh
@@ -13,8 +13,8 @@ # setup
 cat >test-patch <<\EOF
 diff --git a/foo b/bar
 similarity index 47%
-copy from foo
-copy to bar
+rename from foo
+rename to bar
 --- a/foo
 +++ b/bar
 @@ -1 +1 @@
@@ -39,4 +39,24 @@ else
 	    'test -f bar && ls -l bar | grep "^-..x......"'
 fi
 
+test_expect_success 'apply reverse' \
+    'git-apply -R --index --stat --summary --apply test-patch &&
+     test "$(cat foo)" = "This is foo"'
+
+cat >test-patch <<\EOF
+diff --git a/foo b/bar
+similarity index 47%
+copy from foo
+copy to bar
+--- a/foo
++++ b/bar
+@@ -1 +1 @@
+-This is foo
++This is bar
+EOF
+
+test_expect_success 'apply copy' \
+    'git-apply --index --stat --summary --apply test-patch &&
+     test "$(cat bar)" = "This is bar" -a "$(cat foo)" = "This is foo"'
+
 test_done
-- 
1.4.2.rc2.g813d5-dirty

^ permalink raw reply related

* Re: Git clone stalls at a read(3, ...) saw using strace
From: André Goddard Rosa @ 2006-07-28  9:58 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: Git Mailing List, Linus Torvalds, Ribeiro, Humberto Plinio
In-Reply-To: <b8bf37780607280256q485b7ae9p9cdedf9b621a0e9b@mail.gmail.com>

On 7/28/06, André Goddard Rosa <andre.goddard@gmail.com> wrote:
> On 7/27/06, André Goddard Rosa <andre.goddard@gmail.com> wrote:
> > On 7/27/06, Pavel Roskin <proski@gnu.org> wrote:
> > > On Thu, 2006-07-27 at 10:50 -0700, Linus Torvalds wrote:
> > > > Nope. I have a fairly constant 120kbps, and:
> > > >
> > > > [torvalds@g5 ~]$  git clone git://source.mvista.com/git/linux-davinci-2.6.git
> > > > Checking files out...)
> > > >  100% (19754/19754) done
> > >
> > > Same thing here.  Current git from the master branch.
> >
> > Forgot to say that we are using this script in GIT_PROXY_COMMAND
> > environment variable:
> >
> > (echo "CONNECT $1:$2 HTTP/1.0"; echo; cat ) | nc <proxy_add> <portnum>
> > | (read a; read a; cat )
> >
> > The first 'read a' removes the 'CONNECT SUCCESS HTTP RESPONSE 200' and
> > the second removes an empty line as described here:
> >
> > http://www.gelato.unsw.edu.au/archives/git/0605/20664.html
> >
> > I will try from home later again.
>
> Okey, I tried from home (without the proxy trick) and it behaved a lot
> better but my disc went full in the process and I got these messages:
> ...
> ...
> ...
> error: git-checkout-index: unable to write file drivers/scsi/mac53c94.c
> error: git-checkout-index: unable to write file drivers/scsi/mac53c94.h
> error: git-checkout-index: unable to write file drivers/scsi/mac_esp.c
> error: git-checkout-index: unable to create file
> drivers/scsi/mac_scsi.c (No space left on device)
> error: git-checkout-index: unable to create file
> drivers/scsi/mac_scsi.h (No space left on device)
> error: git-checkout-index: unable to create file
> drivers/scsi/mca_53c9x.c (No space left on device)
> error: git-checkout-index: unable to create file
> drivers/scsi/megaraid.c (No space left on device)
> error: git-checkout-index: unable to create file
> drivers/scsi/megaraid.h (No space left on device)
> fatal: cannot create directory at drivers/scsi/megaraid
>
> And it finished keeping the downloaded files, but I still cannot see
> these files listed above.
> I tried to pull but it says that I'm up-to-date:
>
> doctorture:/opt/downloads/mvista/linux-mvista # git-pull
> Already up-to-date.
>
> I remember that using CVS I just used 'cvs update' after checkout and
> it would bring the missing files to me.
>
> What I'm doing wrong here?

I'm also receiving these messages when trying to change branches:

doctorture:/opt/downloads/mvista/linux-mvista # git-checkout origin
fatal: Untracked working tree file '.gitignore' would be overwritten by merge.

Perhaps I will need to download using git-clone again?

Thanks,
-- 
[]s,
André Goddard

^ permalink raw reply

* Re: Git clone stalls at a read(3, ...) saw using strace
From: André Goddard Rosa @ 2006-07-28  9:56 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: Git Mailing List, Linus Torvalds, Ribeiro, Humberto Plinio
In-Reply-To: <b8bf37780607271216i5b1d8d34n900ffeacbe81f380@mail.gmail.com>

On 7/27/06, André Goddard Rosa <andre.goddard@gmail.com> wrote:
> On 7/27/06, Pavel Roskin <proski@gnu.org> wrote:
> > On Thu, 2006-07-27 at 10:50 -0700, Linus Torvalds wrote:
> > > Nope. I have a fairly constant 120kbps, and:
> > >
> > > [torvalds@g5 ~]$  git clone git://source.mvista.com/git/linux-davinci-2.6.git
> > > Checking files out...)
> > >  100% (19754/19754) done
> >
> > Same thing here.  Current git from the master branch.
>
> Forgot to say that we are using this script in GIT_PROXY_COMMAND
> environment variable:
>
> (echo "CONNECT $1:$2 HTTP/1.0"; echo; cat ) | nc <proxy_add> <portnum>
> | (read a; read a; cat )
>
> The first 'read a' removes the 'CONNECT SUCCESS HTTP RESPONSE 200' and
> the second removes an empty line as described here:
>
> http://www.gelato.unsw.edu.au/archives/git/0605/20664.html
>
> I will try from home later again.

Okey, I tried from home (without the proxy trick) and it behaved a lot
better but my disc went full in the process and I got these messages:
...
...
...
error: git-checkout-index: unable to write file drivers/scsi/mac53c94.c
error: git-checkout-index: unable to write file drivers/scsi/mac53c94.h
error: git-checkout-index: unable to write file drivers/scsi/mac_esp.c
error: git-checkout-index: unable to create file
drivers/scsi/mac_scsi.c (No space left on device)
error: git-checkout-index: unable to create file
drivers/scsi/mac_scsi.h (No space left on device)
error: git-checkout-index: unable to create file
drivers/scsi/mca_53c9x.c (No space left on device)
error: git-checkout-index: unable to create file
drivers/scsi/megaraid.c (No space left on device)
error: git-checkout-index: unable to create file
drivers/scsi/megaraid.h (No space left on device)
fatal: cannot create directory at drivers/scsi/megaraid

And it finished keeping the downloaded files, but I still cannot see
these files listed above.
I tried to pull but it says that I'm up-to-date:

doctorture:/opt/downloads/mvista/linux-mvista # git-pull
Already up-to-date.

I remember that using CVS I just used 'cvs update' after checkout and
it would bring the missing files to me.

What I'm doing wrong here?

Thank you so much,
-- 
[]s,
André Goddard

^ permalink raw reply

* [PATCH] Makefile: ssh-pull.o depends on ssh-fetch.c
From: Johannes Schindelin @ 2006-07-28  9:17 UTC (permalink / raw)
  To: git, junkio


Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
 Makefile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index 636679f..e8037ad 100644
--- a/Makefile
+++ b/Makefile
@@ -661,6 +661,7 @@ git-%$X: %.o $(GITLIBS)
 	$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 		$(LIB_FILE) $(SIMPLE_LIB)
 
+ssh-pull.o: ssh-fetch.c
 git-local-fetch$X: fetch.o
 git-ssh-fetch$X: rsh.o fetch.o
 git-ssh-upload$X: rsh.o
-- 
1.4.2.rc2.g51ee8-dirty

^ permalink raw reply related

* Re: Licensing and the library version of git
From: Johannes Schindelin @ 2006-07-28  9:01 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Anand Kumria, git
In-Reply-To: <9e4733910607271743o3b7a27d5v55a216745937c74e@mail.gmail.com>

Hi,

On Thu, 27 Jul 2006, Jon Smirl wrote:

> On 7/27/06, Anand Kumria <wildfire@progsoc.org> wrote:
>
> > So, using CVSNT (a GPL'd SCCI provider) and git-cvsserver would be a way
> > to continue.  I'm assuming that the primary functionality they want via
> > their IDE is checkout/diff/commit/log.
> 
> Now, that's a great strategy. Tell the large project you are
> interested in switching off from CVS to git that they need to run a
> CVS emulation gateway forever. I don't think a switch has much of a
> chance of happening.

Oh, but it has!

The beautiful thing is that you can change to git _without_ changing all 
client software! Just to a git-cvsimport, switch, and some might not even 
notice that the server has changed behind their back.

And then, you can phase out CVS slowly.

BTW have you worked with MSVC's integrated source control? In every single 
case where I had to work with MSVC, I found I'm way faster with external 
tools (and it did not matter if the SCM was Visual Source Safe, CVS or 
PVCS). I know that my colleagues found the same.

BTW2 I agree that some deciding people would make MSVC integration a 
premise for migration to Git. So, why don't you give it a try? (I do not 
have a working MSVC setup, or I would help you.)

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] Allow fetching from multiple repositories at once
From: Johannes Schindelin @ 2006-07-28  8:51 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Junio C Hamano, git, alp
In-Reply-To: <20060728054341.15864.35862.stgit@machine>

Hi,

On Fri, 28 Jul 2006, Petr Baudis wrote:

> This patch enables fetching multiple repositories at once over the Git
> protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
> there). This is done especially for the xorg people who have tons of
> repositories and dislike pulls much slower than they were used to with CVS.
> I'm eager to hear how this affects the situation.

So the scenario is: one remote repository (probably shared), and multiple 
local repositories, all tracking different branches?

So, why not setup a single local (master) repository, setup all the other 
repos with the local master as alternate, and write a simple script which 
first fetches all branches into the master, and then pulls into the other 
local repos from that master?

The beauty of it is: you can still pull/push directly from the remote 
repo, if you want.

Ciao,
Dscho

^ permalink raw reply

* Re: Licensing and the library version of git
From: Johannes Schindelin @ 2006-07-28  8:44 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: Wolfgang Denk, Jon Smirl, git
In-Reply-To: <20060728050444.GA30783@spearce.org>

Hi,

On Fri, 28 Jul 2006, Shawn Pearce wrote:

> [...] as the GPL is incompatible with the Sun JRE runtime lirbary.

This is not true. You can legally write and run GPLed software on the JRE 
runtime library.

BTW I found an Eclipse plugin which is GPLed:

http://www.eclipseplugincentral.com/Web_Links-index-req-viewlink-cid-651.html

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH] Allow fetching from multiple repositories at once
From: Junio C Hamano @ 2006-07-28  7:35 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git, alp
In-Reply-To: <20060728054341.15864.35862.stgit@machine>

This is quite heavyweight.

I'll take a look at it eventually ;-), but I'd like to take a
deeper look at merge-recursive by Johannes and Alex first.
Perhaps I can get to it over the weekend, but Saturday is
already booked for friends' wedding, so it might take a while.

^ permalink raw reply

* Re: print errors from git-update-ref
From: Junio C Hamano @ 2006-07-28  7:26 UTC (permalink / raw)
  To: Shawn Pearce; +Cc: git, Johannes Schindelin
In-Reply-To: <20060728062720.GC30783@spearce.org>

Shawn Pearce <spearce@spearce.org> writes:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>> Hi,
>> 
>> On Wed, 26 Jul 2006, Shawn Pearce wrote:
>> 
>> > This change adds a test for trying to create a ref within a directory
>> > that is actually currently a file, and adds error printing within
>> > the ref locking routine should the resolve operation fail.
>> 
>> Why not just print an error message when the resolve operation fails, 
>> instead of special casing this obscure corner case? It is way shorter, 
>> too. The test should stay, though.
>
> Did you read the patch?  If resolve_ref returns NULL then this
> change prints an error (from errno) no matter what.  If errno is
> ENOTDIR then it tries to figure out what part of the ref path wasn't
> a directory (but was attempted to be used as such) and prints an
> ENOTDIR error about that path instead of the one actually given
> to the ref lock function
>
> So I think I'm doing what you are suggesting...

Not quite.

+		int last_errno = errno;
+		if (errno == ENOTDIR) {
+			char* p = not_a_directory(orig_path);
+			error("unable to resolve reference %s: %s",
+				p, strerror(errno));
+			free(p);
+		} else
+			error("unable to resolve reference %s: %s",
+				orig_path, strerror(errno));
 		unlock_ref(lock);
+		errno = last_errno;

I know you are trying to be nice by pinpointing which component
of the directory hierarchy is offending, but at the same time
the nicety is hiding the orig_path given to the program from the
user.  Maybe showing orig_path _and_ p would be nicer.

But I suspect there is even more serious problem here.

 - lock_ref_sha1_basic() gets "path" from the user; you stash it
   away in "orig_path".

 - resolve_ref() tries to resolve both symbolic links and
   symrefs.  If it fails, it returns NULL.

 - When it returns NULL, you use orig_path (say, "a/b/c/d") to
   see which path component is not a directory (say, "a/b/c" is
   a file).

But the last step does not take into account what resolve_ref()
does, doesn't it?  What if orig_path is "HEAD", which is a
symref, which contained "ref: refs/heads/myhack/one" and
"refs/heads/myhack" is a file?  Ideally you may want to say
something like:

     '''while resolving %s, which points at %s,
        we found out %s is not a directory''' %
        ("HEAD", "refs/heads/myhack/one", "refs/heads/myhack")

So I tend to agree with Johannes's "why bother?" reaction.

^ permalink raw reply

* Re: Java GIT/Eclipse GIT version 0.1.1
From: Peter Baumann @ 2006-07-28  7:23 UTC (permalink / raw)
  To: git
In-Reply-To: <20060728030859.n8ks44ck8884ss44@webmail.spamcop.net>

On 2006-07-28, Pavel Roskin <proski@gnu.org> wrote:
> Quoting Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>:
>
>> On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
>> > My Java GIT library and Eclipse GIT team provider is now at a point
>> > where it may be partially useful to someone else who is also trying
>> > to write something which interacts with GIT.  Or who might also
>> > be interested in seeing a pure-Java Eclipse team provider for GIT.
>> >
>> > So I've posted my repository (currently ~200 KB) on my website:
>> >
>> >   http://www.spearce.org/projects/scm/egit.git
>> >
>>
>> Doesn't work for me.
>
> Neither does it for me:
>
> $ git clone http://www.spearce.org/projects/scm/egit.git
> error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2
> (http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2)
> corrupt
> Getting pack list for http://www.spearce.org/projects/scm/egit.git/
> error: XML error: not well-formed (invalid token)
>
>> *** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
>> /usr/bin/git-clone: line 29: 10712 Aborted                 git-http-fetch -v
>> -a -w "$tname" "$name" "$1/"
>
> I'm not getting that.  I hope you are just using an obsolete version of git.

Not _that_ old, me thinks. I'm using the debian unstable version.

devil:~ dpkg -l |grep git-core
ii  git-core       1.4.1-1        content addressable filesystem

(Yes, I'am aware that this version has the timing bug on the server
side, but I was just too lazy to compile git myself this time :-)

-Peter

^ permalink raw reply

* Re: Java GIT/Eclipse GIT version 0.1.1
From: Pavel Roskin @ 2006-07-28  7:08 UTC (permalink / raw)
  To: Peter Baumann; +Cc: git
In-Reply-To: <slrnecjcsn.8td.Peter.B.Baumann@xp.machine.xx>

Quoting Peter Baumann <Peter.B.Baumann@stud.informatik.uni-erlangen.de>:

> On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
> > My Java GIT library and Eclipse GIT team provider is now at a point
> > where it may be partially useful to someone else who is also trying
> > to write something which interacts with GIT.  Or who might also
> > be interested in seeing a pure-Java Eclipse team provider for GIT.
> >
> > So I've posted my repository (currently ~200 KB) on my website:
> >
> >   http://www.spearce.org/projects/scm/egit.git
> >
>
> Doesn't work for me.

Neither does it for me:

$ git clone http://www.spearce.org/projects/scm/egit.git
error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2
(http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2)
corrupt
Getting pack list for http://www.spearce.org/projects/scm/egit.git/
error: XML error: not well-formed (invalid token)

> *** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
> /usr/bin/git-clone: line 29: 10712 Aborted                 git-http-fetch -v
> -a -w "$tname" "$name" "$1/"

I'm not getting that.  I hope you are just using an obsolete version of git.

--
Regards,
Pavel Roskin

^ permalink raw reply

* Re: Java GIT/Eclipse GIT version 0.1.1
From: Peter Baumann @ 2006-07-28  6:49 UTC (permalink / raw)
  To: git
In-Reply-To: <20060728063620.GD30783@spearce.org>

On 2006-07-28, Shawn Pearce <spearce@spearce.org> wrote:
> My Java GIT library and Eclipse GIT team provider is now at a point
> where it may be partially useful to someone else who is also trying
> to write something which interacts with GIT.  Or who might also
> be interested in seeing a pure-Java Eclipse team provider for GIT.
>
> So I've posted my repository (currently ~200 KB) on my website:
>
>   http://www.spearce.org/projects/scm/egit.git
>

Doesn't work for me.

devil:~/src git clone http://www.spearce.org/projects/scm/egit.git
error: File ac32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2 (http://www.spearce.org/projects/scm/egit.git/objects/ac/32c7cc2f7cf87a1ed80d0cdfca2af2a0385bb2) corrupt
Getting pack list for http://www.spearce.org/projects/scm/egit.git/
Getting alternates list for http://www.spearce.org/projects/scm/egit.git/
Also look at <html xmlns="http://www.w3.org/1999/
Also look at    <title>Insufficiently Random: The lonely musings of a loosely connected software developer.<
Also look at            @import url( http://www.spearce.org/wordpress/wp-content/themes/ir-classic/style
Also look at    <link rel="pingback" href="http://www.spearce.org/wordpress/xmlrpc.
Also look at            <link rel='archives' title='April 2006' href='http://www.spearce.org/2006/
Also look at    <link rel='archives' title='February 2006' href='http://www.spearce.org/2006/
[...]
Also look at <li><a href="feed:http://www.spearce.org/comments/feed/" title="The latest comments to all posts in RSS">Comments <abbr title="Really Simple Syndication">RSS</abbr></
*** glibc detected *** double free or corruption (!prev): 0x080933b0 ***
/usr/bin/git-clone: line 29: 10712 Aborted                 git-http-fetch -v -a -w "$tname" "$name" "$1/"

-Peter

^ permalink raw reply

* Java GIT/Eclipse GIT version 0.1.1
From: Shawn Pearce @ 2006-07-28  6:36 UTC (permalink / raw)
  To: git

My Java GIT library and Eclipse GIT team provider is now at a point
where it may be partially useful to someone else who is also trying
to write something which interacts with GIT.  Or who might also
be interested in seeing a pure-Java Eclipse team provider for GIT.

So I've posted my repository (currently ~200 KB) on my website:

  http://www.spearce.org/projects/scm/egit.git


The underlying Java library is fairly functional and can read and
write a repository.  Creating a series of Ant tasks for use in an
automated build environment would probably be pretty trivial with
this library.

The Eclipse plugin can't commit.  Or do a lot of other really
useful things.  So its not end-user ready.  :-)


The code is licensed under the Apache License, version 2.0.


I would appreciate any and all input, feedback, etc. that anyone
might have on this library or plugin.  Patches are of course
certainly welcome.  :-)

For what its worth I'm trying to keep this library and Eclipse
plugin 100% pure Java and avoid calling out to the canonical C
implementation of GIT.  However I have no plans to implement the
delta packing algorithm used by git-pack-objects.  Consequently if
this code ever produces packs it will be strictly zlib deflated
objects without delta compression.

-- 
Shawn.

^ permalink raw reply

* Re: print errors from git-update-ref
From: Shawn Pearce @ 2006-07-28  6:27 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Junio C Hamano, Alex Riesen, Git Mailing List
In-Reply-To: <Pine.LNX.4.63.0607271302150.29667@wbgn013.biozentrum.uni-wuerzburg.de>

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Hi,
> 
> On Wed, 26 Jul 2006, Shawn Pearce wrote:
> 
> > This change adds a test for trying to create a ref within a directory
> > that is actually currently a file, and adds error printing within
> > the ref locking routine should the resolve operation fail.
> 
> Why not just print an error message when the resolve operation fails, 
> instead of special casing this obscure corner case? It is way shorter, 
> too. The test should stay, though.

Did you read the patch?  If resolve_ref returns NULL then this
change prints an error (from errno) no matter what.  If errno is
ENOTDIR then it tries to figure out what part of the ref path wasn't
a directory (but was attempted to be used as such) and prints an
ENOTDIR error about that path instead of the one actually given
to the ref lock function

So I think I'm doing what you are suggesting...

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-07-28  5:46 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, alp
In-Reply-To: <20060728054341.15864.35862.stgit@machine>

Dear diary, on Fri, Jul 28, 2006 at 07:44:21AM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> So, you need some kind of porcelain for this. The idea is that instead of
> telling git-fetch-pack a single repository, you pass multiple --repo=
> parameters and refs always "belong" to the latest mentioned repository;
> when outputting the new ref values, the appropriate repo is mentioned near
> each ref. In order for this to be useful, on your local side you should
> share the objects database in some way - either using alternates (then
> you must fetch to an object database reachable from everywhere) or symlinked
> object databases.
> 
> You still need to pass git-fetch-pack some URL in addition to the
> repositories - it is used only for git_connect(), the purpose is that
> repositories must be local directories so if you want to talk remote, you
> need to do something like
> 
> 	git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master

This is a simple "porcelain" for it:

-->8--

#!/usr/bin/perl
use warnings;
use strict;

# Remember that you must ensure the obj database is shared - either symlink it
# or setup alternates!
#my $remoteurl = 'git://git.kernel.org/pub/scm/git/git.git';
#my %config = (
#	'/pub/scm/git/git.git' => {
#		'next' => {
#			'/home/xpasky/q/gg' => 'origin'
#		},
#		'master' => {
#			'/home/xpasky/q/gg' => 'origin2',
#			'/home/xpasky/q/gg2' => 'origin'
#		}
#	},
#	'/pub/scm/cogito/cogito-doc.git' => {
#		master => {
#			'/home/xpasky/q/gg2' => 'origin2'
#		}
#	}
#);
my $remoteurl = 'puturlofremotehosthere';
my %config = (
	'remoterepo1' => {
		branch1 => {
			'localrepo1' => 'origin'
		},
		branch2 => {
			'localrepo1' => 'origin2',
			'localrepo2' => 'origin'
		}
	},
	'remoterepo2' => {
		master => {
			'localrepo2' => 'origin2'
		}
	}
);

my @args = ($remoteurl);
foreach my $repo (keys %config) {
	push (@args, '--repo='.$repo);
	foreach my $branch (keys %{$config{$repo}}) {
		push (@args, $branch);
	}
}

open (F, '-|', 'git-fetch-pack', @args) or die "$!";
while (<F>) {
	chomp;
	split / /, $_;
	my ($sha, $ref, $repo) = @_;
	$ref =~ s#^refs/heads/##;
	foreach my $lrepo (keys %{$config{$repo}->{$ref}}) {
		system("GIT_DIR=$lrepo git-update-ref $config{$repo}->{$ref}->{$lrepo} $sha");
	}
}
close (F);

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* [PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-07-28  5:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, alp

This patch enables fetching multiple repositories at once over the Git
protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
there). This is done especially for the xorg people who have tons of
repositories and dislike pulls much slower than they were used to with CVS.
I'm eager to hear how this affects the situation.

It's kind of "superproject" thing, basically, taking reverse approach than
the subproject ideas. However, in practice I think it can be used for
subprojects quite well and perhaps if I find some spare time during the day
I will add the lightweight subproject support to Cogito, using this.

So, you need some kind of porcelain for this. The idea is that instead of
telling git-fetch-pack a single repository, you pass multiple --repo=
parameters and refs always "belong" to the latest mentioned repository;
when outputting the new ref values, the appropriate repo is mentioned near
each ref. In order for this to be useful, on your local side you should
share the objects database in some way - either using alternates (then
you must fetch to an object database reachable from everywhere) or symlinked
object databases.

You still need to pass git-fetch-pack some URL in addition to the
repositories - it is used only for git_connect(), the purpose is that
repositories must be local directories so if you want to talk remote, you
need to do something like

	git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master

The implementation is, well... rather hackish to say the least. :-)
We can do something nicer if it turns out to be a boost huge enough
in reality too.

Signed-off-by: Petr Baudis <pasky@suse.cz>
---

 cache.h       |    7 ++++--
 connect.c     |   11 ++++++---
 daemon.c      |    9 +++++---
 fetch-pack.c  |   58 +++++++++++++++++++++++++++++++++----------------
 path.c        |    5 ++++
 peek-remote.c |    4 ++-
 send-pack.c   |    4 ++-
 sha1_file.c   |    6 +++--
 upload-pack.c |   68 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 9 files changed, 127 insertions(+), 45 deletions(-)

diff --git a/cache.h b/cache.h
index 457d1d0..ea2f5e8 100644
--- a/cache.h
+++ b/cache.h
@@ -225,6 +225,7 @@ int git_config_perm(const char *var, con
 int adjust_shared_perm(const char *path);
 int safe_create_leading_directories(char *path);
 char *enter_repo(char *path, int strict);
+int security_repo_check(int export_all_trees);
 
 /* Read and unpack a sha1 file into memory, write memory to a sha1 file */
 extern int sha1_object_info(const unsigned char *, char *, unsigned long *);
@@ -298,6 +299,7 @@ extern struct alternate_object_database 
 	char base[FLEX_ARRAY]; /* more */
 } *alt_odb_list;
 extern void prepare_alt_odb(void);
+extern int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self);
 
 extern struct packed_git {
 	struct packed_git *next;
@@ -325,6 +327,7 @@ struct ref {
 	unsigned char new_sha1[20];
 	unsigned char force;
 	struct ref *peer_ref; /* when renaming */
+	char *repo; /* when doing multi-repo operations */
 	char name[FLEX_ARRAY]; /* more */
 };
 
@@ -334,11 +337,11 @@ #define REF_TAGS	(1u << 2)
 
 extern int git_connect(int fd[2], char *url, const char *prog);
 extern int finish_connect(pid_t pid);
-extern int path_match(const char *path, int nr, char **match);
+extern int path_match(const char *path, const char *repo, int nr, char **match, char **match_repo);
 extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
 		      int nr_refspec, char **refspec, int all);
 extern int get_ack(int fd, unsigned char *result_sha1);
-extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
+extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, char *repo, unsigned int flags);
 extern int server_supports(const char *feature);
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1);
diff --git a/connect.c b/connect.c
index 4422a0d..63f095c 100644
--- a/connect.c
+++ b/connect.c
@@ -45,9 +45,8 @@ static int check_ref(const char *name, i
  */
 struct ref **get_remote_heads(int in, struct ref **list,
 			      int nr_match, char **match,
-			      unsigned int flags)
+			      char *repo, unsigned int flags)
 {
-	*list = NULL;
 	for (;;) {
 		struct ref *ref;
 		unsigned char old_sha1[20];
@@ -74,11 +73,12 @@ struct ref **get_remote_heads(int in, st
 
 		if (!check_ref(name, name_len, flags))
 			continue;
-		if (nr_match && !path_match(name, nr_match, match))
+		if (nr_match && !path_match(name, NULL, nr_match, match, NULL))
 			continue;
 		ref = xcalloc(1, sizeof(*ref) + len - 40);
 		memcpy(ref->old_sha1, old_sha1, 20);
 		memcpy(ref->name, buffer + 41, len - 40);
+		ref->repo = repo;
 		*list = ref;
 		list = &ref->next;
 	}
@@ -112,7 +112,8 @@ int get_ack(int fd, unsigned char *resul
 	die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
 }
 
-int path_match(const char *path, int nr, char **match)
+int path_match(const char *path, const char *repo, int nr, char **match,
+               char **match_repo)
 {
 	int i;
 	int pathlen = strlen(path);
@@ -121,6 +122,8 @@ int path_match(const char *path, int nr,
 		char *s = match[i];
 		int len = strlen(s);
 
+		if (match_repo && repo != match_repo[i])
+			continue;
 		if (!len || len > pathlen)
 			continue;
 		if (memcmp(path + pathlen - len, s, len))
diff --git a/daemon.c b/daemon.c
index e4ec676..179f2fe 100644
--- a/daemon.c
+++ b/daemon.c
@@ -233,6 +233,7 @@ static int upload(char *dir)
 {
 	/* Timeout as string */
 	char timeout_buf[64];
+	char checkexport_buf[64];
 	const char *path;
 
 	loginfo("Request for '%s'", dir);
@@ -250,8 +251,7 @@ static int upload(char *dir)
 	 * path_ok() uses enter_repo() and does whitelist checking.
 	 * We only need to make sure the repository is exported.
 	 */
-
-	if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
+	if (!security_repo_check(export_all_trees)) {
 		logerror("'%s': repository not exported.", path);
 		errno = EACCES;
 		return -1;
@@ -265,8 +265,11 @@ static int upload(char *dir)
 
 	snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
 
+	strcpy(checkexport_buf, "--check-export");
+	if (export_all_trees) checkexport_buf[1] = '\0'; /* XXX */
+
 	/* git-upload-pack only ever reads stuff, so this is safe */
-	execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
+	execl_git_cmd("upload-pack", "--strict", timeout_buf, checkexport_buf, ".", NULL);
 	return -1;
 }
 
diff --git a/fetch-pack.c b/fetch-pack.c
index b7824db..2b02d0f 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -281,7 +281,8 @@ static void mark_recent_complete_commits
 	}
 }
 
-static void filter_refs(struct ref **refs, int nr_match, char **match)
+static void filter_refs(struct ref **refs, int nr_match, char **match,
+                        char **match_repo)
 {
 	struct ref **return_refs;
 	struct ref *newlist = NULL;
@@ -312,7 +313,7 @@ static void filter_refs(struct ref **ref
 			continue;
 		}
 		else {
-			int order = path_match(ref->name, nr_match, match);
+			int order = path_match(ref->name, ref->repo, nr_match, match, match_repo);
 			if (order) {
 				return_refs[order-1] = ref;
 				continue; /* we will link it later */
@@ -337,7 +338,8 @@ static void filter_refs(struct ref **ref
 	*refs = newlist;
 }
 
-static int everything_local(struct ref **refs, int nr_match, char **match)
+static int everything_local(struct ref **refs, int nr_match, char **match,
+                            char **match_repo)
 {
 	struct ref *ref;
 	int retval;
@@ -386,7 +388,7 @@ static int everything_local(struct ref *
 		}
 	}
 
-	filter_refs(refs, nr_match, match);
+	filter_refs(refs, nr_match, match, match_repo);
 
 	for (retval = 1, ref = *refs; ref ; ref = ref->next) {
 		const unsigned char *remote = ref->old_sha1;
@@ -414,13 +416,15 @@ static int everything_local(struct ref *
 	return retval;
 }
 
-static int fetch_pack(int fd[2], int nr_match, char **match)
+static int fetch_pack(int fd[2], int nr_repo, char **repo,
+                      int nr_match, char **match, char **match_repo)
 {
-	struct ref *ref;
+	struct ref *ref = NULL, **refn;
 	unsigned char sha1[20];
 	int status;
+	int i;
 
-	get_remote_heads(fd[0], &ref, 0, NULL, 0);
+	refn = get_remote_heads(fd[0], &ref, 0, NULL, nr_repo ? repo[0] : NULL, 0);
 	if (server_supports("multi_ack")) {
 		if (verbose)
 			fprintf(stderr, "Server supports multi_ack\n");
@@ -431,11 +435,19 @@ static int fetch_pack(int fd[2], int nr_
 			fprintf(stderr, "Server supports side-band\n");
 		use_sideband = 1;
 	}
+	if (!server_supports("switch-repo") && nr_repo > 1)
+		die("server does not support fetching multiple repositories at once");
+
+	for (i = 1; i < nr_repo; i++) {
+		packet_write(fd[1], "switch-repo %s", repo[i]);
+		refn = get_remote_heads(fd[0], refn, 0, NULL, repo[i], 0);
+	}
+
 	if (!ref) {
 		packet_flush(fd[1]);
 		die("no matching remote head");
 	}
-	if (everything_local(&ref, nr_match, match)) {
+	if (everything_local(&ref, nr_match, match, match_repo)) {
 		packet_flush(fd[1]);
 		goto all_done;
 	}
@@ -456,8 +468,9 @@ static int fetch_pack(int fd[2], int nr_
 
  all_done:
 	while (ref) {
-		printf("%s %s\n",
-		       sha1_to_hex(ref->old_sha1), ref->name);
+		printf("%s %s%s%s\n",
+		       sha1_to_hex(ref->old_sha1), ref->name,
+		       ref->repo ? " " : "", ref->repo ? : "");
 		ref = ref->next;
 	}
 	return 0;
@@ -465,15 +478,16 @@ static int fetch_pack(int fd[2], int nr_
 
 int main(int argc, char **argv)
 {
-	int i, ret, nr_heads;
-	char *dest = NULL, **heads;
+	int i, ret, nr_repo = 0, nr_heads = 0;
+	char *dest = NULL;
+	char **repo = xmalloc(argc * sizeof(*repo));
+	char **heads = xmalloc(argc * sizeof(*heads));
+	char **heads_repo = xmalloc(argc * sizeof(*heads_repo));
 	int fd[2];
 	pid_t pid;
 
 	setup_git_directory();
 
-	nr_heads = 0;
-	heads = NULL;
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
 
@@ -498,16 +512,22 @@ int main(int argc, char **argv)
 				fetch_all = 1;
 				continue;
 			}
+			if (!strncmp("--repo=", arg, 7)) {
+				repo[nr_repo++] = arg + 7;
+				continue;
+			}
 			if (!strcmp("-v", arg)) {
 				verbose = 1;
 				continue;
 			}
 			usage(fetch_pack_usage);
 		}
-		dest = arg;
-		heads = argv + i + 1;
-		nr_heads = argc - i - 1;
-		break;
+		if (!dest) {
+			dest = arg;
+			continue;
+		}
+		heads_repo[nr_heads] = nr_repo ? repo[nr_repo - 1] : NULL;
+		heads[nr_heads++] = arg;
 	}
 	if (!dest)
 		usage(fetch_pack_usage);
@@ -516,7 +536,7 @@ int main(int argc, char **argv)
 	pid = git_connect(fd, dest, exec);
 	if (pid < 0)
 		return 1;
-	ret = fetch_pack(fd, nr_heads, heads);
+	ret = fetch_pack(fd, nr_repo, repo, nr_heads, heads, heads_repo);
 	close(fd[0]);
 	close(fd[1]);
 	finish_connect(pid);
diff --git a/path.c b/path.c
index db8905f..3021164 100644
--- a/path.c
+++ b/path.c
@@ -243,6 +243,11 @@ char *enter_repo(char *path, int strict)
 	return NULL;
 }
 
+int security_repo_check(int export_all_trees)
+{
+	return (export_all_trees || access("git-daemon-export-ok", F_OK));
+}
+
 int adjust_shared_perm(const char *path)
 {
 	struct stat st;
diff --git a/peek-remote.c b/peek-remote.c
index 2b30980..7d8ae3c 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -9,9 +9,9 @@ static const char *exec = "git-upload-pa
 
 static int peek_remote(int fd[2], unsigned flags)
 {
-	struct ref *ref;
+	struct ref *ref = NULL;
 
-	get_remote_heads(fd[0], &ref, 0, NULL, flags);
+	get_remote_heads(fd[0], &ref, 0, NULL, NULL, flags);
 	packet_flush(fd[1]);
 
 	while (ref) {
diff --git a/send-pack.c b/send-pack.c
index 10bc8bc..24c47c9 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -232,14 +232,14 @@ static int receive_status(int in)
 
 static int send_pack(int in, int out, int nr_refspec, char **refspec)
 {
-	struct ref *ref;
+	struct ref *ref = NULL;
 	int new_refs;
 	int ret = 0;
 	int ask_for_status_report = 0;
 	int expect_status_report = 0;
 
 	/* No funny business with the matcher */
-	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
+	remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, NULL, REF_NORMAL);
 	get_local_heads();
 
 	/* Does the other end support the reporting? */
diff --git a/sha1_file.c b/sha1_file.c
index 8f279d8..1ca39e1 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -229,7 +229,7 @@ static void read_info_alternates(const c
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
+int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self)
 {
 	struct stat st;
 	const char *objdir = get_object_directory();
@@ -279,7 +279,7 @@ static int link_alt_odb_entry(const char
 			return -1;
 		}
 	}
-	if (!memcmp(ent->base, objdir, pfxlen)) {
+	if (!allow_self && !memcmp(ent->base, objdir, pfxlen)) {
 		free(ent);
 		return -1;
 	}
@@ -325,7 +325,7 @@ static void link_alt_odb_entries(const c
 						relative_base, last);
 			} else {
 				link_alt_odb_entry(last, cp - last,
-						relative_base, depth);
+						relative_base, depth, 0);
 			}
 		}
 		while (cp < ep && *cp == sep)
diff --git a/upload-pack.c b/upload-pack.c
index bbd6bd6..3440978 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -9,7 +9,7 @@ #include "object.h"
 #include "commit.h"
 #include "exec_cmd.h"
 
-static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
+static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] [--check-export] <dir>";
 
 #define THEY_HAVE (1U << 0)
 #define OUR_REF (1U << 1)
@@ -20,6 +20,8 @@ static struct object_array have_obj;
 static struct object_array want_obj;
 static unsigned int timeout = 0;
 static int use_sideband = 0;
+static int check_export = 0;
+static int strict = 0;
 
 static void reset_timeout(void)
 {
@@ -392,7 +394,7 @@ static int get_common_commits(void)
 	}
 }
 
-static void receive_needs(void)
+static char *receive_needs(void)
 {
 	static char line[1000];
 	int len;
@@ -403,8 +405,10 @@ static void receive_needs(void)
 		len = packet_read_line(0, line, sizeof(line));
 		reset_timeout();
 		if (!len)
-			return;
+			return NULL;
 
+		if (!strncmp("switch-repo ", line, 12))
+			return line+12;
 		if (strncmp("want ", line, 5) ||
 		    get_sha1_hex(line+5, sha1_buf))
 			die("git-upload-pack: protocol error, "
@@ -436,7 +440,7 @@ static void receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
-	static const char *capabilities = "multi_ack thin-pack side-band";
+	static const char *capabilities = "multi_ack thin-pack side-band switch-repo";
 	struct object *o = parse_object(sha1);
 
 	if (!o)
@@ -461,11 +465,52 @@ static int send_ref(const char *refname,
 
 static int upload_pack(void)
 {
-	reset_timeout();
-	head_ref(send_ref);
-	for_each_ref(send_ref);
-	packet_flush(1);
-	receive_needs();
+	int multirepo = 0;
+
+	while (1) {
+		char *repo;
+		char cwd[PATH_MAX];
+
+		reset_timeout();
+		head_ref(send_ref);
+		for_each_ref(send_ref);
+		packet_flush(1);
+		repo = receive_needs();
+		if (!repo)
+			break;
+		multirepo++;
+
+		fprintf(stderr, "git-upload-pack: switching to repo %s", repo);
+
+		/* So that we still find objects of the original repository... */
+		getcwd(cwd, PATH_MAX);
+		if (strlen(cwd) < PATH_MAX - 8)
+			strcat(cwd, "/objects");
+		link_alt_odb_entry(cwd, strlen(cwd), NULL, 0, 1);
+
+		if (!enter_repo(repo, strict) || !security_repo_check(!check_export))
+			die("git-upload-pack: security violation");
+	}
+
+	if (multirepo) {
+#define ALTENV_SIZE 65536
+		/* Propagate all the repositories to the children */
+		char altenv[ALTENV_SIZE], *p = altenv;
+		struct alternate_object_database *alt;
+		strcpy(p, ALTERNATE_DB_ENVIRONMENT "=");
+		p += sizeof(ALTERNATE_DB_ENVIRONMENT);
+		for (alt = alt_odb_list; alt; alt = alt->next) {
+			strncpy(p, alt->base, alt->name - alt->base);
+			p += alt->name - alt->base;
+			if (p - altenv < ALTENV_SIZE)
+				*p++ = ':';
+			if (p - altenv >= ALTENV_SIZE)
+				die("fetching too many repositories");
+		}
+		p[-1] = '\0';
+		putenv(altenv);
+	}
+
 	if (!want_obj.nr)
 		return 0;
 	get_common_commits();
@@ -477,7 +522,6 @@ int main(int argc, char **argv)
 {
 	char *dir;
 	int i;
-	int strict = 0;
 
 	for (i = 1; i < argc; i++) {
 		char *arg = argv[i];
@@ -492,6 +536,10 @@ int main(int argc, char **argv)
 			timeout = atoi(arg+10);
 			continue;
 		}
+		if (!strcmp(arg, "--check-export")) {
+			check_export = 1;
+			continue;
+		}
 		if (!strcmp(arg, "--")) {
 			i++;
 			break;

^ permalink raw reply related

* Re: Licensing and the library version of git
From: Shawn Pearce @ 2006-07-28  5:04 UTC (permalink / raw)
  To: Wolfgang Denk; +Cc: Jon Smirl, git
In-Reply-To: <20060727195614.7EDAE353B04@atlas.denx.de>

Wolfgang Denk <wd@denx.de> wrote:
> In message <9e4733910607270554p5622ee20ida8c264cf3122500@mail.gmail.com> you wrote:
> >
> > I see that someone is already writing a pure Java version which will
> > work around the GPL problem assuming the Java version is released
> > under a compatible license.
> 
> ... and assuming it is a clean-room  implementation  which  does  not
> borrow from the GPL code.

Heh.  This is actually possibly a problem.

I'm the person developing the Java implementation.

I've seen some of the core GIT code.  The reflog implementation is my
most notable contribution, but I've seen other things in there too.

Most of the Java code is quite different from the C code; the
largest common component is the pack delta decompressor.  I ran it
past Nico as he wrote the C version. He didn't seem to think that
the Java version was derived from the C version.

The issue there really was that the pack file format wasn't
completely documented external from the code (I actually found a
bug in the docs and submitted a patch to correct it) and the delta
format is definately not documented so I had to dig around in the
C code to figure it out.  On the other hand the commit format,
tree format and the loose object header were all clearly self
describing so I didn't need to go digging through the source to
figure out how to parse (or generate) them.

So yes, the Java implementation is derived from the C
(GPL'd!) implementation, but also no, its not...

I think its going to really just come down to a list consensus.
If Linus, Junio, Nico, et.al. think that my Java version is too
derived from the C GPL'd implementation to be released under any
license other than the GPL then I'll probably just abandon the code
line entirely, as the GPL is incompatible with the Sun JRE runtime
lirbary.  On the other hand its probably going to be released under
the IBM Common Public License or the Apache License.

-- 
Shawn.

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Junio C Hamano @ 2006-07-28  4:48 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060728025619.GK13776@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

> Dear diary, on Fri, Jul 28, 2006 at 04:41:04AM CEST, I got a letter
> where Junio C Hamano <junkio@cox.net> said that...
>> Petr Baudis <pasky@suse.cz> writes:
>> >   (iv) I need git-apply to add/remove to/from index new/gone files,
>> > while at the same time...
>> >
>> >   (v) I want to allow applying of patches to working copy that is not
>> > completely clean, even on top of modified files
>> 
>> You probably should be able to talk me into doing these, but
>> doesn't it already do (iv) and (v)?
>
> Well, at once? I can do (iv) by adding --index but that contradicts (v).
> But maybe I'm missing something.

What should the semantics of such operation be?  Apply to index
on paths that are clean while leave the index entries untouched
for paths that are dirty?  What should happen on renamed paths
that are dirty?

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Petr Baudis @ 2006-07-28  2:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vvepimoxr.fsf@assigned-by-dhcp.cox.net>

Dear diary, on Fri, Jul 28, 2006 at 04:41:04AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@suse.cz> writes:
> >   (iv) I need git-apply to add/remove to/from index new/gone files,
> > while at the same time...
> >
> >   (v) I want to allow applying of patches to working copy that is not
> > completely clean, even on top of modified files
> 
> You probably should be able to talk me into doing these, but
> doesn't it already do (iv) and (v)?

Well, at once? I can do (iv) by adding --index but that contradicts (v).
But maybe I'm missing something.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Junio C Hamano @ 2006-07-28  2:41 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20060728013038.GH13776@pasky.or.cz>

Petr Baudis <pasky@suse.cz> writes:

>   (i) No git-apply -R - well, it seems to me that I revert patches all
> the time, don't you?
>
>   (ii) I'd like git-apply to be as verbose as patch is, that is list
> the files it touches as it goes
>
>   (iii) There's no reject handling besides "panic" right now - it should
> be able to create .rej files so that the user can fix things up
>
>   (iv) I need git-apply to add/remove to/from index new/gone files,
> while at the same time...
>
>   (v) I want to allow applying of patches to working copy that is not
> completely clean, even on top of modified files

You probably should be able to talk me into doing these, but
doesn't it already do (iv) and (v)?

^ permalink raw reply

* Re: [PATCH 3/4] Teach git-local-fetch the --stdin switch
From: Petr Baudis @ 2006-07-28  1:57 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060727215619.24240.39537.stgit@machine>

Dear diary, on Thu, Jul 27, 2006 at 11:56:19PM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> +--stdin::
> +	Instead of a commit id on the commandline (which is not expected in this
> +	case), 'git-local-fetch' excepts lines on stdin in the format
                                 ^^^^^^^

Oops, should read "expects" in both patches - thanks, alp!

I blame all those tiny bugs lured into the room by light and then, well,
bugging you. (Real-world bugs, but they can transform.)

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: Moving a directory into another fails
From: Petr Baudis @ 2006-07-28  1:43 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Nicolas Vilz, git
In-Reply-To: <9e4733910607261603m6772602cr333d8c58f555edaa@mail.gmail.com>

Dear diary, on Thu, Jul 27, 2006 at 01:03:30AM CEST, I got a letter
where Jon Smirl <jonsmirl@gmail.com> said that...
> This is a simpler sequence
> 
> cg clone git foo
> cg clone git foo1
> cd foo
> mkdir zzz
> git mv gitweb zzz
> cg diff >patch
> cg ../foo1
> cg patch <../foo/patch

Even simpler one:

	mkdir zzz
	cg-mv gitweb zzz
	cg-diff | cg-patch -R

(which would even undo the mess supposing that it worked properly)

> [jonsmirl@jonsmirl foo1]$ cg patch <../foo/patch
> mv: cannot move `gitweb/README' to `zzz/gitweb/README': No such file
> or directory

Oops. Thanks, fixed with this:

diff --git a/cg-patch b/cg-patch
index cc82f1f..923df0e 100755
--- a/cg-patch
+++ b/cg-patch
@@ -145,6 +145,8 @@ redzone_border()
 			echo "$file1: rename destination $file2 already exists, NOT RENAMING" >&2
 			return
 		fi
+		# FIXME: Remove stale empty directories related to $mvfrom
+		case $mvto in */*) mkdir -p "${mvto%/*}";; esac
 		mv "$mvfrom" "$mvto"
 	fi
 	if [ "$op" = "delete" -o "$op" = "rename" ]; then

> mv: cannot stat `"gitweb/test/M\\303\\244rchen"': No such file or directory

Junio, how am I supposed to unmangle this *censored* stuff?

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply related

* Re: [PATCH 1/2] t7001: add test for git-mv dir1 dir2/
From: Petr Baudis @ 2006-07-28  1:30 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: Johannes Schindelin, Jon Smirl, git, junkio
In-Reply-To: <200607262039.25155.Josef.Weidendorfer@gmx.de>

Dear diary, on Wed, Jul 26, 2006 at 08:39:24PM CEST, I got a letter
where Josef Weidendorfer <Josef.Weidendorfer@gmx.de> said that...
> On Wednesday 26 July 2006 19:41, Johannes Schindelin wrote:
> > 
> > If dir2 already exists, git-mv should move dir1 _into_dir2/.
> > Noticed by Jon Smirl.
> 
> Thanks for adding this test.
> BTW, the original PERL script passes it quite fine.
> 
> I just looked at Jon's problem. Doesn't seem to be related to
> git-mv or git at all, but more a cogito problem.
> I have some cogito-0.18pre installed, and cg-patch is patching
> the stuff all itself, not using git for this. Pasky?

Unfortunately, git-apply is still quite unusable for Cogito. It can do
fuzzy merging now, but here's some random list of more issues I still
have with it (I'm leaving for some two weeks or so of holiday soon so I
won't have to fix them soon personally; it'd be nice if someone did,
though ;) :

  (i) No git-apply -R - well, it seems to me that I revert patches all
the time, don't you?

  (ii) I'd like git-apply to be as verbose as patch is, that is list
the files it touches as it goes

  (iii) There's no reject handling besides "panic" right now - it should
be able to create .rej files so that the user can fix things up

  (iv) I need git-apply to add/remove to/from index new/gone files,
while at the same time...

  (v) I want to allow applying of patches to working copy that is not
completely clean, even on top of modified files

But yes, I'd like cg-patch to move to use git-apply. It's currently
_way_ too scary.

-- 
				Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
Snow falling on Perl. White noise covering line noise.
Hides all the bugs too. -- J. Putnam

^ permalink raw reply

* Re: Licensing and the library version of git
From: Jon Smirl @ 2006-07-28  0:43 UTC (permalink / raw)
  To: Anand Kumria; +Cc: git
In-Reply-To: <eablgn$c6a$1@sea.gmane.org>

On 7/27/06, Anand Kumria <wildfire@progsoc.org> wrote:
> On Thu, 27 Jul 2006 12:11:00 -0400, Jon Smirl wrote:
>
> > On 7/27/06, Petr Baudis <pasky@suse.cz> wrote:
> >> > You may like trying to force GPL onto the app but many apps are
> >> > stuck with the license they have and can't be changed since there is
> >> > no way to contact the original developers.
> >>
> >> At this point, git-shortlog lists exactly 200 people (at least entries
> >> like Unknown or No name are all linux@horizon.com ;-).
> >
> > Inability to integrate with Microsoft Visual Studio is going to have a
> > lot of impact on the cross platform use of git.
>
> Could you stop with the histrionics please?

It is usually wise not to make comments like this, they don't help in
building the community.

> > Is a conscious
> > decision being made to stop this integration or is this just unplanned
> > side effect of the original license? If this is an unplanned side
> > effect, the quicker we move, the easier it is to fix.
>
> So, using CVSNT (a GPL'd SCCI provider) and git-cvsserver would be a way
> to continue.  I'm assuming that the primary functionality they want via
> their IDE is checkout/diff/commit/log.

Now, that's a great strategy. Tell the large project you are
interested in switching off from CVS to git that they need to run a
CVS emulation gateway forever. I don't think a switch has much of a
chance of happening.


> Quite a lot of Windows developers have no problems using multiple tools
> for things, I'd assume they would also be able to use any existent port
> of git (to Windows) to do the esoteric things like branching/bisect/etc.
>
> Anand
>
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox