[PATCH] fetch-pack: start multi-head pulling.

2005-08-12 Thread Junio C Hamano
This is a beginning of resurrecting the multi-head pulling support
for git-fetch-pack command.  The git-fetch-script wrapper still
only knows about fetching a single head, without renaming, so it is
not very useful unless you directly call git-fetch-pack itself yet.

It also fixes a longstanding obsolete description of how the command
discovers the list of local commits.
---

Linus, I need a bit of guidance from you about this one; an
ancient commit 4f7770c87ce3c302e1639a7737a6d2531fe4b160 removed
the multi-head support fetch-pack once had, labelling it as a
misguided attempt, and I would like to know if I am making the
same misguided attempt again.  This update actually makes
clone-pack almost redundant.


 Documentation/git-fetch-pack.txt |   18 +---
 fetch-pack.c |   56 +++---
 git-fetch-script |4 +++
 3 files changed, 51 insertions(+), 27 deletions(-)

880df673e412bae9603782833d8a80a7c7c59769
diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt
--- a/Documentation/git-fetch-pack.txt
+++ b/Documentation/git-fetch-pack.txt
@@ -9,19 +9,19 @@ git-fetch-pack - Receive missing objects
 
 SYNOPSIS
 
-git-fetch-pack [-q] [--exec=git-upload-pack] [host:]directory 
[head...]  commit-list
+git-fetch-pack [-q] [--exec=git-upload-pack] [host:]directory [refs...]
 
 DESCRIPTION
 ---
 Invokes 'git-upload-pack' on a potentially remote repository,
 and asks it to send objects missing from this repository, to
 update the named heads.  The list of commits available locally
-is fed from the standard input, to be sent to 'git-upload-pack'
-running on the other end.
+is found out by scanning local $GIT_DIR/refs/ and sent to
+'git-upload-pack' running on the other end.
 
-This command can be used only when the local side has a common
-(ancestor) commit with the remote head that is being pulled
-from.  Use 'git-clone-pack' for that.
+This command degenerates to download everything to complete the
+asked refs from the remote side when the local side does not
+have a common ancestor commit.
 
 
 OPTIONS
@@ -50,15 +50,11 @@ OPTIONS
 directory::
The repository to sync from.
 
-head...::
+refs...::
The remote heads to update from. This is relative to
$GIT_DIR (e.g. HEAD, refs/heads/master).  When
unspecified, update from all heads the remote side has.
 
-   However the program refuses to work if more than one
-   remote head matches the specified heads.  I am not sure
-   what this means... Help!
-
 
 Author
 --
diff --git a/fetch-pack.c b/fetch-pack.c
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -4,10 +4,13 @@
 #include sys/wait.h
 
 static int quiet;
-static const char fetch_pack_usage[] = git-fetch-pack [-q] 
[--exec=upload-pack] [host:]directory [heads]*  mycommitlist;
+static int verbose;
+static const char fetch_pack_usage[] =
+git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory refs...;
 static const char *exec = git-upload-pack;
 
-static int find_common(int fd[2], unsigned char *result_sha1, unsigned char 
*remote)
+static int find_common(int fd[2], unsigned char *result_sha1,
+  struct ref *refs)
 {
static char line[1000];
int count = 0, flushes = 0, retval;
@@ -16,7 +19,16 @@ static int find_common(int fd[2], unsign
revs = popen(git-rev-list $(git-rev-parse --all), r);
if (!revs)
die(unable to run 'git-rev-list');
-   packet_write(fd[1], want %s\n, sha1_to_hex(remote));
+
+   while (refs) {
+   unsigned char *remote = refs-old_sha1;
+   if (verbose)
+   fprintf(stderr,
+   want %s (%s)\n, sha1_to_hex(remote),
+   refs-name);
+   packet_write(fd[1], want %s\n, sha1_to_hex(remote));
+   refs = refs-next;
+   }
packet_flush(fd[1]);
flushes = 1;
retval = -1;
@@ -25,6 +37,8 @@ static int find_common(int fd[2], unsign
if (get_sha1_hex(line, sha1))
die(git-fetch-pack: expected object name, got crud);
packet_write(fd[1], have %s\n, sha1_to_hex(sha1));
+   if (verbose)
+   fprintf(stderr, have %s\n, sha1_to_hex(sha1));
if (!(31  ++count)) {
packet_flush(fd[1]);
flushes++;
@@ -38,6 +52,8 @@ static int find_common(int fd[2], unsign
if (get_ack(fd[0], result_sha1)) {
flushes = 0;
retval = 0;
+   if (verbose)
+   fprintf(stderr, got ack\n);
break;
}
flushes--;
@@ -45,19 +61,19 @@ static int find_common(int fd[2], unsign
}
pclose(revs);
 

Re: [PATCH] fetch-pack: start multi-head pulling.

2005-08-12 Thread Junio C Hamano
Johannes Schindelin [EMAIL PROTECTED] writes:

 I seem to remember Junio does not like bash arrays... And in a recent 
 commit message, he even admits to using something different than bash!

Correct and somewhat misleading.  My usual shell is bash but
from time to time I try to run things with (d)ash to see how far
I strayed from the common denominator.

Yes, I am old fashioned.

I have been trying, admittably perhaps not very successfully, to
stay away from bashism in the core GIT scripts.  I knew we
started using shell array when Linus did the git-diff-script,
but I have been hoping somebody coming from other platforms
(hello, Solaris and Darwin guys) would send in patches if they
cared enough.  So I try to avoid making their life harder than
already is.

Here is a semi off-topic joke, hopefully to give you a better
sense of where I am coming from.

Anybody can start pretending to be an old fashioned shell
programmer by adhering to the following simple rules:

 1. Never, ever say [ ... ]; we old-timers always spell that
test.

 2. Never use test when case would do; this comes from
the days when test was not built-in and machines were
small.  We tried to reduce number of forks in our
scripts.  We also never use echo piped to grep when
case would do.

 3. We tend to write  || more often than we use if
... then ... fi, especially for simple things.  We do
not use parantheses () to introduce command grouping
lightly.  We usually say braces {} and use parentheses
only when we do want a subshell.

 4. Say ${var-default} more often than ${var:-default};
colon form is more recent invention, and we old-timers
tend to be more careful to consider the possibility
that, when a user says this variable is empty, the user
really means it.

 5. We are still allowed to use $() form in preference to
``, because it is clearly superior (it can nest) and
should have been the way to spell it from the beginning.

-jc

-
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html