Git development
 help / color / mirror / Atom feed
* Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script
From: Ryan Anderson @ 2005-07-31 23:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vbr4jmhqe.fsf@assigned-by-dhcp.cox.net>

On Sun, Jul 31, 2005 at 02:45:29AM -0700, Junio C Hamano wrote:
> Ryan Anderson <ryan@michonline.com> writes:
> 
> > 	All emails are sent as a reply to the previous email, making it easy to
> > 	skip a collection of emails that are uninteresting.
> 
> I understand why _some_ people consider this preferable, but
> wonder if this should have a knob to be tweaked.

Hmm, fair enough.

I'll send a few more patches in a minute that deal with the things in
this email but for now:

	--chain-reply-to (or --no-chain-reply-to)

	Will toggle between these two behaviors.  (This will not be
	prompted for by the ReadLine interface, btw.)

> > +# horrible hack of a script to send off a large number of email messages, one after
> > +# each other, all chained together.  This is useful for large numbers of patches.
> > +#
> > +# Use at your own risk!!!!
> 
> Well, if it is "Use at your own risk" maybe it should stay
> outside the official distribution for a while until it gets
> safer ;-).

Heh.  I missed some comments that I meant to clean up that were in
Greg's original script.  One of the patches will clean up the comments.

> > +	my @fields = split /\s+/, $data;
> > +	my $ident = join(" ", @fields[0...(@fields-3)]);
> 
> Wouldn't "s/>.*/>/" be easier than splitting and joining?

Most of GIT_COMMITTER_IDENT (and GIT_AUTHOR_IDENT) is use controllable,
except for the "date" section of it.  I know we delimit that with
spaces, so the above is guaranteed to work unless we change the format
that git-var returns.

If I hope that nobody has done something like:
	GIT_AUTHOR="Ryan <> Anderson"
	GIT_AUTHOR_EMAIL="ryan@michonline.com"

I get more confusing results.  (I suddenly have to think about what that
regular expression does in this case - and I'm pretty sure that the one
you gave would do bad things.)

Probably the best fix for this would be to take libgit.a, make a shared
library out of it, and then interface the Perl scripts directly with it
via a .xs module.  I was thinking that I'd rather have direct access to
the git_ident* functions than calling out to git-var, anyway.  Consider
that a plan for a revamp after the core seems to have settled down a bit
more.

> > +if (!defined $from) {
> > +	$from = $author || $committer;
> > +	1 while (!defined ($_ = $term->readline("Who should the emails appear to be from? ", 
> > +				$from)));
> 
> Judging from your past patches, you seem to really like
> statement modifiers[*].  While they _are_ valid Perl constructs,
> it is extremely hard to read when used outside very simple
> idiomatic use.  Please consider rewriting the above and the like
> using compound statements[*] (I am using these terms according
> to the definition in perlsyn.pod).  Remember, there are people
> Perl is not their native language, but are intelligent enough to
> be of great help fixing problems in programs you write in Perl.
> To most of them, compound statements are more familiar, so try
> to be gentle to them.

I copied this from another program of mine, and I'm *sure* I copied the
style directly from a ReadLine example.  But, I can't find a current
example that says this is good, so, I'll fix this, too.  It is rather
ugly.  (The other uses of this style are... less bad, IMO, than this
abuse here.)


> 
> > +		opendir(DH,$f)
> > +			or die "Failed to opendir $f: $!";
> > +		push @files, map { +$f . "/" . $_ } grep !/^\.{1,2}$/,
> > +			sort readdir(DH);
> 
> Maybe skip potential subdirs while you are at it, something like this?
> 
>     push @files, sort grep { -f $_ } map { "$f/$_" } readdir(DH)

Good point.  One one hand I'd say, "Let it break for people who do
strange things like that", but I'll make it safer anyway.

(Someone is going to reply and ask for it to recurse into subdirectories
now.  Maybe Andrew Morton would find that useful with his rather massive
collection of patches in -mm kernels.  But that's a feature for next
week.)

> > +	my $pseudo_rand = int (rand(4200));
> > +	$message_id = "<$date$pseudo_rand\@foobar.com>";
> > +	print "new message id = $message_id\n";
> 
> I doubt this hardcoded foobar.com is a good idea.  Did you mean
> to print it, by the way?

I'll convert this to something that is based off the $from address
instead.  It's probably better that way, anyway.

> > +	$to{lc(Email::Valid->address($_))}++ for (@to);
> > +	my $to = join(",", keys %to);
> 
> Is this the culprit that produced this mechanical-looking line?
> 
>     To: junkio@cox.net,git@vger.kernel.org

No, that line was exactly what I put into the readline entry.

> Interestingly enough, you do not seem to do it for the From:
> line.
> 
>     From: Ryan Anderson <ryan@michonline.com>
> 
> Also you seem to be losing the ordering in @to and @cc by the
> use of uniquefying "keys %to" and "keys %cc".  I can not offhand
> tell if it matters, but you probably would care, at least for
> the primary recipients listed in @to array.

Well, it was kind of annoying to see the same email address appear 2-3
times in the email, because of the way I pull in all the relevant emails
from various places.  So I really needed a way to cull the duplicates.
I don't believe ordering is really significant in To: or Cc: lines, for
really anyone.  I could do soemthing like this, instead, I suppose:

	my @clean_to = ();
	my %dupe_check_to = ();
	foreach my $to_entry (@to) {
		if (!$dupe_check_to{Email::Valid->address($to_entry)}++) {
			push @clean_to, $to_entry;
		}
	}

	my $to = join(", ", @clean_to);

I just like the first one a little better (though, I can't really pin
down why).

> > +	$mail{smtp} = 'localhost';
> 
> I suspect this probably need to be configurable.  I may be a
> minority, but my outgoing messages are directly handed to my
> local ISP smtp server from my MUA, and the smtp server running
> on the locahost does not talk to the outside world.

Oddly, I think this is even the wrong setting after having read over the
Mail::Sendmail docs to figure out how to change the MIME settings.

> Since there are always 47 different ways to do the same thing in
> Perl, Perl style varies a lot more than Shell style which in
> turn varies a lot more than C.  You should be prepared to be
> nitpicked a lot when you post Perl ;-).  And I was in nitpicking
> mood tonight.

It's Perl.  There does seem to be a lot of nitpicking when people write
Perl.

(If you write it in idiomatic Perl, the non-Perl users hate you.  If you
write it like C, the Perl users complain that you write it like C.
*sigh*)

> Thanks for the patch.  Overall, very good intent.  Slightly
> troublesome details.

Thanks.

I'll have a series of patches out in a few minutes that will update what
I originally sent to fix your issues here.

-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script
From: Ryan Anderson @ 2005-07-31 23:54 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: junkio, git
In-Reply-To: <Pine.LNX.4.58.0507311223240.16181@wgmdd8.biozentrum.uni-wuerzburg.de>

On Sun, Jul 31, 2005 at 12:25:13PM +0200, Johannes Schindelin wrote:
> Hi,
> 
> wouldn't it be a good idea to make $from and $to required parameters? At
> least you could infer a sensible default of $from from GIT_* environment
> variables, no? I am not quite comfortable with a hard coded sender in a
> script possibly deployed into a multi-user environment.

The sender isn't hardcoded.

If it isn't sent on the command line, the return value from git-var -l
is used to set a default, which is then confirmed by the ReadLine
interface.

