Git development
 help / color / mirror / Atom feed
* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Chris Shoemaker @ 2005-10-28  0:50 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0510271709120.4664@g5.osdl.org>

On Thu, Oct 27, 2005 at 05:12:33PM -0700, Linus Torvalds wrote:
> Add the "-r" flag to do the recursive thing, ie
> 
> 	git-diff-tree -r --name-only
> 
> should do the right thing.

Ah, yes, it does.  Thanks.

> > True.  Maybe gitk and gitweb can share a cache containing the tree
> > diffs.  Or maybe git-core can cache tree diffs?
> 
> Creating them is fast enough if there is no IO. Make sure your project is 
> packed, and you should be ok.
> 
> The expensive part is the "-p" thing to create patches. If you avoid the 
> patch creation, you should be ok.

git-diff-tree -r --name-only is pretty quick and it actually does a
halfway reasonable job of representing damage-potential.

> > But, in general, is there interest in a visual indicator of commit
> > size and/or type in gitweb?
> 
> I kind of like it, but I'm not sure how useful it is, and maybe it does 
> really want the whole patch size (not just how many files it touches). 

Hard to say.  Neither one is going to be perfect, so I'm ok with
settling for the cheap one if it's halfway reasonable.  I think I'll
mock up the merge indicator and see if there's any value added there.

So, what's the best way to detect merges?  Maybe see if
'git-cat-file commit $hash | grep ^parent | wc -l' is greater than 1?

> That's where caching might save your *ss.

Ok, but that cache would live inside GIT_DIR an be shared with gitk,
right?

-chris

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Martin Langhoff @ 2005-10-28  1:08 UTC (permalink / raw)
  To: Chris Shoemaker; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <20051028005029.GA2654@pe.Belkin>

On 10/28/05, Chris Shoemaker <c.shoemaker@cox.net> wrote:
> So, what's the best way to detect merges?  Maybe see if
> 'git-cat-file commit $hash | grep ^parent | wc -l' is greater than 1?
>
> > That's where caching might save your *ss.
>
> Ok, but that cache would live inside GIT_DIR an be shared with gitk,
> right?

gitweb should have any caches it wants, regardless of gitk, methinks.

I very rarely run gitk and gitweb on the same repo. The repos where I
run gitk are all development repos, on my desktop machine or laptop.
gitweb runs only on the webserver where I publish those...

So it may be practical to have a common cache format, but unlikely
that both programs will use the same cached data in practice...


martin

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: H. Peter Anvin @ 2005-10-28  1:13 UTC (permalink / raw)
  To: Chris Shoemaker; +Cc: Linus Torvalds, Junio C Hamano, git
In-Reply-To: <20051028005029.GA2654@pe.Belkin>

Chris Shoemaker wrote:
> 
> Ok, but that cache would live inside GIT_DIR an be shared with gitk,
> right?
> 

That would be bad.  Don't assume that the person running gitweb (or 
gitk, for that matter) has write permission.

	-hpa

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Martin Langhoff @ 2005-10-28  1:16 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Chris Shoemaker, git
In-Reply-To: <7vfyqm1uvx.fsf@assigned-by-dhcp.cox.net>

On 10/28/05, Junio C Hamano <junkio@cox.net> wrote:
> > which is pretty slow.  Any suggestions?
>
> * do we really want to know the number of lines?

What about both? And sugar (rename detection) on top! ;-)

If you try an find the largest commit (by line count) in the gitweb
revision history, you bump into the gitweb.pl -> gitweb.cgi rename.

cheers,


martin

^ permalink raw reply

* Re: gitk shows an empty line between "Comments" and changed files
From: Pavel Roskin @ 2005-10-28  1:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vslum3l2w.fsf@assigned-by-dhcp.cox.net>

Hi, Junio!

On Thu, 2005-10-27 at 10:51 -0700, Junio C Hamano wrote:
> Pavel Roskin <proski@gnu.org> writes:
> 
> > Or maybe the SHA1 header should never be printed at all?  It looks like
> > it's not documented anywhere.  It doesn't break the tests.
> 
> AFAIK, its only user (except humans) is patch-id.

Thank you for reply!  git-patch-id is badly documented, and its output
is not documented at all.  It outputs two SHA1 hashes, and the second
one is taken from the line produced by git-diff-tree.  If there is no
such line, the second ID is 0.

git-patch-id is only used by git-cherry.  git-cherry writes the second
SHA1 to some files in a temporary directory, but it never reads those
files, it only checks that they exist.

I'm pretty confident now that the patch I posted in the last message was
correct.

Of course, more cleanup will be needed to remove the second ID from
git-patch-id, to adjust git-cherry accordingly and to remove "p"
assignments in gitk.

-- 
Regards,
Pavel Roskin

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Kay Sievers @ 2005-10-28  1:56 UTC (permalink / raw)
  To: Chris Shoemaker; +Cc: git
In-Reply-To: <20051027203945.GC1622@pe.Belkin>

On Thu, Oct 27, 2005 at 04:39:45PM -0400, Chris Shoemaker wrote:
> 
> I really like gitweb (thanks Kay!), but I thought it would be nice to
> have a visual indication of patch size.  I found this helpful when
> scanning though the shortlogs.

This looks nice, but if the patch size tells you something important,
your commit subjects are probably too short or wrong. :)

> To see what it looks like with the gitweb for gitweb (meta-gitweb?)
> goto:
> 
> http://www.codesifter.com/cgi-bin/gitweb.cgi?p=gitweb.git;a=shortlog
> 
> I rather like the look of what I've hacked up (the enclosed patch),
> but it should be considered as just a prototype: it only affects the
> shortlog, it's horribly inefficient, and I don't really do perl.  :)
> 
> If anyone thinks this is a good feature, then please tell me an
> efficient way to get some heuristic of the patch size.

You may try to use CSS instead of an embedded picture to draw the bar,
just like the RSS logo in the footer, which is simple CSS rendered in the
browser.

Kay

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Chris Shoemaker @ 2005-10-28  2:38 UTC (permalink / raw)
  To: Kay Sievers; +Cc: git
In-Reply-To: <20051028015642.GA31822@vrfy.org>

On Fri, Oct 28, 2005 at 03:56:42AM +0200, Kay Sievers wrote:
> On Thu, Oct 27, 2005 at 04:39:45PM -0400, Chris Shoemaker wrote:
> > 
> > I really like gitweb (thanks Kay!), but I thought it would be nice to
> > have a visual indication of patch size.  I found this helpful when
> > scanning though the shortlogs.
> 
> This looks nice, but if the patch size tells you something important,
> your commit subjects are probably too short or wrong. :)

