]> git.ipfire.org Git - thirdparty/git.git/blame - builtin-receive-pack.c
Merge branch 'lt/maint-diff-reduce-lstat'
[thirdparty/git.git] / builtin-receive-pack.c
CommitLineData
575f4974 1#include "cache.h"
fc04c412 2#include "pack.h"
8a65ff76 3#include "refs.h"
f3a3214e 4#include "pkt-line.h"
b1bf95bb 5#include "run-command.h"
576162a4 6#include "exec_cmd.h"
11031d7e
JS
7#include "commit.h"
8#include "object.h"
d79796bc
JH
9#include "remote.h"
10#include "transport.h"
575f4974 11
34263de0 12static const char receive_pack_usage[] = "git receive-pack <git-dir>";
575f4974 13
986e8239 14enum deny_action {
3d95d92b 15 DENY_UNCONFIGURED,
986e8239
JK
16 DENY_IGNORE,
17 DENY_WARN,
18 DENY_REFUSE,
19};
20
1b53a076
JH
21static int deny_deletes;
22static int deny_non_fast_forwards;
3d95d92b 23static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
747ca245 24static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
20dc0016 25static int receive_fsck_objects;
e28714c5
JH
26static int receive_unpack_limit = -1;
27static int transfer_unpack_limit = -1;
46732fae 28static int unpack_limit = 100;
96f1e58f 29static int report_status;
b74fce16 30static int prefer_ofs_delta = 1;
747ca245 31static const char *head_name;
b74fce16 32static char *capabilities_to_send;
cfee10a7 33
986e8239
JK
34static enum deny_action parse_deny_action(const char *var, const char *value)
35{
36 if (value) {
37 if (!strcasecmp(value, "ignore"))
38 return DENY_IGNORE;
39 if (!strcasecmp(value, "warn"))
40 return DENY_WARN;
41 if (!strcasecmp(value, "refuse"))
42 return DENY_REFUSE;
43 }
44 if (git_config_bool(var, value))
45 return DENY_REFUSE;
46 return DENY_IGNORE;
47}
48
ef90d6d4 49static int receive_pack_config(const char *var, const char *value, void *cb)
6fb75bed 50{
a240de11
JK
51 if (strcmp(var, "receive.denydeletes") == 0) {
52 deny_deletes = git_config_bool(var, value);
53 return 0;
54 }
55
e28714c5 56 if (strcmp(var, "receive.denynonfastforwards") == 0) {
6fb75bed
SP
57 deny_non_fast_forwards = git_config_bool(var, value);
58 return 0;
59 }
60
e28714c5
JH
61 if (strcmp(var, "receive.unpacklimit") == 0) {
62 receive_unpack_limit = git_config_int(var, value);
fc04c412
SP
63 return 0;
64 }
65
e28714c5
JH
66 if (strcmp(var, "transfer.unpacklimit") == 0) {
67 transfer_unpack_limit = git_config_int(var, value);
68 return 0;
69 }
70
20dc0016
MK
71 if (strcmp(var, "receive.fsckobjects") == 0) {
72 receive_fsck_objects = git_config_bool(var, value);
73 return 0;
74 }
75
986e8239
JK
76 if (!strcmp(var, "receive.denycurrentbranch")) {
77 deny_current_branch = parse_deny_action(var, value);
78 return 0;
79 }
80
747ca245
JH
81 if (strcmp(var, "receive.denydeletecurrent") == 0) {
82 deny_delete_current = parse_deny_action(var, value);
83 return 0;
84 }
85
b74fce16
NP
86 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
87 prefer_ofs_delta = git_config_bool(var, value);
88 return 0;
89 }
90
ef90d6d4 91 return git_default_config(var, value, cb);
6fb75bed
SP
92}
93
8da19775 94static int show_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
575f4974 95{
b74fce16 96 if (!capabilities_to_send)
cfee10a7
JH
97 packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
98 else
99 packet_write(1, "%s %s%c%s\n",
b74fce16
NP
100 sha1_to_hex(sha1), path, 0, capabilities_to_send);
101 capabilities_to_send = NULL;
8a65ff76 102 return 0;
575f4974
LT
103}
104
8a65ff76 105static void write_head_info(void)
575f4974 106{
cb5d709f 107 for_each_ref(show_ref, NULL);
b74fce16 108 if (capabilities_to_send)
8da19775 109 show_ref("capabilities^{}", null_sha1, 0, NULL);
cfee10a7 110
575f4974
LT
111}
112
eb1af2df
LT
113struct command {
114 struct command *next;
cfee10a7 115 const char *error_string;
eb1af2df
LT
116 unsigned char old_sha1[20];
117 unsigned char new_sha1[20];
8f1d2e6f 118 char ref_name[FLEX_ARRAY]; /* more */
575f4974
LT
119};
120
96f1e58f 121static struct command *commands;
575f4974 122
05ef58ec
SP
123static const char pre_receive_hook[] = "hooks/pre-receive";
124static const char post_receive_hook[] = "hooks/post-receive";
b1bf95bb 125
6c319a22
SP
126static int hook_status(int code, const char *hook_name)
127{
128 switch (code) {
129 case 0:
130 return 0;
131 case -ERR_RUN_COMMAND_FORK:
132 return error("hook fork failed");
133 case -ERR_RUN_COMMAND_EXEC:
134 return error("hook execute failed");
f43cd49f
SP
135 case -ERR_RUN_COMMAND_PIPE:
136 return error("hook pipe failed");
6c319a22
SP
137 case -ERR_RUN_COMMAND_WAITPID:
138 return error("waitpid failed");
139 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
140 return error("waitpid is confused");
141 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
142 return error("%s died of signal", hook_name);
143 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
144 return error("%s died strangely", hook_name);
145 default:
146 error("%s exited with error code %d", hook_name, -code);
147 return -code;
148 }
149}
150
ae98a008 151static int run_receive_hook(const char *hook_name)
b1bf95bb 152{
f43cd49f 153 static char buf[sizeof(commands->old_sha1) * 2 + PATH_MAX + 4];
c8dd2771 154 struct command *cmd;
f43cd49f
SP
155 struct child_process proc;
156 const char *argv[2];
157 int have_input = 0, code;
c8dd2771 158
f43cd49f 159 for (cmd = commands; !have_input && cmd; cmd = cmd->next) {
c8dd2771 160 if (!cmd->error_string)
f43cd49f 161 have_input = 1;
c8dd2771 162 }
b1bf95bb 163
f43cd49f 164 if (!have_input || access(hook_name, X_OK) < 0)
b1bf95bb 165 return 0;
c8dd2771 166
c8dd2771 167 argv[0] = hook_name;
f43cd49f
SP
168 argv[1] = NULL;
169
170 memset(&proc, 0, sizeof(proc));
171 proc.argv = argv;
172 proc.in = -1;
173 proc.stdout_to_stderr = 1;
174
175 code = start_command(&proc);
176 if (code)
177 return hook_status(code, hook_name);
178 for (cmd = commands; cmd; cmd = cmd->next) {
c8dd2771 179 if (!cmd->error_string) {
f43cd49f
SP
180 size_t n = snprintf(buf, sizeof(buf), "%s %s %s\n",
181 sha1_to_hex(cmd->old_sha1),
182 sha1_to_hex(cmd->new_sha1),
183 cmd->ref_name);
184 if (write_in_full(proc.in, buf, n) != n)
185 break;
c8dd2771 186 }
c8dd2771 187 }
e72ae288 188 close(proc.in);
f43cd49f 189 return hook_status(finish_command(&proc), hook_name);
b1bf95bb
JW
190}
191
1d9e8b56
SP
192static int run_update_hook(struct command *cmd)
193{
194 static const char update_hook[] = "hooks/update";
195 struct child_process proc;
196 const char *argv[5];
197
198 if (access(update_hook, X_OK) < 0)
199 return 0;
200
201 argv[0] = update_hook;
202 argv[1] = cmd->ref_name;
203 argv[2] = sha1_to_hex(cmd->old_sha1);
204 argv[3] = sha1_to_hex(cmd->new_sha1);
205 argv[4] = NULL;
206
207 memset(&proc, 0, sizeof(proc));
208 proc.argv = argv;
209 proc.no_stdin = 1;
210 proc.stdout_to_stderr = 1;
211
212 return hook_status(run_command(&proc), update_hook);
213}
214
986e8239
JK
215static int is_ref_checked_out(const char *ref)
216{
986e8239
JK
217 if (is_bare_repository())
218 return 0;
219
747ca245 220 if (!head_name)
986e8239 221 return 0;
747ca245 222 return !strcmp(head_name, ref);
986e8239
JK
223}
224
3d95d92b
JH
225static char *warn_unconfigured_deny_msg[] = {
226 "Updating the currently checked out branch may cause confusion,",
227 "as the index and work tree do not reflect changes that are in HEAD.",
228 "As a result, you may see the changes you just pushed into it",
229 "reverted when you run 'git diff' over there, and you may want",
230 "to run 'git reset --hard' before starting to work to recover.",
231 "",
232 "You can set 'receive.denyCurrentBranch' configuration variable to",
233 "'refuse' in the remote repository to forbid pushing into its",
234 "current branch."
235 "",
236 "To allow pushing into the current branch, you can set it to 'ignore';",
237 "but this is not recommended unless you arranged to update its work",
238 "tree to match what you pushed in some other way.",
239 "",
240 "To squelch this message, you can set it to 'warn'.",
241 "",
242 "Note that the default will change in a future version of git",
243 "to refuse updating the current branch unless you have the",
244 "configuration variable set to either 'ignore' or 'warn'."
245};
246
247static void warn_unconfigured_deny(void)
248{
249 int i;
250 for (i = 0; i < ARRAY_SIZE(warn_unconfigured_deny_msg); i++)
88a667f0 251 warning("%s", warn_unconfigured_deny_msg[i]);
3d95d92b
JH
252}
253
747ca245
JH
254static char *warn_unconfigured_deny_delete_current_msg[] = {
255 "Deleting the current branch can cause confusion by making the next",
256 "'git clone' not check out any file.",
257 "",
258 "You can set 'receive.denyDeleteCurrent' configuration variable to",
259 "'refuse' in the remote repository to disallow deleting the current",
260 "branch.",
261 "",
262 "You can set it to 'ignore' to allow such a delete without a warning.",
263 "",
264 "To make this warning message less loud, you can set it to 'warn'.",
265 "",
266 "Note that the default will change in a future version of git",
267 "to refuse deleting the current branch unless you have the",
268 "configuration variable set to either 'ignore' or 'warn'."
269};
270
271static void warn_unconfigured_deny_delete_current(void)
272{
273 int i;
274 for (i = 0;
275 i < ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg);
276 i++)
88a667f0 277 warning("%s", warn_unconfigured_deny_delete_current_msg[i]);
747ca245
JH
278}
279
8aaf7d64 280static const char *update(struct command *cmd)
2eca23da 281{
cfee10a7
JH
282 const char *name = cmd->ref_name;
283 unsigned char *old_sha1 = cmd->old_sha1;
284 unsigned char *new_sha1 = cmd->new_sha1;
3159c8dc 285 struct ref_lock *lock;
2eca23da 286
061d6b9a
MK
287 /* only refs/... are allowed */
288 if (prefixcmp(name, "refs/") || check_ref_format(name + 5)) {
0b8293f6 289 error("refusing to create funny ref '%s' remotely", name);
8aaf7d64 290 return "funny refname";
cfee10a7 291 }
d8a1deec 292
3d95d92b
JH
293 if (is_ref_checked_out(name)) {
294 switch (deny_current_branch) {
295 case DENY_IGNORE:
986e8239 296 break;
3d95d92b
JH
297 case DENY_UNCONFIGURED:
298 case DENY_WARN:
299 warning("updating the current branch");
300 if (deny_current_branch == DENY_UNCONFIGURED)
301 warn_unconfigured_deny();
986e8239 302 break;
3d95d92b
JH
303 case DENY_REFUSE:
304 error("refusing to update checked out branch: %s", name);
305 return "branch is currently checked out";
306 }
986e8239
JK
307 }
308
d4f694ba 309 if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
8aaf7d64
SP
310 error("unpack should have generated %s, "
311 "but I can't find it!", sha1_to_hex(new_sha1));
312 return "bad pack";
cfee10a7 313 }
747ca245
JH
314
315 if (!is_null_sha1(old_sha1) && is_null_sha1(new_sha1)) {
316 if (deny_deletes && !prefixcmp(name, "refs/heads/")) {
317 error("denying ref deletion for %s", name);
318 return "deletion prohibited";
319 }
320
321 if (!strcmp(name, head_name)) {
322 switch (deny_delete_current) {
323 case DENY_IGNORE:
324 break;
325 case DENY_WARN:
326 case DENY_UNCONFIGURED:
327 if (deny_delete_current == DENY_UNCONFIGURED)
328 warn_unconfigured_deny_delete_current();
329 warning("deleting the current branch");
330 break;
331 case DENY_REFUSE:
332 error("refusing to delete the current branch: %s", name);
333 return "deletion of the current branch prohibited";
334 }
335 }
a240de11 336 }
747ca245 337
d4f694ba 338 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
ba988a83 339 !is_null_sha1(old_sha1) &&
cc44c765 340 !prefixcmp(name, "refs/heads/")) {
eab82707 341 struct object *old_object, *new_object;
11031d7e 342 struct commit *old_commit, *new_commit;
9edd7e46 343 struct commit_list *bases, *ent;
11031d7e 344
eab82707
MK
345 old_object = parse_object(old_sha1);
346 new_object = parse_object(new_sha1);
347
348 if (!old_object || !new_object ||
349 old_object->type != OBJ_COMMIT ||
350 new_object->type != OBJ_COMMIT) {
351 error("bad sha1 objects for %s", name);
352 return "bad ref";
353 }
354 old_commit = (struct commit *)old_object;
355 new_commit = (struct commit *)new_object;
9edd7e46
JS
356 bases = get_merge_bases(old_commit, new_commit, 1);
357 for (ent = bases; ent; ent = ent->next)
358 if (!hashcmp(old_sha1, ent->item->object.sha1))
11031d7e 359 break;
9edd7e46 360 free_commit_list(bases);
8aaf7d64
SP
361 if (!ent) {
362 error("denying non-fast forward %s"
363 " (you should pull first)", name);
364 return "non-fast forward";
365 }
11031d7e 366 }
1d9e8b56 367 if (run_update_hook(cmd)) {
8aaf7d64
SP
368 error("hook declined to update %s", name);
369 return "hook declined";
b1bf95bb 370 }
3159c8dc 371
d4f694ba 372 if (is_null_sha1(new_sha1)) {
28391a80
JS
373 if (!parse_object(old_sha1)) {
374 warning ("Allowing deletion of corrupt ref.");
375 old_sha1 = NULL;
376 }
eca35a25 377 if (delete_ref(name, old_sha1, 0)) {
8aaf7d64
SP
378 error("failed to delete %s", name);
379 return "failed to delete";
d4f694ba 380 }
8aaf7d64 381 return NULL; /* good */
d4f694ba
JH
382 }
383 else {
68db31cc 384 lock = lock_any_ref_for_update(name, old_sha1, 0);
d4f694ba 385 if (!lock) {
8aaf7d64
SP
386 error("failed to lock %s", name);
387 return "failed to lock";
d4f694ba 388 }
ef203f08 389 if (write_ref_sha1(lock, new_sha1, "push")) {
8aaf7d64 390 return "failed to write"; /* error() already called */
ef203f08 391 }
8aaf7d64 392 return NULL; /* good */
19614330 393 }
2eca23da
LT
394}
395
19614330
JH
396static char update_post_hook[] = "hooks/post-update";
397
398static void run_update_post_hook(struct command *cmd)
399{
400 struct command *cmd_p;
401 int argc;
9201c707 402 const char **argv;
19614330 403
3e6e152c 404 for (argc = 0, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
cfee10a7 405 if (cmd_p->error_string)
19614330
JH
406 continue;
407 argc++;
408 }
3e6e152c
SP
409 if (!argc || access(update_post_hook, X_OK) < 0)
410 return;
411 argv = xmalloc(sizeof(*argv) * (2 + argc));
19614330
JH
412 argv[0] = update_post_hook;
413
414 for (argc = 1, cmd_p = cmd; cmd_p; cmd_p = cmd_p->next) {
9201c707 415 char *p;
cfee10a7 416 if (cmd_p->error_string)
19614330 417 continue;
9201c707
JH
418 p = xmalloc(strlen(cmd_p->ref_name) + 1);
419 strcpy(p, cmd_p->ref_name);
420 argv[argc] = p;
19614330
JH
421 argc++;
422 }
423 argv[argc] = NULL;
95d3c4f5
SP
424 run_command_v_opt(argv, RUN_COMMAND_NO_STDIN
425 | RUN_COMMAND_STDOUT_TO_STDERR);
19614330 426}
2eca23da 427
8aaf7d64 428static void execute_commands(const char *unpacker_error)
575f4974 429{
eb1af2df 430 struct command *cmd = commands;
747ca245 431 unsigned char sha1[20];
8aaf7d64
SP
432
433 if (unpacker_error) {
434 while (cmd) {
435 cmd->error_string = "n/a (unpacker error)";
436 cmd = cmd->next;
437 }
438 return;
439 }
440
ae98a008 441 if (run_receive_hook(pre_receive_hook)) {
05ef58ec
SP
442 while (cmd) {
443 cmd->error_string = "pre-receive hook declined";
444 cmd = cmd->next;
445 }
446 return;
447 }
448
747ca245
JH
449 head_name = resolve_ref("HEAD", sha1, 0, NULL);
450
eb1af2df 451 while (cmd) {
8aaf7d64 452 cmd->error_string = update(cmd);
eb1af2df 453 cmd = cmd->next;
575f4974
LT
454 }
455}
456
457static void read_head_info(void)
458{
eb1af2df 459 struct command **p = &commands;
575f4974
LT
460 for (;;) {
461 static char line[1000];
eb1af2df
LT
462 unsigned char old_sha1[20], new_sha1[20];
463 struct command *cmd;
cfee10a7
JH
464 char *refname;
465 int len, reflen;
eb1af2df
LT
466
467 len = packet_read_line(0, line, sizeof(line));
575f4974
LT
468 if (!len)
469 break;
eb1af2df
LT
470 if (line[len-1] == '\n')
471 line[--len] = 0;
472 if (len < 83 ||
473 line[40] != ' ' ||
474 line[81] != ' ' ||
475 get_sha1_hex(line, old_sha1) ||
476 get_sha1_hex(line + 41, new_sha1))
cfee10a7
JH
477 die("protocol error: expected old/new/ref, got '%s'",
478 line);
479
480 refname = line + 82;
481 reflen = strlen(refname);
482 if (reflen + 82 < len) {
483 if (strstr(refname + reflen + 1, "report-status"))
484 report_status = 1;
485 }
eb1af2df 486 cmd = xmalloc(sizeof(struct command) + len - 80);
e702496e
SP
487 hashcpy(cmd->old_sha1, old_sha1);
488 hashcpy(cmd->new_sha1, new_sha1);
eb1af2df 489 memcpy(cmd->ref_name, line + 82, len - 81);
8aaf7d64 490 cmd->error_string = NULL;
eb1af2df
LT
491 cmd->next = NULL;
492 *p = cmd;
493 p = &cmd->next;
575f4974
LT
494 }
495}
496
fc04c412
SP
497static const char *parse_pack_header(struct pack_header *hdr)
498{
a69e5429
JH
499 switch (read_pack_header(0, hdr)) {
500 case PH_ERROR_EOF:
501 return "eof before pack header was fully read";
502
503 case PH_ERROR_PACK_SIGNATURE:
fc04c412 504 return "protocol error (pack signature mismatch detected)";
a69e5429
JH
505
506 case PH_ERROR_PROTOCOL:
fc04c412 507 return "protocol error (pack version unsupported)";
a69e5429
JH
508
509 default:
510 return "unknown error in parse_pack_header";
511
512 case 0:
513 return NULL;
514 }
fc04c412
SP
515}
516
576162a4
NP
517static const char *pack_lockfile;
518
861ed121 519static const char *unpack(void)
575f4974 520{
fc04c412
SP
521 struct pack_header hdr;
522 const char *hdr_err;
523 char hdr_arg[38];
fc04c412
SP
524
525 hdr_err = parse_pack_header(&hdr);
526 if (hdr_err)
527 return hdr_err;
6e1c2344
RJ
528 snprintf(hdr_arg, sizeof(hdr_arg),
529 "--pack_header=%"PRIu32",%"PRIu32,
fc04c412
SP
530 ntohl(hdr.hdr_version), ntohl(hdr.hdr_entries));
531
532 if (ntohl(hdr.hdr_entries) < unpack_limit) {
20dc0016
MK
533 int code, i = 0;
534 const char *unpacker[4];
535 unpacker[i++] = "unpack-objects";
536 if (receive_fsck_objects)
537 unpacker[i++] = "--strict";
538 unpacker[i++] = hdr_arg;
539 unpacker[i++] = NULL;
9b0b5093 540 code = run_command_v_opt(unpacker, RUN_GIT_CMD);
576162a4 541 switch (code) {
fc04c412
SP
542 case 0:
543 return NULL;
544 case -ERR_RUN_COMMAND_FORK:
545 return "unpack fork failed";
546 case -ERR_RUN_COMMAND_EXEC:
547 return "unpack execute failed";
548 case -ERR_RUN_COMMAND_WAITPID:
549 return "waitpid failed";
550 case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
551 return "waitpid is confused";
552 case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
553 return "unpacker died of signal";
554 case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
555 return "unpacker died strangely";
556 default:
557 return "unpacker exited with error code";
576162a4
NP
558 }
559 } else {
20dc0016
MK
560 const char *keeper[7];
561 int s, status, i = 0;
576162a4 562 char keep_arg[256];
e8016abf 563 struct child_process ip;
576162a4 564
85e72830 565 s = sprintf(keep_arg, "--keep=receive-pack %"PRIuMAX" on ", (uintmax_t) getpid());
576162a4
NP
566 if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
567 strcpy(keep_arg + s, "localhost");
568
20dc0016
MK
569 keeper[i++] = "index-pack";
570 keeper[i++] = "--stdin";
571 if (receive_fsck_objects)
572 keeper[i++] = "--strict";
573 keeper[i++] = "--fix-thin";
574 keeper[i++] = hdr_arg;
575 keeper[i++] = keep_arg;
576 keeper[i++] = NULL;
e8016abf
SP
577 memset(&ip, 0, sizeof(ip));
578 ip.argv = keeper;
579 ip.out = -1;
580 ip.git_cmd = 1;
581 if (start_command(&ip))
576162a4 582 return "index-pack fork failed";
106764e6 583 pack_lockfile = index_pack_lockfile(ip.out);
e72ae288 584 close(ip.out);
e8016abf
SP
585 status = finish_command(&ip);
586 if (!status) {
576162a4
NP
587 reprepare_packed_git();
588 return NULL;
589 }
590 return "index-pack abnormal exit";
cfee10a7
JH
591 }
592}
593
594static void report(const char *unpack_status)
595{
596 struct command *cmd;
597 packet_write(1, "unpack %s\n",
598 unpack_status ? unpack_status : "ok");
599 for (cmd = commands; cmd; cmd = cmd->next) {
600 if (!cmd->error_string)
601 packet_write(1, "ok %s\n",
602 cmd->ref_name);
603 else
604 packet_write(1, "ng %s %s\n",
605 cmd->ref_name, cmd->error_string);
575f4974 606 }
cfee10a7 607 packet_flush(1);
575f4974
LT
608}
609
d4f694ba
JH
610static int delete_only(struct command *cmd)
611{
612 while (cmd) {
613 if (!is_null_sha1(cmd->new_sha1))
614 return 0;
615 cmd = cmd->next;
616 }
617 return 1;
618}
619
d79796bc
JH
620static int add_refs_from_alternate(struct alternate_object_database *e, void *unused)
621{
b8492539
JH
622 char *other;
623 size_t len;
d79796bc
JH
624 struct remote *remote;
625 struct transport *transport;
626 const struct ref *extra;
627
b8492539
JH
628 e->name[-1] = '\0';
629 other = xstrdup(make_absolute_path(e->base));
630 e->name[-1] = '/';
631 len = strlen(other);
632
d79796bc
JH
633 while (other[len-1] == '/')
634 other[--len] = '\0';
635 if (len < 8 || memcmp(other + len - 8, "/objects", 8))
636 return 0;
637 /* Is this a git repository with refs? */
638 memcpy(other + len - 8, "/refs", 6);
639 if (!is_directory(other))
640 return 0;
641 other[len - 8] = '\0';
642 remote = remote_get(other);
643 transport = transport_get(remote, other);
644 for (extra = transport_get_remote_refs(transport);
645 extra;
646 extra = extra->next) {
647 add_extra_ref(".have", extra->old_sha1, 0);
648 }
649 transport_disconnect(transport);
650 free(other);
651 return 0;
652}
653
654static void add_alternate_refs(void)
655{
656 foreach_alt_odb(add_refs_from_alternate, NULL);
657}
658
be5908ae 659int cmd_receive_pack(int argc, const char **argv, const char *prefix)
575f4974 660{
d0efc8a7 661 int i;
8d630132 662 char *dir = NULL;
575f4974
LT
663
664 argv++;
665 for (i = 1; i < argc; i++) {
be5908ae 666 const char *arg = *argv++;
575f4974
LT
667
668 if (*arg == '-') {
575f4974
LT
669 /* Do flag handling here */
670 usage(receive_pack_usage);
671 }
d0efc8a7
LT
672 if (dir)
673 usage(receive_pack_usage);
be5908ae 674 dir = xstrdup(arg);
575f4974
LT
675 }
676 if (!dir)
677 usage(receive_pack_usage);
678
e1464ca7 679 setup_path();
5c09f321 680
3159c8dc 681 if (!enter_repo(dir, 0))
05ac6b34 682 die("'%s' does not appear to be a git repository", dir);
575f4974 683
a0022eeb
JH
684 if (is_repository_shallow())
685 die("attempt to push into a shallow repository");
686
ef90d6d4 687 git_config(receive_pack_config, NULL);
6fb75bed 688
e28714c5
JH
689 if (0 <= transfer_unpack_limit)
690 unpack_limit = transfer_unpack_limit;
691 else if (0 <= receive_unpack_limit)
692 unpack_limit = receive_unpack_limit;
693
b74fce16
NP
694 capabilities_to_send = (prefer_ofs_delta) ?
695 " report-status delete-refs ofs-delta " :
696 " report-status delete-refs ";
697
d79796bc 698 add_alternate_refs();
8a65ff76 699 write_head_info();
d79796bc 700 clear_extra_refs();
575f4974
LT
701
702 /* EOF */
f3a3214e 703 packet_flush(1);
575f4974
LT
704
705 read_head_info();
7f8e9828 706 if (commands) {
d4f694ba
JH
707 const char *unpack_status = NULL;
708
709 if (!delete_only(commands))
710 unpack_status = unpack();
8aaf7d64 711 execute_commands(unpack_status);
576162a4 712 if (pack_lockfile)
691f1a28 713 unlink_or_warn(pack_lockfile);
cfee10a7
JH
714 if (report_status)
715 report(unpack_status);
ae98a008 716 run_receive_hook(post_receive_hook);
8e663d9e 717 run_update_post_hook(commands);
7f8e9828 718 }
575f4974
LT
719 return 0;
720}