6 #include "run-command.h"
11 #include "transport.h"
13 static const char receive_pack_usage
[] = "git receive-pack <git-dir>";
22 static int deny_deletes
;
23 static int deny_non_fast_forwards
;
24 static enum deny_action deny_current_branch
= DENY_UNCONFIGURED
;
25 static enum deny_action deny_delete_current
= DENY_UNCONFIGURED
;
26 static int receive_fsck_objects
;
27 static int receive_unpack_limit
= -1;
28 static int transfer_unpack_limit
= -1;
29 static int unpack_limit
= 100;
30 static int report_status
;
31 static int use_sideband
;
32 static int prefer_ofs_delta
= 1;
33 static int auto_update_server_info
;
34 static int auto_gc
= 1;
35 static const char *head_name
;
36 static int sent_capabilities
;
38 static enum deny_action
parse_deny_action(const char *var
, const char *value
)
41 if (!strcasecmp(value
, "ignore"))
43 if (!strcasecmp(value
, "warn"))
45 if (!strcasecmp(value
, "refuse"))
48 if (git_config_bool(var
, value
))
53 static int receive_pack_config(const char *var
, const char *value
, void *cb
)
55 if (strcmp(var
, "receive.denydeletes") == 0) {
56 deny_deletes
= git_config_bool(var
, value
);
60 if (strcmp(var
, "receive.denynonfastforwards") == 0) {
61 deny_non_fast_forwards
= git_config_bool(var
, value
);
65 if (strcmp(var
, "receive.unpacklimit") == 0) {
66 receive_unpack_limit
= git_config_int(var
, value
);
70 if (strcmp(var
, "transfer.unpacklimit") == 0) {
71 transfer_unpack_limit
= git_config_int(var
, value
);
75 if (strcmp(var
, "receive.fsckobjects") == 0) {
76 receive_fsck_objects
= git_config_bool(var
, value
);
80 if (!strcmp(var
, "receive.denycurrentbranch")) {
81 deny_current_branch
= parse_deny_action(var
, value
);
85 if (strcmp(var
, "receive.denydeletecurrent") == 0) {
86 deny_delete_current
= parse_deny_action(var
, value
);
90 if (strcmp(var
, "repack.usedeltabaseoffset") == 0) {
91 prefer_ofs_delta
= git_config_bool(var
, value
);
95 if (strcmp(var
, "receive.updateserverinfo") == 0) {
96 auto_update_server_info
= git_config_bool(var
, value
);
100 if (strcmp(var
, "receive.autogc") == 0) {
101 auto_gc
= git_config_bool(var
, value
);
105 return git_default_config(var
, value
, cb
);
108 static int show_ref(const char *path
, const unsigned char *sha1
, int flag
, void *cb_data
)
110 if (sent_capabilities
)
111 packet_write(1, "%s %s\n", sha1_to_hex(sha1
), path
);
113 packet_write(1, "%s %s%c%s%s\n",
114 sha1_to_hex(sha1
), path
, 0,
115 " report-status delete-refs side-band-64k",
116 prefer_ofs_delta
? " ofs-delta" : "");
117 sent_capabilities
= 1;
121 static void write_head_info(void)
123 for_each_ref(show_ref
, NULL
);
124 if (!sent_capabilities
)
125 show_ref("capabilities^{}", null_sha1
, 0, NULL
);
130 struct command
*next
;
131 const char *error_string
;
132 unsigned char old_sha1
[20];
133 unsigned char new_sha1
[20];
134 char ref_name
[FLEX_ARRAY
]; /* more */
137 static struct command
*commands
;
139 static const char pre_receive_hook
[] = "hooks/pre-receive";
140 static const char post_receive_hook
[] = "hooks/post-receive";
142 static int copy_to_sideband(int in
, int out
, void *arg
)
146 ssize_t sz
= xread(in
, data
, sizeof(data
));
149 send_sideband(1, 2, data
, sz
, use_sideband
);
155 static int run_receive_hook(const char *hook_name
)
157 static char buf
[sizeof(commands
->old_sha1
) * 2 + PATH_MAX
+ 4];
159 struct child_process proc
;
162 int have_input
= 0, code
;
164 for (cmd
= commands
; !have_input
&& cmd
; cmd
= cmd
->next
) {
165 if (!cmd
->error_string
)
169 if (!have_input
|| access(hook_name
, X_OK
) < 0)
175 memset(&proc
, 0, sizeof(proc
));
178 proc
.stdout_to_stderr
= 1;
181 memset(&muxer
, 0, sizeof(muxer
));
182 muxer
.proc
= copy_to_sideband
;
184 code
= start_async(&muxer
);
190 code
= start_command(&proc
);
193 finish_async(&muxer
);
197 for (cmd
= commands
; cmd
; cmd
= cmd
->next
) {
198 if (!cmd
->error_string
) {
199 size_t n
= snprintf(buf
, sizeof(buf
), "%s %s %s\n",
200 sha1_to_hex(cmd
->old_sha1
),
201 sha1_to_hex(cmd
->new_sha1
),
203 if (write_in_full(proc
.in
, buf
, n
) != n
)
209 finish_async(&muxer
);
210 return finish_command(&proc
);
213 static int run_update_hook(struct command
*cmd
)
215 static const char update_hook
[] = "hooks/update";
217 struct child_process proc
;
220 if (access(update_hook
, X_OK
) < 0)
223 argv
[0] = update_hook
;
224 argv
[1] = cmd
->ref_name
;
225 argv
[2] = sha1_to_hex(cmd
->old_sha1
);
226 argv
[3] = sha1_to_hex(cmd
->new_sha1
);
229 memset(&proc
, 0, sizeof(proc
));
231 proc
.stdout_to_stderr
= 1;
232 proc
.err
= use_sideband
? -1 : 0;
235 code
= start_command(&proc
);
239 copy_to_sideband(proc
.err
, -1, NULL
);
240 return finish_command(&proc
);
243 static int is_ref_checked_out(const char *ref
)
245 if (is_bare_repository())
250 return !strcmp(head_name
, ref
);
253 static char *warn_unconfigured_deny_msg
[] = {
254 "Updating the currently checked out branch may cause confusion,",
255 "as the index and work tree do not reflect changes that are in HEAD.",
256 "As a result, you may see the changes you just pushed into it",
257 "reverted when you run 'git diff' over there, and you may want",
258 "to run 'git reset --hard' before starting to work to recover.",
260 "You can set 'receive.denyCurrentBranch' configuration variable to",
261 "'refuse' in the remote repository to forbid pushing into its",
264 "To allow pushing into the current branch, you can set it to 'ignore';",
265 "but this is not recommended unless you arranged to update its work",
266 "tree to match what you pushed in some other way.",
268 "To squelch this message, you can set it to 'warn'.",
270 "Note that the default will change in a future version of git",
271 "to refuse updating the current branch unless you have the",
272 "configuration variable set to either 'ignore' or 'warn'."
275 static void warn_unconfigured_deny(void)
278 for (i
= 0; i
< ARRAY_SIZE(warn_unconfigured_deny_msg
); i
++)
279 warning("%s", warn_unconfigured_deny_msg
[i
]);
282 static char *warn_unconfigured_deny_delete_current_msg
[] = {
283 "Deleting the current branch can cause confusion by making the next",
284 "'git clone' not check out any file.",
286 "You can set 'receive.denyDeleteCurrent' configuration variable to",
287 "'refuse' in the remote repository to disallow deleting the current",
290 "You can set it to 'ignore' to allow such a delete without a warning.",
292 "To make this warning message less loud, you can set it to 'warn'.",
294 "Note that the default will change in a future version of git",
295 "to refuse deleting the current branch unless you have the",
296 "configuration variable set to either 'ignore' or 'warn'."
299 static void warn_unconfigured_deny_delete_current(void)
303 i
< ARRAY_SIZE(warn_unconfigured_deny_delete_current_msg
);
305 warning("%s", warn_unconfigured_deny_delete_current_msg
[i
]);
308 static const char *update(struct command
*cmd
)
310 const char *name
= cmd
->ref_name
;
311 unsigned char *old_sha1
= cmd
->old_sha1
;
312 unsigned char *new_sha1
= cmd
->new_sha1
;
313 struct ref_lock
*lock
;
315 /* only refs/... are allowed */
316 if (prefixcmp(name
, "refs/") || check_ref_format(name
+ 5)) {
317 error("refusing to create funny ref '%s' remotely", name
);
318 return "funny refname";
321 if (is_ref_checked_out(name
)) {
322 switch (deny_current_branch
) {
325 case DENY_UNCONFIGURED
:
327 warning("updating the current branch");
328 if (deny_current_branch
== DENY_UNCONFIGURED
)
329 warn_unconfigured_deny();
332 error("refusing to update checked out branch: %s", name
);
333 return "branch is currently checked out";
337 if (!is_null_sha1(new_sha1
) && !has_sha1_file(new_sha1
)) {
338 error("unpack should have generated %s, "
339 "but I can't find it!", sha1_to_hex(new_sha1
));
343 if (!is_null_sha1(old_sha1
) && is_null_sha1(new_sha1
)) {
344 if (deny_deletes
&& !prefixcmp(name
, "refs/heads/")) {
345 error("denying ref deletion for %s", name
);
346 return "deletion prohibited";
349 if (!strcmp(name
, head_name
)) {
350 switch (deny_delete_current
) {
354 case DENY_UNCONFIGURED
:
355 if (deny_delete_current
== DENY_UNCONFIGURED
)
356 warn_unconfigured_deny_delete_current();
357 warning("deleting the current branch");
360 error("refusing to delete the current branch: %s", name
);
361 return "deletion of the current branch prohibited";
366 if (deny_non_fast_forwards
&& !is_null_sha1(new_sha1
) &&
367 !is_null_sha1(old_sha1
) &&
368 !prefixcmp(name
, "refs/heads/")) {
369 struct object
*old_object
, *new_object
;
370 struct commit
*old_commit
, *new_commit
;
371 struct commit_list
*bases
, *ent
;
373 old_object
= parse_object(old_sha1
);
374 new_object
= parse_object(new_sha1
);
376 if (!old_object
|| !new_object
||
377 old_object
->type
!= OBJ_COMMIT
||
378 new_object
->type
!= OBJ_COMMIT
) {
379 error("bad sha1 objects for %s", name
);
382 old_commit
= (struct commit
*)old_object
;
383 new_commit
= (struct commit
*)new_object
;
384 bases
= get_merge_bases(old_commit
, new_commit
, 1);
385 for (ent
= bases
; ent
; ent
= ent
->next
)
386 if (!hashcmp(old_sha1
, ent
->item
->object
.sha1
))
388 free_commit_list(bases
);
390 error("denying non-fast-forward %s"
391 " (you should pull first)", name
);
392 return "non-fast-forward";
395 if (run_update_hook(cmd
)) {
396 error("hook declined to update %s", name
);
397 return "hook declined";
400 if (is_null_sha1(new_sha1
)) {
401 if (!parse_object(old_sha1
)) {
402 warning ("Allowing deletion of corrupt ref.");
405 if (delete_ref(name
, old_sha1
, 0)) {
406 error("failed to delete %s", name
);
407 return "failed to delete";
409 return NULL
; /* good */
412 lock
= lock_any_ref_for_update(name
, old_sha1
, 0);
414 error("failed to lock %s", name
);
415 return "failed to lock";
417 if (write_ref_sha1(lock
, new_sha1
, "push")) {
418 return "failed to write"; /* error() already called */
420 return NULL
; /* good */
424 static char update_post_hook
[] = "hooks/post-update";
426 static void run_update_post_hook(struct command
*cmd
)
428 struct command
*cmd_p
;
431 struct child_process proc
;
433 for (argc
= 0, cmd_p
= cmd
; cmd_p
; cmd_p
= cmd_p
->next
) {
434 if (cmd_p
->error_string
)
438 if (!argc
|| access(update_post_hook
, X_OK
) < 0)
440 argv
= xmalloc(sizeof(*argv
) * (2 + argc
));
441 argv
[0] = update_post_hook
;
443 for (argc
= 1, cmd_p
= cmd
; cmd_p
; cmd_p
= cmd_p
->next
) {
445 if (cmd_p
->error_string
)
447 p
= xmalloc(strlen(cmd_p
->ref_name
) + 1);
448 strcpy(p
, cmd_p
->ref_name
);
454 memset(&proc
, 0, sizeof(proc
));
456 proc
.stdout_to_stderr
= 1;
457 proc
.err
= use_sideband
? -1 : 0;
460 if (!start_command(&proc
)) {
462 copy_to_sideband(proc
.err
, -1, NULL
);
463 finish_command(&proc
);
467 static void execute_commands(const char *unpacker_error
)
469 struct command
*cmd
= commands
;
470 unsigned char sha1
[20];
472 if (unpacker_error
) {
474 cmd
->error_string
= "n/a (unpacker error)";
480 if (run_receive_hook(pre_receive_hook
)) {
482 cmd
->error_string
= "pre-receive hook declined";
488 head_name
= resolve_ref("HEAD", sha1
, 0, NULL
);
491 cmd
->error_string
= update(cmd
);
496 static void read_head_info(void)
498 struct command
**p
= &commands
;
500 static char line
[1000];
501 unsigned char old_sha1
[20], new_sha1
[20];
506 len
= packet_read_line(0, line
, sizeof(line
));
509 if (line
[len
-1] == '\n')
514 get_sha1_hex(line
, old_sha1
) ||
515 get_sha1_hex(line
+ 41, new_sha1
))
516 die("protocol error: expected old/new/ref, got '%s'",
520 reflen
= strlen(refname
);
521 if (reflen
+ 82 < len
) {
522 if (strstr(refname
+ reflen
+ 1, "report-status"))
524 if (strstr(refname
+ reflen
+ 1, "side-band-64k"))
525 use_sideband
= LARGE_PACKET_MAX
;
527 cmd
= xmalloc(sizeof(struct command
) + len
- 80);
528 hashcpy(cmd
->old_sha1
, old_sha1
);
529 hashcpy(cmd
->new_sha1
, new_sha1
);
530 memcpy(cmd
->ref_name
, line
+ 82, len
- 81);
531 cmd
->error_string
= NULL
;
538 static const char *parse_pack_header(struct pack_header
*hdr
)
540 switch (read_pack_header(0, hdr
)) {
542 return "eof before pack header was fully read";
544 case PH_ERROR_PACK_SIGNATURE
:
545 return "protocol error (pack signature mismatch detected)";
547 case PH_ERROR_PROTOCOL
:
548 return "protocol error (pack version unsupported)";
551 return "unknown error in parse_pack_header";
558 static const char *pack_lockfile
;
560 static const char *unpack(void)
562 struct pack_header hdr
;
566 hdr_err
= parse_pack_header(&hdr
);
569 snprintf(hdr_arg
, sizeof(hdr_arg
),
570 "--pack_header=%"PRIu32
",%"PRIu32
,
571 ntohl(hdr
.hdr_version
), ntohl(hdr
.hdr_entries
));
573 if (ntohl(hdr
.hdr_entries
) < unpack_limit
) {
575 const char *unpacker
[4];
576 unpacker
[i
++] = "unpack-objects";
577 if (receive_fsck_objects
)
578 unpacker
[i
++] = "--strict";
579 unpacker
[i
++] = hdr_arg
;
580 unpacker
[i
++] = NULL
;
581 code
= run_command_v_opt(unpacker
, RUN_GIT_CMD
);
584 return "unpack-objects abnormal exit";
586 const char *keeper
[7];
587 int s
, status
, i
= 0;
589 struct child_process ip
;
591 s
= sprintf(keep_arg
, "--keep=receive-pack %"PRIuMAX
" on ", (uintmax_t) getpid());
592 if (gethostname(keep_arg
+ s
, sizeof(keep_arg
) - s
))
593 strcpy(keep_arg
+ s
, "localhost");
595 keeper
[i
++] = "index-pack";
596 keeper
[i
++] = "--stdin";
597 if (receive_fsck_objects
)
598 keeper
[i
++] = "--strict";
599 keeper
[i
++] = "--fix-thin";
600 keeper
[i
++] = hdr_arg
;
601 keeper
[i
++] = keep_arg
;
603 memset(&ip
, 0, sizeof(ip
));
607 status
= start_command(&ip
);
609 return "index-pack fork failed";
611 pack_lockfile
= index_pack_lockfile(ip
.out
);
613 status
= finish_command(&ip
);
615 reprepare_packed_git();
618 return "index-pack abnormal exit";
622 static void report(const char *unpack_status
)
625 struct strbuf buf
= STRBUF_INIT
;
627 packet_buf_write(&buf
, "unpack %s\n",
628 unpack_status
? unpack_status
: "ok");
629 for (cmd
= commands
; cmd
; cmd
= cmd
->next
) {
630 if (!cmd
->error_string
)
631 packet_buf_write(&buf
, "ok %s\n",
634 packet_buf_write(&buf
, "ng %s %s\n",
635 cmd
->ref_name
, cmd
->error_string
);
637 packet_buf_flush(&buf
);
640 send_sideband(1, 1, buf
.buf
, buf
.len
, use_sideband
);
642 safe_write(1, buf
.buf
, buf
.len
);
643 strbuf_release(&buf
);
646 static int delete_only(struct command
*cmd
)
649 if (!is_null_sha1(cmd
->new_sha1
))
656 static int add_refs_from_alternate(struct alternate_object_database
*e
, void *unused
)
660 struct remote
*remote
;
661 struct transport
*transport
;
662 const struct ref
*extra
;
665 other
= xstrdup(make_absolute_path(e
->base
));
669 while (other
[len
-1] == '/')
671 if (len
< 8 || memcmp(other
+ len
- 8, "/objects", 8))
673 /* Is this a git repository with refs? */
674 memcpy(other
+ len
- 8, "/refs", 6);
675 if (!is_directory(other
))
677 other
[len
- 8] = '\0';
678 remote
= remote_get(other
);
679 transport
= transport_get(remote
, other
);
680 for (extra
= transport_get_remote_refs(transport
);
682 extra
= extra
->next
) {
683 add_extra_ref(".have", extra
->old_sha1
, 0);
685 transport_disconnect(transport
);
690 static void add_alternate_refs(void)
692 foreach_alt_odb(add_refs_from_alternate
, NULL
);
695 int cmd_receive_pack(int argc
, const char **argv
, const char *prefix
)
697 int advertise_refs
= 0;
698 int stateless_rpc
= 0;
703 for (i
= 1; i
< argc
; i
++) {
704 const char *arg
= *argv
++;
707 if (!strcmp(arg
, "--advertise-refs")) {
711 if (!strcmp(arg
, "--stateless-rpc")) {
716 usage(receive_pack_usage
);
719 usage(receive_pack_usage
);
723 usage(receive_pack_usage
);
727 if (!enter_repo(dir
, 0))
728 die("'%s' does not appear to be a git repository", dir
);
730 if (is_repository_shallow())
731 die("attempt to push into a shallow repository");
733 git_config(receive_pack_config
, NULL
);
735 if (0 <= transfer_unpack_limit
)
736 unpack_limit
= transfer_unpack_limit
;
737 else if (0 <= receive_unpack_limit
)
738 unpack_limit
= receive_unpack_limit
;
740 if (advertise_refs
|| !stateless_rpc
) {
741 add_alternate_refs();
753 const char *unpack_status
= NULL
;
755 if (!delete_only(commands
))
756 unpack_status
= unpack();
757 execute_commands(unpack_status
);
759 unlink_or_warn(pack_lockfile
);
761 report(unpack_status
);
762 run_receive_hook(post_receive_hook
);
763 run_update_post_hook(commands
);
765 const char *argv_gc_auto
[] = {
766 "gc", "--auto", "--quiet", NULL
,
768 run_command_v_opt(argv_gc_auto
, RUN_GIT_CMD
);
770 if (auto_update_server_info
)
771 update_server_info(0);