{"thread":{"id":"2250","subject":"[PATCH 2/8] Make maximal use of the remote refs","startedAt":"2005-10-28T02:47:07Z","lastAt":"2005-10-28T02:47:07Z","messageCount":1,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"10737","messageId":"Pine.LNX.4.63.0510280446410.20516@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"2250","inReplyTo":null,"subject":"[PATCH 2/8] Make maximal use of the remote refs","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2005-10-28T02:47:07Z","receivedAt":"2005-10-28T02:47:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWhen git-fetch-pack gets the remote refs, it does not need to filter them\nright away, but it can see which refs are common (taking advantage of the\npatch which makes git-fetch-pack not use git-rev-list).\n\nThis means that we ask get_remote_heads() to return all remote refs,\nincluding the funny refs, and filtering them with a separate function later.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n fetch-pack.c |   72 ++++++++++++++++++++++++++++++++++++++++++----------------\n 1 files changed, 52 insertions(+), 20 deletions(-)\n\napplies-to: 828f6fc88faefd10f2b09b11a2758afde21049c7\nc3c4f518f0174292917d01734f58a57b6eb9871e\ndiff --git a/fetch-pack.c b/fetch-pack.c\nindex 3be77c3..b584264 100644\n--- a/fetch-pack.c\n+++ b/fetch-pack.c\n@@ -153,16 +153,7 @@ static int find_common(int fd[2], unsign\n \t\t * reachable and we have already scanned it.\n \t\t */\n \t\tif (((o = lookup_object(remote)) != NULL) &&\n-\t\t    (o->flags & COMPLETE)) {\n-\t\t\to = deref_tag(o);\n-\n-\t\t\tif (o->type == commit_type) {\n-\t\t\t\tstruct commit *commit = (struct commit *)o;\n-\n-\t\t\t\trev_list_push(commit, COMMON_REF | SEEN);\n-\n-\t\t\t\tmark_common(commit, 1, 1);\n-\t\t\t}\n+\t\t\t\t(o->flags & COMPLETE)) {\n \t\t\tcontinue;\n \t\t}\n \n@@ -247,7 +238,29 @@ static void mark_recent_complete_commits\n \t}\n }\n \n-static int everything_local(struct ref *refs)\n+static void filter_refs(struct ref **refs, int nr_match, char **match)\n+{\n+\tstruct ref *prev, *current, *next;\n+\n+\tif (!nr_match)\n+\t\treturn;\n+\n+\tfor (prev = NULL, current = *refs; current; current = next) {\n+\t\tnext = current->next;\n+\t\tif ((!memcmp(current->name, \"refs/\", 5) &&\n+\t\t\t\t\tcheck_ref_format(current->name + 5)) ||\n+\t\t\t\t!path_match(current->name, nr_match, match)) {\n+\t\t\tif (prev == NULL)\n+\t\t\t\t*refs = next;\n+\t\t\telse\n+\t\t\t\tprev->next = next;\n+\t\t\tfree(current);\n+\t\t} else\n+\t\t\tprev = current;\n+\t}\n+}\n+\n+static int everything_local(struct ref **refs, int nr_match, char **match)\n {\n \tstruct ref *ref;\n \tint retval;\n@@ -256,7 +269,7 @@ static int everything_local(struct ref *\n \ttrack_object_refs = 0;\n \tsave_commit_buffer = 0;\n \n-\tfor (ref = refs; ref; ref = ref->next) {\n+\tfor (ref = *refs; ref; ref = ref->next) {\n \t\tstruct object *o;\n \n \t\to = parse_object(ref->old_sha1);\n@@ -278,28 +291,47 @@ static int everything_local(struct ref *\n \tif (cutoff)\n \t\tmark_recent_complete_commits(cutoff);\n \n-\tfor (retval = 1; refs ; refs = refs->next) {\n-\t\tconst unsigned char *remote = refs->old_sha1;\n+\t/*\n+\t * Mark all complete remote refs as common refs.\n+\t * Don't mark them common yet; the server has to be told so first.\n+\t */\n+\tfor (ref = *refs; ref; ref = ref->next) {\n+\t\tstruct object *o = deref_tag(lookup_object(ref->old_sha1));\n+\n+\t\tif (!o || o->type != commit_type || !(o->flags & COMPLETE))\n+\t\t\tcontinue;\n+\n+\t\tif (!(o->flags & SEEN)) {\n+\t\t\trev_list_push((struct commit *)o, COMMON_REF | SEEN);\n+\n+\t\t\tmark_common((struct commit *)o, 1, 1);\n+\t\t}\n+\t}\n+\n+\tfilter_refs(refs, nr_match, match);\n+\n+\tfor (retval = 1, ref = *refs; ref ; ref = ref->next) {\n+\t\tconst unsigned char *remote = ref->old_sha1;\n \t\tunsigned char local[20];\n \t\tstruct object *o;\n \n-\t\to = parse_object(remote);\n+\t\to = lookup_object(remote);\n \t\tif (!o || !(o->flags & COMPLETE)) {\n \t\t\tretval = 0;\n \t\t\tif (!verbose)\n \t\t\t\tcontinue;\n \t\t\tfprintf(stderr,\n \t\t\t\t\"want %s (%s)\\n\", sha1_to_hex(remote),\n-\t\t\t\trefs->name);\n+\t\t\t\tref->name);\n \t\t\tcontinue;\n \t\t}\n \n-\t\tmemcpy(refs->new_sha1, local, 20);\n+\t\tmemcpy(ref->new_sha1, local, 20);\n \t\tif (!verbose)\n \t\t\tcontinue;\n \t\tfprintf(stderr,\n \t\t\t\"already have %s (%s)\\n\", sha1_to_hex(remote),\n-\t\t\trefs->name);\n+\t\t\tref->name);\n \t}\n \treturn retval;\n }\n@@ -311,12 +343,12 @@ static int fetch_pack(int fd[2], int nr_\n \tint status;\n \tpid_t pid;\n \n-\tget_remote_heads(fd[0], &ref, nr_match, match, 1);\n+\tget_remote_heads(fd[0], &ref, 0, NULL, 0);\n \tif (!ref) {\n \t\tpacket_flush(fd[1]);\n \t\tdie(\"no matching remote head\");\n \t}\n-\tif (everything_local(ref)) {\n+\tif (everything_local(&ref, nr_match, match)) {\n \t\tpacket_flush(fd[1]);\n \t\tgoto all_done;\n \t}\n---\n0.99.8.GIT\n"}]}