git-fetch-pack: Do not use git-rev-list
[git.git] / fetch-pack.c
blob3a903c4f9092d914aaa754067eed74ff7efd09e6
1 #include "cache.h"
2 #include "refs.h"
3 #include "pkt-line.h"
4 #include "commit.h"
5 #include "tag.h"
6 #include <time.h>
7 #include <sys/wait.h>
9 static int quiet;
10 static int verbose;
11 static const char fetch_pack_usage[] =
12 "git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
13 static const char *exec = "git-upload-pack";
15 #define COMPLETE (1U << 0)
16 #define COMMON (1U << 1)
17 #define COMMON_REF (1U << 2 | COMMON)
18 #define SEEN (1U << 3)
19 #define POPPED (1U << 4)
21 static struct commit_list *rev_list = NULL;
22 static struct commit_list *rev_list_end = NULL;
23 static unsigned long non_common_revs = 0;
25 static void rev_list_append(struct commit *commit, int mark)
27 if (!(commit->object.flags & mark)) {
28 commit->object.flags |= mark;
30 if (rev_list == NULL) {
31 commit_list_insert(commit, &rev_list);
32 rev_list_end = rev_list;
33 } else {
34 commit_list_insert(commit, &(rev_list_end->next));
35 rev_list_end = rev_list_end->next;
38 if (!(commit->object.flags & COMMON))
39 non_common_revs++;
43 static int rev_list_append_sha1(const char *path, const unsigned char *sha1)
45 struct object *o = deref_tag(parse_object(sha1));
47 if (o->type == commit_type)
48 rev_list_append((struct commit *)o, SEEN);
50 return 0;
53 static void mark_common(struct commit *commit)
55 if (commit != NULL && !(commit->object.flags & COMMON)) {
56 struct object *o = (struct object *)commit;
57 o->flags |= COMMON;
58 if (!(o->flags & SEEN))
59 rev_list_append(commit, SEEN);
60 else {
61 struct commit_list *parents;
63 if (!(o->flags & POPPED))
64 non_common_revs--;
65 if (!o->parsed)
66 parse_commit(commit);
67 for (parents = commit->parents;
68 parents;
69 parents = parents->next)
70 mark_common(parents->item);
76 Get the next rev to send, ignoring the common.
79 static const unsigned char* get_rev()
81 struct commit *commit = NULL;
83 while (commit == NULL) {
84 unsigned int mark;
85 struct commit_list* parents;
87 if (rev_list == NULL || non_common_revs == 0)
88 return NULL;
90 commit = rev_list->item;
91 if (!(commit->object.parsed))
92 parse_commit(commit);
93 commit->object.flags |= POPPED;
94 if (!(commit->object.flags & COMMON))
95 non_common_revs--;
97 parents = commit->parents;
99 if (commit->object.flags & COMMON) {
100 /* do not send "have", and ignore ancestors */
101 commit = NULL;
102 mark = COMMON | SEEN;
103 } else if (commit->object.flags & COMMON_REF)
104 /* send "have", and ignore ancestors */
105 mark = COMMON | SEEN;
106 else
107 /* send "have", also for its ancestors */
108 mark = SEEN;
110 while (parents) {
111 if (mark & COMMON)
112 mark_common(parents->item);
113 else
114 rev_list_append(parents->item, mark);
115 parents = parents->next;
118 rev_list = rev_list->next;
121 return commit->object.sha1;
124 static int find_common(int fd[2], unsigned char *result_sha1,
125 struct ref *refs)
127 int fetching;
128 int count = 0, flushes = 0, retval;
129 const unsigned char *sha1;
131 for_each_ref(rev_list_append_sha1);
133 fetching = 0;
134 for ( ; refs ; refs = refs->next) {
135 unsigned char *remote = refs->old_sha1;
136 struct object *o;
139 * If that object is complete (i.e. it is an ancestor of a
140 * local ref), we tell them we have it but do not have to
141 * tell them about its ancestors, which they already know
142 * about.
144 * We use lookup_object here because we are only
145 * interested in the case we *know* the object is
146 * reachable and we have already scanned it.
148 if (((o = lookup_object(remote)) != NULL) &&
149 (o->flags & COMPLETE)) {
150 o = deref_tag(o);
152 if (o->type == commit_type)
153 rev_list_append((struct commit *)o,
154 COMMON_REF | SEEN);
156 continue;
159 packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
160 fetching++;
162 packet_flush(fd[1]);
163 if (!fetching)
164 return 1;
166 flushes = 1;
167 retval = -1;
168 while ((sha1 = get_rev())) {
169 packet_write(fd[1], "have %s\n", sha1_to_hex(sha1));
170 if (verbose)
171 fprintf(stderr, "have %s\n", sha1_to_hex(sha1));
172 if (!(31 & ++count)) {
173 packet_flush(fd[1]);
174 flushes++;
177 * We keep one window "ahead" of the other side, and
178 * will wait for an ACK only on the next one
180 if (count == 32)
181 continue;
182 if (get_ack(fd[0], result_sha1)) {
183 flushes = 0;
184 retval = 0;
185 if (verbose)
186 fprintf(stderr, "got ack\n");
187 break;
189 flushes--;
192 packet_write(fd[1], "done\n");
193 if (verbose)
194 fprintf(stderr, "done\n");
195 while (flushes) {
196 flushes--;
197 if (get_ack(fd[0], result_sha1)) {
198 if (verbose)
199 fprintf(stderr, "got ack\n");
200 return 0;
203 return retval;
206 static struct commit_list *complete = NULL;
208 static int mark_complete(const char *path, const unsigned char *sha1)
210 struct object *o = parse_object(sha1);
212 while (o && o->type == tag_type) {
213 struct tag *t = (struct tag *) o;
214 if (!t->tagged)
215 break; /* broken repository */
216 o->flags |= COMPLETE;
217 o = parse_object(t->tagged->sha1);
219 if (o && o->type == commit_type) {
220 struct commit *commit = (struct commit *)o;
221 commit->object.flags |= COMPLETE;
222 insert_by_date(commit, &complete);
224 return 0;
227 static void mark_recent_complete_commits(unsigned long cutoff)
229 while (complete && cutoff <= complete->item->date) {
230 if (verbose)
231 fprintf(stderr, "Marking %s as complete\n",
232 sha1_to_hex(complete->item->object.sha1));
233 pop_most_recent_commit(&complete, COMPLETE);
237 static int everything_local(struct ref *refs)
239 struct ref *ref;
240 int retval;
241 unsigned long cutoff = 0;
243 track_object_refs = 0;
244 save_commit_buffer = 0;
246 for (ref = refs; ref; ref = ref->next) {
247 struct object *o;
249 o = parse_object(ref->old_sha1);
250 if (!o)
251 continue;
253 /* We already have it -- which may mean that we were
254 * in sync with the other side at some time after
255 * that (it is OK if we guess wrong here).
257 if (o->type == commit_type) {
258 struct commit *commit = (struct commit *)o;
259 if (!cutoff || cutoff < commit->date)
260 cutoff = commit->date;
264 for_each_ref(mark_complete);
265 if (cutoff)
266 mark_recent_complete_commits(cutoff);
268 for (retval = 1; refs ; refs = refs->next) {
269 const unsigned char *remote = refs->old_sha1;
270 unsigned char local[20];
271 struct object *o;
273 o = parse_object(remote);
274 if (!o || !(o->flags & COMPLETE)) {
275 retval = 0;
276 if (!verbose)
277 continue;
278 fprintf(stderr,
279 "want %s (%s)\n", sha1_to_hex(remote),
280 refs->name);
281 continue;
284 memcpy(refs->new_sha1, local, 20);
285 if (!verbose)
286 continue;
287 fprintf(stderr,
288 "already have %s (%s)\n", sha1_to_hex(remote),
289 refs->name);
291 return retval;
294 static int fetch_pack(int fd[2], int nr_match, char **match)
296 struct ref *ref;
297 unsigned char sha1[20];
298 int status;
299 pid_t pid;
301 get_remote_heads(fd[0], &ref, nr_match, match, 1);
302 if (!ref) {
303 packet_flush(fd[1]);
304 die("no matching remote head");
306 if (everything_local(ref)) {
307 packet_flush(fd[1]);
308 goto all_done;
310 if (find_common(fd, sha1, ref) < 0)
311 fprintf(stderr, "warning: no common commits\n");
312 pid = fork();
313 if (pid < 0)
314 die("git-fetch-pack: unable to fork off git-unpack-objects");
315 if (!pid) {
316 dup2(fd[0], 0);
317 close(fd[0]);
318 close(fd[1]);
319 execlp("git-unpack-objects", "git-unpack-objects",
320 quiet ? "-q" : NULL, NULL);
321 die("git-unpack-objects exec failed");
323 close(fd[0]);
324 close(fd[1]);
325 while (waitpid(pid, &status, 0) < 0) {
326 if (errno != EINTR)
327 die("waiting for git-unpack-objects: %s", strerror(errno));
329 if (WIFEXITED(status)) {
330 int code = WEXITSTATUS(status);
331 if (code)
332 die("git-unpack-objects died with error code %d", code);
333 all_done:
334 while (ref) {
335 printf("%s %s\n",
336 sha1_to_hex(ref->old_sha1), ref->name);
337 ref = ref->next;
339 return 0;
341 if (WIFSIGNALED(status)) {
342 int sig = WTERMSIG(status);
343 die("git-unpack-objects died of signal %d", sig);
345 die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
348 int main(int argc, char **argv)
350 int i, ret, nr_heads;
351 char *dest = NULL, **heads;
352 int fd[2];
353 pid_t pid;
355 nr_heads = 0;
356 heads = NULL;
357 for (i = 1; i < argc; i++) {
358 char *arg = argv[i];
360 if (*arg == '-') {
361 if (!strncmp("--exec=", arg, 7)) {
362 exec = arg + 7;
363 continue;
365 if (!strcmp("-q", arg)) {
366 quiet = 1;
367 continue;
369 if (!strcmp("-v", arg)) {
370 verbose = 1;
371 continue;
373 usage(fetch_pack_usage);
375 dest = arg;
376 heads = argv + i + 1;
377 nr_heads = argc - i - 1;
378 break;
380 if (!dest)
381 usage(fetch_pack_usage);
382 pid = git_connect(fd, dest, exec);
383 if (pid < 0)
384 return 1;
385 ret = fetch_pack(fd, nr_heads, heads);
386 close(fd[0]);
387 close(fd[1]);
388 finish_connect(pid);
389 return ret;