mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
Make maximal use of the remote refs
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> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
23d61f8343
commit
1baaae5e1f
1 changed files with 52 additions and 20 deletions
70
fetch-pack.c
70
fetch-pack.c
|
@ -154,15 +154,6 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
||||||
*/
|
*/
|
||||||
if (((o = lookup_object(remote)) != NULL) &&
|
if (((o = lookup_object(remote)) != NULL) &&
|
||||||
(o->flags & COMPLETE)) {
|
(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);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +238,29 @@ static void mark_recent_complete_commits(unsigned long cutoff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
struct ref *ref;
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -256,7 +269,7 @@ static int everything_local(struct ref *refs)
|
||||||
track_object_refs = 0;
|
track_object_refs = 0;
|
||||||
save_commit_buffer = 0;
|
save_commit_buffer = 0;
|
||||||
|
|
||||||
for (ref = refs; ref; ref = ref->next) {
|
for (ref = *refs; ref; ref = ref->next) {
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
|
||||||
o = parse_object(ref->old_sha1);
|
o = parse_object(ref->old_sha1);
|
||||||
|
@ -278,28 +291,47 @@ static int everything_local(struct ref *refs)
|
||||||
if (cutoff)
|
if (cutoff)
|
||||||
mark_recent_complete_commits(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];
|
unsigned char local[20];
|
||||||
struct object *o;
|
struct object *o;
|
||||||
|
|
||||||
o = parse_object(remote);
|
o = lookup_object(remote);
|
||||||
if (!o || !(o->flags & COMPLETE)) {
|
if (!o || !(o->flags & COMPLETE)) {
|
||||||
retval = 0;
|
retval = 0;
|
||||||
if (!verbose)
|
if (!verbose)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"want %s (%s)\n", sha1_to_hex(remote),
|
"want %s (%s)\n", sha1_to_hex(remote),
|
||||||
refs->name);
|
ref->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(refs->new_sha1, local, 20);
|
memcpy(ref->new_sha1, local, 20);
|
||||||
if (!verbose)
|
if (!verbose)
|
||||||
continue;
|
continue;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"already have %s (%s)\n", sha1_to_hex(remote),
|
"already have %s (%s)\n", sha1_to_hex(remote),
|
||||||
refs->name);
|
ref->name);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -311,12 +343,12 @@ static int fetch_pack(int fd[2], int nr_match, char **match)
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
get_remote_heads(fd[0], &ref, nr_match, match, 1);
|
get_remote_heads(fd[0], &ref, 0, NULL, 0);
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
packet_flush(fd[1]);
|
packet_flush(fd[1]);
|
||||||
die("no matching remote head");
|
die("no matching remote head");
|
||||||
}
|
}
|
||||||
if (everything_local(ref)) {
|
if (everything_local(&ref, nr_match, match)) {
|
||||||
packet_flush(fd[1]);
|
packet_flush(fd[1]);
|
||||||
goto all_done;
|
goto all_done;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue