Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 735 lines (667 sloc) 17.931 kb
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
1 #include "cache.h"
2 #include "refs.h"
3 #include "pkt-line.h"
958c24b Move sideband server side support into reusable form.
Junio C Hamano authored
4 #include "sideband.h"
f6b42a8 Show peeled onion from upload-pack and server-info.
Junio C Hamano authored
5 #include "tag.h"
6 #include "object.h"
f0243f2 @dscho git-upload-pack: More efficient usage of the has_sha1 array
dscho authored
7 #include "commit.h"
77cb17e Exec git programs without using PATH.
Michal Ostrowski authored
8 #include "exec_cmd.h"
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
9 #include "diff.h"
10 #include "revision.h"
11 #include "list-objects.h"
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
12 #include "run-command.h"
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
13
34263de @aspotashev Replace deprecated dashed git commands in usage
aspotashev authored
14 static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=nn] <dir>";
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
15
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
16 /* bits #0..7 in revision.h, #8..10 in commit.c */
17 #define THEY_HAVE (1u << 11)
18 #define OUR_REF (1u << 12)
19 #define WANTED (1u << 13)
20 #define COMMON_KNOWN (1u << 14)
21 #define REACHABLE (1u << 15)
22
f53514b @dscho allow deepening of a shallow repository
dscho authored
23 #define SHALLOW (1u << 16)
24 #define NOT_SHALLOW (1u << 17)
25 #define CLIENT_SHALLOW (1u << 18)
26
3fbe2d5 Merge branch 'jc/upload-pack'
Junio C Hamano authored
27 static unsigned long oldest_have;
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
28
96f1e58 remove unnecessary initializations
David Rientjes authored
29 static int multi_ack, nr_our_refs;
348e390 @spearce Teach fetch-pack/upload-pack about --include-tag
spearce authored
30 static int use_thin_pack, use_ofs_delta, use_include_tag;
9462e3f upload-pack: squelch progress indicator if client cannot see it
Johannes Sixt authored
31 static int no_progress, daemon_mode;
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
32 static int shallow_nr;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
33 static struct object_array have_obj;
34 static struct object_array want_obj;
6523078 make shallow repository deepening more network efficient
Nicolas Pitre authored
35 static struct object_array extra_edge_obj;
96f1e58 remove unnecessary initializations
David Rientjes authored
36 static unsigned int timeout;
d47f3db Prepare larger packet buffer for upload-pack protocol.
Junio C Hamano authored
37 /* 0 for no sideband,
38 * otherwise maximum packet size (up to 65520 bytes).
39 */
96f1e58 remove unnecessary initializations
David Rientjes authored
40 static int use_sideband;
49aaddd @spearce Teach upload-pack to log the received need lines to an fd
spearce authored
41 static int debug_fd;
42526b4 @spearce Add stateless RPC options to upload-pack, receive-pack
spearce authored
42 static int advertise_refs;
43 static int stateless_rpc;
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
44
45 static void reset_timeout(void)
46 {
47 alarm(timeout);
48 }
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
49
75bfc6c Make git-fetch-pack actually do all the unpacking etc.
Linus Torvalds authored
50 static int strip(char *line, int len)
51 {
52 if (len && line[len-1] == '\n')
53 line[--len] = 0;
54 return len;
55 }
56
583b7ea upload-pack/fetch-pack: support side-band communication
Junio C Hamano authored
57 static ssize_t send_client_data(int fd, const char *data, ssize_t sz)
58 {
958c24b Move sideband server side support into reusable form.
Junio C Hamano authored
59 if (use_sideband)
d47f3db Prepare larger packet buffer for upload-pack protocol.
Junio C Hamano authored
60 return send_sideband(1, fd, data, sz, use_sideband);
958c24b Move sideband server side support into reusable form.
Junio C Hamano authored
61 if (fd == 3)
62 /* emergency quit */
63 fd = 2;
64 if (fd == 2) {
93822c2 @awhitcroft short i/o: fix calls to write to use xwrite or write_in_full
awhitcroft authored
65 /* XXX: are we happy to lose stuff here? */
958c24b Move sideband server side support into reusable form.
Junio C Hamano authored
66 xwrite(fd, data, sz);
67 return sz;
583b7ea upload-pack/fetch-pack: support side-band communication
Junio C Hamano authored
68 }
958c24b Move sideband server side support into reusable form.
Junio C Hamano authored
69 return safe_write(fd, data, sz);
583b7ea upload-pack/fetch-pack: support side-band communication
Junio C Hamano authored
70 }
71
16befb8 @gitster Even more missing static
gitster authored
72 static FILE *pack_pipe = NULL;
11c211f @chriscool list-objects: add "void *data" parameter to show functions
chriscool authored
73 static void show_commit(struct commit *commit, void *data)
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
74 {
75 if (commit->object.flags & BOUNDARY)
76 fputc('-', pack_pipe);
77 if (fputs(sha1_to_hex(commit->object.sha1), pack_pipe) < 0)
78 die("broken output pipe");
79 fputc('\n', pack_pipe);
80 fflush(pack_pipe);
81 free(commit->buffer);
82 commit->buffer = NULL;
83 }
84
cf2ab91 @torvalds show_object(): push path_name() call further down
torvalds authored
85 static void show_object(struct object *obj, const struct name_path *path, const char *component)
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
86 {
87 /* An object with name "foo\n0000000..." can be used to
88 * confuse downstream git-pack-objects very badly.
89 */
cf2ab91 @torvalds show_object(): push path_name() call further down
torvalds authored
90 const char *name = path_name(path, component);
8d2dfc4 @torvalds process_{tree,blob}: show objects without buffering
torvalds authored
91 const char *ep = strchr(name, '\n');
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
92 if (ep) {
8d2dfc4 @torvalds process_{tree,blob}: show objects without buffering
torvalds authored
93 fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(obj->sha1),
94 (int) (ep - name),
95 name);
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
96 }
97 else
98 fprintf(pack_pipe, "%s %s\n",
8d2dfc4 @torvalds process_{tree,blob}: show objects without buffering
torvalds authored
99 sha1_to_hex(obj->sha1), name);
cf2ab91 @torvalds show_object(): push path_name() call further down
torvalds authored
100 free((char *)name);
9b8dc26 @dscho upload-pack: no longer call rev-list
dscho authored
101 }
102
103 static void show_edge(struct commit *commit)
104 {
105 fprintf(pack_pipe, "-%s\n", sha1_to_hex(commit->object.sha1));
106 }
107
21edd3f upload-pack: Run rev-list in an asynchronous function.
Johannes Sixt authored
108 static int do_rev_list(int fd, void *create_full_pack)
80ccaa7 upload-pack: Move the revision walker into a separate function.
Johannes Sixt authored
109 {
110 int i;
111 struct rev_info revs;
112
4169837 don't dereference NULL upon fdopen failure
Jim Meyering authored
113 pack_pipe = xfdopen(fd, "w");
80ccaa7 upload-pack: Move the revision walker into a separate function.
Johannes Sixt authored
114 init_revisions(&revs, NULL);
115 revs.tag_objects = 1;
116 revs.tree_objects = 1;
117 revs.blob_objects = 1;
118 if (use_thin_pack)
119 revs.edge_hint = 1;
120
121 if (create_full_pack) {
122 const char *args[] = {"rev-list", "--all", NULL};
123 setup_revisions(2, args, &revs, NULL);
124 } else {
125 for (i = 0; i < want_obj.nr; i++) {
126 struct object *o = want_obj.objects[i].item;
127 /* why??? */
128 o->flags &= ~UNINTERESTING;
129 add_pending_object(&revs, o, NULL);
130 }
131 for (i = 0; i < have_obj.nr; i++) {
132 struct object *o = have_obj.objects[i].item;
133 o->flags |= UNINTERESTING;
134 add_pending_object(&revs, o, NULL);
135 }
136 setup_revisions(0, NULL, &revs, NULL);
137 }
3d51e1b check return code of prepare_revision_walk
Martin Koegler authored
138 if (prepare_revision_walk(&revs))
139 die("revision walk setup failed");
80ccaa7 upload-pack: Move the revision walker into a separate function.
Johannes Sixt authored
140 mark_edges_uninteresting(revs.commits, &revs, show_edge);
6523078 make shallow repository deepening more network efficient
Nicolas Pitre authored
141 if (use_thin_pack)
142 for (i = 0; i < extra_edge_obj.nr; i++)
143 fprintf(pack_pipe, "-%s\n", sha1_to_hex(
144 extra_edge_obj.objects[i].item->sha1));
11c211f @chriscool list-objects: add "void *data" parameter to show functions
chriscool authored
145 traverse_commit_list(&revs, show_commit, show_object, NULL);
618ebe9 Windows: Implement asynchronous functions as threads.
Johannes Sixt authored
146 fflush(pack_pipe);
147 fclose(pack_pipe);
21edd3f upload-pack: Run rev-list in an asynchronous function.
Johannes Sixt authored
148 return 0;
80ccaa7 upload-pack: Move the revision walker into a separate function.
Johannes Sixt authored
149 }
150
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
151 static void create_pack_file(void)
152 {
21edd3f upload-pack: Run rev-list in an asynchronous function.
Johannes Sixt authored
153 struct async rev_list;
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
154 struct child_process pack_objects;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
155 int create_full_pack = (nr_our_refs == want_obj.nr && !have_obj.nr);
363b781 upload-pack: prepare for sideband message support.
Junio C Hamano authored
156 char data[8193], progress[128];
583b7ea upload-pack/fetch-pack: support side-band communication
Junio C Hamano authored
157 char abort_msg[] = "aborting due to possible repository "
158 "corruption on the remote side.";
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
159 int buffered = -1;
1456b04 @gitster Remove post-upload-hook
gitster authored
160 ssize_t sz;
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
161 const char *argv[10];
162 int arg = 0;
75bfc6c Make git-fetch-pack actually do all the unpacking etc.
Linus Torvalds authored
163
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
164 if (shallow_nr) {
165 rev_list.proc = do_rev_list;
166 rev_list.data = 0;
167 if (start_async(&rev_list))
168 die("git upload-pack: unable to fork git-rev-list");
169 argv[arg++] = "pack-objects";
170 } else {
171 argv[arg++] = "pack-objects";
172 argv[arg++] = "--revs";
173 if (create_full_pack)
174 argv[arg++] = "--all";
175 else if (use_thin_pack)
176 argv[arg++] = "--thin";
177 }
75bfc6c Make git-fetch-pack actually do all the unpacking etc.
Linus Torvalds authored
178
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
179 argv[arg++] = "--stdout";
180 if (!no_progress)
181 argv[arg++] = "--progress";
182 if (use_ofs_delta)
183 argv[arg++] = "--delta-base-offset";
348e390 @spearce Teach fetch-pack/upload-pack about --include-tag
spearce authored
184 if (use_include_tag)
185 argv[arg++] = "--include-tag";
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
186 argv[arg++] = NULL;
187
188 memset(&pack_objects, 0, sizeof(pack_objects));
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
189 pack_objects.in = shallow_nr ? rev_list.out : -1;
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
190 pack_objects.out = -1;
191 pack_objects.err = -1;
192 pack_objects.git_cmd = 1;
193 pack_objects.argv = argv;
21edd3f upload-pack: Run rev-list in an asynchronous function.
Johannes Sixt authored
194
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
195 if (start_command(&pack_objects))
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
196 die("git upload-pack: unable to fork git-pack-objects");
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
197
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
198 /* pass on revisions we (don't) want */
199 if (!shallow_nr) {
4169837 don't dereference NULL upon fdopen failure
Jim Meyering authored
200 FILE *pipe_fd = xfdopen(pack_objects.in, "w");
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
201 if (!create_full_pack) {
202 int i;
203 for (i = 0; i < want_obj.nr; i++)
204 fprintf(pipe_fd, "%s\n", sha1_to_hex(want_obj.objects[i].item->sha1));
205 fprintf(pipe_fd, "--not\n");
206 for (i = 0; i < have_obj.nr; i++)
207 fprintf(pipe_fd, "%s\n", sha1_to_hex(have_obj.objects[i].item->sha1));
208 }
209
210 fprintf(pipe_fd, "\n");
211 fflush(pipe_fd);
212 fclose(pipe_fd);
213 }
214
215
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
216 /* We read from pack_objects.err to capture stderr output for
217 * progress bar, and pack_objects.out to capture the pack data.
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
218 */
219
220 while (1) {
221 struct pollfd pfd[2];
363b781 upload-pack: prepare for sideband message support.
Junio C Hamano authored
222 int pe, pu, pollsize;
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
223
0d516ad @matled upload-pack: fix timeout in create_pack_file
matled authored
224 reset_timeout();
225
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
226 pollsize = 0;
363b781 upload-pack: prepare for sideband message support.
Junio C Hamano authored
227 pe = pu = -1;
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
228
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
229 if (0 <= pack_objects.out) {
230 pfd[pollsize].fd = pack_objects.out;
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
231 pfd[pollsize].events = POLLIN;
232 pu = pollsize;
233 pollsize++;
234 }
cc41fa8 upload-pack: Use start_command() to run pack-objects in create_pack_file...
Johannes Sixt authored
235 if (0 <= pack_objects.err) {
236 pfd[pollsize].fd = pack_objects.err;
363b781 upload-pack: prepare for sideband message support.
Junio C Hamano authored
237 pfd[pollsize].events = POLLIN;
238 pe = pollsize;
239 pollsize++;
240 }
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
241
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
242 if (!pollsize)
243 break;
244
245 if (poll(pfd, pollsize, -1) < 0) {
246 if (errno != EINTR) {
247 error("poll failed, resuming: %s",
248 strerror(errno));
249 sleep(1);
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
250 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
251 continue;
252 }
6b59f51 @npitre give priority to progress messages
npitre authored
253 if (0 <= pe && (pfd[pe].revents & (POLLIN|POLLHUP))) {
254 /* Status ready; we ship that in the side-band
255 * or dump to the standard error.
256 */
257 sz = xread(pack_objects.err, progress,
258 sizeof(progress));
259 if (0 < sz)
260 send_client_data(2, progress, sz);
261 else if (sz == 0) {
262 close(pack_objects.err);
263 pack_objects.err = -1;
264 }
265 else
266 goto fail;
267 /* give priority to status messages */
268 continue;
269 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
270 if (0 <= pu && (pfd[pu].revents & (POLLIN|POLLHUP))) {
271 /* Data ready; we keep the last byte to ourselves
272 * in case we detect broken rev-list, so that we
273 * can leave the stream corrupted. This is
274 * unfortunate -- unpack-objects would happily
275 * accept a valid packdata with trailing garbage,
276 * so appending garbage after we pass all the
277 * pack data is not good enough to signal
278 * breakage to downstream.
279 */
280 char *cp = data;
281 ssize_t outsz = 0;
282 if (0 <= buffered) {
283 *cp++ = buffered;
284 outsz++;
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
285 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
286 sz = xread(pack_objects.out, cp,
287 sizeof(data) - outsz);
288 if (0 < sz)
1456b04 @gitster Remove post-upload-hook
gitster authored
289 ;
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
290 else if (sz == 0) {
291 close(pack_objects.out);
292 pack_objects.out = -1;
363b781 upload-pack: prepare for sideband message support.
Junio C Hamano authored
293 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
294 else
295 goto fail;
296 sz += outsz;
297 if (1 < sz) {
298 buffered = data[sz-1] & 0xFF;
299 sz--;
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
300 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
301 else
302 buffered = -1;
303 sz = send_client_data(1, data, sz);
304 if (sz < 0)
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
305 goto fail;
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
306 }
307 }
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
308
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
309 if (finish_command(&pack_objects)) {
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
310 error("git upload-pack: git-pack-objects died with error.");
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
311 goto fail;
312 }
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
313 if (shallow_nr && finish_async(&rev_list))
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
314 goto fail; /* error was already reported */
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
315
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
316 /* flush the data */
317 if (0 <= buffered) {
318 data[0] = buffered;
319 sz = send_client_data(1, data, 1);
320 if (sz < 0)
321 goto fail;
322 fprintf(stderr, "flushed.\n");
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
323 }
4c324c0 upload-pack: Use finish_{command,async}() instead of waitpid().
Johannes Sixt authored
324 if (use_sideband)
325 packet_flush(1);
326 return;
327
b1c71b7 upload-pack: avoid sending an incomplete pack upon failure
Junio C Hamano authored
328 fail:
583b7ea upload-pack/fetch-pack: support side-band communication
Junio C Hamano authored
329 send_client_data(3, abort_msg, sizeof(abort_msg));
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
330 die("git upload-pack: %s", abort_msg);
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
331 }
332
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
333 static int got_sha1(char *hex, unsigned char *sha1)
334 {
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
335 struct object *o;
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
336 int we_knew_they_have = 0;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
337
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
338 if (get_sha1_hex(hex, sha1))
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
339 die("git upload-pack: expected SHA1 object, got '%s'", hex);
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
340 if (!has_sha1_file(sha1))
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
341 return -1;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
342
343 o = lookup_object(sha1);
344 if (!(o && o->parsed))
345 o = parse_object(sha1);
346 if (!o)
347 die("oops (%s)", sha1_to_hex(sha1));
182a8da Merge branch 'jc/upload-pack'
Junio C Hamano authored
348 if (o->type == OBJ_COMMIT) {
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
349 struct commit_list *parents;
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
350 struct commit *commit = (struct commit *)o;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
351 if (o->flags & THEY_HAVE)
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
352 we_knew_they_have = 1;
353 else
354 o->flags |= THEY_HAVE;
355 if (!oldest_have || (commit->date < oldest_have))
356 oldest_have = commit->date;
357 for (parents = commit->parents;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
358 parents;
359 parents = parents->next)
360 parents->item->object.flags |= THEY_HAVE;
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
361 }
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
362 if (!we_knew_they_have) {
363 add_object_array(o, NULL, &have_obj);
364 return 1;
365 }
366 return 0;
367 }
368
369 static int reachable(struct commit *want)
370 {
371 struct commit_list *work = NULL;
372
373 insert_by_date(want, &work);
374 while (work) {
375 struct commit_list *list = work->next;
376 struct commit *commit = work->item;
377 free(work);
378 work = list;
379
380 if (commit->object.flags & THEY_HAVE) {
381 want->object.flags |= COMMON_KNOWN;
382 break;
383 }
384 if (!commit->object.parsed)
385 parse_object(commit->object.sha1);
386 if (commit->object.flags & REACHABLE)
387 continue;
388 commit->object.flags |= REACHABLE;
389 if (commit->date < oldest_have)
390 continue;
391 for (list = commit->parents; list; list = list->next) {
392 struct commit *parent = list->item;
393 if (!(parent->object.flags & REACHABLE))
394 insert_by_date(parent, &work);
395 }
396 }
397 want->object.flags |= REACHABLE;
398 clear_commit_marks(want, REACHABLE);
399 free_commit_list(work);
400 return (want->object.flags & COMMON_KNOWN);
401 }
402
403 static int ok_to_give_up(void)
404 {
405 int i;
406
407 if (!have_obj.nr)
408 return 0;
409
410 for (i = 0; i < want_obj.nr; i++) {
411 struct object *want = want_obj.objects[i].item;
412
413 if (want->flags & COMMON_KNOWN)
414 continue;
415 want = deref_tag(want, "a want line", 0);
416 if (!want || want->type != OBJ_COMMIT) {
417 /* no way to tell if this is reachable by
418 * looking at the ancestry chain alone, so
419 * leave a note to ourselves not to worry about
420 * this object anymore.
421 */
422 want_obj.objects[i].item->flags |= COMMON_KNOWN;
423 continue;
424 }
425 if (!reachable((struct commit *)want))
426 return 0;
427 }
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
428 return 1;
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
429 }
430
431 static int get_common_commits(void)
432 {
433 static char line[1000];
c04c4e5 upload-pack: minor clean-up in multi-ack logic
Junio C Hamano authored
434 unsigned char sha1[20];
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
435 char last_hex[41];
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
436
f0243f2 @dscho git-upload-pack: More efficient usage of the has_sha1 array
dscho authored
437 save_commit_buffer = 0;
438
eeefa7c @bgianfo Style fixes, add a space after if/for/while.
bgianfo authored
439 for (;;) {
fd13b21 @d0k Move local variables to narrower scopes
d0k authored
440 int len = packet_read_line(0, line, sizeof(line));
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
441 reset_timeout();
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
442
443 if (!len) {
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
444 if (have_obj.nr == 0 || multi_ack)
1bd8c8f @dscho git-upload-pack: Support the multi_ack protocol
dscho authored
445 packet_write(1, "NAK\n");
42526b4 @spearce Add stateless RPC options to upload-pack, receive-pack
spearce authored
446 if (stateless_rpc)
447 exit(0);
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
448 continue;
449 }
fd13b21 @d0k Move local variables to narrower scopes
d0k authored
450 strip(line, len);
cc44c76 Mechanical conversion to use prefixcmp()
Junio C Hamano authored
451 if (!prefixcmp(line, "have ")) {
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
452 switch (got_sha1(line+5, sha1)) {
453 case -1: /* they have what we do not */
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
454 if (multi_ack && ok_to_give_up()) {
455 const char *hex = sha1_to_hex(sha1);
456 if (multi_ack == 2)
457 packet_write(1, "ACK %s ready\n", hex);
458 else
459 packet_write(1, "ACK %s continue\n", hex);
460 }
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
461 break;
462 default:
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
463 memcpy(last_hex, sha1_to_hex(sha1), 41);
464 if (multi_ack == 2)
465 packet_write(1, "ACK %s common\n", last_hex);
466 else if (multi_ack)
467 packet_write(1, "ACK %s continue\n", last_hex);
c04c4e5 upload-pack: minor clean-up in multi-ack logic
Junio C Hamano authored
468 else if (have_obj.nr == 1)
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
469 packet_write(1, "ACK %s\n", last_hex);
937a515 upload-pack: stop the other side when they have more roots than we do.
Junio C Hamano authored
470 break;
af2d3aa Revert recent fetch-pack/upload-pack updates.
Junio C Hamano authored
471 }
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
472 continue;
473 }
474 if (!strcmp(line, "done")) {
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
475 if (have_obj.nr > 0) {
1bd8c8f @dscho git-upload-pack: Support the multi_ack protocol
dscho authored
476 if (multi_ack)
c04c4e5 upload-pack: minor clean-up in multi-ack logic
Junio C Hamano authored
477 packet_write(1, "ACK %s\n", last_hex);
1bd8c8f @dscho git-upload-pack: Support the multi_ack protocol
dscho authored
478 return 0;
479 }
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
480 packet_write(1, "NAK\n");
481 return -1;
482 }
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
483 die("git upload-pack: expected SHA1 list, got '%s'", line);
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
484 }
485 }
486
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
487 static void receive_needs(void)
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
488 {
ed09aef @dscho support fetching into a shallow repository
dscho authored
489 struct object_array shallows = {0, 0, NULL};
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
490 static char line[1000];
016e6cc @dscho allow cloning a repository "shallowly"
dscho authored
491 int len, depth = 0;
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
492
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
493 shallow_nr = 0;
49aaddd @spearce Teach upload-pack to log the received need lines to an fd
spearce authored
494 if (debug_fd)
2b7ca83 @meyering use write_str_in_full helper to avoid literal string lengths
meyering authored
495 write_str_in_full(debug_fd, "#S\n");
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
496 for (;;) {
565ebbf upload-pack: tighten request validation.
Junio C Hamano authored
497 struct object *o;
6ece0d3 upload-pack: use object pointer not copy of sha1 to keep track of has/ne...
Junio C Hamano authored
498 unsigned char sha1_buf[20];
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
499 len = packet_read_line(0, line, sizeof(line));
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
500 reset_timeout();
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
501 if (!len)
ed09aef @dscho support fetching into a shallow repository
dscho authored
502 break;
49aaddd @spearce Teach upload-pack to log the received need lines to an fd
spearce authored
503 if (debug_fd)
504 write_in_full(debug_fd, line, len);
e091eb9 upload-pack: Do not choke on too many heads request.
Junio C Hamano authored
505
599065a prefixcmp(): fix-up mechanical conversion.
Junio C Hamano authored
506 if (!prefixcmp(line, "shallow ")) {
ed09aef @dscho support fetching into a shallow repository
dscho authored
507 unsigned char sha1[20];
508 struct object *object;
509 if (get_sha1(line + 8, sha1))
510 die("invalid shallow line: %s", line);
511 object = parse_object(sha1);
512 if (!object)
513 die("did not find object for %s", line);
f53514b @dscho allow deepening of a shallow repository
dscho authored
514 object->flags |= CLIENT_SHALLOW;
ed09aef @dscho support fetching into a shallow repository
dscho authored
515 add_object_array(object, NULL, &shallows);
516 continue;
517 }
599065a prefixcmp(): fix-up mechanical conversion.
Junio C Hamano authored
518 if (!prefixcmp(line, "deepen ")) {
016e6cc @dscho allow cloning a repository "shallowly"
dscho authored
519 char *end;
520 depth = strtol(line + 7, &end, 0);
521 if (end == line + 7 || depth <= 0)
522 die("Invalid deepen: %s", line);
523 continue;
524 }
599065a prefixcmp(): fix-up mechanical conversion.
Junio C Hamano authored
525 if (prefixcmp(line, "want ") ||
6ece0d3 upload-pack: use object pointer not copy of sha1 to keep track of has/ne...
Junio C Hamano authored
526 get_sha1_hex(line+5, sha1_buf))
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
527 die("git upload-pack: protocol error, "
e091eb9 upload-pack: Do not choke on too many heads request.
Junio C Hamano authored
528 "expected to get sha, not '%s'", line);
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
529 if (strstr(line+45, "multi_ack_detailed"))
530 multi_ack = 2;
531 else if (strstr(line+45, "multi_ack"))
1bd8c8f @dscho git-upload-pack: Support the multi_ack protocol
dscho authored
532 multi_ack = 1;
b19696c Use thin pack transfer in "git fetch".
Junio C Hamano authored
533 if (strstr(line+45, "thin-pack"))
534 use_thin_pack = 1;
e4fe4b8 let the GIT native protocol use offsets to delta base when possible
Nicolas Pitre authored
535 if (strstr(line+45, "ofs-delta"))
536 use_ofs_delta = 1;
d47f3db Prepare larger packet buffer for upload-pack protocol.
Junio C Hamano authored
537 if (strstr(line+45, "side-band-64k"))
538 use_sideband = LARGE_PACKET_MAX;
539 else if (strstr(line+45, "side-band"))
540 use_sideband = DEFAULT_PACKET_MAX;
b0e9089 @dscho Fixup no-progress for fetch & clone
dscho authored
541 if (strstr(line+45, "no-progress"))
542 no_progress = 1;
348e390 @spearce Teach fetch-pack/upload-pack about --include-tag
spearce authored
543 if (strstr(line+45, "include-tag"))
544 use_include_tag = 1;
565ebbf upload-pack: tighten request validation.
Junio C Hamano authored
545
546 /* We have sent all our refs already, and the other end
547 * should have chosen out of them; otherwise they are
548 * asking for nonsense.
549 *
550 * Hmph. We may later want to allow "want" line that
551 * asks for something like "master~10" (symbolic)...
552 * would it make sense? I don't know.
553 */
554 o = lookup_object(sha1_buf);
555 if (!o || !(o->flags & OUR_REF))
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
556 die("git upload-pack: not our ref %s", line+5);
565ebbf upload-pack: tighten request validation.
Junio C Hamano authored
557 if (!(o->flags & WANTED)) {
558 o->flags |= WANTED;
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
559 add_object_array(o, NULL, &want_obj);
565ebbf upload-pack: tighten request validation.
Junio C Hamano authored
560 }
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
561 }
49aaddd @spearce Teach upload-pack to log the received need lines to an fd
spearce authored
562 if (debug_fd)
2b7ca83 @meyering use write_str_in_full helper to avoid literal string lengths
meyering authored
563 write_str_in_full(debug_fd, "#E\n");
9462e3f upload-pack: squelch progress indicator if client cannot see it
Johannes Sixt authored
564
565 if (!use_sideband && daemon_mode)
566 no_progress = 1;
567
f53514b @dscho allow deepening of a shallow repository
dscho authored
568 if (depth == 0 && shallows.nr == 0)
569 return;
016e6cc @dscho allow cloning a repository "shallowly"
dscho authored
570 if (depth > 0) {
571 struct commit_list *result, *backup;
f53514b @dscho allow deepening of a shallow repository
dscho authored
572 int i;
573 backup = result = get_shallow_commits(&want_obj, depth,
574 SHALLOW, NOT_SHALLOW);
016e6cc @dscho allow cloning a repository "shallowly"
dscho authored
575 while (result) {
f53514b @dscho allow deepening of a shallow repository
dscho authored
576 struct object *object = &result->item->object;
1f2de76 @julliard upload-pack: Check for NOT_SHALLOW flag before sending a shallow to the ...
julliard authored
577 if (!(object->flags & (CLIENT_SHALLOW|NOT_SHALLOW))) {
f53514b @dscho allow deepening of a shallow repository
dscho authored
578 packet_write(1, "shallow %s",
579 sha1_to_hex(object->sha1));
580 register_shallow(object->sha1);
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
581 shallow_nr++;
f53514b @dscho allow deepening of a shallow repository
dscho authored
582 }
016e6cc @dscho allow cloning a repository "shallowly"
dscho authored
583 result = result->next;
584 }
585 free_commit_list(backup);
f53514b @dscho allow deepening of a shallow repository
dscho authored
586 for (i = 0; i < shallows.nr; i++) {
587 struct object *object = shallows.objects[i].item;
588 if (object->flags & NOT_SHALLOW) {
589 struct commit_list *parents;
590 packet_write(1, "unshallow %s",
591 sha1_to_hex(object->sha1));
592 object->flags &= ~CLIENT_SHALLOW;
593 /* make sure the real parents are parsed */
594 unregister_shallow(object->sha1);
176d45c shallow clone: unparse and reparse an unshallowed commit
Junio C Hamano authored
595 object->parsed = 0;
dec38c8 check return value from parse_commit() in various functions
Martin Koegler authored
596 if (parse_commit((struct commit *)object))
597 die("invalid commit");
f53514b @dscho allow deepening of a shallow repository
dscho authored
598 parents = ((struct commit *)object)->parents;
599 while (parents) {
600 add_object_array(&parents->item->object,
601 NULL, &want_obj);
602 parents = parents->next;
603 }
6523078 make shallow repository deepening more network efficient
Nicolas Pitre authored
604 add_object_array(object, NULL, &extra_edge_obj);
f53514b @dscho allow deepening of a shallow repository
dscho authored
605 }
606 /* make sure commit traversal conforms to client */
607 register_shallow(object->sha1);
608 }
609 packet_flush(1);
610 } else
611 if (shallows.nr > 0) {
612 int i;
613 for (i = 0; i < shallows.nr; i++)
614 register_shallow(shallows.objects[i].item->sha1);
615 }
f0cea83 @sirnot Shift object enumeration out of upload-pack
sirnot authored
616
617 shallow_nr += shallows.nr;
f53514b @dscho allow deepening of a shallow repository
dscho authored
618 free(shallows.objects);
fb9040c Make git-fetch-pack and git-upload-pack negotiate needs/haves fully
Linus Torvalds authored
619 }
620
8da1977 Tell between packed, unpacked and symbolic refs.
Junio C Hamano authored
621 static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
622 {
ed09aef @dscho support fetching into a shallow repository
dscho authored
623 static const char *capabilities = "multi_ack thin-pack side-band"
348e390 @spearce Teach fetch-pack/upload-pack about --include-tag
spearce authored
624 " side-band-64k ofs-delta shallow no-progress"
78affc4 @spearce Add multi_ack_detailed capability to fetch-pack/upload-pack
spearce authored
625 " include-tag multi_ack_detailed";
f6b42a8 Show peeled onion from upload-pack and server-info.
Junio C Hamano authored
626 struct object *o = parse_object(sha1);
627
b5b1699 @cworth-gh Prevent git-upload-pack segfault if object cannot be found
cworth-gh authored
628 if (!o)
7e44c93 @gitster 'git foo' program identifies itself without dash in die() messages
gitster authored
629 die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
b5b1699 @cworth-gh Prevent git-upload-pack segfault if object cannot be found
cworth-gh authored
630
1f5881b @dscho fix multi_ack.
dscho authored
631 if (capabilities)
632 packet_write(1, "%s %s%c%s\n", sha1_to_hex(sha1), refname,
633 0, capabilities);
634 else
635 packet_write(1, "%s %s\n", sha1_to_hex(sha1), refname);
636 capabilities = NULL;
565ebbf upload-pack: tighten request validation.
Junio C Hamano authored
637 if (!(o->flags & OUR_REF)) {
638 o->flags |= OUR_REF;
639 nr_our_refs++;
640 }
1974632 Remove TYPE_* constant macros and use object_type enums consistently.
Linus Torvalds authored
641 if (o->type == OBJ_TAG) {
9534f40 Be careful when dereferencing tags.
Junio C Hamano authored
642 o = deref_tag(o, refname, 0);
affeef1 deref_tag: handle return value NULL
Martin Koegler authored
643 if (o)
644 packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
f6b42a8 Show peeled onion from upload-pack and server-info.
Junio C Hamano authored
645 }
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
646 return 0;
647 }
648
42526b4 @spearce Add stateless RPC options to upload-pack, receive-pack
spearce authored
649 static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
650 {
651 struct object *o = parse_object(sha1);
652 if (!o)
653 die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1));
654 if (!(o->flags & OUR_REF)) {
655 o->flags |= OUR_REF;
656 nr_our_refs++;
657 }
658 return 0;
659 }
660
59076eb Make upload_pack void and remove conditional return.
David Rientjes authored
661 static void upload_pack(void)
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
662 {
42526b4 @spearce Add stateless RPC options to upload-pack, receive-pack
spearce authored
663 if (advertise_refs || !stateless_rpc) {
664 reset_timeout();
665 head_ref(send_ref, NULL);
666 for_each_ref(send_ref, NULL);
667 packet_flush(1);
668 } else {
669 head_ref(mark_our_ref, NULL);
670 for_each_ref(mark_our_ref, NULL);
671 }
672 if (advertise_refs)
673 return;
674
b1e9fff upload-pack: lift MAX_NEEDS and MAX_HAS limitation
Junio C Hamano authored
675 receive_needs();
59076eb Make upload_pack void and remove conditional return.
David Rientjes authored
676 if (want_obj.nr) {
677 get_common_commits();
678 create_pack_file();
679 }
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
680 }
681
682 int main(int argc, char **argv)
683 {
8d63013 Server-side support for user-relative paths.
Andreas Ericsson authored
684 char *dir;
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
685 int i;
686 int strict = 0;
687
2fb3f6d @sprohaska Add calls to git_extract_argv0_path() in programs that call git_config_*
sprohaska authored
688 git_extract_argv0_path(argv[0]);
dae556b @chriscool environment: add global variable to disable replacement
chriscool authored
689 read_replace_refs = 0;
2fb3f6d @sprohaska Add calls to git_extract_argv0_path() in programs that call git_config_*
sprohaska authored
690
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
691 for (i = 1; i < argc; i++) {
692 char *arg = argv[i];
693
694 if (arg[0] != '-')
695 break;
42526b4 @spearce Add stateless RPC options to upload-pack, receive-pack
spearce authored
696 if (!strcmp(arg, "--advertise-refs")) {
697 advertise_refs = 1;
698 continue;
699 }
700 if (!strcmp(arg, "--stateless-rpc")) {
701 stateless_rpc = 1;
702 continue;
703 }
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
704 if (!strcmp(arg, "--strict")) {
705 strict = 1;
706 continue;
707 }
cc44c76 Mechanical conversion to use prefixcmp()
Junio C Hamano authored
708 if (!prefixcmp(arg, "--timeout=")) {
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
709 timeout = atoi(arg+10);
9462e3f upload-pack: squelch progress indicator if client cannot see it
Johannes Sixt authored
710 daemon_mode = 1;
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
711 continue;
712 }
713 if (!strcmp(arg, "--")) {
714 i++;
715 break;
716 }
717 }
a6080a0 @gitster War on whitespace
gitster authored
718
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
719 if (i != argc-1)
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
720 usage(upload_pack_usage);
04b3305 upload-pack: Initialize the exec-path.
Johannes Sixt authored
721
e1464ca Record the command invocation path early
Johannes Sixt authored
722 setup_path();
04b3305 upload-pack: Initialize the exec-path.
Johannes Sixt authored
723
960decc git-daemon: timeout, eliminate double DWIM
H. Peter Anvin authored
724 dir = argv[i];
113b947 Make "upload-pack" match git-fetch-pack usage
Linus Torvalds authored
725
8d63013 Server-side support for user-relative paths.
Andreas Ericsson authored
726 if (!enter_repo(dir, strict))
05ac6b3 @peff improve missing repository error message
peff authored
727 die("'%s' does not appear to be a git repository", dir);
a0022ee shallow repository: disable unsupported operations for now.
Junio C Hamano authored
728 if (is_repository_shallow())
729 die("attempt to fetch/clone from a shallow repository");
49aaddd @spearce Teach upload-pack to log the received need lines to an fd
spearce authored
730 if (getenv("GIT_DEBUG_SEND_PACK"))
731 debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK"));
def88e9 Commit first cut at "git-fetch-pack"
Linus Torvalds authored
732 upload_pack();
733 return 0;
734 }
Something went wrong with that request. Please try again.