Yeah, some people write lousy commit subjects.  But me?  Nooo,
/never/.  :)

> You may try to use CSS instead of an embedded picture to draw the bar,
> just like the RSS logo in the footer, which is simple CSS rendered in the
> browser.

I'll look into that, but the cost wasn't in the image; it was in the
width calculation.

Here's a side-by-side comparison.  Open two browser tabs and flip between them:

http://www.codesifter.com/cgi-bin/gitweb-difftreeP.cgi?p=git.git;a=shortlog
http://www.codesifter.com/cgi-bin/gitweb-difftreeNames.cgi?p=git.git;a=shortlog

I've used a project you all are familar with, and that has more than
two files.  The first page uses 'git-diff-tree -p $hash|wc -l'.  The
second page uses 'git-diff-tree -r --name-only|wc -l'.  (Oh and I have
a merge indicator now.)

How do they compare for showing damage-potential?  I think they both
do a reasonable job.  I think the full patch diff is a bit better, but
it does cost.

-chris

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Linus Torvalds @ 2005-10-28  2:38 UTC (permalink / raw)
  To: Martin Langhoff; +Cc: Junio C Hamano, Chris Shoemaker, git
In-Reply-To: <46a038f90510271816i26389d5cqe136f515007ca057@mail.gmail.com>



On Fri, 28 Oct 2005, Martin Langhoff wrote:
>
> On 10/28/05, Junio C Hamano <junkio@cox.net> wrote:
> > > which is pretty slow.  Any suggestions?
> >
> > * do we really want to know the number of lines?
> 
> What about both? And sugar (rename detection) on top! ;-)

Well, if you do full copy detection (and break detection), then 
git-diff-tree will actually have effectively calculated the size of the 
diff of each file. It just doesn't print them (well, it does a percentage 
for the renames/copies).

So you could make git-diff-tree tell you how big the patch was, without 
actually generating a patch at all. It will be quite a bit more expensive 
than just a plain "git-diff-tree -r --name-only", but if you cache the 
result is might be quite acceptable.

Caching the result might be as simple as just telling the caching 
web-server that the result is static and never changes - no need to 
cache things inside of gitweb itself. Just set expiration to "never".

Anybody wants to add a new output format to git-diff-tree that outputs how 
big the changes are in absolute terms (rather than the "similarity index", 
which is obviously relative to the original size of the file in question)?

		Linus

^ permalink raw reply

* [PATCH] Make cg-clean faster and space-safe
From: Pavel Roskin @ 2005-10-28  2:39 UTC (permalink / raw)
  To: git, Petr Baudis

Use bash pattern matching to list all parent directories instead of
using arrays.  This makes cg-clean run twice as fast on the Linux kernel
(4 seconds vs 8 seconds).

The new code is also for directory names containing spaces and other
symbols that need to be quoted.  Also, the new code is easier to read.

Signed-off-by: Pavel Roskin <proski@gnu.org>

diff --git a/cg-clean b/cg-clean
index ea00d2b..f7b5151 100755
--- a/cg-clean
+++ b/cg-clean
@@ -53,16 +53,12 @@ clean_dirs()
 	git-ls-files --cached |
 		sed -n 's|^'"$_git_relpath"'||p' |
 		sed -n 's|/[^/]*$||p' |
-		while IFS='/' read -a dir; do
-			i=0
-			while test $i != ${#dir[@]}; do
-				j=0
-				while test $i != $j; do
-					echo -n ${dir[$j]}/
-					j=$[$j+1]
-				done
-				echo ${dir[$i]}
-				i=$[$i+1]
+		while read dir; do
+			while true; do
+				echo "$dir"
+				updir="${dir%/*}"
+				test "$dir" = "$updir" && break
+				dir="$updir"
 			done
 		done |
 		sort -u >"$dirlist"


-- 
Regards,
Pavel Roskin

^ permalink raw reply related

* [PATCH 0/8] fetch-pack/upload-pack enhancements
From: Johannes Schindelin @ 2005-10-28  2:45 UTC (permalink / raw)
  To: git, junkio


This time, I not only tested things more thoroughly, but included two 
tests enabling you to verify yourself that it's less buggy this time. (I 
actually have a more extensive test which I used, but it is just too big 
for occasional regression testing).

The most important change is probably "Make maximal use of the remote 
refs" which is based on Junio's proposal, and actually makes a big, big 
difference.

Nevertheless, I would like to see the multi_ack extension go into master, 
since it is Just The Right Thing (famous last Capitalized words).

A few of these patches depend on others:

1 - 2 - 3 - 4
  \
6 - 8
  \
    7

5

Thank you for your time & Ciao,
Dscho

^ permalink raw reply

* Subject: [PATCH] git-fetch-pack: Do not use git-rev-list
From: Johannes Schindelin @ 2005-10-28  2:46 UTC (permalink / raw)
  To: git, junkio


The code used to call git-rev-list to enumerate the local revisions.
A disadvantage of that method was that git-rev-list, lacking a
control apart from the command line, would happily enumerate
ancestors of acknowledged common commits, which was just taking
unnecessary bandwidth.

Therefore, do not use git-rev-list on the fetching side, but rather
construct the list on the go. Send the revisions starting from the
local heads, ignoring the revisions known to be common.

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

---

 fetch-pack.c |  164 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 132 insertions(+), 32 deletions(-)

applies-to: 196fedc0bea0ee34dc3f807bb444cfcf5fb947dc
bdee3e007e604b3ca00e48f9c8378533c1a0d7af
diff --git a/fetch-pack.c b/fetch-pack.c
index 8566ab1..3be77c3 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -13,18 +13,130 @@ static const char fetch_pack_usage[] =
 static const char *exec = "git-upload-pack";
 
 #define COMPLETE	(1U << 0)
