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