5 #include "run-command.h"
10 #include "transport.h"
12 static const char receive_pack_usage
[] = "git receive-pack <git-dir>";
23 static int deny_deletes
;
24 static int deny_non_fast_forwards
;
25 static enum deny_action deny_current_branch
= DENY_UNCONFIGURED
;
26 static enum deny_action deny_delete_current
= DENY_UNCONFIGURED
;
27 static int receive_fsck_objects
;
28 static int receive_unpack_limit
= -1;
29 static int transfer_unpack_limit
= -1;
30 static int unpack_limit
= 100;
31 static int report_status
;
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 char *capabilities_to_send
;
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 if (value
&& !strcasecmp(value
, "updateinstead"))
82 deny_current_branch
= DENY_UPDATE_INSTEAD
;
83 else if (value
&& !strcasecmp(value
, "detachinstead"))
84 deny_current_branch
= DENY_DETACH_INSTEAD
;
86 deny_current_branch
= parse_deny_action(var
, value
);
90 if (strcmp(var
, "receive.denydeletecurrent") == 0) {
91 deny_delete_current
= parse_deny_action(var
, value
);
95 if (strcmp(var
, "repack.usedeltabaseoffset") == 0) {
96 prefer_ofs_delta
= git_config_bool(var
, value
);
100 if (strcmp(var
, "receive.updateserverinfo") == 0) {
101 auto_update_server_info
= git_config_bool(var
, value
);
105 if (strcmp(var
, "receive.autogc") == 0) {
106 auto_gc
= git_config_bool(var
, value
);
110 return git_default_config(var
, value
, cb
);
113 static int show_ref(const char *path
, const unsigned char *sha1
, int flag
, void *cb_data
)
115 if (!capabilities_to_send
)
116 packet_write(1, "%s %s\n", sha1_to_hex(sha1
), path
);
118 packet_write(1, "%s %s%c%s\n",
119 sha1_to_hex(sha1
), path
, 0, capabilities_to_send
);
120 capabilities_to_send
= NULL
;
124 static void write_head_info(void)
126 for_each_ref(show_ref
, NULL
);
127 if (capabilities_to_send
)
128 show_ref("capabilities^{}", null_sha1
, 0, NULL
);
133 struct command
*next
;
134 const char *error_string
;
135 unsigned char old_sha1
[20];
136 unsigned char new_sha1
[20];
137 char ref_name
[FLEX_ARRAY
]; /* more */
140 static struct command
*commands
;
142 static const char pre_receive_hook
[] = "hooks/pre-receive";
143 static const char post_receive_hook
[] = "hooks/post-receive";
145 static int run_receive_hook(const char *hook_name
)
147 static char buf
[sizeof(commands
->old_sha1
) * 2 + PATH_MAX
+ 4];
149 struct child_process proc
;
151 int have_input
= 0, code
;
153 for (cmd
= commands
; !have_input
&& cmd
; cmd
= cmd
->next
) {
154 if (!cmd
->error_string
)
158 if (!have_input
|| access(hook_name
, X_OK
) < 0)
164 memset(&proc
, 0, sizeof(proc
));
167 proc
.stdout_to_stderr
= 1;
169 code
= start_command(&proc
);
172 for (cmd
= commands
; cmd
; cmd
= cmd
->next
) {
173 if (!cmd
->error_string
) {
174 size_t n
= snprintf(buf
, sizeof(buf
), "%s %s %s\n",
175 sha1_to_hex(cmd
->old_sha1
),
176 sha1_to_hex(cmd
->new_sha1
),
178 if (write_in_full(proc
.in
, buf
, n
) != n
)
183 return finish_command(&proc
);
186 static int run_update_hook(struct command
*cmd
)
188 static const char update_hook
[] = "hooks/update";
191 if (access(update_hook
, X_OK
) < 0)
194 argv
[0] = update_hook
;
195 argv
[1] = cmd
->ref_name
;
196 argv
[2] = sha1_to_hex(cmd
->old_sha1
);
197 argv
[3] = sha1_to_hex(cmd
->new_sha1
);
200 return run_command_v_opt(argv
, RUN_COMMAND_NO_STDIN
|
201 RUN_COMMAND_STDOUT_TO_STDERR
);
204 static int is_ref_checked_out(const char *ref
)
206 if (is_bare_repository())
211 return !strcmp(head_name
, ref
);
214 static char *refuse_unconfigured_deny_msg
[] = {
215 "By default, updating the current branch in a non-bare repository",
216 "is denied, because it will make the index and work tree inconsistent",
217 "with what you pushed, and will require 'git reset --hard' to match",
218 "the work tree to HEAD.",
220 "You can set 'receive.denyCurrentBranch' configuration variable to",
221 "'ignore' or 'warn' in the remote repository to allow pushing into",
222 "its current branch; however, this is not recommended unless you",
223 "arranged to update its work tree to match what you pushed in some",
226 "To squelch this message and still keep the default behaviour, set",
227 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
230 static void refuse_unconfigured_deny(void)
233 for (i
= 0; i
< ARRAY_SIZE(refuse_unconfigured_deny_msg
); i
++)
234 error("%s", refuse_unconfigured_deny_msg
[i
]);
237 static char *refuse_unconfigured_deny_delete_current_msg
[] = {
238 "By default, deleting the current branch is denied, because the next",
239 "'git clone' won't result in any file checked out, causing confusion.",
241 "You can set 'receive.denyDeleteCurrent' configuration variable to",
242 "'warn' or 'ignore' in the remote repository to allow deleting the",
243 "current branch, with or without a warning message.",
245 "To squelch this message, you can set it to 'refuse'."
248 static void refuse_unconfigured_deny_delete_current(void)
252 i
< ARRAY_SIZE(refuse_unconfigured_deny_delete_current_msg
);
254 error("%s", refuse_unconfigured_deny_delete_current_msg
[i
]);
257 static void merge_worktree(unsigned char *sha1
)
259 const char *update_refresh
[] = {
260 "update-index", "--refresh", NULL
262 const char *read_tree
[] = {
263 "read-tree", "-u", "-m", sha1_to_hex(sha1
), NULL
265 struct child_process child
;
266 struct strbuf git_env
= STRBUF_INIT
;
269 if (is_bare_repository())
270 die ("denyCurrentBranch = updateInstead needs a worktree");
272 strbuf_addf(&git_env
, "GIT_DIR=%s", make_absolute_path(get_git_dir()));
273 env
[0] = git_env
.buf
;
276 memset(&child
, 0, sizeof(child
));
277 child
.argv
= update_refresh
;
279 child
.dir
= git_work_tree_cfg
? git_work_tree_cfg
: "..";
280 child
.stdout_to_stderr
= 1;
282 if (run_command(&child
))
283 die ("Could not refresh the index");
285 child
.argv
= read_tree
;
288 child
.stdout_to_stderr
= 0;
289 if (run_command(&child
))
290 die ("Could not merge working tree with new HEAD. Good luck.");
292 strbuf_release(&git_env
);
295 static const char *update(struct command
*cmd
)
297 const char *name
= cmd
->ref_name
;
298 unsigned char *old_sha1
= cmd
->old_sha1
;
299 unsigned char *new_sha1
= cmd
->new_sha1
;
300 struct ref_lock
*lock
;
302 /* only refs/... are allowed */
303 if (prefixcmp(name
, "refs/") || check_ref_format(name
+ 5)) {
304 error("refusing to create funny ref '%s' remotely", name
);
305 return "funny refname";
308 if (is_ref_checked_out(name
)) {
309 switch (deny_current_branch
) {
313 warning("updating the current branch");
316 case DENY_UNCONFIGURED
:
317 error("refusing to update checked out branch: %s", name
);
318 if (deny_current_branch
== DENY_UNCONFIGURED
)
319 refuse_unconfigured_deny();
320 return "branch is currently checked out";
321 case DENY_UPDATE_INSTEAD
:
322 merge_worktree(new_sha1
);
324 case DENY_DETACH_INSTEAD
:
325 update_ref("push into current branch (detach)", "HEAD",
326 old_sha1
, NULL
, REF_NODEREF
, DIE_ON_ERR
);
331 if (!is_null_sha1(new_sha1
) && !has_sha1_file(new_sha1
)) {
332 error("unpack should have generated %s, "
333 "but I can't find it!", sha1_to_hex(new_sha1
));
337 if (!is_null_sha1(old_sha1
) && is_null_sha1(new_sha1
)) {
338 if (deny_deletes
&& !prefixcmp(name
, "refs/heads/")) {
339 error("denying ref deletion for %s", name
);
340 return "deletion prohibited";
343 if (!strcmp(name
, head_name
)) {
344 switch (deny_delete_current
) {
348 warning("deleting the current branch");
351 case DENY_UNCONFIGURED
:
352 if (deny_delete_current
== DENY_UNCONFIGURED
)
353 refuse_unconfigured_deny_delete_current();
354 error("refusing to delete the current branch: %s", name
);
355 return "deletion of the current branch prohibited";
357 die ("Invalid denyDeleteCurrent setting");
362 if (deny_non_fast_forwards
&& !is_null_sha1(new_sha1
) &&
363 !is_null_sha1(old_sha1
) &&
364 !prefixcmp(name
, "refs/heads/")) {
365 struct object
*old_object
, *new_object
;
366 struct commit
*old_commit
, *new_commit
;
367 struct commit_list
*bases
, *ent
;
369 old_object
= parse_object(old_sha1
);
370 new_object
= parse_object(new_sha1
);
372 if (!old_object
|| !new_object
||
373 old_object
->type
!= OBJ_COMMIT
||
374 new_object
->type
!= OBJ_COMMIT
) {
375 error("bad sha1 objects for %s", name
);
378 old_commit
= (struct commit
*)old_object
;
379 new_commit
= (struct commit
*)new_object
;
380 bases
= get_merge_bases(old_commit
, new_commit
, 1);
381 for (ent
= bases
; ent
; ent
= ent
->next
)
382 if (!hashcmp(old_sha1
, ent
->item
->object
.sha1
))
384 free_commit_list(bases
);
386 error("denying non-fast-forward %s"
387 " (you should pull first)", name
);
388 return "non-fast-forward";
391 if (run_update_hook(cmd
)) {
392 error("hook declined to update %s", name
);
393 return "hook declined";
396 if (is_null_sha1(new_sha1
)) {
397 if (!parse_object(old_sha1
)) {
398 warning ("Allowing deletion of corrupt ref.");
401 if (delete_ref(name
, old_sha1
, 0)) {
402 error("failed to delete %s", name
);
403 return "failed to delete";
405 return NULL
; /* good */
408 lock
= lock_any_ref_for_update(name
, old_sha1
, 0);
410 error("failed to lock %s", name
);
411 return "failed to lock";
413 if (write_ref_sha1(lock
, new_sha1
, "push")) {
414 return "failed to write"; /* error() already called */
416 return NULL
; /* good */
420 static char update_post_hook
[] = "hooks/post-update";
422 static void run_update_post_hook(struct command
*cmd
)
424 struct command
*cmd_p
;
428 for (argc
= 0, cmd_p
= cmd
; cmd_p
; cmd_p
= cmd_p
->next
) {
429 if (cmd_p
->error_string
)
433 if (!argc
|| access(update_post_hook
, X_OK
) < 0)
435 argv
= xmalloc(sizeof(*argv
) * (2 + argc
));
436 argv
[0] = update_post_hook
;
438 for (argc
= 1, cmd_p
= cmd
; cmd_p
; cmd_p
= cmd_p
->next
) {
440 if (cmd_p
->error_string
)
442 p
= xmalloc(strlen(cmd_p
->ref_name
) + 1);
443 strcpy(p
, cmd_p
->ref_name
);
448 status
= run_command_v_opt(argv
, RUN_COMMAND_NO_STDIN
449 | RUN_COMMAND_STDOUT_TO_STDERR
);
452 static void execute_commands(const char *unpacker_error
)
454 struct command
*cmd
= commands
;
455 unsigned char sha1
[20];
457 if (unpacker_error
) {
459 cmd
->error_string
= "n/a (unpacker error)";
465 if (run_receive_hook(pre_receive_hook
)) {
467 cmd
->error_string
= "pre-receive hook declined";
473 head_name
= resolve_ref("HEAD", sha1
, 0, NULL
);
476 cmd
->error_string
= update(cmd
);
481 static void read_head_info(void)
483 struct command
**p
= &commands
;
485 static char line
[1000];
486 unsigned char old_sha1
[20], new_sha1
[20];
491 len
= packet_read_line(0, line
, sizeof(line
));
494 if (line
[len
-1] == '\n')
499 get_sha1_hex(line
, old_sha1
) ||
500 get_sha1_hex(line
+ 41, new_sha1
))
501 die("protocol error: expected old/new/ref, got '%s'",
505 reflen
= strlen(refname
);
506 if (reflen
+ 82 < len
) {
507 if (strstr(refname
+ reflen
+ 1, "report-status"))
510 cmd
= xmalloc(sizeof(struct command
) + len
- 80);
511 hashcpy(cmd
->old_sha1
, old_sha1
);
512 hashcpy(cmd
->new_sha1
, new_sha1
);
513 memcpy(cmd
->ref_name
, line
+ 82, len
- 81);
514 cmd
->error_string
= NULL
;
521 static const char *parse_pack_header(struct pack_header
*hdr
)
523 switch (read_pack_header(0, hdr
)) {
525 return "eof before pack header was fully read";
527 case PH_ERROR_PACK_SIGNATURE
:
528 return "protocol error (pack signature mismatch detected)";
530 case PH_ERROR_PROTOCOL
:
531 return "protocol error (pack version unsupported)";
534 return "unknown error in parse_pack_header";
541 static const char *pack_lockfile
;
543 static const char *unpack(void)
545 struct pack_header hdr
;
549 hdr_err
= parse_pack_header(&hdr
);
552 snprintf(hdr_arg
, sizeof(hdr_arg
),
553 "--pack_header=%"PRIu32
",%"PRIu32
,
554 ntohl(hdr
.hdr_version
), ntohl(hdr
.hdr_entries
));
556 if (ntohl(hdr
.hdr_entries
) < unpack_limit
) {
558 const char *unpacker
[4];
559 unpacker
[i
++] = "unpack-objects";
560 if (receive_fsck_objects
)
561 unpacker
[i
++] = "--strict";
562 unpacker
[i
++] = hdr_arg
;
563 unpacker
[i
++] = NULL
;
564 code
= run_command_v_opt(unpacker
, RUN_GIT_CMD
);
567 return "unpack-objects abnormal exit";
569 const char *keeper
[7];
570 int s
, status
, i
= 0;
572 struct child_process ip
;
574 s
= sprintf(keep_arg
, "--keep=receive-pack %"PRIuMAX
" on ", (uintmax_t) getpid());
575 if (gethostname(keep_arg
+ s
, sizeof(keep_arg
) - s
))
576 strcpy(keep_arg
+ s
, "localhost");
578 keeper
[i
++] = "index-pack";
579 keeper
[i
++] = "--stdin";
580 if (receive_fsck_objects
)
581 keeper
[i
++] = "--strict";
582 keeper
[i
++] = "--fix-thin";
583 keeper
[i
++] = hdr_arg
;
584 keeper
[i
++] = keep_arg
;
586 memset(&ip
, 0, sizeof(ip
));
590 status
= start_command(&ip
);
592 return "index-pack fork failed";
594 pack_lockfile
= index_pack_lockfile(ip
.out
);
596 status
= finish_command(&ip
);
598 reprepare_packed_git();
601 return "index-pack abnormal exit";
605 static void report(const char *unpack_status
)
608 packet_write(1, "unpack %s\n",
609 unpack_status
? unpack_status
: "ok");
610 for (cmd
= commands
; cmd
; cmd
= cmd
->next
) {
611 if (!cmd
->error_string
)
612 packet_write(1, "ok %s\n",
615 packet_write(1, "ng %s %s\n",
616 cmd
->ref_name
, cmd
->error_string
);
621 static int delete_only(struct command
*cmd
)
624 if (!is_null_sha1(cmd
->new_sha1
))
631 static int add_refs_from_alternate(struct alternate_object_database
*e
, void *unused
)
635 struct remote
*remote
;
636 struct transport
*transport
;
637 const struct ref
*extra
;
640 other
= xstrdup(make_absolute_path(e
->base
));
644 while (other
[len
-1] == '/')
646 if (len
< 8 || memcmp(other
+ len
- 8, "/objects", 8))
648 /* Is this a git repository with refs? */
649 memcpy(other
+ len
- 8, "/refs", 6);
650 if (!is_directory(other
))
652 other
[len
- 8] = '\0';
653 remote
= remote_get(other
);
654 transport
= transport_get(remote
, other
);
655 for (extra
= transport_get_remote_refs(transport
);
657 extra
= extra
->next
) {
658 add_extra_ref(".have", extra
->old_sha1
, 0);
660 transport_disconnect(transport
);
665 static void add_alternate_refs(void)
667 foreach_alt_odb(add_refs_from_alternate
, NULL
);
670 int cmd_receive_pack(int argc
, const char **argv
, const char *prefix
)
672 int advertise_refs
= 0;
673 int stateless_rpc
= 0;
678 for (i
= 1; i
< argc
; i
++) {
679 const char *arg
= *argv
++;
682 if (!strcmp(arg
, "--advertise-refs")) {
686 if (!strcmp(arg
, "--stateless-rpc")) {
691 usage(receive_pack_usage
);
694 usage(receive_pack_usage
);
698 usage(receive_pack_usage
);
702 if (!enter_repo(dir
, 0))
703 die("'%s' does not appear to be a git repository", dir
);
705 if (is_repository_shallow())
706 die("attempt to push into a shallow repository");
708 git_config(receive_pack_config
, NULL
);
710 if (0 <= transfer_unpack_limit
)
711 unpack_limit
= transfer_unpack_limit
;
712 else if (0 <= receive_unpack_limit
)
713 unpack_limit
= receive_unpack_limit
;
715 capabilities_to_send
= (prefer_ofs_delta
) ?
716 " report-status delete-refs ofs-delta " :
717 " report-status delete-refs ";
719 if (advertise_refs
|| !stateless_rpc
) {
720 add_alternate_refs();
732 const char *unpack_status
= NULL
;
734 if (!delete_only(commands
))
735 unpack_status
= unpack();
736 execute_commands(unpack_status
);
738 unlink_or_warn(pack_lockfile
);
740 report(unpack_status
);
741 run_receive_hook(post_receive_hook
);
742 run_update_post_hook(commands
);
744 const char *argv_gc_auto
[] = {
745 "gc", "--auto", "--quiet", NULL
,
747 run_command_v_opt(argv_gc_auto
, RUN_GIT_CMD
);
749 if (auto_update_server_info
)
750 update_server_info(0);