Skip to content

Commit

Permalink
fetch-pack: start multi-head pulling.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Junio C Hamano committed Aug 12, 2005
1 parent 87b7b84 commit 33b8303
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 27 deletions.
18 changes: 7 additions & 11 deletions Documentation/git-fetch-pack.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ git-fetch-pack - Receive missing objects from another repository.

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
Expand Down Expand Up @@ -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
------
Expand Down
56 changes: 40 additions & 16 deletions fetch-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -16,7 +19,16 @@ static int find_common(int fd[2], unsigned char *result_sha1, unsigned char *rem
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;
Expand All @@ -25,6 +37,8 @@ static int find_common(int fd[2], unsigned char *result_sha1, unsigned char *rem
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++;
Expand All @@ -38,26 +52,28 @@ static int find_common(int fd[2], unsigned char *result_sha1, unsigned char *rem
if (get_ack(fd[0], result_sha1)) {
flushes = 0;
retval = 0;
if (verbose)
fprintf(stderr, "got ack\n");
break;
}
flushes--;
}
}
pclose(revs);
packet_write(fd[1], "done\n");
if (verbose)
fprintf(stderr, "done\n");
while (flushes) {
flushes--;
if (get_ack(fd[0], result_sha1))
if (get_ack(fd[0], result_sha1)) {
if (verbose)
fprintf(stderr, "got ack\n");
return 0;
}
}
return retval;
}

/*
* Eventually we'll want to be able to fetch multiple heads.
*
* Right now we'll just require a single match.
*/
static int fetch_pack(int fd[2], int nr_match, char **match)
{
struct ref *ref;
Expand All @@ -70,12 +86,8 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
packet_flush(fd[1]);
die("no matching remote head");
}
if (ref->next) {
packet_flush(fd[1]);
die("multiple remote heads");
}
if (find_common(fd, sha1, ref->old_sha1) < 0)
die("git-fetch-pack: no common commits");
if (find_common(fd, sha1, ref) < 0)
fprintf(stderr, "warning: no common commits\n");
pid = fork();
if (pid < 0)
die("git-fetch-pack: unable to fork off git-unpack-objects");
Expand All @@ -97,7 +109,11 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
int code = WEXITSTATUS(status);
if (code)
die("git-unpack-objects died with error code %d", code);
puts(sha1_to_hex(ref->old_sha1));
while (ref) {
printf("%s %s\n",
sha1_to_hex(ref->old_sha1), ref->name);
ref = ref->next;
}
return 0;
}
if (WIFSIGNALED(status)) {
Expand All @@ -124,6 +140,14 @@ int main(int argc, char **argv)
exec = arg + 7;
continue;
}
if (!strcmp("-q", arg)) {
quiet = 1;
continue;
}
if (!strcmp("-v", arg)) {
verbose = 1;
continue;
}
usage(fetch_pack_usage);
}
dest = arg;
Expand Down
4 changes: 4 additions & 0 deletions git-fetch-script
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ rsync://*)
;;
*)
head=$(git-fetch-pack "$merge_repo" "$merge_head")
if h=`expr "$head" : '\([^ ][^ ]*\) '`
then
head=$h
fi
;;
esac || exit 1

Expand Down

0 comments on commit 33b8303

Please sign in to comment.