Some of the comments were leftover from Greg's original, before I
remembered to remove them - it should be better now if you take another
look.  (See my, soon to be sent, set of additional changes.)

-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* Re: [PATCH] Added hook in git-receive-pack
From: Junio C Hamano @ 2005-08-01  0:11 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Josef Weidendorfer, Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0507311627280.14342@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> In the "central repo model" you have another issue - you have potentially
> parallell pushes to different branches with no locking what-so-ever (and
> that's definitely _supposed_ to work), and I have this suspicion that the 
> "update for dumb servers" code isn't really safe in that setting anyway. I 
> haven't checked.

You are absolutely right.  It should grab some sort of lock
while it does its thing (would fcntl(F_GETLK) be acceptable to
networked filesystem folks?).

I have one question regarding the hooks.  We seem to prefer
avoiding system and roll our own.  Is there a particular reason,
other than bypassing the need to quote parameters for shell?

^ permalink raw reply

* Re: [PATCH] Added hook in git-receive-pack
From: Linus Torvalds @ 2005-08-01  0:25 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Josef Weidendorfer, Git Mailing List
In-Reply-To: <7vhdeabjo7.fsf@assigned-by-dhcp.cox.net>



On Sun, 31 Jul 2005, Junio C Hamano wrote:
> 
> You are absolutely right.  It should grab some sort of lock
> while it does its thing (would fcntl(F_GETLK) be acceptable to
> networked filesystem folks?).

There is no lock that works reliably except for the "create a directory 
and rename it onto another directory"

Please do it in the hook layer.

> I have one question regarding the hooks.  We seem to prefer
> avoiding system and roll our own.  Is there a particular reason,
> other than bypassing the need to quote parameters for shell?

Hmm.. I suspect it's partly just because there is existing code that does
the fork()/exec() thing because it needs to do IO, and system() doesn't
close the right pipes after fork etc.

"system()" really is very inflexible. It basically never works if you have 
any shared file descriptors.

		Linus

^ permalink raw reply

* Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script
From: Junio C Hamano @ 2005-08-01  0:40 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: git
In-Reply-To: <20050731235242.GH32263@mythryan2.michonline.com>

Ryan Anderson <ryan@michonline.com> writes:

> If I hope that nobody has done something like:
> 	GIT_AUTHOR="Ryan <> Anderson"
> 	GIT_AUTHOR_EMAIL="ryan@michonline.com"
>
> I get more confusing results.

The function git_author_info() would remove <> from the above
GIT_AUTHOR_* environment values by calling ident.c:copy(), so I
think you would get more-or-less what you _should_ expect without
getting confused.

    $ GIT_AUTHOR_NAME="Ryan <> Anderson" \
      GIT_AUTHOR_EMAIL="ryan@michonline.com" git-var -l
    GIT_COMMITTER_IDENT=Junio C Hamano <junkio@cox.net> 1122855849 -0700
    GIT_AUTHOR_IDENT=Ryan  Anderson <ryan@michonline.com> 1122855849 -0700

>> Is this the culprit that produced this mechanical-looking line?
>> 
>>     To: junkio@cox.net,git@vger.kernel.org
>
> No, that line was exactly what I put into the readline entry.

I was mostly talking about Email::Valid seeming to be stripping
out the display-name[*] part and keeping only addr-spec[*] part,
like this:

    $ cat j.perl
    #!/usr/bin/perl
    use Email::Valid;
    for ('Junio C Hamano <junkio@cox.net>',
         'Ryan Anderson <ryan@michonline.com>') {
        print $_, " => ", lc(Email::Valid->address($_)), "\n";
    }
    $ perl j.perl
    Junio C Hamano <junkio@cox.net> => junkio@cox.net
    Ryan Anderson <ryan@michonline.com> => ryan@michonline.com

Also, I wonder if running lc() to downcase the local-part[*] is
safe/allowed/correct; domain[*] part is case insensitive and
should be OK to downcase, though.

> ..., because of the way I pull in all the relevant emails
> from various places.  So I really needed a way to cull the duplicates.
> ...  I could do soemthing like this, instead, I suppose:

I understand your needs, and you can make it a "sub
filter_dups", which I think would make things a lot more
pleasant to read.


[Footnote]

Terms marked [*] are from RFC2822, section 3.4.

^ permalink raw reply

* [PATCH 1/2] Functions for managing the set of packs the library is using (whitespace fixed)
From: barkalow @ 2005-08-01  0:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.62.0507311600040.23721@iabervon.org>

This adds support for reading an uninstalled index, and installing a
pack file that was added while the program was running, as well as
functions for determining where to put the file.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---

 cache.h     |   13 ++++++
 sha1_file.c |  123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 135 insertions(+), 1 deletions(-)

20fcc8f66a6780cf9bbd2fc2ba3b918c33696a67
diff --git a/cache.h b/cache.h
--- a/cache.h
+++ b/cache.h
@@ -172,6 +172,8 @@ extern void rollback_index_file(struct c
 extern char *mkpath(const char *fmt, ...);
 extern char *git_path(const char *fmt, ...);
 extern char *sha1_file_name(const unsigned char *sha1);
+extern char *sha1_pack_name(const unsigned char *sha1);
+extern char *sha1_pack_index_name(const unsigned char *sha1);
 
 int safe_create_leading_directories(char *path);
 
@@ -200,6 +202,9 @@ extern int write_sha1_to_fd(int fd, cons
 extern int has_sha1_pack(const unsigned char *sha1);
 extern int has_sha1_file(const unsigned char *sha1);
 
+extern int has_pack_file(const unsigned char *sha1);
+extern int has_pack_index(const unsigned char *sha1);
+
 /* Convert to/from hex/sha1 representation */
 extern int get_sha1(const char *str, unsigned char *sha1);
 extern int get_sha1_hex(const char *hex, unsigned char *sha1);
@@ -276,6 +281,7 @@ extern struct packed_git {
 	void *pack_base;
 	unsigned int pack_last_used;
 	unsigned int pack_use_cnt;
+	unsigned char sha1[20];
 	char pack_name[0]; /* something like ".git/objects/pack/xxxxx.pack" */
 } *packed_git;
 
@@ -298,7 +304,14 @@ extern int path_match(const char *path, 
 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);
 
+extern struct packed_git *parse_pack_index(unsigned char *sha1);
+
 extern void prepare_packed_git(void);
+extern void install_packed_git(struct packed_git *pack);
+
+extern struct packed_git *find_sha1_pack(const unsigned char *sha1, 
+					 struct packed_git *packs);
+
 extern int use_packed_git(struct packed_git *);
 extern void unuse_packed_git(struct packed_git *);
 extern struct packed_git *add_packed_git(char *, int);
diff --git a/sha1_file.c b/sha1_file.c
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -200,6 +200,56 @@ char *sha1_file_name(const unsigned char
 	return base;
 }
 
+char *sha1_pack_name(const unsigned char *sha1)
+{
+	static const char hex[] = "0123456789abcdef";
+	static char *name, *base, *buf;
+	int i;
+
+	if (!base) {
+		const char *sha1_file_directory = get_object_directory();
+		int len = strlen(sha1_file_directory);
+		base = xmalloc(len + 60);
+		sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.pack", sha1_file_directory);
+		name = base + len + 11;
+	}
+
+	buf = name;
+
+	for (i = 0; i < 20; i++) {
+		unsigned int val = *sha1++;
+		*buf++ = hex[val >> 4];
+		*buf++ = hex[val & 0xf];
+	}
+	
+	return base;
+}
+
+char *sha1_pack_index_name(const unsigned char *sha1)
+{
+	static const char hex[] = "0123456789abcdef";
+	static char *name, *base, *buf;
+	int i;
+
+	if (!base) {
+		const char *sha1_file_directory = get_object_directory();
+		int len = strlen(sha1_file_directory);
+		base = xmalloc(len + 60);
+		sprintf(base, "%s/pack/pack-1234567890123456789012345678901234567890.idx", sha1_file_directory);
+		name = base + len + 11;
+	}
+
+	buf = name;
+
+	for (i = 0; i < 20; i++) {
+		unsigned int val = *sha1++;
+		*buf++ = hex[val >> 4];
+		*buf++ = hex[val & 0xf];
+	}
+	
+	return base;
+}
+
 struct alternate_object_database *alt_odb;
 
 /*
@@ -360,6 +410,14 @@ void unuse_packed_git(struct packed_git 
 
 int use_packed_git(struct packed_git *p)
 {
+	if (!p->pack_size) {
+		struct stat st;
+		// We created the struct before we had the pack
+		stat(p->pack_name, &st);
+		if (!S_ISREG(st.st_mode))
+			die("packfile %s not a regular file", p->pack_name);
+		p->pack_size = st.st_size;
+	}
 	if (!p->pack_base) {
 		int fd;
 		struct stat st;
@@ -387,8 +445,10 @@ int use_packed_git(struct packed_git *p)
 		 * this is cheap.
 		 */
 		if (memcmp((char*)(p->index_base) + p->index_size - 40,
-			   p->pack_base + p->pack_size - 20, 20))
+			   p->pack_base + p->pack_size - 20, 20)) {
+			      
 			die("packfile %s does not match index.", p->pack_name);
+		}
 	}
 	p->pack_last_used = pack_used_ctr++;
 	p->pack_use_cnt++;
