diff options
author | Junio C Hamano <junkio@cox.net> | 2005-10-25 14:55:24 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-10-25 14:55:24 -0700 |
commit | af2d3aa4d84fd3475d9b676f669eab3c4227189f (patch) | |
tree | 2ada0cb8fce070b6b2c56fa689791230636f1857 /fetch-pack.c | |
parent | 7efc8e43508b415e2540dbcb79521bde16c51e0c (diff) | |
download | git-af2d3aa4d84fd3475d9b676f669eab3c4227189f.tar.gz git-af2d3aa4d84fd3475d9b676f669eab3c4227189f.tar.xz |
Revert recent fetch-pack/upload-pack updates.
Let's have it simmer a bit longer in the proposed updates branch
and shake the problems out.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'fetch-pack.c')
-rw-r--r-- | fetch-pack.c | 199 |
1 files changed, 44 insertions, 155 deletions
diff --git a/fetch-pack.c b/fetch-pack.c index 57602b956..8566ab174 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -13,123 +13,18 @@ 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 | COMMON) -#define SEEN (1U << 3) -#define POPPED (1U << 4) - -static struct commit_list *rev_list = NULL; -static struct commit_list *rev_list_end = NULL; -static unsigned long non_common_revs = 0; - -static void rev_list_append(struct commit *commit, int mark) -{ - if (!(commit->object.flags & mark)) { - commit->object.flags |= mark; - - if (rev_list == NULL) { - commit_list_insert(commit, &rev_list); - rev_list_end = rev_list; - } else { - commit_list_insert(commit, &(rev_list_end->next)); - rev_list_end = rev_list_end->next; - } - - if (!(commit->object.flags & COMMON)) - non_common_revs++; - } -} - -static int rev_list_append_sha1(const char *path, const unsigned char *sha1) -{ - struct object *o = deref_tag(parse_object(sha1)); - - if (o->type == commit_type) - rev_list_append((struct commit *)o, SEEN); - - return 0; -} - -static void mark_common(struct commit *commit) -{ - if (commit != NULL && !(commit->object.flags & COMMON)) { - struct object *o = (struct object *)commit; - o->flags |= COMMON; - if (!(o->flags & SEEN)) - rev_list_append(commit, SEEN); - else { - struct commit_list *parents; - - if (!(o->flags & POPPED)) - non_common_revs--; - if (!o->parsed) - parse_commit(commit); - for (parents = commit->parents; - parents; - parents = parents->next) - mark_common(parents->item); - } - } -} - -/* - 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 (mark & COMMON) - mark_common(parents->item); - else - rev_list_append(parents->item, mark); - 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; - int count = 0, flushes = 0, multi_ack = 0, retval; - const unsigned char *sha1; - - for_each_ref(rev_list_append_sha1); + static char line[1000]; + static char rev_command[1024]; + int count = 0, flushes = 0, retval, rev_command_len; + FILE *revs; + 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; @@ -147,31 +42,46 @@ static int find_common(int fd[2], unsigned char *result_sha1, */ if (((o = lookup_object(remote)) != NULL) && (o->flags & COMPLETE)) { - o = deref_tag(o); - - if (o->type == commit_type) - rev_list_append((struct commit *)o, - COMMON_REF | SEEN); - + 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; + } continue; } - - packet_write(fd[1], "want %s multi_ack\n", sha1_to_hex(remote)); + repair: + packet_write(fd[1], "want %s\n", sha1_to_hex(remote)); fetching++; } packet_flush(fd[1]); if (!fetching) return 1; - flushes = 0; + revs = popen(rev_command, "r"); + if (!revs) + die("unable to run 'git-rev-list'"); + + flushes = 1; retval = -1; - while ((sha1 = get_rev())) { + 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"); 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)) { - int ack; - packet_flush(fd[1]); flushes++; @@ -181,48 +91,27 @@ static int find_common(int fd[2], unsigned char *result_sha1, */ if (count == 32) continue; - - 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) { - if (!multi_ack) - flushes = 0; - retval = 0; - goto done; - } else if (ack == 2) { - multi_ack = 1; - mark_common((struct commit *) - lookup_object(result_sha1)); - retval = 0; - } - } while(ack); + if (get_ack(fd[0], result_sha1)) { + flushes = 0; + retval = 0; + if (verbose) + fprintf(stderr, "got ack\n"); + break; + } flushes--; } } -done: - if (multi_ack) { - packet_flush(fd[1]); - 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)) { if (verbose) - fprintf(stderr, "got ack %s\n", - sha1_to_hex(result_sha1)); - if (!multi_ack) - return 0; - retval = 0; - continue; + fprintf(stderr, "got ack\n"); + return 0; } - flushes--; } return retval; } |