+#define COMMON		(1U << 1)
+#define COMMON_REF	(1U << 2)
+#define SEEN		(1U << 3)
+#define POPPED		(1U << 4)
+
+static struct commit_list *rev_list = NULL;
+static int non_common_revs = 0;
+
+static void rev_list_push(struct commit *commit, int mark)
+{
+	if (!(commit->object.flags & mark)) {
+		commit->object.flags |= mark;
+
+		if (!(commit->object.parsed))
+			parse_commit(commit);
+
+		insert_by_date(commit, &rev_list);
+
+		if (!(commit->object.flags & COMMON))
+			non_common_revs++;
+	}
+}
+
+static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
+{
+	struct object *o = deref_tag(parse_object(sha1));
+
+	if (o->type == commit_type)
+		rev_list_push((struct commit *)o, SEEN);
+
+	return 0;
+}
+
+/*
+   This function marks a rev and its ancestors as common.
+   In some cases, it is desirable to mark only the ancestors (for example
+   when only the server does not yet know that they are common).
+*/
+
+static void mark_common(struct commit *commit,
+		int ancestors_only, int dont_parse)
+{
+	if (commit != NULL && !(commit->object.flags & COMMON)) {
+		struct object *o = (struct object *)commit;
+
+		if (!ancestors_only)
+			o->flags |= COMMON;
+
+		if (!(o->flags & SEEN))
+			rev_list_push(commit, SEEN);
+		else {
+			struct commit_list *parents;
+
+			if (!ancestors_only && !(o->flags & POPPED))
+				non_common_revs--;
+			if (!o->parsed && !dont_parse)
+				parse_commit(commit);
+
+			for (parents = commit->parents;
+					parents;
+					parents = parents->next)
+				mark_common(parents->item, 0, dont_parse);
+		}
+	}
+}
+
+/*
+  Get the next rev to send, ignoring the common.
+*/
+
+static const unsigned char* get_rev()
+{
+	struct commit *commit = NULL;
+
+	while (commit == NULL) {
+		unsigned int mark;
+		struct commit_list* parents;
+
+		if (rev_list == NULL || non_common_revs == 0)
+			return NULL;
+
+		commit = rev_list->item;
+		if (!(commit->object.parsed))
+			parse_commit(commit);
+		commit->object.flags |= POPPED;
+		if (!(commit->object.flags & COMMON))
+			non_common_revs--;
+	
+		parents = commit->parents;
+
+		if (commit->object.flags & COMMON) {
+			/* do not send "have", and ignore ancestors */
+			commit = NULL;
+			mark = COMMON | SEEN;
+		} else if (commit->object.flags & COMMON_REF)
+			/* send "have", and ignore ancestors */
+			mark = COMMON | SEEN;
+		else
+			/* send "have", also for its ancestors */
+			mark = SEEN;
+
+		while (parents) {
+			if (!(parents->item->object.flags & SEEN))
+				rev_list_push(parents->item, mark);
+			if (mark & COMMON)
+				mark_common(parents->item, 1, 0);
+			parents = parents->next;
+		}
+
+		rev_list = rev_list->next;
+	}
+
+	return commit->object.sha1;
+}
 
 static int find_common(int fd[2], unsigned char *result_sha1,
 		       struct ref *refs)
 {
 	int fetching;
-	static char line[1000];
-	static char rev_command[1024];
-	int count = 0, flushes = 0, retval, rev_command_len;
-	FILE *revs;
+	int count = 0, flushes = 0, retval;
+	const unsigned char *sha1;
+
+	for_each_ref(rev_list_insert_ref);
 
-	strcpy(rev_command, "git-rev-list $(git-rev-parse --all)");
-	rev_command_len = strlen(rev_command);
 	fetching = 0;
 	for ( ; refs ; refs = refs->next) {
 		unsigned char *remote = refs->old_sha1;
@@ -42,25 +154,18 @@ static int find_common(int fd[2], unsign
 		 */
 		if (((o = lookup_object(remote)) != NULL) &&
 		    (o->flags & COMPLETE)) {
-			struct commit_list *p;
-			struct commit *commit =
-				(struct commit *) (o = deref_tag(o));
-			if (!o)
-				goto repair;
-			if (o->type != commit_type)
-				continue;
-			p = commit->parents;
-			while (p &&
-			       rev_command_len + 44 < sizeof(rev_command)) {
-				snprintf(rev_command + rev_command_len, 44,
-					 " ^%s",
-					 sha1_to_hex(p->item->object.sha1));
-				rev_command_len += 43;
-				p = p->next;
+			o = deref_tag(o);
+
+			if (o->type == commit_type) {
+				struct commit *commit = (struct commit *)o;
+
+				rev_list_push(commit, COMMON_REF | SEEN);
+
+				mark_common(commit, 1, 1);
 			}
 			continue;
 		}
-	repair:
+
 		packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
 		fetching++;
 	}
@@ -68,16 +173,9 @@ static int find_common(int fd[2], unsign
 	if (!fetching)
 		return 1;
 
-	revs = popen(rev_command, "r");
-	if (!revs)
-		die("unable to run 'git-rev-list'");
-
-	flushes = 1;
+	flushes = 0;
 	retval = -1;
-	while (fgets(line, sizeof(line), revs) != NULL) {
-		unsigned char sha1[20];
-		if (get_sha1_hex(line, sha1))
-			die("git-fetch-pack: expected object name, got crud");
+	while ((sha1 = get_rev())) {
 		packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
 		if (verbose)
 			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
@@ -101,10 +199,12 @@ static int find_common(int fd[2], unsign
 			flushes--;
 		}
 	}
-	pclose(revs);
+
 	packet_write(fd[1], "done\n");
 	if (verbose)
 		fprintf(stderr, "done\n");
+	if (retval != 0)
+		flushes++;
 	while (flushes) {
 		flushes--;
 		if (get_ack(fd[0], result_sha1)) {
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 2/8] Make maximal use of the remote refs
From: Johannes Schindelin @ 2005-10-28  2:47 UTC (permalink / raw)
  To: git, junkio


When git-fetch-pack gets the remote refs, it does not need to filter them
right away, but it can see which refs are common (taking advantage of the
patch which makes git-fetch-pack not use git-rev-list).

This means that we ask get_remote_heads() to return all remote refs,
including the funny refs, and filtering them with a separate function later.

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

---

 fetch-pack.c |   72 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 52 insertions(+), 20 deletions(-)

applies-to: 828f6fc88faefd10f2b09b11a2758afde21049c7
c3c4f518f0174292917d01734f58a57b6eb9871e
diff --git a/fetch-pack.c b/fetch-pack.c
index 3be77c3..b584264 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -153,16 +153,7 @@ static int find_common(int fd[2], unsign
 		 * reachable and we have already scanned it.
 		 */
 		if (((o = lookup_object(remote)) != NULL) &&
-		    (o->flags & COMPLETE)) {
-			o = deref_tag(o);
-
-			if (o->type == commit_type) {
-				struct commit *commit = (struct commit *)o;
-
-				rev_list_push(commit, COMMON_REF | SEEN);
-
-				mark_common(commit, 1, 1);
-			}
+				(o->flags & COMPLETE)) {
 			continue;
 		}
 
@@ -247,7 +238,29 @@ static void mark_recent_complete_commits
 	}
 }
 
-static int everything_local(struct ref *refs)
+static void filter_refs(struct ref **refs, int nr_match, char **match)
+{
+	struct ref *prev, *current, *next;
+
+	if (!nr_match)
+		return;
+
+	for (prev = NULL, current = *refs; current; current = next) {
+		next = current->next;
+		if ((!memcmp(current->name, "refs/", 5) &&
+					check_ref_format(current->name + 5)) ||
+				!path_match(current->name, nr_match, match)) {
+			if (prev == NULL)
+				*refs = next;
+			else
+				prev->next = next;
+			free(current);
+		} else
+			prev = current;
+	}
+}
+
+static int everything_local(struct ref **refs, int nr_match, char **match)
 {
 	struct ref *ref;
 	int retval;
@@ -256,7 +269,7 @@ static int everything_local(struct ref *
 	track_object_refs = 0;
 	save_commit_buffer = 0;
 
-	for (ref = refs; ref; ref = ref->next) {
+	for (ref = *refs; ref; ref = ref->next) {
 		struct object *o;
 
 		o = parse_object(ref->old_sha1);
@@ -278,28 +291,47 @@ static int everything_local(struct ref *
 	if (cutoff)
 		mark_recent_complete_commits(cutoff);
 
-	for (retval = 1; refs ; refs = refs->next) {
-		const unsigned char *remote = refs->old_sha1;
+	/*
+	 * Mark all complete remote refs as common refs.
+	 * Don't mark them common yet; the server has to be told so first.
+	 */
+	for (ref = *refs; ref; ref = ref->next) {
+		struct object *o = deref_tag(lookup_object(ref->old_sha1));
+
+		if (!o || o->type != commit_type || !(o->flags & COMPLETE))
+			continue;
+
+		if (!(o->flags & SEEN)) {
+			rev_list_push((struct commit *)o, COMMON_REF | SEEN);
+
+			mark_common((struct commit *)o, 1, 1);
+		}
+	}
+
+	filter_refs(refs, nr_match, match);
+
+	for (retval = 1, ref = *refs; ref ; ref = ref->next) {
+		const unsigned char *remote = ref->old_sha1;
 		unsigned char local[20];
 		struct object *o;
 
-		o = parse_object(remote);
+		o = lookup_object(remote);
 		if (!o || !(o->flags & COMPLETE)) {
 			retval = 0;
 			if (!verbose)
 				continue;
 			fprintf(stderr,
 				"want %s (%s)\n", sha1_to_hex(remote),
-				refs->name);
+				ref->name);
 			continue;
 		}
 
-		memcpy(refs->new_sha1, local, 20);
+		memcpy(ref->new_sha1, local, 20);
 		if (!verbose)
 			continue;
 		fprintf(stderr,
 			"already have %s (%s)\n", sha1_to_hex(remote),
-			refs->name);
+			ref->name);
 	}
 	return retval;
 }
@@ -311,12 +343,12 @@ static int fetch_pack(int fd[2], int nr_
 	int status;
 	pid_t pid;
 
-	get_remote_heads(fd[0], &ref, nr_match, match, 1);
+	get_remote_heads(fd[0], &ref, 0, NULL, 0);
 	if (!ref) {
 		packet_flush(fd[1]);
 		die("no matching remote head");
 	}
-	if (everything_local(ref)) {
+	if (everything_local(&ref, nr_match, match)) {
 		packet_flush(fd[1]);
 		goto all_done;
 	}
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 3/8] Implement a test for git-fetch-pack/git-upload-pack
From: Johannes Schindelin @ 2005-10-28  2:47 UTC (permalink / raw)
  To: git, junkio


This test provides a minimal example of what went wrong with the old
git-fetch-pack (and now works beautifully).

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

---

 t/t5500-fetch-pack.sh |  136 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 136 insertions(+), 0 deletions(-)
 create mode 100644 t/t5500-fetch-pack.sh

applies-to: 641053c478870febdf3b6c525821f1bfdc43a2a5
1dfccc68d5700ea5c0f062aaf77fdf76a9c06a5e
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
new file mode 100644
index 0000000..0781bd2
--- /dev/null
+++ b/t/t5500-fetch-pack.sh
@@ -0,0 +1,136 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Johannes Schindelin
+#
+
+test_description='Testing multi_ack pack fetching
+
+'
+. ./test-lib.sh
+
+# Test fetch-pack/upload-pack pair.
+
+# Some convenience functions
+
+function show_count () {
+	commit_count=$(($commit_count+1))
+	printf "      %d\r" $commit_count
+}
+
+function add () {
+	local name=$1
+	local text="$@"
+	local branch=${name:0:1}
+	local parents=""
+
+	shift
+	while test $1; do
+		parents="$parents -p $1"
+		shift
+	done
+
+	echo "$text" > test.txt
+	git-update-index --add test.txt
+	tree=$(git-write-tree)
+	# make sure timestamps are in correct order
+	sec=$(($sec+1))
+	commit=$(echo "$text" | GIT_AUTHOR_DATE=$sec \
+		git-commit-tree $tree $parents 2>>log2.txt)
+	export $name=$commit
+	echo $commit > .git/refs/heads/$branch
+	eval ${branch}TIP=$commit
+}
+
+function count_objects () {
+	ls .git/objects/??/* 2>>log2.txt | wc -l | tr -d " "
+}
+
+function test_expect_object_count () {
+	local message=$1
+	local count=$2
+
+	output="$(count_objects)"
+	test_expect_success \
+		"new object count $message" \
+		"test $count = $output"
+}
+
+function test_repack () {
+	local rep=$1
+
+	test_expect_success "repack && prune-packed in $rep" \
+		'(git-repack && git-prune-packed)2>>log.txt'
+}
+
+function pull_to_client () {
+	local number=$1
+	local heads=$2
+	local count=$3
+	local no_strict_count_check=$4
+
+	cd client
+	test_expect_success "$number pull" \
+		"git-fetch-pack -v .. $heads > log.txt 2>&1"
+	case "$heads" in *A*) echo $ATIP > .git/refs/heads/A;; esac
+	case "$heads" in *B*) echo $BTIP > .git/refs/heads/B;; esac
+	git-symbolic-ref HEAD refs/heads/${heads:0:1}
+	test_expect_success "fsck" 'git-fsck-objects --full > fsck.txt 2>&1'
+	test_expect_object_count "after $number pull" $count
+	pack_count=$(grep Packing log.txt|tr -dc "0-9")
+	test -z "$pack_count" && pack_count=0
+	if [ -z "$no_strict_count_check" ]; then
+		test_expect_success "minimal count" "test $count = $pack_count"
+	else
+		test $count != $pack_count && \
+			echo "WARNING: $pack_count objects transmitted, only $count of which were needed"
+	fi
+	cd ..
+}
+
+# Here begins the actual testing
+
+# A1 - ... - A20 - A21
+#    \
+#      B1  -   B2 - .. - B70
+
+# client pulls A20, B1. Then tracks only B. Then pulls A.
+
+(
+	mkdir client &&
+	cd client &&
+	git-init-db 2>> log2.txt
+)
+
+add A1
+
+prev=1; cur=2; while [ $cur -le 10 ]; do
+	add A$cur $(eval echo \$A$prev)
+	prev=$cur
+	cur=$(($cur+1))
+done
+
+add B1 $A1
+
+echo $ATIP > .git/refs/heads/A
+echo $BTIP > .git/refs/heads/B
+git-symbolic-ref HEAD refs/heads/B
+
+pull_to_client 1st "B A" $((11*3))
+
+(cd client; test_repack client)
+
+add A11 $A10
+
+prev=1; cur=2; while [ $cur -le 65 ]; do
+	add B$cur $(eval echo \$B$prev)
+	prev=$cur
+	cur=$(($cur+1))
+done
+
+pull_to_client 2nd "B" $((64*3))
+
+(cd client; test_repack client)
+
+pull_to_client 3rd "A" $((1*3)) # old fails
+
+test_done
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 4/8] Implement an interoperability test for fetch-pack/upload-pack
From: Johannes Schindelin @ 2005-10-28  2:48 UTC (permalink / raw)
  To: git, junkio


The next patches will extend the pack protocol. This test assures that this
extension is compatible to earlier versions of git-fetch-pack/git-upload-pack.

All you need to do to take advantage of this test, is to install older
known-to-be-working binaries in the path as "old-git-fetch-pack" and
"old-git-upload-pack".

Note that the warning when testing with old-git-fetch-pack is to be
expected (it just says that the old version was not taking advantage
of all the information which the server sent).

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

---

 t/t5501-old-fetch-and-upload.sh |   43 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 43 insertions(+), 0 deletions(-)
 create mode 100755 t/t5501-old-fetch-and-upload.sh

applies-to: 4286a14deeaa64cf1d00fc5f7cb197e91f230ab9
0bae675fd1eb4ec33834a6c8d0b6bbc88adc30da
diff --git a/t/t5501-old-fetch-and-upload.sh b/t/t5501-old-fetch-and-upload.sh
new file mode 100755
index 0000000..86df785
--- /dev/null
+++ b/t/t5501-old-fetch-and-upload.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Johannes Schindelin
+#
+
+# Test that the current fetch-pack/upload-pack plays nicely with
+# an old counterpart
+
+cd $(dirname $0) || exit 1
+
+tmp=$(mktemp tmp-XXXX)
+
+retval=0
+
+if [ -z "$1" ]; then
+	list="fetch upload"
+else
+	list="$@"
+fi
+
+for i in $list; do
+	case "$i" in
+	fetch) pgm="old-git-fetch-pack"; replace="$pgm";;
+	upload) pgm="old-git-upload-pack"; replace="git-fetch-pack --exec=$pgm";;
+	both) pgm="old-git-upload-pack"; replace="old-git-fetch-pack --exec=$pgm";;
+	esac
+
+	if which $pgm; then
+		echo "Testing with $pgm"
+		sed -e "s/git-fetch-pack/$replace/g" \
+			-e "s/# old fails/warn/" < t5500-fetch-pack.sh > $tmp
+
+		sh $tmp || retval=$?
+		rm $tmp
+
+		test $retval != 0 && exit $retval
+	else
+		echo "Skipping test for $i, since I cannot find $pgm"
+	fi
+done
+
+exit 0
+
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 5/8] git-upload-pack: More efficient usage of the has_sha1 array
From: Johannes Schindelin @ 2005-10-28  2:48 UTC (permalink / raw)
  To: git, junkio


This patch is based on Junio's proposal. It marks parents of common revs
so that they do not clutter up the has_sha1 array.

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

---

 upload-pack.c |   27 ++++++++++++++++++++++-----
 1 files changed, 22 insertions(+), 5 deletions(-)

applies-to: fe38f9ff9bd88b9a98346d4a256416f29fdb3892
11905ac9b1eea9ac1dca5eae542b15fa28ec3242
diff --git a/upload-pack.c b/upload-pack.c
index 878254d..660d7c4 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -3,9 +3,11 @@
 #include "pkt-line.h"
 #include "tag.h"
 #include "object.h"
+#include "commit.h"
 
 static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
 
+#define THEY_HAVE (1U << 0)
 #define OUR_REF (1U << 1)
 #define WANTED (1U << 2)
 #define MAX_HAS 256
@@ -89,15 +91,27 @@ static void create_pack_file(void)
 
 static int got_sha1(char *hex, unsigned char *sha1)
 {
-	int nr;
 	if (get_sha1_hex(hex, sha1))
 		die("git-upload-pack: expected SHA1 object, got '%s'", hex);
 	if (!has_sha1_file(sha1))
 		return 0;
-	nr = nr_has;
-	if (nr < MAX_HAS) {
-		memcpy(has_sha1[nr], sha1, 20);
-		nr_has = nr+1;
+	if (nr_has < MAX_HAS) {
+		struct object *o = lookup_object(sha1);
+		if (!(o && o->parsed))
+			o = parse_object(sha1);
+		if (!o)
+			die("oops (%s)", sha1_to_hex(sha1));
+		if (o->type == commit_type) {
+			struct commit_list *parents;
+			if (o->flags & THEY_HAVE)
+				return 0;
+			o->flags |= THEY_HAVE;
+			for (parents = ((struct commit*)o)->parents;
+			     parents;
+			     parents = parents->next)
+				parents->item->object.flags |= THEY_HAVE;
+		}
+		memcpy(has_sha1[nr_has++], sha1, 20);
 	}
 	return 1;
 }
@@ -108,6 +122,9 @@ static int get_common_commits(void)
 	unsigned char sha1[20];
 	int len;
 
+	track_object_refs = 0;
+	save_commit_buffer = 0;
+
 	for(;;) {
 		len = packet_read_line(0, line, sizeof(line));
 		reset_timeout();
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 6/8] Support receiving server capabilities
From: Johannes Schindelin @ 2005-10-28  2:48 UTC (permalink / raw)
  To: git, junkio


On Thu, 27 Oct 2005, Sergey Vlasov wrote:

> Actually, there is another way to pass some data from the server
> which would be ignored by older clients - at the first stage,
> when upload-pack sends the list of refs to the client:
>
>       packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname, '\0',
>                    server_capabilities);

This patch implements the client side of it. server_capabilities is supposed
to be a string containing space separated features of the server.

After get_remote_heads(), check if the server supports the feature like

	if (server_supports("multi_ack"))
		do_something();

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

---

 cache.h   |    1 +
 connect.c |   16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletions(-)

applies-to: 755b5d7a6bb3861a284381a8adb26c2241217355
883ea2e2bf664c78a7bee5b29ad9584339085310
diff --git a/cache.h b/cache.h
index 2e36cc5..677c6ac 100644
--- a/cache.h
+++ b/cache.h
@@ -340,6 +340,7 @@ extern int match_refs(struct ref *src, s
 		      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, int ignore_funny);
+extern int server_supports(const char *feature);
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1);
 extern struct packed_git *parse_pack_index_file(const unsigned char *sha1,
diff --git a/connect.c b/connect.c
index b171c5d..5cc49f9 100644
--- a/connect.c
+++ b/connect.c
@@ -8,6 +8,8 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
+static char *server_capabilities = "";
+
 /*
  * Read all the refs from the other end
  */
@@ -20,7 +22,7 @@ struct ref **get_remote_heads(int in, st
 		unsigned char old_sha1[20];
 		static char buffer[1000];
 		char *name;
-		int len;
+		int len, name_len;
 
 		len = packet_read_line(in, buffer, sizeof(buffer));
 		if (!len)
@@ -36,6 +38,13 @@ struct ref **get_remote_heads(int in, st
 		    check_ref_format(name + 5))
 			continue;
 
+		name_len = strlen(name);
+		if (len != name_len + 41) {
+			if (server_capabilities)
+				free(server_capabilities);
+			server_capabilities = strdup(name + name_len + 1);
+		}
+
 		if (nr_match && !path_match(name, nr_match, match))
 			continue;
 		ref = xcalloc(1, sizeof(*ref) + len - 40);
@@ -47,6 +56,11 @@ struct ref **get_remote_heads(int in, st
 	return list;
 }
 
+int server_supports(const char *feature)
+{
+	return strstr(feature, server_capabilities) != NULL;
+}
+
 int get_ack(int fd, unsigned char *result_sha1)
 {
 	static char line[1000];
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 7/8] git-upload-pack: Support the multi_ack protocol
From: Johannes Schindelin @ 2005-10-28  2:49 UTC (permalink / raw)
  To: git, junkio


This implements three things (trying very hard to be backwards
compatible):

It sends the "multi_ack" capability via the mechanism proposed by
Sergey Vlasov.

When the client sends "multi_ack" with at least one "want", multi_ack
is enabled.

When multi_ack is enabled, "continue" is appended to each "ACK" until
either the server can not store more refs, or "done" is received.

In contrast to the original protocol, as long as "continue" is sent,
flushes are answered by a "NAK" (not just until an "ACK" was sent),
and if "continue" was sent at least once, the last message is an
"ACK" without "continue".

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

---

 upload-pack.c |   47 ++++++++++++++++++++++++-----------------------
 1 files changed, 24 insertions(+), 23 deletions(-)

applies-to: 4a808fae0b12e633b13bc0e76ec31ee19eecb21b
42affc8d8fa1ed7e7d95fd7385d118cc57a0c420
diff --git a/upload-pack.c b/upload-pack.c
index 660d7c4..686445e 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -12,7 +12,7 @@ static const char upload_pack_usage[] = 
 #define WANTED (1U << 2)
 #define MAX_HAS 256
 #define MAX_NEEDS 256
-static int nr_has = 0, nr_needs = 0, nr_our_refs = 0;
+static int nr_has = 0, nr_needs = 0, multi_ack = 0, nr_our_refs = 0;
 static unsigned char has_sha1[MAX_HAS][20];
 static unsigned char needs_sha1[MAX_NEEDS][20];
 static unsigned int timeout = 0;
@@ -119,7 +119,7 @@ static int got_sha1(char *hex, unsigned 
 static int get_common_commits(void)
 {
 	static char line[1000];
-	unsigned char sha1[20];
+	unsigned char sha1[20], last_sha1[20];
 	int len;
 
 	track_object_refs = 0;
@@ -130,39 +130,36 @@ static int get_common_commits(void)
 		reset_timeout();
 
 		if (!len) {
-			packet_write(1, "NAK\n");
+			if (nr_has == 0 || multi_ack)
+				packet_write(1, "NAK\n");
 			continue;
 		}
 		len = strip(line, len);
 		if (!strncmp(line, "have ", 5)) {
-			if (got_sha1(line+5, sha1)) {
-				packet_write(1, "ACK %s\n", sha1_to_hex(sha1));
-				break;
+			if (got_sha1(line+5, sha1) &&
+					(multi_ack || nr_has == 1)) {
+				if (nr_has >= MAX_HAS)
+					multi_ack = 0;
+				packet_write(1, "ACK %s%s\n",
+					sha1_to_hex(sha1),
+					multi_ack ?  " continue" : "");
+				if (multi_ack)
+					memcpy(last_sha1, sha1, 20);
 			}
 			continue;
 		}
 		if (!strcmp(line, "done")) {
+			if (nr_has > 0) {
+				if (multi_ack)
+					packet_write(1, "ACK %s\n",
+							sha1_to_hex(last_sha1));
+				return 0;
+			}
 			packet_write(1, "NAK\n");
 			return -1;
 		}
 		die("git-upload-pack: expected SHA1 list, got '%s'", line);
 	}
-
-	for (;;) {
-		len = packet_read_line(0, line, sizeof(line));
-		reset_timeout();
-		if (!len)
-			continue;
-		len = strip(line, len);
-		if (!strncmp(line, "have ", 5)) {
-			got_sha1(line+5, sha1);
-			continue;
-		}
-		if (!strcmp(line, "done"))
-			break;
-		die("git-upload-pack: expected SHA1 list, got '%s'", line);
-	}
-	return 0;
 }
 
 static int receive_needs(void)
@@ -192,6 +189,8 @@ static int receive_needs(void)
 		if (strncmp("want ", line, 5) || get_sha1_hex(line+5, sha1_buf))
 			die("git-upload-pack: protocol error, "
 			    "expected to get sha, not '%s'", line);
+		if (strstr(line+45, "multi_ack"))
+			multi_ack = 1;
 
 		/* We have sent all our refs already, and the other end
 		 * should have chosen out of them; otherwise they are
@@ -213,9 +212,11 @@ static int receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
+	static char *capabilities = "\0multi_ack";
 	struct object *o = parse_object(sha1);
 
-	packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
+	packet_write(1, "%s %s%s\n", sha1_to_hex(sha1), refname, capabilities);
+	capabilities = "";
 	if (!(o->flags & OUR_REF)) {
 		o->flags |= OUR_REF;
 		nr_our_refs++;
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH 8/8] git-fetch-pack: Support multi_ack extension
From: Johannes Schindelin @ 2005-10-28  2:50 UTC (permalink / raw)
  To: git, junkio


The client side support for multi_ack.

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

---

	So yes, I forgot to rewrite the "Subject: [PATCH]" of the first 
	patch of this series. Please be gentle, I am going to bed now.

 connect.c    |    5 ++++-
 fetch-pack.c |   58 ++++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 46 insertions(+), 17 deletions(-)

applies-to: e91233a8f0446016384e8f2c8faafc9c129b95d3
b851d9a0cad95cedc6082e6de00c25d9588519e7
diff --git a/connect.c b/connect.c
index 5cc49f9..b8aea35 100644
--- a/connect.c
+++ b/connect.c
@@ -73,8 +73,11 @@ int get_ack(int fd, unsigned char *resul
 	if (!strcmp(line, "NAK"))
 		return 0;
 	if (!strncmp(line, "ACK ", 3)) {
-		if (!get_sha1_hex(line+4, result_sha1))
+		if (!get_sha1_hex(line+4, result_sha1)) {
+			if (strstr(line+45, "continue"))
+				return 2;
 			return 1;
+		}
 	}
 	die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
 }
diff --git a/fetch-pack.c b/fetch-pack.c
index b584264..3df9911 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -19,7 +19,7 @@ static const char *exec = "git-upload-pa
 #define POPPED		(1U << 4)
 
 static struct commit_list *rev_list = NULL;
-static int non_common_revs = 0;
+static int non_common_revs = 0, multi_ack = 0;
 
 static void rev_list_push(struct commit *commit, int mark)
 {
@@ -157,7 +157,8 @@ static int find_common(int fd[2], unsign
 			continue;
 		}
 
-		packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
+		packet_write(fd[1], "want %s%s\n", sha1_to_hex(remote),
+			multi_ack ? " multi_ack" : "");
 		fetching++;
 	}
 	packet_flush(fd[1]);
@@ -171,6 +172,8 @@ static int find_common(int fd[2], unsign
 		if (verbose)
 			fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
 		if (!(31 & ++count)) {
+			int ack;
+
 			packet_flush(fd[1]);
 			flushes++;
 
@@ -180,29 +183,47 @@ static int find_common(int fd[2], unsign
 			 */
 			if (count == 32)
 				continue;
-			if (get_ack(fd[0], result_sha1)) {
-				flushes = 0;
-				retval = 0;
-				if (verbose)
-					fprintf(stderr, "got ack\n");
-				break;
-			}
+
+			do {
+				ack = get_ack(fd[0], result_sha1);
+				if (verbose && ack)
+					fprintf(stderr, "got ack %d %s\n", ack,
+							sha1_to_hex(result_sha1));
+				if (ack == 1) {
+					flushes = 0;
+					multi_ack = 0;
+					retval = 0;
+					goto done;
+				} else if (ack == 2) {
+					struct commit *commit =
+						lookup_commit(result_sha1);
+					mark_common(commit, 0, 1);
+					retval = 0;
+				}
+			} while (ack);
 			flushes--;
 		}
 	}
-
+done:
 	packet_write(fd[1], "done\n");
 	if (verbose)
 		fprintf(stderr, "done\n");
-	if (retval != 0)
+	if (retval != 0) {
+		multi_ack = 0;
 		flushes++;
-	while (flushes) {
-		flushes--;
-		if (get_ack(fd[0], result_sha1)) {
+	}
+	while (flushes || multi_ack) {
+		int ack = get_ack(fd[0], result_sha1);
+		if (ack) {
 			if (verbose)
-				fprintf(stderr, "got ack\n");
-			return 0;
+				fprintf(stderr, "got ack (%d) %s\n", ack,
+					sha1_to_hex(result_sha1));
+			if (ack == 1)
+				return 0;
+			multi_ack = 1;
+			continue;
 		}
+		flushes--;
 	}
 	return retval;
 }
@@ -344,6 +365,11 @@ static int fetch_pack(int fd[2], int nr_
 	pid_t pid;
 
 	get_remote_heads(fd[0], &ref, 0, NULL, 0);
+	if (server_supports("multi_ack")) {
+		if (verbose)
+			fprintf(stderr, "Server supports multi_ack\n");
+		multi_ack = 1;
+	}
 	if (!ref) {
 		packet_flush(fd[1]);
 		die("no matching remote head");
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH] fix testsuite to tolerate spaces in path
From: Pavel Roskin @ 2005-10-28  3:00 UTC (permalink / raw)
  To: git

This patch allows the testsuite to run properly when the full path to
the git sources contains spaces or other symbols that need to be quoted.

Signed-off-by: Pavel Roskin <proski@gnu.org>

diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 96db98b..5b50536 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -49,7 +49,7 @@ test_expect_success \
      git-unpack-objects <test-1-${packname_1}.pack"
 
 unset GIT_OBJECT_DIRECTORY
-cd $TRASH/.git2
+cd "$TRASH/.git2"
 
 test_expect_success \
     'check unpack without delta' \
@@ -61,7 +61,7 @@ test_expect_success \
 	     return 1
 	 }
      done'
-cd $TRASH
+cd "$TRASH"
 
 test_expect_success \
     'pack with delta' \
@@ -80,7 +80,7 @@ test_expect_success \
      git-unpack-objects <test-2-${packname_2}.pack'
 
 unset GIT_OBJECT_DIRECTORY
-cd $TRASH/.git2
+cd "$TRASH/.git2"
 test_expect_success \
     'check unpack with delta' \
     '(cd ../.git && find objects -type f -print) |
@@ -91,7 +91,7 @@ test_expect_success \
 	     return 1
 	 }
      done'
-cd $TRASH
+cd "$TRASH"
 
 rm -fr .git2
 mkdir .git2


-- 
Regards,
Pavel Roskin

^ permalink raw reply related

* Re: [PATCH] Avoid using dc in git-count-objects
From: Herbert Xu @ 2005-10-28  3:20 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: smurf, git
In-Reply-To: <Pine.LNX.4.64.0510270801560.4664@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> wrote:
> 
> Oh - there's another similarity between $(..) and $((..)). They're both 
> POSIX 1003.2 standard features, so any "modern" shell should support them. 
> Although in practice I don't know if that means anything else than ksh 
> (where both syntaxes came from, actually).

There is also dash (http://gondor.apana.org.au/~herbert/dash/).
It complies with POSIX, is less than half the size of pdksh (83960 bytes
currently on i386), and is faster than pdksh.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH 8/8] git-fetch-pack: Support multi_ack extension
From: Johannes Schindelin @ 2005-10-28  3:36 UTC (permalink / raw)
  To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0510280449240.20516@wbgn013.biozentrum.uni-wuerzburg.de>

Hi,

never mind patch 7 and 8. I succeeded in fscking up again. Will patch 
tomorrow.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH gitweb] Visually indicating patch size with horizontal bars
From: Junio C Hamano @ 2005-10-28  3:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Martin Langhoff, Chris Shoemaker, git
In-Reply-To: <Pine.LNX.4.64.0510271933140.4664@g5.osdl.org>

Linus Torvalds <torvalds@osdl.org> writes:

> Well, if you do full copy detection (and break detection), then 
> git-diff-tree will actually have effectively calculated the size of the 
> diff of each file. It just doesn't print them (well, it does a percentage 
> for the renames/copies).

Unbroken in-place edit would never go through diffcore-rename,
so that is a gross overstatement.

But we could if we wanted to.  I do not know how useful it would
be, but if somebody wants to do it, I think the best strategy is
to do as a separate diffcore backend that comes after
diffcore_rename() runs, and do the similarity estimator only on
filepairs that rename/copy did not touch.

^ permalink raw reply

* [PATCH] fix multi_ack, was Re: [PATCH 8/8] git-fetch-pack: Support multi_ack extension
From: Johannes Schindelin @ 2005-10-28  3:56 UTC (permalink / raw)
  To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0510280535480.1460@wbgn013.biozentrum.uni-wuerzburg.de>


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

	I was already half asleep when I realized that

		printf("%s", "\0multi_ack");

	could not work. All the more astounding, that my tests
	said that the server has multi_ack capability. But that
	was my mixing up arguments to strstr().

	Aargh.

	On Fri, 28 Oct 2005, Johannes Schindelin wrote:

	> never mind patch 7 and 8. I succeeded in fscking up again.
	> Will patch tomorrow.

	Well, I could not sleep with such silly a bug.

 connect.c     |    5 +++--
 upload-pack.c |   10 +++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

applies-to: c45879487343238adc4e926abf0e6280a3f4291c
2c3e9bb8ab663976132315c970c0feea5176fb81
diff --git a/connect.c b/connect.c
index b8aea35..c2badc7 100644
--- a/connect.c
+++ b/connect.c
@@ -8,7 +8,7 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 
-static char *server_capabilities = "";
+static char *server_capabilities = NULL;
 
 /*
  * Read all the refs from the other end
@@ -58,7 +58,8 @@ struct ref **get_remote_heads(int in, st
 
 int server_supports(const char *feature)
 {
-	return strstr(feature, server_capabilities) != NULL;
+	return server_capabilities &&
+		strstr(server_capabilities, feature) != NULL;
 }
 
 int get_ack(int fd, unsigned char *result_sha1)
diff --git a/upload-pack.c b/upload-pack.c
index 686445e..c5eff21 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -212,11 +212,15 @@ static int receive_needs(void)
 
 static int send_ref(const char *refname, const unsigned char *sha1)
 {
-	static char *capabilities = "\0multi_ack";
+	static char *capabilities = "multi_ack";
 	struct object *o = parse_object(sha1);
 
-	packet_write(1, "%s %s%s\n", sha1_to_hex(sha1), refname, capabilities);
-	capabilities = "";
+	if (capabilities)
+		packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
+			0, capabilities);
+	else
+		packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
+	capabilities = NULL;
 	if (!(o->flags & OUR_REF)) {
 		o->flags |= OUR_REF;
 		nr_our_refs++;
---
0.99.8.GIT

^ permalink raw reply related

* [PATCH] make t5501 less annoying, was Re: [PATCH 4/8] Implement an interoperability test for fetch-pack/upload-pack
From: Johannes Schindelin @ 2005-10-28  3:59 UTC (permalink / raw)
  To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0510280447440.20516@wbgn013.biozentrum.uni-wuerzburg.de>


On Linux, "mktemp tmp-XXXX" will not work. Also, redirect stderr on which,
so it does not complain too loudly. After all, this test should only be
executed when old binaries are available.

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

 t/t5501-old-fetch-and-upload.sh |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: f961b5204f8ead99f2beb0b2dc9f1e662c47fd74
4462bf60f4fca1d7774f441b374943109083efd9
diff --git a/t/t5501-old-fetch-and-upload.sh b/t/t5501-old-fetch-and-upload.sh
index 86df785..ada5130 100755
--- a/t/t5501-old-fetch-and-upload.sh
+++ b/t/t5501-old-fetch-and-upload.sh
@@ -8,7 +8,7 @@
 
 cd $(dirname $0) || exit 1
 
-tmp=$(mktemp tmp-XXXX)
+tmp=$(mktemp /tmp/tmp-XXXXXXXX)
 
 retval=0
 
@@ -25,7 +25,7 @@ for i in $list; do
 	both) pgm="old-git-upload-pack"; replace="old-git-fetch-pack --exec=$pgm";;
 	esac
 
-	if which $pgm; then
+	if which $pgm 2>/dev/null; then
 		echo "Testing with $pgm"
 		sed -e "s/git-fetch-pack/$replace/g" \
 			-e "s/# old fails/warn/" < t5500-fetch-pack.sh > $tmp
---
0.99.8.GIT

^ permalink raw reply related

* Re: [PATCH] Avoid using dc in git-count-objects
From: H. Peter Anvin @ 2005-10-28  4:14 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linus Torvalds, smurf, git
In-Reply-To: <E1EVKmt-0003xn-00@gondolin.me.apana.org.au>

Herbert Xu wrote:
> Linus Torvalds <torvalds@osdl.org> wrote:
> 
>>Oh - there's another similarity between $(..) and $((..)). They're both 
>>POSIX 1003.2 standard features, so any "modern" shell should support them. 
>>Although in practice I don't know if that means anything else than ksh 
>>(where both syntaxes came from, actually).
> 
> 
> There is also dash (http://gondor.apana.org.au/~herbert/dash/).
> It complies with POSIX, is less than half the size of pdksh (83960 bytes
> currently on i386), and is faster than pdksh.

Current ash also has these features, and is about that size compiled 
static with klibc :)

	-hpa

^ 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