@@ -426,6 +486,37 @@ struct packed_git *add_packed_git(char *
 	return p;
 }
 
+struct packed_git *parse_pack_index(unsigned char *sha1)
+{
+	struct packed_git *p;
+	unsigned long idx_size;
+	void *idx_map;
+	char *path = sha1_pack_index_name(sha1);
+
+	if (check_packed_git_idx(path, &idx_size, &idx_map))
+		return NULL;
+
+	path = sha1_pack_name(sha1);
+
+	p = xmalloc(sizeof(*p) + strlen(path) + 2);
+	strcpy(p->pack_name, path);
+	p->index_size = idx_size;
+	p->pack_size = 0;
+	p->index_base = idx_map;
+	p->next = NULL;
+	p->pack_base = NULL;
+	p->pack_last_used = 0;
+	p->pack_use_cnt = 0;
+	memcpy(p->sha1, sha1, 20);
+	return p;
+}
+
+void install_packed_git(struct packed_git *pack)
+{
+	pack->next = packed_git;
+	packed_git = pack;
+}
+
 static void prepare_packed_git_one(char *objdir)
 {
 	char path[PATH_MAX];
@@ -989,6 +1080,20 @@ static int find_pack_entry(const unsigne
 	return 0;
 }
 
+struct packed_git *find_sha1_pack(const unsigned char *sha1, 
+				  struct packed_git *packs)
+{
+	struct packed_git *p;
+	struct pack_entry e;
+
+	for (p = packs; p; p = p->next) {
+		if (find_pack_entry_one(sha1, &e, p))
+			return p;
+	}
+	return NULL;
+	
+}
+
 int sha1_object_info(const unsigned char *sha1, char *type, unsigned long *sizep)
 {
 	int status;
@@ -1335,6 +1440,22 @@ int write_sha1_from_fd(const unsigned ch
 	return 0;
 }
 
+int has_pack_index(const unsigned char *sha1)
+{
+	struct stat st;
+	if (stat(sha1_pack_index_name(sha1), &st))
+		return 0;
+	return 1;
+}
+
+int has_pack_file(const unsigned char *sha1)
+{
+	struct stat st;
+	if (stat(sha1_pack_name(sha1), &st))
+		return 0;
+	return 1;
+}
+
 int has_sha1_pack(const unsigned char *sha1)
 {
 	struct pack_entry e;

^ permalink raw reply

* [PATCH 2/2] Support downloading packs by HTTP (whitespace fixed)
From: barkalow @ 2005-08-01  0:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <Pine.LNX.4.62.0507311600040.23721@iabervon.org>

This adds support to http-pull for finding the list of pack files
available on the server, downloading the index files for those pack
files, and downloading pack files when they contain needed objects not
available individually. It retains the index files even if the pack
files were not needed, but downloads the list of pack files once per
run if an object is not found separately.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---

 http-pull.c |  181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 175 insertions(+), 6 deletions(-)

dff0b76c4a2efbb8407778a1da6dc2ea2ca1458f
diff --git a/http-pull.c b/http-pull.c
--- a/http-pull.c
+++ b/http-pull.c
@@ -33,7 +33,8 @@ struct buffer
 };
 
 static size_t fwrite_buffer(void *ptr, size_t eltsize, size_t nmemb,
-                            struct buffer *buffer) {
+                            struct buffer *buffer)
+{
         size_t size = eltsize * nmemb;
         if (size > buffer->size - buffer->posn)
                 size = buffer->size - buffer->posn;
@@ -42,8 +43,9 @@ static size_t fwrite_buffer(void *ptr, s
         return size;
 }
 
-static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, 
-			       void *data) {
+static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb,
+			       void *data)
+{
 	unsigned char expn[4096];
 	size_t size = eltsize * nmemb;
 	int posn = 0;
@@ -65,6 +67,168 @@ static size_t fwrite_sha1_file(void *ptr
 	return size;
 }
 
+static int got_indices = 0;
+
+static struct packed_git *packs = NULL;
+
+static int fetch_index(unsigned char *sha1)
+{
+	char *filename;
+	char *url;
+
+	FILE *indexfile;
+
+	if (has_pack_index(sha1))
+		return 0;
+
+	if (get_verbosely)
+		fprintf(stderr, "Getting index for pack %s\n",
+			sha1_to_hex(sha1));
+	
+	url = xmalloc(strlen(base) + 64);
+	sprintf(url, "%s/objects/pack/pack-%s.idx",
+		base, sha1_to_hex(sha1));
+	
+	filename = sha1_pack_index_name(sha1);
+	indexfile = fopen(filename, "w");
+	if (!indexfile)
+		return error("Unable to open local file %s for pack index",
+			     filename);
+
+	curl_easy_setopt(curl, CURLOPT_FILE, indexfile);
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
+	curl_easy_setopt(curl, CURLOPT_URL, url);
+	
+	if (curl_easy_perform(curl)) {
+		fclose(indexfile);
+		return error("Unable to get pack index %s", url);
+	}
+
+	fclose(indexfile);
+	return 0;
+}
+
+static int setup_index(unsigned char *sha1)
+{
+	struct packed_git *new_pack;
+	if (has_pack_file(sha1))
+		return 0; // don't list this as something we can get
+
+	if (fetch_index(sha1))
+		return -1;
+
+	new_pack = parse_pack_index(sha1);
+	new_pack->next = packs;
+	packs = new_pack;
+	return 0;
+}
+
+static int fetch_indices(void)
+{
+	unsigned char sha1[20];
+	char *url;
+	struct buffer buffer;
+	char *data;
+	int i = 0;
+
+	if (got_indices)
+		return 0;
+
+	data = xmalloc(4096);
+	buffer.size = 4096;
+	buffer.posn = 0;
+	buffer.buffer = data;
+
+	if (get_verbosely)
+		fprintf(stderr, "Getting pack list\n");
+	
+	url = xmalloc(strlen(base) + 21);
+	sprintf(url, "%s/objects/info/packs", base);
+
+	curl_easy_setopt(curl, CURLOPT_FILE, &buffer);
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
+	curl_easy_setopt(curl, CURLOPT_URL, url);
+	
+	if (curl_easy_perform(curl)) {
+		return error("Unable to get pack index %s", url);
+	}
+
+	do {
+		switch (data[i]) {
+		case 'P':
+			i++;
+			if (i + 52 < buffer.posn &&
+			    !strncmp(data + i, " pack-", 6) &&
+			    !strncmp(data + i + 46, ".pack\n", 6)) {
+				get_sha1_hex(data + i + 6, sha1);
+				setup_index(sha1);
+				i += 51;
+				break;
+			}
+		default:
+			while (data[i] != '\n')
+				i++;
+		}
+		i++;
+	} while (i < buffer.posn);
+
+	got_indices = 1;
+	return 0;
+}
+
+static int fetch_pack(unsigned char *sha1)
+{
+	char *url;
+	struct packed_git *target;
+	struct packed_git **lst;
+	FILE *packfile;
+	char *filename;
+
+	if (fetch_indices())
+		return -1;
+	target = find_sha1_pack(sha1, packs);
+	if (!target)
+		return error("Couldn't get %s: not separate or in any pack",
+			     sha1_to_hex(sha1));
+
+	if (get_verbosely) {
+		fprintf(stderr, "Getting pack %s\n",
+			sha1_to_hex(target->sha1));
+		fprintf(stderr, " which contains %s\n",
+			sha1_to_hex(sha1));
+	}
+
+	url = xmalloc(strlen(base) + 65);
+	sprintf(url, "%s/objects/pack/pack-%s.pack",
+		base, sha1_to_hex(target->sha1));
+
+	filename = sha1_pack_name(target->sha1);
+	packfile = fopen(filename, "w");
+	if (!packfile)
+		return error("Unable to open local file %s for pack",
+			     filename);
+
+	curl_easy_setopt(curl, CURLOPT_FILE, packfile);
+	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
+	curl_easy_setopt(curl, CURLOPT_URL, url);
+	
+	if (curl_easy_perform(curl)) {
+		fclose(packfile);
+		return error("Unable to get pack file %s", url);
+	}
+
+	fclose(packfile);
+
+	lst = &packs;
+	while (*lst != target)
+		lst = &((*lst)->next);
+	*lst = (*lst)->next;
+
+	install_packed_git(target);
+
+	return 0;
+}
+
 int fetch(unsigned char *sha1)
 {
 	char *hex = sha1_to_hex(sha1);
@@ -76,7 +240,7 @@ int fetch(unsigned char *sha1)
 	local = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
 
 	if (local < 0)
-		return error("Couldn't open %s\n", filename);
+		return error("Couldn't open local object %s\n", filename);
 
 	memset(&stream, 0, sizeof(stream));
 
@@ -84,6 +248,7 @@ int fetch(unsigned char *sha1)
 
 	SHA1_Init(&c);
 
+	curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
 	curl_easy_setopt(curl, CURLOPT_FILE, NULL);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite_sha1_file);
 
@@ -99,8 +264,12 @@ int fetch(unsigned char *sha1)
 
 	curl_easy_setopt(curl, CURLOPT_URL, url);
 
-	if (curl_easy_perform(curl))
-		return error("Couldn't get %s for %s\n", url, hex);
+	if (curl_easy_perform(curl)) {
+		unlink(filename);
+		if (fetch_pack(sha1))
+			return error("Tried %s", url);
+		return 0;
+	}
 
 	close(local);
 	inflateEnd(&stream);

^ permalink raw reply

* Re: git diffs
From: Linus Torvalds @ 2005-08-01  1:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Git Mailing List
In-Reply-To: <20050731172256.73f91a20.akpm@osdl.org>



On Sun, 31 Jul 2005, Andrew Morton wrote:
> 
> So I finally decided to take a look at my git problems.  Discovered I
> couldn't fix them with zero git knowledge :(

Heh. We're here to please.

I'll cc the git list too, because there really _are_ a lot of people out 
there that know it fairly well, and may even have better suggestions than 
I do.

> What I want to do is to pull zillions of people's git trees into one repo
> and then run some magic command to give me unified diffs from everyone's
> trees which will apply to your latest.

Absolutely. 

Here's how to do it:

 - start off by fetching every single tree you want to have into its own 
   local branch. I think you basically do this already. If you're using 
   cogito, I think a simple "cg-pull" will do it for you.

   If you are using raw git, the easiest thing to do is to really just do

	result=$(git-fetch-pack "$repo" "$head") || exit

   which will fetch the named "head" from the named "repo", and stuff the 
   result in the "result" variable. You can then stuff that result 
   anywhere, so for example, if you pull _my_ repostiry, you could then 
   name the result "linus-tree" by just doing

	echo $result > .git/refs/heads/linus-tree

   and it really is that easy.

   So just do this for all the repos you want to pull, so that you have 
   <n> heads in the same tree, names however you wish (it the head naming
   _you_ have in your tree do not necessarily have anything at all to do 
   with the head naming in the heads in the trees the data came from. In
   fact, that's very important, because there can be multiple HEAD or
   "master" source branches, of course, and you need to make _your_ heads
   be unique).

 - second phase is to select some kind of order for these things, and just 
   start merging. Start off with a known base, and for each tree you merge 
   it against the previous merge, and then just generate the diff against 
   the previous merge.

   Now, one downside is that the current "git resolve" will _always_ 
   resolve into HEAD, which is admittedly a bit of a bummer: you can't 
   resolve into a totally temporary tree, which is what your usage might 
   want.

   This might be something git could do better for you, but the upside is
   that "git resolve" will always leave the previous tree in ORIG_HEAD,
   and since you really need to generate a temporary branch for all your
   merges anyway, you might as well just do exactly that, and switch to it
   before you start the merge process.

   Anyway, this example script will jusy always create a temporary branch
   called "merge-branch" that starts at whatever point you use as your
   base. Not a biggie. You can choose whatever as your starting point, I'm 
   just assuming that it's the "master" branch, and that you'd keep (for 
   example) my last release in there as the base.

   But if you want to keep the result of your quilt stuff, that should be 
   doable too, for example. I'm _assuming_ that you'd do the git merge 
   diffs first, and then do the quilt stuff on top of the result, but 
   there's nothing really that forces that order.

   So it should literally be as simple as something like this:

	#
	# Start off from "master", create a new branch "merge-branch"
	# off that state.
	#
	git checkout -f master
	git-rev-parse master > .git/refs/heads/merge-branch

	#
	# Switch to it, always leaving "master" untouched
	#
	git checkout -f merge-branch

	#
	#
	# For each tree you want to merge, just do so..
	#
	# This also decides the order of the patches
	#
	for i in linus-tree davem-net-tree davem-sparc-tree ...
	do
		git resolve HEAD $i "Merging $i"
		if [ "$?" -ne 0 ]; then
			echo "Automatic resolve failed, skipping $i" >&2

			#
			# Revert back to previous state, we're not going
			# to do any manual fixups here.
			#
			git checkout -f
		else
			#
			# Yay! The resolve worked, let's just diff what
			# it did and continue onward from here
			#
			git diff ORIG_HEAD.. > merge-diff-$i
		fi
	done

	#
	# Finally, just switch back to "master", throw away all the work
	# we did (the objects will stay around, but you can do a
	#
	#	git prune
	#
	# once a week to get rid of the temporary objects. Don't do it
	# here, it's too expensive and there's no real point).
	#
	git checkout -f master
	rm .git/refs/heads/merge-branch

and you're hopefully done. It really _should_ be that easy.

The above will leave you with a series of diffs called

	merge-diff-linus-tree
	merge-diff-davem-net-tree
	merge-diff-davem-sparc-tree
	...

which are all relative to each other (ie order very much matters, and 
comes directly from the order you did the merging in).

NOTE NOTE NOTE! I wrote the above in this email client, I've not tested it 
at all. It _looks_ straightforward enough, but hey, maybe I'm a retard.

And btw, this should all be quite efficient. It really shouldn't take many 
seconds per tree. The most expensive op _should_ be downloading the 
changes, and the fact that "git resolve" will always do a "diffstat" of 
the result..

		Linus

^ permalink raw reply

* [RFC PATCH 0/2] Parallel pull core
From: barkalow @ 2005-08-01  1:11 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

This series makes the core of the pull programs parallel. It should not 
actually make any difference yet. It arranges to call prefetch() for each 
object as soon as it is determined to be needed, and then call fetch() on 
each object once there is nothing left to prefetch. By implementing 
prefetch(), an implementation can make additional requests while waiting 
for the data from the earlier ones to come in. Additionally, fetch() will 
be called in the same order that prefetch() was called, so the 
implementation can just make a series of requests and get responses.

If anyone else is also interested in working on this, it could go into 
-pu; I've tested it reasonably well, and I'm pretty sure that it doesn't 
have any effect until the implementations are changed to have prefetch() 
do something. I'm working on support for it in ssh-pull, and haven't 
started looking at http-pull support.

 1: Adds support to the struct object code to produce struct objects when 
    the type is unknown and the content is unavailable; this allocates 
    memory for the union of the supported types, so it is slightly less 
    efficient, but allows the pull code to track objects it doesn't know 
    anything about (such as the targets to tags).
 2: Parallelizes the pull algorithm.

	-Daniel

^ permalink raw reply

* [PATCH 1/2] Support for making struct objects for absent objects of unknown type
From: barkalow @ 2005-08-01  1:29 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <Pine.LNX.4.62.0507312055030.23721@iabervon.org>

This adds support for calling lookup_object_type() with NULL for the type, 
which will cause it to allocate enough memory for the largest type. This 
allows struct object_lists for objects that need to be fetched to find out 
what they are.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---

 object.c |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 object.h |    8 ++++++++
 tree.h   |    1 +
 3 files changed, 53 insertions(+), 1 deletions(-)

6ed7f76e658c02cb2539a52813fe20d3fd9aa250
diff --git a/object.c b/object.c
--- a/object.c
+++ b/object.c
@@ -99,7 +99,9 @@ void mark_reachable(struct object *obj, 
 
 struct object *lookup_object_type(const unsigned char *sha1, const char *type)
 {
-	if (!strcmp(type, blob_type)) {
+	if (!type) {
+		return lookup_unknown_object(sha1);
+	} else if (!strcmp(type, blob_type)) {
 		return &lookup_blob(sha1)->object;
 	} else if (!strcmp(type, tree_type)) {
 		return &lookup_tree(sha1)->object;
@@ -113,6 +115,27 @@ struct object *lookup_object_type(const 
 	}
 }
 
+union any_object {
+	struct object object;
+	struct commit commit;
+	struct tree tree;
+	struct blob blob;
+	struct tag tag;
+};
+
+struct object *lookup_unknown_object(const unsigned char *sha1)
+{
+	struct object *obj = lookup_object(sha1);
+	if (!obj) {
+		union any_object *ret = xmalloc(sizeof(*ret));
+		memset(ret, 0, sizeof(*ret));
+		created_object(sha1, &ret->object);
+		ret->object.type = NULL;
+		return &ret->object;
+	}
+	return obj;
+}
+
 struct object *parse_object(const unsigned char *sha1)
 {
 	unsigned long size;
@@ -150,3 +173,23 @@ struct object *parse_object(const unsign
 	}
 	return NULL;
 }
+
+struct object_list *object_list_insert(struct object *item,
+				       struct object_list **list_p)
+{
+	struct object_list *new_list = xmalloc(sizeof(struct object_list));
+        new_list->item = item;
+        new_list->next = *list_p;
+        *list_p = new_list;
+        return new_list;
+}
+
+unsigned object_list_length(struct object_list *list)
+{
+	unsigned ret = 0;
+	while (list) {
+		list = list->next;
+		ret++;
+	}
+	return ret;
+}
diff --git a/object.h b/object.h
--- a/object.h
+++ b/object.h
@@ -31,8 +31,16 @@ void created_object(const unsigned char 
 /** Returns the object, having parsed it to find out what it is. **/
 struct object *parse_object(const unsigned char *sha1);
 
+/** Returns the object, with potentially excess memory allocated. **/
+struct object *lookup_unknown_object(const unsigned  char *sha1);
+
 void add_ref(struct object *refer, struct object *target);
 
 void mark_reachable(struct object *obj, unsigned int mask);
 
+struct object_list *object_list_insert(struct object *item, 
+				       struct object_list **list_p);
+
+unsigned object_list_length(struct object_list *list);
+
 #endif /* OBJECT_H */
diff --git a/tree.h b/tree.h
--- a/tree.h
+++ b/tree.h
@@ -14,6 +14,7 @@ struct tree_entry_list {
 	unsigned int mode;
 	char *name;
 	union {
+		struct object *any;
 		struct tree *tree;
 		struct blob *blob;
 	} item;

^ permalink raw reply

* [PATCH 2/2] Parallelize pull algorithm (no change to behavior).
From: barkalow @ 2005-08-01  1:32 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano
In-Reply-To: <Pine.LNX.4.62.0507312055030.23721@iabervon.org>

This patch makes the core pull algorithm request all of the objects it can 
(with prefetch()) before actually reading them (with fetch()). Future 
patches (in a later series) will make use of this behavior to have 
multiple requests in flight at the same time, reducing the need for 
round-trips.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---

 http-pull.c  |    4 ++
 local-pull.c |    4 ++
 pull.c       |  128 ++++++++++++++++++++++++++++++++++------------------------
 pull.h       |    7 +++
 ssh-pull.c   |    4 ++
 5 files changed, 93 insertions(+), 54 deletions(-)

02aae5a570341c5b86b914d59732009f015800d8
diff --git a/http-pull.c b/http-pull.c
--- a/http-pull.c
+++ b/http-pull.c
@@ -68,6 +68,10 @@ static size_t fwrite_sha1_file(void *ptr
 	return size;
 }
 
+void prefetch(unsigned char *sha1)
+{
+}
+
 int fetch(unsigned char *sha1)
 {
 	char *hex = sha1_to_hex(sha1);
diff --git a/local-pull.c b/local-pull.c
--- a/local-pull.c
+++ b/local-pull.c
@@ -11,6 +11,10 @@ static int use_filecopy = 1;
 
 static char *path; /* "Remote" git repository */
 
+void prefetch(unsigned char *sha1)
+{
+}
+
 int fetch(unsigned char *sha1)
 {
 	static int object_name_start = -1;
diff --git a/pull.c b/pull.c
--- a/pull.c
+++ b/pull.c
@@ -17,11 +17,8 @@ int get_all = 0;
 int get_verbosely = 0;
 static unsigned char current_commit_sha1[20];
 
-static const char commitS[] = "commit";
-static const char treeS[] = "tree";
-static const char blobS[] = "blob";
-
-void pull_say(const char *fmt, const char *hex) {
+void pull_say(const char *fmt, const char *hex) 
+{
 	if (get_verbosely)
 		fprintf(stderr, fmt, hex);
 }
@@ -48,93 +45,114 @@ static int make_sure_we_have_it(const ch
 	return status;
 }
 
-static int process_unknown(unsigned char *sha1);
+static int process(unsigned char *sha1, const char *type);
 
-static int process_tree(unsigned char *sha1)
+static int process_tree(struct tree *tree)
 {
-	struct tree *tree = lookup_tree(sha1);
 	struct tree_entry_list *entries;
 
 	if (parse_tree(tree))
 		return -1;
 
 	for (entries = tree->entries; entries; entries = entries->next) {
-		const char *what = entries->directory ? treeS : blobS;
-		if (make_sure_we_have_it(what, entries->item.tree->object.sha1))
+		if (process(entries->item.any->sha1,
+			    entries->directory ? tree_type : blob_type))
 			return -1;
-		if (entries->directory) {
-			if (process_tree(entries->item.tree->object.sha1))
-				return -1;
-		}
 	}
 	return 0;
 }
 
-static int process_commit(unsigned char *sha1)
+static int process_commit(struct commit *commit)
 {
-	struct commit *obj = lookup_commit(sha1);
-
-	if (make_sure_we_have_it(commitS, sha1))
+	if (parse_commit(commit))
 		return -1;
 
-	if (parse_commit(obj))
-		return -1;
+	memcpy(current_commit_sha1, commit->object.sha1, 20);
 
 	if (get_tree) {
-		if (make_sure_we_have_it(treeS, obj->tree->object.sha1))
-			return -1;
-		if (process_tree(obj->tree->object.sha1))
+		if (process(commit->tree->object.sha1, tree_type))
 			return -1;
 		if (!get_all)
 			get_tree = 0;
 	}
 	if (get_history) {
-		struct commit_list *parents = obj->parents;
+		struct commit_list *parents = commit->parents;
 		for (; parents; parents = parents->next) {
 			if (has_sha1_file(parents->item->object.sha1))
 				continue;
-			if (make_sure_we_have_it(NULL,
-						 parents->item->object.sha1)) {
-				/* The server might not have it, and
-				 * we don't mind. 
-				 */
-				continue;
-			}
-			if (process_commit(parents->item->object.sha1))
+			if (process(parents->item->object.sha1,
+				    commit_type))
 				return -1;
-			memcpy(current_commit_sha1, sha1, 20);
 		}
 	}
 	return 0;
 }
 
-static int process_tag(unsigned char *sha1)
+static int process_tag(struct tag *tag)
 {
-	struct tag *obj = lookup_tag(sha1);
-
-	if (parse_tag(obj))
+	if (parse_tag(tag))
 		return -1;
-	return process_unknown(obj->tagged->sha1);
+	return process(tag->tagged->sha1, NULL);
 }
 
-static int process_unknown(unsigned char *sha1)
+static struct object_list *process_queue = NULL;
+static struct object_list **process_queue_end = &process_queue;
+
+static int process(unsigned char *sha1, const char *type)
 {
 	struct object *obj;
-	if (make_sure_we_have_it("object", sha1))
-		return -1;
-	obj = parse_object(sha1);
-	if (!obj)
-		return error("Unable to parse object %s", sha1_to_hex(sha1));
-	if (obj->type == commit_type)
-		return process_commit(sha1);
-	if (obj->type == tree_type)
-		return process_tree(sha1);
-	if (obj->type == blob_type)
+	if (has_sha1_file(sha1))
 		return 0;
-	if (obj->type == tag_type)
-		return process_tag(sha1);
-	return error("Unable to determine requirement of type %s for %s",
-		     obj->type, sha1_to_hex(sha1));
+	obj = lookup_object_type(sha1, type);
+	object_list_insert(obj, process_queue_end);
+	process_queue_end = &(*process_queue_end)->next;
+
+	fprintf(stderr, "prefetch %s\n", sha1_to_hex(sha1));
+	prefetch(sha1);
+		
+	return 0;
+}
+
+static int loop(void)
+{
+	while (process_queue) {
+		struct object *obj = process_queue->item;
+		fprintf(stderr, "%d objects to pull\n", 
+			object_list_length(process_queue));
+		process_queue = process_queue->next;
+		if (!process_queue)
+			process_queue_end = &process_queue;
+
+		fprintf(stderr, "fetch %s\n", sha1_to_hex(obj->sha1));
+		
+		if (make_sure_we_have_it(obj->type ?: "object", 
+					 obj->sha1))
+			return -1;
+		if (!obj->type)
+			parse_object(obj->sha1);
+		if (obj->type == commit_type) {
+			if (process_commit((struct commit *)obj))
+				return -1;
+			continue;
+		}
+		if (obj->type == tree_type) {
+			if (process_tree((struct tree *)obj))
+				return -1;
+			continue;
+		}
+		if (obj->type == blob_type) {
+			continue;
+		}
+		if (obj->type == tag_type) {
+			if (process_tag((struct tag *)obj))
+				return -1;
+			continue;
+		}
+		return error("Unable to determine requirements "
+			     "of type %s for %s",
+			     obj->type, sha1_to_hex(obj->sha1));
+	};
+	return 0;
 }
 
 static int interpret_target(char *target, unsigned char *sha1)
@@ -164,7 +182,9 @@ int pull(char *target)
 	if (interpret_target(target, sha1))
 		return error("Could not interpret %s as something to pull",
 			     target);
-	if (process_unknown(sha1))
+	if (process(sha1, NULL))
+		return -1;
+	if (loop())
 		return -1;
 	
 	if (write_ref) {
diff --git a/pull.h b/pull.h
--- a/pull.h
+++ b/pull.h
@@ -9,6 +9,13 @@
 extern int fetch(unsigned char *sha1);
 
 /*
+ * Fetch the specified object and store it locally; fetch() will be
+ * called later to determine success. To be provided by the particular
+ * implementation.
+ */
+extern void prefetch(unsigned char *sha1);
+
+/*
  * Fetch ref (relative to $GIT_DIR/refs) from the remote, and store
  * the 20-byte SHA1 in sha1.  Return 0 on success, -1 on failure.  To
  * be provided by the particular implementation.
diff --git a/ssh-pull.c b/ssh-pull.c
--- a/ssh-pull.c
+++ b/ssh-pull.c
@@ -10,6 +10,10 @@ static int fd_out;
 static unsigned char remote_version = 0;
 static unsigned char local_version = 1;
 
+void prefetch(unsigned char *sha1)
+{
+}
+
 int fetch(unsigned char *sha1)
 {
 	int ret;

^ permalink raw reply

* cg-clone failing to get cogito latest tree.
From: Martin Langhoff @ 2005-08-01  2:49 UTC (permalink / raw)
  To: GIT

On a new machine, trying to boostrap into latest cogito, I download
and make cogito 0.12.1, and then...

$ cg-clone http://www.kernel.org/pub/scm/cogito/cogito.git cogito
defaulting to local storage area
14:48:53 URL:http://www.kernel.org/pub/scm/cogito/cogito.git/refs/heads/master
[41/41] -> "refs/heads/origin" [1]
progress: 34 objects, 45126 bytes
error: File d2072194059c65f92487c84c53b9f6b5da780d14
(http://www.kernel.org/pub/scm/cogito/cogito.git/objects/d2/072194059c65f92487c84c53b9f6b5da780d14)
corrupt

Cannot obtain needed blob d2072194059c65f92487c84c53b9f6b5da780d14
while processing commit 0000000000000000000000000000000000000000.
cg-pull: objects pull failed
cg-init: pull failed

any hints? I have a similar problem fetching git with cg-clone: 

$ cg-clone http://www.kernel.org/pub/scm/git/git.git git
defaulting to local storage area
14:53:44 URL:http://www.kernel.org/pub/scm/git/git.git/refs/heads/master
[41/41] -> "refs/heads/origin" [1]
progress: 2 objects, 4666 bytes
error: File 6ff87c4664981e4397625791c8ea3bbb5f2279a3
(http://www.kernel.org/pub/scm/git/git.git/objects/6f/f87c4664981e4397625791c8ea3bbb5f2279a3)
corrupt

Cannot obtain needed blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3
while processing commit 0000000000000000000000000000000000000000.
cg-pull: objects pull failed
cg-init: pull failed

Probably doing somethginf hopelessly wrong...


martin

^ permalink raw reply

* Re: git diffs
From: Matthias Urlichs @ 2005-08-01  7:55 UTC (permalink / raw)
  To: git
In-Reply-To: <Pine.LNX.4.58.0507311725590.14342@g5.osdl.org>

Hi, Linus Torvalds wrote:

> 	git checkout -f master
> 	git-rev-parse master > .git/refs/heads/merge-branch
> 
> 	#
> 	# Switch to it, always leaving "master" untouched
> 	#
> 	git checkout -f merge-branch

Isn't that equivalent to (but slower than)

    git checkout -f -b merge-branch master

?

-- 
Matthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de
Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de
 - -
You can tell it's going to be a rotten day when the bird singing outside your
window is a buzzard.

^ permalink raw reply

* Re: [PATCH 1/3] Add git-send-email-script - tool to send emails from git-format-patch-script
From: Matthias Urlichs @ 2005-08-01  7:59 UTC (permalink / raw)
  To: git
In-Reply-To: <7vk6j6a3rh.fsf@assigned-by-dhcp.cox.net>

Hi, Junio C Hamano wrote:

> Also, I wonder if running lc() to downcase the local-part[*] is
> safe/allowed/correct

mostly/no/no.

It's unlikely to be a real-life problem, but we still shouldn't do it.

-- 
Matthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de
Disclaimer: The quote was selected randomly. Really. | http://smurf.noris.de
 - -
Amusements to virtue are like breezes of air to the flame -- gentle ones will
fan it, but strong ones will put it out.
					-- David Thomas

^ permalink raw reply

* Re: [PATCH] Added hook in git-receive-pack
From: Junio C Hamano @ 2005-08-01  8:14 UTC (permalink / raw)
  To: Josef Weidendorfer; +Cc: git
In-Reply-To: <200508010117.41848.Josef.Weidendorfer@gmx.de>

Josef, I've committed a version that has slightly different
semantics from what you originally posted.

The differences are:

 - Instead of being post-change hook, the script is run just
   before each ref is updated.  The script can exit with
   non-zero status to tell receive-pack not to update that ref
   if it wants to.  This means that you should explicitly exit
   with zero status if all you want to do in the hook is to send
   a mail out.

 - The script is called once at the very end with a single
   parameter "" (i.e. $refname == ""), to signal that
   receive-pack is about to finish.  This is a good place to add
   any "final cleanup" hook.

The latter change allowed me to remove the mandatory
update_server_info call Linus did not like and make it
optional.

-jc

^ permalink raw reply

* Re: cg-clone failing to get cogito latest tree.
From: Komal Shah @ 2005-08-01  8:13 UTC (permalink / raw)
  To: Martin Langhoff, GIT
In-Reply-To: <46a038f905073119492e521bde@mail.gmail.com>

 
--- Martin Langhoff <martin.langhoff@gmail.com> wrote:

> On a new machine, trying to boostrap into latest cogito, I download
> and make cogito 0.12.1, and then...
> 
> $ cg-clone http://www.kernel.org/pub/scm/cogito/cogito.git cogito
> defaulting to local storage area
> 14:48:53

Please try "rsync" method too. Last week http seem to be broken. I have
tried linux-omap tree and "rsync" worked, but "http" was failing.

---Komal Shah

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 

^ permalink raw reply

* Re: [PATCH 1/2] Functions for managing the set of packs the library is using (whitespace fixed)
From: Junio C Hamano @ 2005-08-01  8:16 UTC (permalink / raw)
  To: barkalow; +Cc: git
In-Reply-To: <Pine.LNX.4.62.0507312053010.23721@iabervon.org>

barkalow@iabervon.org writes:

> This adds support for reading an uninstalled index, and installing a
> pack file that was added while the program was running, as well as
> functions for determining where to put the file.

Thanks.  Applied and pushed out.

I removed my own version of stop-gap hack; git-fetch-script
now directly calls git-http-pull.

^ permalink raw reply

* Re: Status of git.git repository
From: Horst von Brand @ 2005-08-01  3:29 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vhded6o0r.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano <junkio@cox.net> wrote:

[...]

> By the way, do people mind my posting my own patches to the
> list?  I keep the same in the "pu" (proposed updates) branch, so
> if the list readers think I am just adding noise to the list
> traffic, I would stop doing so, and instead just invite
> interested people to browse the "pu" branch.

It's fine with me for you to post your patches here. I'd hope that by
posting your patches get more review (and might spark ideas elsewhere).
I.e., open source development, Linus style.
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply

* Re: Git 1.0 Synopis (Draft v3
From: Horst von Brand @ 2005-07-31 22:15 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: git
In-Reply-To: <20050729082941.GD32263@mythryan2.michonline.com>

Ryan Anderson <ryan@michonline.com> wrote:
> Source Code Management with Git

More bugging...

- Either stay with your idea of "Git is the idea, git the implementation"
  (iff blessed by the Git Powers That Be) and be consistent about it, or
  just use "git" throughout.

- Attribute the meaning appropiately, say by:

In Linus' own words as the inventor of git:

> "git" can mean anything, depending on your mood.
> 
>  - random three-letter combination that is pronounceable, and not
>    actually used by any common UNIX command.  The fact that it is a
>    mispronunciation of "get" may or may not be relevant.
>  - stupid. contemptible and despicable. simple. Take your pick from the
>    dictionary of slang.
>  - "global information tracker": you're in a good mood, and it actually
>    works for you. Angels sing, and a light suddenly fills the room. 
>  - "goddamn idiotic truckload of sh*t": when it breaks
[...]

> To get a copy of Git:
> 	Daily snapshots are available at:
> 	http://www.codemonkey.org.uk/projects/git-snapshots/git/
> 	(Thanks to Dave Jones)
> 
> 	Source tarballs and RPMs at:
> 	http://www.kernel.org/pub/software/scm/git/
> 
> 	Deb packages at:
> 	<insert url here>
> 
> 	Or via Git itself:
> 	git clone http://www.kernel.org/pub/scm/git/git.git/ <local directory>
> 	git clone rsync://rsync.kernel.org/pub/scm/git/git.git/ <local directory>
> 
> 	(rsync is generally faster for an initial clone, you can switch later
> 	by editing .git/branches/origin and changing the url)
> 
> To get the 'Porcelain' tools mentioned above:
> 	SCM Interface layers:
> 	cogito - http://www.kernel.org/pub/software/scm/cogito/
> 	StGIT - http://www.procode.org/stgit/

At least cogito includes a (slightly old) version of git. Dunno about
StGIT. And git and cogito have a gitk inside too. This should be mentioned,
i.e., look at the package(s) you are interested and see what else they
carry or require and keep in mind that (for now?) getting git as part of
one package is /not/ guaranteed to be compatible with another or standard
git.
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply

* Re: Git 1.0 Synopis (Draft v3
From: Horst von Brand @ 2005-07-31 22:18 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: Ryan Anderson, git
In-Reply-To: <20050729212621.GB8263@mars.ravnborg.org>

Sam Ravnborg <sam@ravnborg.org> wrote:
> On Fri, Jul 29, 2005 at 04:29:41AM -0400, Ryan Anderson wrote:
> > Source Code Management with Git
> ....

> The article should include a HOWTO part alos.

I'd vote for a separate file.

>                                               So people can see how to
> edit a file, pull from a remote repository etc.

Exactly.

> Since you have introduced core and porcelains it would be most logical
> to use one of the porcelains in these examples, maybe accompanied by the
> raw git commands being executed.

Better leave the Porcelain-HOWTO to individual Porcelain. Perhaps the
Plumbing-HOWTO should include a section on interfacing to Porcelain (or it
should be yet another file).
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply

* Re: Git 1.0 Synopis (Draft v3
From: Horst von Brand @ 2005-08-01 13:21 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Ryan Anderson, git
In-Reply-To: <200507312215.j6VMFeqn030963@laptop11.inf.utfsm.cl>

[Yes, I know it is considered odd when you speak to yourself in public...]

Horst von Brand <vonbrand@inf.utfsm.cl> wrote:
> Ryan Anderson <ryan@michonline.com> wrote:
> > Source Code Management with Git

> More bugging...

And then some.

> > To get the 'Porcelain' tools mentioned above:
> > 	SCM Interface layers:
> > 	cogito - http://www.kernel.org/pub/software/scm/cogito/
> > 	StGIT - http://www.procode.org/stgit/
> 
> At least cogito includes a (slightly old) version of git. Dunno about
> StGIT. And git and cogito have a gitk inside too. This should be mentioned,
> i.e., look at the package(s) you are interested and see what else they
> carry or require and keep in mind that (for now?) getting git as part of
> one package is /not/ guaranteed to be compatible with another or standard
> git.

Also note that StGIT is /not/ a SCM (as cogito is), it is a tool to shuffle
patches that uses git as a backend/target.
-- 
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply

* [ANNOUNCE] mtkdiff-20050801 (with patchkdiff, quiltkdiff, gitkdiff and modified gitk)
From: Tejun Heo @ 2005-08-01 13:28 UTC (permalink / raw)
  To: git, lkml, snemana, paulus, rdunlap, mingo

Hello, guys.

New version of mtkdiff package is available.  Changes since last release 
(20050514) are.

* patchkdiff added.  Idea is from patchview of Randy Dunlap (Hi!).
   patchkdiff can show multiple diff files.

* quiltkdiff rewritten in perl.  It's faster and doesn't push/pop quilt
   repository.  Patches are rolled back and applied in a temporary
   working directory.

* gitkdiff rewritten in perl.  It now works with the new git diff
   output format and a bit faster.  Also, this version can show
   multiple commits.  For example, you can do the following.
   $ git-rev-list HEAD ^OLD_HEAD | gitkdiff -c -r

* modified gitk-1.2.

For more information...

http://home-tj.org/mtkdiff

Tarball is available at

http://home-tj.org/mtkdiff/files/mtkdiff-20050801.tar.gz

Thanks.

-- 
tejun

^ permalink raw reply

* Re: Dump http servers still slow?
From: Darrin Thompson @ 2005-08-01 14:03 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, barkalow
In-Reply-To: <7v1x5ftqn5.fsf@assigned-by-dhcp.cox.net>

On Sat, 2005-07-30 at 23:51 -0700, Junio C Hamano wrote:
> Darrin Thompson <darrint@progeny.com> writes:
> 
> > 1. Pack files should reduce the number of http round trips.
> > 2. What I'm seeing when I check out mainline git is the acquisition of a
> > single large pack, then 600+ more recent objects. Better than before,
> > but still hundreds of round trips.
> 
> I've packed the git.git repository, by the way.  It has 43
> unpacked objects totalling 224 kilobytes, so cloning over dumb
> http should go a lot faster until we accumulate more unpacked
> objects.

I did a pull from the office and the times were 27 sec for http and 17
sec for rsync. So the moral of the story should be that frequent repacks
are sufficient for decent http performance.

--
Darrin

^ permalink raw reply

* [PATCH] Fix warning about non-void return in a void function.
From: A Large Angry SCM @ 2005-08-01 14:05 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Junio C Hamano

[PATCH] Fix warning about non-void return in a void function.

Signed-off-by: A Large Angry SCM <gitzilla@gmail.com>
---

 receive-pack.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

8eda2e60f24221255b77e48f4dd60e2b025839ed
diff --git a/receive-pack.c b/receive-pack.c
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -186,7 +186,7 @@ static void unpack(void)
 	int code = run_command(unpacker, NULL);
 	switch (code) {
 	case 0:
-		return 0;
+		return;
 	case -ERR_RUN_COMMAND_FORK:
 		die("unpack fork failed");
 	case -ERR_RUN_COMMAND_EXEC:

^ permalink raw reply

* [PATCH] Do not rely on a sane wc
From: Johannes Schindelin @ 2005-08-01 14:32 UTC (permalink / raw)
  To: git

Some implementations of wc pad the line number with white space, which
expr does not grok as a number.

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

 git-format-patch-script |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

da0488e94f7f949cbfce7422980eb2fe38166b9a
diff --git a/git-format-patch-script b/git-format-patch-script
--- a/git-format-patch-script
+++ b/git-format-patch-script
@@ -109,7 +109,7 @@ _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x4
 stripCommitHead='/^'"$_x40"' (from '"$_x40"')$/d'

 git-rev-list --merge-order "$junio" "^$linus" >$series
-total=`wc -l <$series`
+total=`wc -l <$series | tr -dc "[0-9]"`
 i=$total
 while read commit
 do

^ 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