blob: 439f29d6c7f4c5bc856611a3e900ff7e9a77b9f5 [file] [log] [blame]
Stephen Boyd1e4cd682011-04-03 00:06:54 -07001#include "builtin.h"
Stefan Bellera49d2832018-03-23 18:45:21 +01002#include "repository.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07003#include "config.h"
Michael Haggerty697cc8e2014-10-01 12:28:42 +02004#include "lockfile.h"
Shawn Pearcefc04c412006-11-01 17:06:21 -05005#include "pack.h"
Linus Torvalds8a65ff72005-07-02 20:23:36 -07006#include "refs.h"
Linus Torvaldsf3a32142005-06-29 20:50:15 -07007#include "pkt-line.h"
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08008#include "sideband.h"
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +02009#include "run-command.h"
Stefan Bellerd807c4a2018-04-10 14:26:18 -070010#include "exec-cmd.h"
Johannes Schindelin11031d72006-09-21 01:07:54 +020011#include "commit.h"
12#include "object.h"
Junio C Hamanod79796b2008-09-09 01:27:10 -070013#include "remote.h"
Junio C Hamano47a59182013-07-08 13:56:53 -070014#include "connect.h"
Jay Soffianda3efdb2010-04-19 18:19:18 -040015#include "string-list.h"
Jeff Kingfe299ec2020-03-30 10:03:46 -040016#include "oid-array.h"
Junio C Hamano52fed6e2011-09-02 16:52:08 -070017#include "connected.h"
Jeff Kingdbbcd442020-07-28 16:23:39 -040018#include "strvec.h"
Jeff Kingff5effd2012-08-03 12:19:16 -040019#include "version.h"
Junio C Hamanod05b9612014-08-14 15:59:21 -070020#include "tag.h"
21#include "gpg-interface.h"
Junio C Hamanoec7dbd12014-09-12 15:48:07 -070022#include "sigchain.h"
Johannes Schindelin5d477a32015-06-22 17:25:31 +020023#include "fsck.h"
Jeff King722ff7f2016-10-03 16:49:14 -040024#include "tmp-objdir.h"
Jeff Kingab6eea62017-02-08 15:53:10 -050025#include "oidset.h"
Jonathan Tan3836d882017-08-18 15:20:21 -070026#include "packfile.h"
Stefan Bellercbd53a22018-05-15 16:42:15 -070027#include "object-store.h"
Brandon Williamsaa9bab22017-10-16 10:55:26 -070028#include "protocol.h"
Derrick Stolee64043552018-07-20 16:33:04 +000029#include "commit-reach.h"
Hariom Verma4ef34642020-02-23 18:57:10 +000030#include "worktree.h"
Taylor Blau120ad2b2020-04-30 13:48:50 -060031#include "shallow.h"
Linus Torvalds575f4972005-06-29 17:52:11 -070032
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +053033static const char * const receive_pack_usage[] = {
34 N_("git receive-pack <git-dir>"),
35 NULL
36};
Linus Torvalds575f4972005-06-29 17:52:11 -070037
Jeff King986e8232008-11-08 20:49:27 -050038enum deny_action {
Junio C Hamano3d95d922009-01-31 17:34:05 -080039 DENY_UNCONFIGURED,
Jeff King986e8232008-11-08 20:49:27 -050040 DENY_IGNORE,
41 DENY_WARN,
Johannes Schindelin1404bcb2014-11-26 23:44:16 +010042 DENY_REFUSE,
43 DENY_UPDATE_INSTEAD
Jeff King986e8232008-11-08 20:49:27 -050044};
45
Junio C Hamano1b53a072009-02-08 22:19:43 -080046static int deny_deletes;
47static int deny_non_fast_forwards;
Junio C Hamano3d95d922009-01-31 17:34:05 -080048static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
Junio C Hamano747ca242009-02-08 22:31:21 -080049static enum deny_action deny_delete_current = DENY_UNCONFIGURED;
Junio C Hamanodab76d32011-09-04 12:37:45 -070050static int receive_fsck_objects = -1;
51static int transfer_fsck_objects = -1;
Johannes Schindelin5d477a32015-06-22 17:25:31 +020052static struct strbuf fsck_msg_types = STRBUF_INIT;
Junio C Hamanoe28714c2007-01-24 17:02:15 -080053static int receive_unpack_limit = -1;
54static int transfer_unpack_limit = -1;
Ronnie Sahlberg1b70fe52015-01-07 19:23:20 -080055static int advertise_atomic_push = 1;
Stefan Bellerc714e452016-07-14 14:49:46 -070056static int advertise_push_options;
Nicolas Pitre46732fa2006-12-06 23:01:00 -050057static int unpack_limit = 100;
Jeff Kingc08db5a2016-08-24 20:41:57 +020058static off_t max_input_size;
David Rientjes96f1e582006-08-15 10:23:48 -070059static int report_status;
Shawn O. Pearce38a81b42010-02-05 12:57:41 -080060static int use_sideband;
Stefan Beller68deed22015-01-07 19:23:19 -080061static int use_atomic;
Stefan Bellerc714e452016-07-14 14:49:46 -070062static int use_push_options;
Clemens Buchacherc207e342012-01-08 22:06:20 +010063static int quiet;
Nicolas Pitreb74fce12009-05-01 16:56:47 -040064static int prefer_ofs_delta = 1;
Junio C Hamano77e3efb2009-10-20 14:56:40 -070065static int auto_update_server_info;
66static int auto_gc = 1;
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +053067static int reject_thin;
Junio C Hamano57323732014-09-05 10:46:04 -070068static int stateless_rpc;
69static const char *service_dir;
Junio C Hamano747ca242009-02-08 22:31:21 -080070static const char *head_name;
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +070071static void *head_name_to_free;
Shawn O. Pearce185c04e2010-02-05 12:57:40 -080072static int sent_capabilities;
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +070073static int shallow_update;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +070074static const char *alt_shallow_file;
Junio C Hamanoa85b3772014-09-12 11:17:07 -070075static struct strbuf push_cert = STRBUF_INIT;
Patryk Obaraa09c9852018-01-28 01:13:19 +010076static struct object_id push_cert_oid;
Junio C Hamanod05b9612014-08-14 15:59:21 -070077static struct signature_check sigcheck;
Junio C Hamanob89363e2014-08-21 16:45:30 -070078static const char *push_cert_nonce;
79static const char *cert_nonce_seed;
80
81static const char *NONCE_UNSOLICITED = "UNSOLICITED";
82static const char *NONCE_BAD = "BAD";
83static const char *NONCE_MISSING = "MISSING";
84static const char *NONCE_OK = "OK";
Junio C Hamano57323732014-09-05 10:46:04 -070085static const char *NONCE_SLOP = "SLOP";
Junio C Hamanob89363e2014-08-21 16:45:30 -070086static const char *nonce_status;
Junio C Hamano57323732014-09-05 10:46:04 -070087static long nonce_stamp_slop;
Johannes Schindelindddbad72017-04-26 21:29:31 +020088static timestamp_t nonce_stamp_slop_limit;
Stefan Beller222368c2015-01-07 19:23:18 -080089static struct ref_transaction *transaction;
Junio C Hamanocfee10a2005-12-25 23:18:37 -080090
Jeff King83558682016-07-15 06:43:47 -040091static enum {
92 KEEPALIVE_NEVER = 0,
93 KEEPALIVE_AFTER_NUL,
94 KEEPALIVE_ALWAYS
95} use_keepalive;
96static int keepalive_in_sec = 5;
97
Jeff King722ff7f2016-10-03 16:49:14 -040098static struct tmp_objdir *tmp_objdir;
99
Jeff King986e8232008-11-08 20:49:27 -0500100static enum deny_action parse_deny_action(const char *var, const char *value)
101{
102 if (value) {
103 if (!strcasecmp(value, "ignore"))
104 return DENY_IGNORE;
105 if (!strcasecmp(value, "warn"))
106 return DENY_WARN;
107 if (!strcasecmp(value, "refuse"))
108 return DENY_REFUSE;
Johannes Schindelin1404bcb2014-11-26 23:44:16 +0100109 if (!strcasecmp(value, "updateinstead"))
110 return DENY_UPDATE_INSTEAD;
Jeff King986e8232008-11-08 20:49:27 -0500111 }
112 if (git_config_bool(var, value))
113 return DENY_REFUSE;
114 return DENY_IGNORE;
115}
116
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100117static int receive_pack_config(const char *var, const char *value, void *cb)
Shawn Pearce6fb75be2006-10-30 17:35:18 -0500118{
Junio C Hamanodaebaa72013-01-18 16:08:30 -0800119 int status = parse_hide_refs_config(var, value, "receive");
120
121 if (status)
122 return status;
123
Jan Krügera240de12008-11-01 15:42:16 +0100124 if (strcmp(var, "receive.denydeletes") == 0) {
125 deny_deletes = git_config_bool(var, value);
126 return 0;
127 }
128
Junio C Hamanoe28714c2007-01-24 17:02:15 -0800129 if (strcmp(var, "receive.denynonfastforwards") == 0) {
Shawn Pearce6fb75be2006-10-30 17:35:18 -0500130 deny_non_fast_forwards = git_config_bool(var, value);
131 return 0;
132 }
133
Junio C Hamanoe28714c2007-01-24 17:02:15 -0800134 if (strcmp(var, "receive.unpacklimit") == 0) {
135 receive_unpack_limit = git_config_int(var, value);
Shawn Pearcefc04c412006-11-01 17:06:21 -0500136 return 0;
137 }
138
Junio C Hamanoe28714c2007-01-24 17:02:15 -0800139 if (strcmp(var, "transfer.unpacklimit") == 0) {
140 transfer_unpack_limit = git_config_int(var, value);
141 return 0;
142 }
143
Johannes Schindelincd94c6f2015-06-22 17:27:18 +0200144 if (strcmp(var, "receive.fsck.skiplist") == 0) {
145 const char *path;
146
147 if (git_config_pathname(&path, var, value))
148 return 1;
149 strbuf_addf(&fsck_msg_types, "%cskiplist=%s",
150 fsck_msg_types.len ? ',' : '=', path);
151 free((char *)path);
152 return 0;
153 }
154
Johannes Schindelin5d477a32015-06-22 17:25:31 +0200155 if (skip_prefix(var, "receive.fsck.", &var)) {
156 if (is_valid_msg_type(var, value))
157 strbuf_addf(&fsck_msg_types, "%c%s=%s",
158 fsck_msg_types.len ? ',' : '=', var, value);
159 else
160 warning("Skipping unknown msg id '%s'", var);
161 return 0;
162 }
163
Martin Koegler20dc0012008-02-25 22:46:13 +0100164 if (strcmp(var, "receive.fsckobjects") == 0) {
165 receive_fsck_objects = git_config_bool(var, value);
166 return 0;
167 }
168
Junio C Hamanodab76d32011-09-04 12:37:45 -0700169 if (strcmp(var, "transfer.fsckobjects") == 0) {
170 transfer_fsck_objects = git_config_bool(var, value);
171 return 0;
172 }
173
Jeff King986e8232008-11-08 20:49:27 -0500174 if (!strcmp(var, "receive.denycurrentbranch")) {
175 deny_current_branch = parse_deny_action(var, value);
176 return 0;
177 }
178
Junio C Hamano747ca242009-02-08 22:31:21 -0800179 if (strcmp(var, "receive.denydeletecurrent") == 0) {
180 deny_delete_current = parse_deny_action(var, value);
181 return 0;
182 }
183
Nicolas Pitreb74fce12009-05-01 16:56:47 -0400184 if (strcmp(var, "repack.usedeltabaseoffset") == 0) {
185 prefer_ofs_delta = git_config_bool(var, value);
186 return 0;
187 }
188
Junio C Hamano77e3efb2009-10-20 14:56:40 -0700189 if (strcmp(var, "receive.updateserverinfo") == 0) {
190 auto_update_server_info = git_config_bool(var, value);
191 return 0;
192 }
193
194 if (strcmp(var, "receive.autogc") == 0) {
195 auto_gc = git_config_bool(var, value);
196 return 0;
197 }
198
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700199 if (strcmp(var, "receive.shallowupdate") == 0) {
200 shallow_update = git_config_bool(var, value);
201 return 0;
202 }
203
Junio C Hamanob89363e2014-08-21 16:45:30 -0700204 if (strcmp(var, "receive.certnonceseed") == 0)
205 return git_config_string(&cert_nonce_seed, var, value);
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700206
Junio C Hamano57323732014-09-05 10:46:04 -0700207 if (strcmp(var, "receive.certnonceslop") == 0) {
208 nonce_stamp_slop_limit = git_config_ulong(var, value);
209 return 0;
210 }
211
Ronnie Sahlberg1b70fe52015-01-07 19:23:20 -0800212 if (strcmp(var, "receive.advertiseatomic") == 0) {
213 advertise_atomic_push = git_config_bool(var, value);
214 return 0;
215 }
216
Stefan Bellerc714e452016-07-14 14:49:46 -0700217 if (strcmp(var, "receive.advertisepushoptions") == 0) {
218 advertise_push_options = git_config_bool(var, value);
219 return 0;
220 }
221
Jeff King83558682016-07-15 06:43:47 -0400222 if (strcmp(var, "receive.keepalive") == 0) {
223 keepalive_in_sec = git_config_int(var, value);
224 return 0;
225 }
226
Jeff Kingc08db5a2016-08-24 20:41:57 +0200227 if (strcmp(var, "receive.maxinputsize") == 0) {
228 max_input_size = git_config_int64(var, value);
229 return 0;
230 }
231
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100232 return git_default_config(var, value, cb);
Shawn Pearce6fb75be2006-10-30 17:35:18 -0500233}
234
brian m. carlson1b7ba792017-03-31 01:39:59 +0000235static void show_ref(const char *path, const struct object_id *oid)
Linus Torvalds575f4972005-06-29 17:52:11 -0700236{
Junio C Hamano52d2ae52014-09-04 12:13:32 -0700237 if (sent_capabilities) {
brian m. carlson1b7ba792017-03-31 01:39:59 +0000238 packet_write_fmt(1, "%s %s\n", oid_to_hex(oid), path);
Junio C Hamano52d2ae52014-09-04 12:13:32 -0700239 } else {
240 struct strbuf cap = STRBUF_INIT;
241
242 strbuf_addstr(&cap,
243 "report-status delete-refs side-band-64k quiet");
Ronnie Sahlberg1b70fe52015-01-07 19:23:20 -0800244 if (advertise_atomic_push)
245 strbuf_addstr(&cap, " atomic");
Junio C Hamano52d2ae52014-09-04 12:13:32 -0700246 if (prefer_ofs_delta)
247 strbuf_addstr(&cap, " ofs-delta");
Junio C Hamanob89363e2014-08-21 16:45:30 -0700248 if (push_cert_nonce)
249 strbuf_addf(&cap, " push-cert=%s", push_cert_nonce);
Stefan Bellerc714e452016-07-14 14:49:46 -0700250 if (advertise_push_options)
251 strbuf_addstr(&cap, " push-options");
brian m. carlsonbf30dbf2020-05-25 19:58:51 +0000252 strbuf_addf(&cap, " object-format=%s", the_hash_algo->name);
Junio C Hamano52d2ae52014-09-04 12:13:32 -0700253 strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
Lars Schneider81c634e2016-10-16 16:20:29 -0700254 packet_write_fmt(1, "%s %s%c%s\n",
brian m. carlson1b7ba792017-03-31 01:39:59 +0000255 oid_to_hex(oid), path, 0, cap.buf);
Junio C Hamano52d2ae52014-09-04 12:13:32 -0700256 strbuf_release(&cap);
257 sent_capabilities = 1;
258 }
Linus Torvalds575f4972005-06-29 17:52:11 -0700259}
260
Lukas Fleischer78a766a2015-11-03 08:58:16 +0100261static int show_ref_cb(const char *path_full, const struct object_id *oid,
Jeff King8b24b9e2017-02-08 15:53:16 -0500262 int flag, void *data)
Josh Triplett6b01ecf2011-07-08 16:13:32 -0700263{
Jeff King8b24b9e2017-02-08 15:53:16 -0500264 struct oidset *seen = data;
Lukas Fleischer78a766a2015-11-03 08:58:16 +0100265 const char *path = strip_namespace(path_full);
266
267 if (ref_is_hidden(path, path_full))
268 return 0;
269
Josh Triplett6b01ecf2011-07-08 16:13:32 -0700270 /*
271 * Advertise refs outside our current namespace as ".have"
272 * refs, so that the client can use them to minimize data
Jeff Kingfea6c472017-02-08 15:53:13 -0500273 * transfer but will otherwise ignore them.
Josh Triplett6b01ecf2011-07-08 16:13:32 -0700274 */
Jeff King8b24b9e2017-02-08 15:53:16 -0500275 if (!path) {
276 if (oidset_insert(seen, oid))
277 return 0;
Josh Triplett6b01ecf2011-07-08 16:13:32 -0700278 path = ".have";
Jeff King63d428e2017-02-08 15:53:19 -0500279 } else {
280 oidset_insert(seen, oid);
Jeff King8b24b9e2017-02-08 15:53:16 -0500281 }
brian m. carlson1b7ba792017-03-31 01:39:59 +0000282 show_ref(path, oid);
Michael Haggertybc982012012-01-06 15:12:32 +0100283 return 0;
Josh Triplett6b01ecf2011-07-08 16:13:32 -0700284}
285
Jeff Kingbdf42762018-10-08 11:09:23 -0700286static void show_one_alternate_ref(const struct object_id *oid,
Jeff Kingab6eea62017-02-08 15:53:10 -0500287 void *data)
Michael Haggertyb7a025d2012-01-06 15:12:31 +0100288{
Jeff Kingab6eea62017-02-08 15:53:10 -0500289 struct oidset *seen = data;
Michael Haggertyb7a025d2012-01-06 15:12:31 +0100290
Jeff Kingab6eea62017-02-08 15:53:10 -0500291 if (oidset_insert(seen, oid))
292 return;
293
brian m. carlson1b7ba792017-03-31 01:39:59 +0000294 show_ref(".have", oid);
Linus Torvalds575f4972005-06-29 17:52:11 -0700295}
296
Linus Torvalds8a65ff72005-07-02 20:23:36 -0700297static void write_head_info(void)
Linus Torvalds575f4972005-06-29 17:52:11 -0700298{
Jeff Kingab6eea62017-02-08 15:53:10 -0500299 static struct oidset seen = OIDSET_INIT;
Michael Haggerty2b2a5be2015-05-25 18:38:28 +0000300
Jeff King63d428e2017-02-08 15:53:19 -0500301 for_each_ref(show_ref_cb, &seen);
Jeff Kingab6eea62017-02-08 15:53:10 -0500302 for_each_alternate_ref(show_one_alternate_ref, &seen);
303 oidset_clear(&seen);
Shawn O. Pearce185c04e2010-02-05 12:57:40 -0800304 if (!sent_capabilities)
brian m. carlson1b7ba792017-03-31 01:39:59 +0000305 show_ref("capabilities^{}", &null_oid);
Junio C Hamanocfee10a2005-12-25 23:18:37 -0800306
Nguyễn Thái Ngọc Duyad491362013-12-05 20:02:32 +0700307 advertise_shallow_grafts(1);
308
Michael Haggertyb7a025d2012-01-06 15:12:31 +0100309 /* EOF */
310 packet_flush(1);
Linus Torvalds575f4972005-06-29 17:52:11 -0700311}
312
Linus Torvaldseb1af2d2005-06-29 23:01:14 -0700313struct command {
314 struct command *next;
Junio C Hamanocfee10a2005-12-25 23:18:37 -0800315 const char *error_string;
Pang Yan Han160b81e2011-09-28 23:39:35 +0800316 unsigned int skip_update:1,
317 did_not_exist:1;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +0700318 int index;
brian m. carlson9c44ea42017-03-26 16:01:29 +0000319 struct object_id old_oid;
320 struct object_id new_oid;
Junio C Hamano8f1d2e62006-01-07 01:33:54 -0800321 char ref_name[FLEX_ARRAY]; /* more */
Linus Torvalds575f4972005-06-29 17:52:11 -0700322};
323
Shawn O. Pearce466dbc42010-02-10 09:34:12 -0800324static void rp_error(const char *err, ...) __attribute__((format (printf, 1, 2)));
325static void rp_warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
326
327static void report_message(const char *prefix, const char *err, va_list params)
328{
Jeff Kingb7115a32015-09-24 17:07:00 -0400329 int sz;
Shawn O. Pearce466dbc42010-02-10 09:34:12 -0800330 char msg[4096];
331
Jeff Kingb7115a32015-09-24 17:07:00 -0400332 sz = xsnprintf(msg, sizeof(msg), "%s", prefix);
Shawn O. Pearce466dbc42010-02-10 09:34:12 -0800333 sz += vsnprintf(msg + sz, sizeof(msg) - sz, err, params);
334 if (sz > (sizeof(msg) - 1))
335 sz = sizeof(msg) - 1;
336 msg[sz++] = '\n';
337
338 if (use_sideband)
339 send_sideband(1, 2, msg, sz, use_sideband);
340 else
341 xwrite(2, msg, sz);
342}
343
344static void rp_warning(const char *err, ...)
345{
346 va_list params;
347 va_start(params, err);
348 report_message("warning: ", err, params);
349 va_end(params);
350}
351
352static void rp_error(const char *err, ...)
353{
354 va_list params;
355 va_start(params, err);
356 report_message("error: ", err, params);
357 va_end(params);
358}
359
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800360static int copy_to_sideband(int in, int out, void *arg)
361{
362 char data[128];
Jeff King83558682016-07-15 06:43:47 -0400363 int keepalive_active = 0;
364
365 if (keepalive_in_sec <= 0)
366 use_keepalive = KEEPALIVE_NEVER;
367 if (use_keepalive == KEEPALIVE_ALWAYS)
368 keepalive_active = 1;
369
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800370 while (1) {
Jeff King83558682016-07-15 06:43:47 -0400371 ssize_t sz;
372
373 if (keepalive_active) {
374 struct pollfd pfd;
375 int ret;
376
377 pfd.fd = in;
378 pfd.events = POLLIN;
379 ret = poll(&pfd, 1, 1000 * keepalive_in_sec);
380
381 if (ret < 0) {
382 if (errno == EINTR)
383 continue;
384 else
385 break;
386 } else if (ret == 0) {
387 /* no data; send a keepalive packet */
388 static const char buf[] = "0005\1";
389 write_or_die(1, buf, sizeof(buf) - 1);
390 continue;
391 } /* else there is actual data to read */
392 }
393
394 sz = xread(in, data, sizeof(data));
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800395 if (sz <= 0)
396 break;
Jeff King83558682016-07-15 06:43:47 -0400397
398 if (use_keepalive == KEEPALIVE_AFTER_NUL && !keepalive_active) {
399 const char *p = memchr(data, '\0', sz);
400 if (p) {
401 /*
402 * The NUL tells us to start sending keepalives. Make
403 * sure we send any other data we read along
404 * with it.
405 */
406 keepalive_active = 1;
407 send_sideband(1, 2, data, p - data, use_sideband);
408 send_sideband(1, 2, p + 1, sz - (p - data + 1), use_sideband);
409 continue;
410 }
411 }
412
413 /*
414 * Either we're not looking for a NUL signal, or we didn't see
415 * it yet; just pass along the data.
416 */
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800417 send_sideband(1, 2, data, sz, use_sideband);
418 }
419 close(in);
420 return 0;
421}
422
Carlo Marcelo Arenas Belón30131182020-05-05 02:53:26 -0700423static void hmac_hash(unsigned char *out,
Junio C Hamanob89363e2014-08-21 16:45:30 -0700424 const char *key_in, size_t key_len,
425 const char *text, size_t text_len)
426{
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000427 unsigned char key[GIT_MAX_BLKSZ];
428 unsigned char k_ipad[GIT_MAX_BLKSZ];
429 unsigned char k_opad[GIT_MAX_BLKSZ];
Junio C Hamanob89363e2014-08-21 16:45:30 -0700430 int i;
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000431 git_hash_ctx ctx;
Junio C Hamanob89363e2014-08-21 16:45:30 -0700432
433 /* RFC 2104 2. (1) */
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000434 memset(key, '\0', GIT_MAX_BLKSZ);
435 if (the_hash_algo->blksz < key_len) {
436 the_hash_algo->init_fn(&ctx);
437 the_hash_algo->update_fn(&ctx, key_in, key_len);
438 the_hash_algo->final_fn(key, &ctx);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700439 } else {
440 memcpy(key, key_in, key_len);
441 }
442
443 /* RFC 2104 2. (2) & (5) */
444 for (i = 0; i < sizeof(key); i++) {
445 k_ipad[i] = key[i] ^ 0x36;
446 k_opad[i] = key[i] ^ 0x5c;
447 }
448
449 /* RFC 2104 2. (3) & (4) */
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000450 the_hash_algo->init_fn(&ctx);
451 the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad));
452 the_hash_algo->update_fn(&ctx, text, text_len);
453 the_hash_algo->final_fn(out, &ctx);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700454
455 /* RFC 2104 2. (6) & (7) */
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000456 the_hash_algo->init_fn(&ctx);
457 the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad));
458 the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz);
459 the_hash_algo->final_fn(out, &ctx);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700460}
461
Johannes Schindelindddbad72017-04-26 21:29:31 +0200462static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
Junio C Hamanob89363e2014-08-21 16:45:30 -0700463{
464 struct strbuf buf = STRBUF_INIT;
brian m. carlsonfabec2c2019-08-18 20:04:05 +0000465 unsigned char hash[GIT_MAX_RAWSZ];
Junio C Hamanob89363e2014-08-21 16:45:30 -0700466
Johannes Schindelincb71f8b2017-04-21 12:45:48 +0200467 strbuf_addf(&buf, "%s:%"PRItime, path, stamp);
Carlo Marcelo Arenas Belón30131182020-05-05 02:53:26 -0700468 hmac_hash(hash, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));
Junio C Hamanob89363e2014-08-21 16:45:30 -0700469 strbuf_release(&buf);
470
Carlo Marcelo Arenas Belón30131182020-05-05 02:53:26 -0700471 /* RFC 2104 5. HMAC-SHA1 or HMAC-SHA256 */
brian m. carlsonfc06be32019-08-18 20:04:24 +0000472 strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, (int)the_hash_algo->hexsz, hash_to_hex(hash));
Junio C Hamanob89363e2014-08-21 16:45:30 -0700473 return strbuf_detach(&buf, NULL);
474}
475
476/*
477 * NEEDSWORK: reuse find_commit_header() from jk/commit-author-parsing
478 * after dropping "_commit" from its name and possibly moving it out
479 * of commit.c
480 */
Jonathan Tancbaf82c2017-05-09 12:23:53 -0700481static char *find_header(const char *msg, size_t len, const char *key,
482 const char **next_line)
Junio C Hamanob89363e2014-08-21 16:45:30 -0700483{
484 int key_len = strlen(key);
485 const char *line = msg;
486
487 while (line && line < msg + len) {
488 const char *eol = strchrnul(line, '\n');
489
490 if ((msg + len <= eol) || line == eol)
491 return NULL;
492 if (line + key_len < eol &&
493 !memcmp(line, key, key_len) && line[key_len] == ' ') {
494 int offset = key_len + 1;
Jonathan Tancbaf82c2017-05-09 12:23:53 -0700495 if (next_line)
496 *next_line = *eol ? eol + 1 : eol;
Junio C Hamanob89363e2014-08-21 16:45:30 -0700497 return xmemdupz(line + offset, (eol - line) - offset);
498 }
499 line = *eol ? eol + 1 : NULL;
500 }
501 return NULL;
502}
503
brian m. carlsonedc6dcc2020-04-09 23:37:30 +0000504/*
505 * Return zero if a and b are equal up to n bytes and nonzero if they are not.
506 * This operation is guaranteed to run in constant time to avoid leaking data.
507 */
508static int constant_memequal(const char *a, const char *b, size_t n)
509{
510 int res = 0;
Junio C Hamano719483e2020-04-22 08:55:11 -0700511 size_t i;
512
513 for (i = 0; i < n; i++)
brian m. carlsonedc6dcc2020-04-09 23:37:30 +0000514 res |= a[i] ^ b[i];
515 return res;
516}
517
Junio C Hamanob89363e2014-08-21 16:45:30 -0700518static const char *check_nonce(const char *buf, size_t len)
519{
Jonathan Tancbaf82c2017-05-09 12:23:53 -0700520 char *nonce = find_header(buf, len, "nonce", NULL);
Johannes Schindelindddbad72017-04-26 21:29:31 +0200521 timestamp_t stamp, ostamp;
Junio C Hamano57323732014-09-05 10:46:04 -0700522 char *bohmac, *expect = NULL;
Junio C Hamanob89363e2014-08-21 16:45:30 -0700523 const char *retval = NONCE_BAD;
brian m. carlsonedc6dcc2020-04-09 23:37:30 +0000524 size_t noncelen;
Junio C Hamanob89363e2014-08-21 16:45:30 -0700525
526 if (!nonce) {
527 retval = NONCE_MISSING;
528 goto leave;
529 } else if (!push_cert_nonce) {
530 retval = NONCE_UNSOLICITED;
531 goto leave;
532 } else if (!strcmp(push_cert_nonce, nonce)) {
533 retval = NONCE_OK;
534 goto leave;
535 }
536
Junio C Hamano57323732014-09-05 10:46:04 -0700537 if (!stateless_rpc) {
538 /* returned nonce MUST match what we gave out earlier */
539 retval = NONCE_BAD;
540 goto leave;
541 }
542
543 /*
544 * In stateless mode, we may be receiving a nonce issued by
545 * another instance of the server that serving the same
546 * repository, and the timestamps may not match, but the
547 * nonce-seed and dir should match, so we can recompute and
548 * report the time slop.
549 *
550 * In addition, when a nonce issued by another instance has
551 * timestamp within receive.certnonceslop seconds, we pretend
552 * as if we issued that nonce when reporting to the hook.
553 */
554
555 /* nonce is concat(<seconds-since-epoch>, "-", <hmac>) */
556 if (*nonce <= '0' || '9' < *nonce) {
557 retval = NONCE_BAD;
558 goto leave;
559 }
Johannes Schindelin1aeb7e72017-04-21 12:45:44 +0200560 stamp = parse_timestamp(nonce, &bohmac, 10);
Junio C Hamano57323732014-09-05 10:46:04 -0700561 if (bohmac == nonce || bohmac[0] != '-') {
562 retval = NONCE_BAD;
563 goto leave;
564 }
565
brian m. carlsonedc6dcc2020-04-09 23:37:30 +0000566 noncelen = strlen(nonce);
Junio C Hamano57323732014-09-05 10:46:04 -0700567 expect = prepare_push_cert_nonce(service_dir, stamp);
brian m. carlsonedc6dcc2020-04-09 23:37:30 +0000568 if (noncelen != strlen(expect)) {
569 /* This is not even the right size. */
570 retval = NONCE_BAD;
571 goto leave;
572 }
573 if (constant_memequal(expect, nonce, noncelen)) {
Junio C Hamano57323732014-09-05 10:46:04 -0700574 /* Not what we would have signed earlier */
575 retval = NONCE_BAD;
576 goto leave;
577 }
578
579 /*
580 * By how many seconds is this nonce stale? Negative value
581 * would mean it was issued by another server with its clock
582 * skewed in the future.
583 */
Johannes Schindelin1aeb7e72017-04-21 12:45:44 +0200584 ostamp = parse_timestamp(push_cert_nonce, NULL, 10);
Junio C Hamano57323732014-09-05 10:46:04 -0700585 nonce_stamp_slop = (long)ostamp - (long)stamp;
586
587 if (nonce_stamp_slop_limit &&
René Scharfe31a8aa12014-11-15 14:27:21 +0100588 labs(nonce_stamp_slop) <= nonce_stamp_slop_limit) {
Junio C Hamano57323732014-09-05 10:46:04 -0700589 /*
590 * Pretend as if the received nonce (which passes the
591 * HMAC check, so it is not a forged by third-party)
592 * is what we issued.
593 */
594 free((void *)push_cert_nonce);
595 push_cert_nonce = xstrdup(nonce);
596 retval = NONCE_OK;
597 } else {
598 retval = NONCE_SLOP;
599 }
Junio C Hamanob89363e2014-08-21 16:45:30 -0700600
601leave:
602 free(nonce);
Junio C Hamano57323732014-09-05 10:46:04 -0700603 free(expect);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700604 return retval;
605}
606
Jonathan Tancbaf82c2017-05-09 12:23:53 -0700607/*
608 * Return 1 if there is no push_cert or if the push options in push_cert are
609 * the same as those in the argument; 0 otherwise.
610 */
611static int check_cert_push_options(const struct string_list *push_options)
612{
613 const char *buf = push_cert.buf;
614 int len = push_cert.len;
615
616 char *option;
617 const char *next_line;
618 int options_seen = 0;
619
620 int retval = 1;
621
622 if (!len)
623 return 1;
624
625 while ((option = find_header(buf, len, "push-option", &next_line))) {
626 len -= (next_line - buf);
627 buf = next_line;
628 options_seen++;
629 if (options_seen > push_options->nr
630 || strcmp(option,
631 push_options->items[options_seen - 1].string)) {
632 retval = 0;
633 goto leave;
634 }
635 free(option);
636 }
637
638 if (options_seen != push_options->nr)
639 retval = 0;
640
641leave:
642 free(option);
643 return retval;
644}
645
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700646static void prepare_push_cert_sha1(struct child_process *proc)
647{
648 static int already_done;
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700649
650 if (!push_cert.len)
651 return;
652
653 if (!already_done) {
Junio C Hamanod05b9612014-08-14 15:59:21 -0700654 int bogs /* beginning_of_gpg_sig */;
655
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700656 already_done = 1;
Patryk Obaraa09c9852018-01-28 01:13:19 +0100657 if (write_object_file(push_cert.buf, push_cert.len, "blob",
658 &push_cert_oid))
659 oidclr(&push_cert_oid);
Junio C Hamanod05b9612014-08-14 15:59:21 -0700660
661 memset(&sigcheck, '\0', sizeof(sigcheck));
Junio C Hamanod05b9612014-08-14 15:59:21 -0700662
663 bogs = parse_signature(push_cert.buf, push_cert.len);
Henning Schild3b9291e2018-07-11 10:38:24 +0200664 check_signature(push_cert.buf, bogs, push_cert.buf + bogs,
665 push_cert.len - bogs, &sigcheck);
Junio C Hamanod05b9612014-08-14 15:59:21 -0700666
Junio C Hamanob89363e2014-08-21 16:45:30 -0700667 nonce_status = check_nonce(push_cert.buf, bogs);
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700668 }
Patryk Obaraa09c9852018-01-28 01:13:19 +0100669 if (!is_null_oid(&push_cert_oid)) {
Jeff King22f9b7f2020-07-28 16:24:27 -0400670 strvec_pushf(&proc->env_array, "GIT_PUSH_CERT=%s",
Jeff Kingf6d89422020-07-28 16:26:31 -0400671 oid_to_hex(&push_cert_oid));
Jeff King22f9b7f2020-07-28 16:24:27 -0400672 strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s",
Jeff Kingf6d89422020-07-28 16:26:31 -0400673 sigcheck.signer ? sigcheck.signer : "");
Jeff King22f9b7f2020-07-28 16:24:27 -0400674 strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s",
Jeff Kingf6d89422020-07-28 16:26:31 -0400675 sigcheck.key ? sigcheck.key : "");
Jeff King22f9b7f2020-07-28 16:24:27 -0400676 strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c",
Jeff Kingf6d89422020-07-28 16:26:31 -0400677 sigcheck.result);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700678 if (push_cert_nonce) {
Jeff King22f9b7f2020-07-28 16:24:27 -0400679 strvec_pushf(&proc->env_array,
Jeff Kingf6d89422020-07-28 16:26:31 -0400680 "GIT_PUSH_CERT_NONCE=%s",
681 push_cert_nonce);
Jeff King22f9b7f2020-07-28 16:24:27 -0400682 strvec_pushf(&proc->env_array,
Jeff Kingf6d89422020-07-28 16:26:31 -0400683 "GIT_PUSH_CERT_NONCE_STATUS=%s",
684 nonce_status);
Junio C Hamano57323732014-09-05 10:46:04 -0700685 if (nonce_status == NONCE_SLOP)
Jeff King22f9b7f2020-07-28 16:24:27 -0400686 strvec_pushf(&proc->env_array,
Jeff Kingf6d89422020-07-28 16:26:31 -0400687 "GIT_PUSH_CERT_NONCE_SLOP=%ld",
688 nonce_stamp_slop);
Junio C Hamanob89363e2014-08-21 16:45:30 -0700689 }
Junio C Hamanoa85b3772014-09-12 11:17:07 -0700690 }
691}
692
Stefan Beller77a97452016-07-14 14:49:45 -0700693struct receive_hook_feed_state {
694 struct command *cmd;
695 int skip_broken;
696 struct strbuf buf;
697 const struct string_list *push_options;
698};
699
Junio C Hamano9684e442011-09-08 12:17:09 -0700700typedef int (*feed_fn)(void *, const char **, size_t *);
Stefan Beller77a97452016-07-14 14:49:45 -0700701static int run_and_feed_hook(const char *hook_name, feed_fn feed,
702 struct receive_hook_feed_state *feed_state)
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +0200703{
René Scharfed3180272014-08-19 21:09:35 +0200704 struct child_process proc = CHILD_PROCESS_INIT;
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800705 struct async muxer;
Shawn O. Pearcef43cd492007-03-10 03:28:16 -0500706 const char *argv[2];
Junio C Hamano9684e442011-09-08 12:17:09 -0700707 int code;
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +0200708
Aaron Schrab5a7da2d2013-01-13 00:17:02 -0500709 argv[0] = find_hook(hook_name);
710 if (!argv[0])
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +0200711 return 0;
Shawn O. Pearcec8dd2772007-03-07 16:51:09 -0500712
Shawn O. Pearcef43cd492007-03-10 03:28:16 -0500713 argv[1] = NULL;
714
Shawn O. Pearcef43cd492007-03-10 03:28:16 -0500715 proc.argv = argv;
716 proc.in = -1;
717 proc.stdout_to_stderr = 1;
Jeff Hostetler62062862019-02-22 14:25:06 -0800718 proc.trace2_hook_name = hook_name;
719
Stefan Beller77a97452016-07-14 14:49:45 -0700720 if (feed_state->push_options) {
721 int i;
722 for (i = 0; i < feed_state->push_options->nr; i++)
Jeff King22f9b7f2020-07-28 16:24:27 -0400723 strvec_pushf(&proc.env_array,
Jeff Kingf6d89422020-07-28 16:26:31 -0400724 "GIT_PUSH_OPTION_%d=%s", i,
725 feed_state->push_options->items[i].string);
Jeff King22f9b7f2020-07-28 16:24:27 -0400726 strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%d",
Jeff Kingf6d89422020-07-28 16:26:31 -0400727 feed_state->push_options->nr);
Stefan Beller77a97452016-07-14 14:49:45 -0700728 } else
Jeff King22f9b7f2020-07-28 16:24:27 -0400729 strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT");
Shawn O. Pearcef43cd492007-03-10 03:28:16 -0500730
Jeff King722ff7f2016-10-03 16:49:14 -0400731 if (tmp_objdir)
Jeff King22f9b7f2020-07-28 16:24:27 -0400732 strvec_pushv(&proc.env_array, tmp_objdir_env(tmp_objdir));
Jeff King722ff7f2016-10-03 16:49:14 -0400733
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800734 if (use_sideband) {
735 memset(&muxer, 0, sizeof(muxer));
736 muxer.proc = copy_to_sideband;
737 muxer.in = -1;
738 code = start_async(&muxer);
739 if (code)
740 return code;
741 proc.err = muxer.in;
742 }
743
René Scharfe5d222c02014-10-28 21:27:54 +0100744 prepare_push_cert_sha1(&proc);
745
Shawn O. Pearcef43cd492007-03-10 03:28:16 -0500746 code = start_command(&proc);
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800747 if (code) {
748 if (use_sideband)
749 finish_async(&muxer);
Johannes Sixt90e41a82009-07-04 21:26:43 +0200750 return code;
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800751 }
752
Junio C Hamanoec7dbd12014-09-12 15:48:07 -0700753 sigchain_push(SIGPIPE, SIG_IGN);
754
Junio C Hamano9684e442011-09-08 12:17:09 -0700755 while (1) {
756 const char *buf;
757 size_t n;
758 if (feed(feed_state, &buf, &n))
759 break;
Jeff King06f46f22017-09-13 13:16:03 -0400760 if (write_in_full(proc.in, buf, n) < 0)
Junio C Hamano9684e442011-09-08 12:17:09 -0700761 break;
Shawn O. Pearcec8dd2772007-03-07 16:51:09 -0500762 }
Johannes Sixte72ae282008-02-16 18:36:38 +0100763 close(proc.in);
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800764 if (use_sideband)
765 finish_async(&muxer);
Junio C Hamanoec7dbd12014-09-12 15:48:07 -0700766
767 sigchain_pop(SIGPIPE);
768
Johannes Sixt90e41a82009-07-04 21:26:43 +0200769 return finish_command(&proc);
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +0200770}
771
Junio C Hamano9684e442011-09-08 12:17:09 -0700772static int feed_receive_hook(void *state_, const char **bufp, size_t *sizep)
773{
774 struct receive_hook_feed_state *state = state_;
775 struct command *cmd = state->cmd;
776
Junio C Hamanocdc2b2f2011-10-17 21:37:10 -0700777 while (cmd &&
778 state->skip_broken && (cmd->error_string || cmd->did_not_exist))
Junio C Hamano9684e442011-09-08 12:17:09 -0700779 cmd = cmd->next;
780 if (!cmd)
781 return -1; /* EOF */
782 strbuf_reset(&state->buf);
783 strbuf_addf(&state->buf, "%s %s %s\n",
brian m. carlson9c44ea42017-03-26 16:01:29 +0000784 oid_to_hex(&cmd->old_oid), oid_to_hex(&cmd->new_oid),
Junio C Hamano9684e442011-09-08 12:17:09 -0700785 cmd->ref_name);
786 state->cmd = cmd->next;
787 if (bufp) {
788 *bufp = state->buf.buf;
789 *sizep = state->buf.len;
790 }
791 return 0;
792}
793
Stefan Beller77a97452016-07-14 14:49:45 -0700794static int run_receive_hook(struct command *commands,
795 const char *hook_name,
796 int skip_broken,
797 const struct string_list *push_options)
Junio C Hamano9684e442011-09-08 12:17:09 -0700798{
799 struct receive_hook_feed_state state;
800 int status;
801
802 strbuf_init(&state.buf, 0);
803 state.cmd = commands;
Junio C Hamanocdc2b2f2011-10-17 21:37:10 -0700804 state.skip_broken = skip_broken;
Junio C Hamano9684e442011-09-08 12:17:09 -0700805 if (feed_receive_hook(&state, NULL, NULL))
806 return 0;
807 state.cmd = commands;
Stefan Beller77a97452016-07-14 14:49:45 -0700808 state.push_options = push_options;
Junio C Hamano9684e442011-09-08 12:17:09 -0700809 status = run_and_feed_hook(hook_name, feed_receive_hook, &state);
810 strbuf_release(&state.buf);
811 return status;
812}
813
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500814static int run_update_hook(struct command *cmd)
815{
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500816 const char *argv[5];
René Scharfed3180272014-08-19 21:09:35 +0200817 struct child_process proc = CHILD_PROCESS_INIT;
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800818 int code;
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500819
Aaron Schrab5a7da2d2013-01-13 00:17:02 -0500820 argv[0] = find_hook("update");
821 if (!argv[0])
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500822 return 0;
823
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500824 argv[1] = cmd->ref_name;
brian m. carlson9c44ea42017-03-26 16:01:29 +0000825 argv[2] = oid_to_hex(&cmd->old_oid);
826 argv[3] = oid_to_hex(&cmd->new_oid);
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500827 argv[4] = NULL;
828
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800829 proc.no_stdin = 1;
830 proc.stdout_to_stderr = 1;
831 proc.err = use_sideband ? -1 : 0;
832 proc.argv = argv;
Jeff Hostetler62062862019-02-22 14:25:06 -0800833 proc.trace2_hook_name = "update";
Shawn O. Pearce6d525d32010-02-05 12:57:42 -0800834
835 code = start_command(&proc);
836 if (code)
837 return code;
838 if (use_sideband)
839 copy_to_sideband(proc.err, -1, NULL);
840 return finish_command(&proc);
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -0500841}
842
Vasco Almeida8ba35a22016-09-15 14:59:05 +0000843static char *refuse_unconfigured_deny_msg =
844 N_("By default, updating the current branch in a non-bare repository\n"
845 "is denied, because it will make the index and work tree inconsistent\n"
846 "with what you pushed, and will require 'git reset --hard' to match\n"
847 "the work tree to HEAD.\n"
848 "\n"
Alex Henrie2ddaa422016-12-04 15:04:40 -0700849 "You can set the 'receive.denyCurrentBranch' configuration variable\n"
850 "to 'ignore' or 'warn' in the remote repository to allow pushing into\n"
Vasco Almeida8ba35a22016-09-15 14:59:05 +0000851 "its current branch; however, this is not recommended unless you\n"
852 "arranged to update its work tree to match what you pushed in some\n"
853 "other way.\n"
854 "\n"
855 "To squelch this message and still keep the default behaviour, set\n"
856 "'receive.denyCurrentBranch' configuration variable to 'refuse'.");
Junio C Hamano3d95d922009-01-31 17:34:05 -0800857
Junio C Hamanoacd2a452009-02-11 02:28:03 -0800858static void refuse_unconfigured_deny(void)
Junio C Hamano3d95d922009-01-31 17:34:05 -0800859{
Vasco Almeida8ba35a22016-09-15 14:59:05 +0000860 rp_error("%s", _(refuse_unconfigured_deny_msg));
Junio C Hamano3d95d922009-01-31 17:34:05 -0800861}
862
Vasco Almeida8ba35a22016-09-15 14:59:05 +0000863static char *refuse_unconfigured_deny_delete_current_msg =
864 N_("By default, deleting the current branch is denied, because the next\n"
865 "'git clone' won't result in any file checked out, causing confusion.\n"
866 "\n"
867 "You can set 'receive.denyDeleteCurrent' configuration variable to\n"
868 "'warn' or 'ignore' in the remote repository to allow deleting the\n"
869 "current branch, with or without a warning message.\n"
870 "\n"
871 "To squelch this message, you can set it to 'refuse'.");
Junio C Hamano747ca242009-02-08 22:31:21 -0800872
Junio C Hamano375881f2009-02-09 00:19:46 -0800873static void refuse_unconfigured_deny_delete_current(void)
Junio C Hamano747ca242009-02-08 22:31:21 -0800874{
Vasco Almeida8ba35a22016-09-15 14:59:05 +0000875 rp_error("%s", _(refuse_unconfigured_deny_delete_current_msg));
Junio C Hamano747ca242009-02-08 22:31:21 -0800876}
877
brian m. carlson6ccac9e2017-10-15 22:06:54 +0000878static int command_singleton_iterator(void *cb_data, struct object_id *oid);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700879static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
880{
Taylor Blaucac4b8e2020-04-30 13:48:57 -0600881 struct shallow_lock shallow_lock = SHALLOW_LOCK_INIT;
brian m. carlson910650d2017-03-31 01:40:00 +0000882 struct oid_array extra = OID_ARRAY_INIT;
Jeff King7043c702016-07-15 06:30:40 -0400883 struct check_connected_options opt = CHECK_CONNECTED_INIT;
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700884 uint32_t mask = 1 << (cmd->index % 32);
885 int i;
886
Karsten Blees6aa30852014-07-12 02:00:06 +0200887 trace_printf_key(&trace_shallow,
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700888 "shallow: update_shallow_ref %s\n", cmd->ref_name);
889 for (i = 0; i < si->shallow->nr; i++)
890 if (si->used_shallow[i] &&
891 (si->used_shallow[i][cmd->index / 32] & mask) &&
892 !delayed_reachability_test(si, i))
brian m. carlson910650d2017-03-31 01:40:00 +0000893 oid_array_append(&extra, &si->shallow->oid[i]);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700894
Jeff King722ff7f2016-10-03 16:49:14 -0400895 opt.env = tmp_objdir_env(tmp_objdir);
Jeff King7043c702016-07-15 06:30:40 -0400896 setup_alternate_shallow(&shallow_lock, &opt.shallow_file, &extra);
897 if (check_connected(command_singleton_iterator, cmd, &opt)) {
Taylor Blau37b9dca2020-04-22 18:25:45 -0600898 rollback_shallow_file(the_repository, &shallow_lock);
brian m. carlson910650d2017-03-31 01:40:00 +0000899 oid_array_clear(&extra);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700900 return -1;
901 }
902
Taylor Blau37b9dca2020-04-22 18:25:45 -0600903 commit_shallow_file(the_repository, &shallow_lock);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700904
905 /*
906 * Make sure setup_alternate_shallow() for the next ref does
907 * not lose these new roots..
908 */
909 for (i = 0; i < extra.nr; i++)
Stefan Beller19143f12018-05-17 15:51:44 -0700910 register_shallow(the_repository, &extra.oid[i]);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700911
912 si->shallow_ref[cmd->index] = 0;
brian m. carlson910650d2017-03-31 01:40:00 +0000913 oid_array_clear(&extra);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +0700914 return 0;
915}
916
Junio C Hamano1a51b522015-03-31 23:15:45 -0700917/*
918 * NEEDSWORK: we should consolidate various implementions of "are we
919 * on an unborn branch?" test into one, and make the unified one more
920 * robust. !get_sha1() based check used here and elsewhere would not
921 * allow us to tell an unborn branch from corrupt ref, for example.
922 * For the purpose of fixing "deploy-to-update does not work when
923 * pushing into an empty repository" issue, this should suffice for
924 * now.
925 */
926static int head_has_history(void)
927{
brian m. carlson15be4a52017-07-13 23:49:27 +0000928 struct object_id oid;
Junio C Hamano1a51b522015-03-31 23:15:45 -0700929
brian m. carlson15be4a52017-07-13 23:49:27 +0000930 return !get_oid("HEAD", &oid);
Junio C Hamano1a51b522015-03-31 23:15:45 -0700931}
932
Junio C Hamano21b138d2014-12-01 13:57:28 -0800933static const char *push_to_deploy(unsigned char *sha1,
Jeff King22f9b7f2020-07-28 16:24:27 -0400934 struct strvec *env,
Junio C Hamano21b138d2014-12-01 13:57:28 -0800935 const char *work_tree)
Johannes Schindelin1404bcb2014-11-26 23:44:16 +0100936{
937 const char *update_refresh[] = {
938 "update-index", "-q", "--ignore-submodules", "--refresh", NULL
939 };
940 const char *diff_files[] = {
941 "diff-files", "--quiet", "--ignore-submodules", "--", NULL
942 };
943 const char *diff_index[] = {
944 "diff-index", "--quiet", "--cached", "--ignore-submodules",
Junio C Hamano1a51b522015-03-31 23:15:45 -0700945 NULL, "--", NULL
Johannes Schindelin1404bcb2014-11-26 23:44:16 +0100946 };
947 const char *read_tree[] = {
948 "read-tree", "-u", "-m", NULL, NULL
949 };
Junio C Hamano21b138d2014-12-01 13:57:28 -0800950 struct child_process child = CHILD_PROCESS_INIT;
951
952 child.argv = update_refresh;
Jeff Kingd70a9eb2020-07-28 20:37:20 -0400953 child.env = env->v;
Junio C Hamano21b138d2014-12-01 13:57:28 -0800954 child.dir = work_tree;
955 child.no_stdin = 1;
956 child.stdout_to_stderr = 1;
957 child.git_cmd = 1;
958 if (run_command(&child))
959 return "Up-to-date check failed";
960
961 /* run_command() does not clean up completely; reinitialize */
962 child_process_init(&child);
963 child.argv = diff_files;
Jeff Kingd70a9eb2020-07-28 20:37:20 -0400964 child.env = env->v;
Junio C Hamano21b138d2014-12-01 13:57:28 -0800965 child.dir = work_tree;
966 child.no_stdin = 1;
967 child.stdout_to_stderr = 1;
968 child.git_cmd = 1;
969 if (run_command(&child))
970 return "Working directory has unstaged changes";
971
Junio C Hamano1a51b522015-03-31 23:15:45 -0700972 /* diff-index with either HEAD or an empty tree */
brian m. carlsonc00866a2018-05-02 00:26:01 +0000973 diff_index[4] = head_has_history() ? "HEAD" : empty_tree_oid_hex();
Junio C Hamano1a51b522015-03-31 23:15:45 -0700974
Junio C Hamano21b138d2014-12-01 13:57:28 -0800975 child_process_init(&child);
976 child.argv = diff_index;
Jeff Kingd70a9eb2020-07-28 20:37:20 -0400977 child.env = env->v;
Junio C Hamano21b138d2014-12-01 13:57:28 -0800978 child.no_stdin = 1;
979 child.no_stdout = 1;
980 child.stdout_to_stderr = 0;
981 child.git_cmd = 1;
982 if (run_command(&child))
983 return "Working directory has staged changes";
984
brian m. carlsonfc06be32019-08-18 20:04:24 +0000985 read_tree[3] = hash_to_hex(sha1);
Junio C Hamano21b138d2014-12-01 13:57:28 -0800986 child_process_init(&child);
987 child.argv = read_tree;
Jeff Kingd70a9eb2020-07-28 20:37:20 -0400988 child.env = env->v;
Junio C Hamano21b138d2014-12-01 13:57:28 -0800989 child.dir = work_tree;
990 child.no_stdin = 1;
991 child.no_stdout = 1;
992 child.stdout_to_stderr = 0;
993 child.git_cmd = 1;
994 if (run_command(&child))
995 return "Could not update working tree to new HEAD";
996
997 return NULL;
998}
999
Junio C Hamano08553312014-12-01 15:29:54 -08001000static const char *push_to_checkout_hook = "push-to-checkout";
1001
brian m. carlsonfc06be32019-08-18 20:04:24 +00001002static const char *push_to_checkout(unsigned char *hash,
Jeff King22f9b7f2020-07-28 16:24:27 -04001003 struct strvec *env,
Junio C Hamano08553312014-12-01 15:29:54 -08001004 const char *work_tree)
1005{
Jeff King22f9b7f2020-07-28 16:24:27 -04001006 strvec_pushf(env, "GIT_WORK_TREE=%s", absolute_path(work_tree));
Jeff Kingd70a9eb2020-07-28 20:37:20 -04001007 if (run_hook_le(env->v, push_to_checkout_hook,
brian m. carlsonfc06be32019-08-18 20:04:24 +00001008 hash_to_hex(hash), NULL))
Junio C Hamano08553312014-12-01 15:29:54 -08001009 return "push-to-checkout hook declined";
1010 else
1011 return NULL;
1012}
1013
Hariom Verma4ef34642020-02-23 18:57:10 +00001014static const char *update_worktree(unsigned char *sha1, const struct worktree *worktree)
Junio C Hamano21b138d2014-12-01 13:57:28 -08001015{
Hariom Verma4ef34642020-02-23 18:57:10 +00001016 const char *retval, *work_tree, *git_dir = NULL;
Jeff King22f9b7f2020-07-28 16:24:27 -04001017 struct strvec env = STRVEC_INIT;
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001018
Hariom Verma4ef34642020-02-23 18:57:10 +00001019 if (worktree && worktree->path)
1020 work_tree = worktree->path;
1021 else if (git_work_tree_cfg)
1022 work_tree = git_work_tree_cfg;
1023 else
1024 work_tree = "..";
1025
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001026 if (is_bare_repository())
1027 return "denyCurrentBranch = updateInstead needs a worktree";
Hariom Verma4ef34642020-02-23 18:57:10 +00001028 if (worktree)
1029 git_dir = get_worktree_git_dir(worktree);
1030 if (!git_dir)
1031 git_dir = get_git_dir();
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001032
Jeff King22f9b7f2020-07-28 16:24:27 -04001033 strvec_pushf(&env, "GIT_DIR=%s", absolute_path(git_dir));
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001034
Junio C Hamano08553312014-12-01 15:29:54 -08001035 if (!find_hook(push_to_checkout_hook))
1036 retval = push_to_deploy(sha1, &env, work_tree);
1037 else
1038 retval = push_to_checkout(sha1, &env, work_tree);
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001039
Jeff King22f9b7f2020-07-28 16:24:27 -04001040 strvec_clear(&env);
Junio C Hamano21b138d2014-12-01 13:57:28 -08001041 return retval;
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001042}
1043
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001044static const char *update(struct command *cmd, struct shallow_info *si)
Linus Torvalds2eca23d2005-06-30 10:15:22 -07001045{
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001046 const char *name = cmd->ref_name;
Josh Triplett6b01ecf2011-07-08 16:13:32 -07001047 struct strbuf namespaced_name_buf = STRBUF_INIT;
Johannes Schindelinbda6e822017-05-04 15:57:55 +02001048 static char *namespaced_name;
1049 const char *ret;
brian m. carlson9c44ea42017-03-26 16:01:29 +00001050 struct object_id *old_oid = &cmd->old_oid;
1051 struct object_id *new_oid = &cmd->new_oid;
Junio C Hamanob072a252018-10-19 13:57:35 +09001052 int do_update_worktree = 0;
Hariom Verma4ef34642020-02-23 18:57:10 +00001053 const struct worktree *worktree = is_bare_repository() ? NULL : find_shared_symref("HEAD", name);
Linus Torvalds2eca23d2005-06-30 10:15:22 -07001054
Martin Koegler061d6b92008-01-04 20:37:17 +01001055 /* only refs/... are allowed */
Christian Couder59556542013-11-30 21:55:40 +01001056 if (!starts_with(name, "refs/") || check_refname_format(name + 5, 0)) {
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001057 rp_error("refusing to create funny ref '%s' remotely", name);
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001058 return "funny refname";
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001059 }
Junio C Hamanod8a1dee2005-10-13 18:57:39 -07001060
Josh Triplett6b01ecf2011-07-08 16:13:32 -07001061 strbuf_addf(&namespaced_name_buf, "%s%s", get_git_namespace(), name);
Johannes Schindelinbda6e822017-05-04 15:57:55 +02001062 free(namespaced_name);
Josh Triplett6b01ecf2011-07-08 16:13:32 -07001063 namespaced_name = strbuf_detach(&namespaced_name_buf, NULL);
1064
Hariom Verma4ef34642020-02-23 18:57:10 +00001065 if (worktree) {
Junio C Hamano3d95d922009-01-31 17:34:05 -08001066 switch (deny_current_branch) {
1067 case DENY_IGNORE:
Jeff King986e8232008-11-08 20:49:27 -05001068 break;
Junio C Hamano3d95d922009-01-31 17:34:05 -08001069 case DENY_WARN:
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001070 rp_warning("updating the current branch");
Jeff King986e8232008-11-08 20:49:27 -05001071 break;
Junio C Hamano3d95d922009-01-31 17:34:05 -08001072 case DENY_REFUSE:
Junio C Hamanoacd2a452009-02-11 02:28:03 -08001073 case DENY_UNCONFIGURED:
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001074 rp_error("refusing to update checked out branch: %s", name);
Junio C Hamanoacd2a452009-02-11 02:28:03 -08001075 if (deny_current_branch == DENY_UNCONFIGURED)
1076 refuse_unconfigured_deny();
Junio C Hamano3d95d922009-01-31 17:34:05 -08001077 return "branch is currently checked out";
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001078 case DENY_UPDATE_INSTEAD:
Junio C Hamanob072a252018-10-19 13:57:35 +09001079 /* pass -- let other checks intervene first */
1080 do_update_worktree = 1;
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001081 break;
Junio C Hamano3d95d922009-01-31 17:34:05 -08001082 }
Jeff King986e8232008-11-08 20:49:27 -05001083 }
1084
brian m. carlson9c44ea42017-03-26 16:01:29 +00001085 if (!is_null_oid(new_oid) && !has_object_file(new_oid)) {
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001086 error("unpack should have generated %s, "
brian m. carlson9c44ea42017-03-26 16:01:29 +00001087 "but I can't find it!", oid_to_hex(new_oid));
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001088 return "bad pack";
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001089 }
Junio C Hamano747ca242009-02-08 22:31:21 -08001090
brian m. carlson9c44ea42017-03-26 16:01:29 +00001091 if (!is_null_oid(old_oid) && is_null_oid(new_oid)) {
Christian Couder59556542013-11-30 21:55:40 +01001092 if (deny_deletes && starts_with(name, "refs/heads/")) {
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001093 rp_error("denying ref deletion for %s", name);
Junio C Hamano747ca242009-02-08 22:31:21 -08001094 return "deletion prohibited";
1095 }
1096
Hariom Verma4ef34642020-02-23 18:57:10 +00001097 if (worktree || (head_name && !strcmp(namespaced_name, head_name))) {
Junio C Hamano747ca242009-02-08 22:31:21 -08001098 switch (deny_delete_current) {
1099 case DENY_IGNORE:
1100 break;
1101 case DENY_WARN:
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001102 rp_warning("deleting the current branch");
Junio C Hamano747ca242009-02-08 22:31:21 -08001103 break;
1104 case DENY_REFUSE:
Junio C Hamano375881f2009-02-09 00:19:46 -08001105 case DENY_UNCONFIGURED:
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001106 case DENY_UPDATE_INSTEAD:
Junio C Hamano375881f2009-02-09 00:19:46 -08001107 if (deny_delete_current == DENY_UNCONFIGURED)
1108 refuse_unconfigured_deny_delete_current();
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001109 rp_error("refusing to delete the current branch: %s", name);
Junio C Hamano747ca242009-02-08 22:31:21 -08001110 return "deletion of the current branch prohibited";
Johannes Schindelin1404bcb2014-11-26 23:44:16 +01001111 default:
1112 return "Invalid denyDeleteCurrent setting";
Junio C Hamano747ca242009-02-08 22:31:21 -08001113 }
1114 }
Jan Krügera240de12008-11-01 15:42:16 +01001115 }
Junio C Hamano747ca242009-02-08 22:31:21 -08001116
brian m. carlson9c44ea42017-03-26 16:01:29 +00001117 if (deny_non_fast_forwards && !is_null_oid(new_oid) &&
1118 !is_null_oid(old_oid) &&
Christian Couder59556542013-11-30 21:55:40 +01001119 starts_with(name, "refs/heads/")) {
Martin Koeglereab82702008-01-02 08:39:21 +01001120 struct object *old_object, *new_object;
Johannes Schindelin11031d72006-09-21 01:07:54 +02001121 struct commit *old_commit, *new_commit;
Johannes Schindelin11031d72006-09-21 01:07:54 +02001122
Stefan Beller109cd762018-06-28 18:21:51 -07001123 old_object = parse_object(the_repository, old_oid);
1124 new_object = parse_object(the_repository, new_oid);
Martin Koeglereab82702008-01-02 08:39:21 +01001125
1126 if (!old_object || !new_object ||
1127 old_object->type != OBJ_COMMIT ||
1128 new_object->type != OBJ_COMMIT) {
1129 error("bad sha1 objects for %s", name);
1130 return "bad ref";
1131 }
1132 old_commit = (struct commit *)old_object;
1133 new_commit = (struct commit *)new_object;
Junio C Hamano5d559152012-08-27 15:16:38 -07001134 if (!in_merge_bases(old_commit, new_commit)) {
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001135 rp_error("denying non-fast-forward %s"
1136 " (you should pull first)", name);
Felipe Contrerasa75d7b52009-10-24 11:31:32 +03001137 return "non-fast-forward";
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001138 }
Johannes Schindelin11031d72006-09-21 01:07:54 +02001139 }
Shawn O. Pearce1d9e8b52007-03-10 03:28:13 -05001140 if (run_update_hook(cmd)) {
Shawn O. Pearce466dbc42010-02-10 09:34:12 -08001141 rp_error("hook declined to update %s", name);
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001142 return "hook declined";
Josef Weidendorferb1bf95b2005-07-31 21:17:43 +02001143 }
Junio C Hamano3159c8d2006-09-27 02:40:06 -07001144
Junio C Hamanob072a252018-10-19 13:57:35 +09001145 if (do_update_worktree) {
Hariom Verma4ef34642020-02-23 18:57:10 +00001146 ret = update_worktree(new_oid->hash, find_shared_symref("HEAD", name));
Junio C Hamanob072a252018-10-19 13:57:35 +09001147 if (ret)
1148 return ret;
1149 }
1150
brian m. carlson9c44ea42017-03-26 16:01:29 +00001151 if (is_null_oid(new_oid)) {
Stefan Beller222368c2015-01-07 19:23:18 -08001152 struct strbuf err = STRBUF_INIT;
Stefan Beller109cd762018-06-28 18:21:51 -07001153 if (!parse_object(the_repository, old_oid)) {
brian m. carlson9c44ea42017-03-26 16:01:29 +00001154 old_oid = NULL;
Pang Yan Han160b81e2011-09-28 23:39:35 +08001155 if (ref_exists(name)) {
1156 rp_warning("Allowing deletion of corrupt ref.");
1157 } else {
1158 rp_warning("Deleting a non-existent ref.");
1159 cmd->did_not_exist = 1;
1160 }
Johannes Schindelin28391a82007-11-29 01:02:53 +00001161 }
Stefan Beller222368c2015-01-07 19:23:18 -08001162 if (ref_transaction_delete(transaction,
1163 namespaced_name,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001164 old_oid,
Michael Haggertyfb5a6bb2015-02-17 18:00:16 +01001165 0, "push", &err)) {
Stefan Beller222368c2015-01-07 19:23:18 -08001166 rp_error("%s", err.buf);
1167 strbuf_release(&err);
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001168 return "failed to delete";
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001169 }
Stefan Beller222368c2015-01-07 19:23:18 -08001170 strbuf_release(&err);
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001171 return NULL; /* good */
Linus Torvalds2eca23d2005-06-30 10:15:22 -07001172 }
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001173 else {
Ronnie Sahlberg6629ea22014-04-28 14:36:15 -07001174 struct strbuf err = STRBUF_INIT;
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001175 if (shallow_update && si->shallow_ref[cmd->index] &&
1176 update_shallow_ref(cmd, si))
1177 return "shallow error";
1178
Stefan Beller222368c2015-01-07 19:23:18 -08001179 if (ref_transaction_update(transaction,
1180 namespaced_name,
brian m. carlson89f3bbd2017-10-15 22:06:53 +00001181 new_oid, old_oid,
Michael Haggerty1d147bd2015-02-17 18:00:15 +01001182 0, "push",
Stefan Beller222368c2015-01-07 19:23:18 -08001183 &err)) {
Ronnie Sahlberg6629ea22014-04-28 14:36:15 -07001184 rp_error("%s", err.buf);
1185 strbuf_release(&err);
Stefan Beller222368c2015-01-07 19:23:18 -08001186
Ronnie Sahlberg6629ea22014-04-28 14:36:15 -07001187 return "failed to update ref";
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001188 }
Ronnie Sahlberg6629ea22014-04-28 14:36:15 -07001189 strbuf_release(&err);
Stefan Beller222368c2015-01-07 19:23:18 -08001190
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001191 return NULL; /* good */
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001192 }
Linus Torvalds2eca23d2005-06-30 10:15:22 -07001193}
1194
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001195static void run_update_post_hook(struct command *commands)
Junio C Hamano19614332005-08-02 14:24:22 -07001196{
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001197 struct command *cmd;
René Scharfed3180272014-08-19 21:09:35 +02001198 struct child_process proc = CHILD_PROCESS_INIT;
Nguyễn Thái Ngọc Duydcf69262014-11-30 15:24:27 +07001199 const char *hook;
Junio C Hamano19614332005-08-02 14:24:22 -07001200
Aaron Schrab5a7da2d2013-01-13 00:17:02 -05001201 hook = find_hook("post-update");
René Scharfedce96c42017-03-17 23:02:13 +01001202 if (!hook)
Shawn O. Pearce3e6e1522007-03-07 16:50:43 -05001203 return;
Aaron Schrab5a7da2d2013-01-13 00:17:02 -05001204
Jeff King850d2fe2016-02-22 17:44:21 -05001205 for (cmd = commands; cmd; cmd = cmd->next) {
Pang Yan Han160b81e2011-09-28 23:39:35 +08001206 if (cmd->error_string || cmd->did_not_exist)
Junio C Hamano19614332005-08-02 14:24:22 -07001207 continue;
Jeff Kingd70a9eb2020-07-28 20:37:20 -04001208 if (!proc.args.nr)
Jeff King22f9b7f2020-07-28 16:24:27 -04001209 strvec_push(&proc.args, hook);
1210 strvec_push(&proc.args, cmd->ref_name);
Junio C Hamano19614332005-08-02 14:24:22 -07001211 }
Jeff Kingd70a9eb2020-07-28 20:37:20 -04001212 if (!proc.args.nr)
René Scharfedce96c42017-03-17 23:02:13 +01001213 return;
Shawn O. Pearce6d525d32010-02-05 12:57:42 -08001214
Shawn O. Pearce6d525d32010-02-05 12:57:42 -08001215 proc.no_stdin = 1;
1216 proc.stdout_to_stderr = 1;
1217 proc.err = use_sideband ? -1 : 0;
Jeff Hostetler62062862019-02-22 14:25:06 -08001218 proc.trace2_hook_name = "post-update";
Shawn O. Pearce6d525d32010-02-05 12:57:42 -08001219
1220 if (!start_command(&proc)) {
1221 if (use_sideband)
1222 copy_to_sideband(proc.err, -1, NULL);
1223 finish_command(&proc);
1224 }
Junio C Hamano19614332005-08-02 14:24:22 -07001225}
Linus Torvalds2eca23d2005-06-30 10:15:22 -07001226
Ævar Arnfjörð Bjarmason99036232019-02-20 01:00:33 +01001227static void check_aliased_update_internal(struct command *cmd,
1228 struct string_list *list,
1229 const char *dst_name, int flag)
Jay Soffianda3efdb2010-04-19 18:19:18 -04001230{
1231 struct string_list_item *item;
1232 struct command *dst_cmd;
Jay Soffianda3efdb2010-04-19 18:19:18 -04001233
1234 if (!(flag & REF_ISSYMREF))
1235 return;
1236
Josh Triplett6b01ecf2011-07-08 16:13:32 -07001237 if (!dst_name) {
1238 rp_error("refusing update to broken symref '%s'", cmd->ref_name);
1239 cmd->skip_update = 1;
1240 cmd->error_string = "broken symref";
1241 return;
1242 }
Michael Haggertyded83932016-04-07 15:03:08 -04001243 dst_name = strip_namespace(dst_name);
Josh Triplett6b01ecf2011-07-08 16:13:32 -07001244
Julian Phillipse8c8b712010-06-26 00:41:37 +01001245 if ((item = string_list_lookup(list, dst_name)) == NULL)
Jay Soffianda3efdb2010-04-19 18:19:18 -04001246 return;
1247
1248 cmd->skip_update = 1;
1249
1250 dst_cmd = (struct command *) item->util;
1251
Jeff King4a7e27e2018-08-28 17:22:40 -04001252 if (oideq(&cmd->old_oid, &dst_cmd->old_oid) &&
1253 oideq(&cmd->new_oid, &dst_cmd->new_oid))
Jay Soffianda3efdb2010-04-19 18:19:18 -04001254 return;
1255
1256 dst_cmd->skip_update = 1;
1257
Jay Soffianda3efdb2010-04-19 18:19:18 -04001258 rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
1259 " its target '%s' (%s..%s)",
Jeff Kingef2ed502016-10-20 02:19:19 -04001260 cmd->ref_name,
brian m. carlsonaab95832018-03-12 02:27:30 +00001261 find_unique_abbrev(&cmd->old_oid, DEFAULT_ABBREV),
1262 find_unique_abbrev(&cmd->new_oid, DEFAULT_ABBREV),
Jeff Kingef2ed502016-10-20 02:19:19 -04001263 dst_cmd->ref_name,
brian m. carlsonaab95832018-03-12 02:27:30 +00001264 find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
1265 find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
Jay Soffianda3efdb2010-04-19 18:19:18 -04001266
1267 cmd->error_string = dst_cmd->error_string =
1268 "inconsistent aliased update";
1269}
1270
Ævar Arnfjörð Bjarmason99036232019-02-20 01:00:33 +01001271static void check_aliased_update(struct command *cmd, struct string_list *list)
1272{
1273 struct strbuf buf = STRBUF_INIT;
1274 const char *dst_name;
1275 int flag;
1276
1277 strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
1278 dst_name = resolve_ref_unsafe(buf.buf, 0, NULL, &flag);
1279 check_aliased_update_internal(cmd, list, dst_name, flag);
1280 strbuf_release(&buf);
1281}
1282
Jay Soffianda3efdb2010-04-19 18:19:18 -04001283static void check_aliased_updates(struct command *commands)
1284{
1285 struct command *cmd;
Thiago Farina183113a2010-07-04 16:46:19 -03001286 struct string_list ref_list = STRING_LIST_INIT_NODUP;
Jay Soffianda3efdb2010-04-19 18:19:18 -04001287
1288 for (cmd = commands; cmd; cmd = cmd->next) {
1289 struct string_list_item *item =
Julian Phillips1d2f80f2010-06-26 00:41:38 +01001290 string_list_append(&ref_list, cmd->ref_name);
Jay Soffianda3efdb2010-04-19 18:19:18 -04001291 item->util = (void *)cmd;
1292 }
Michael Haggerty3383e192014-11-25 09:02:35 +01001293 string_list_sort(&ref_list);
Jay Soffianda3efdb2010-04-19 18:19:18 -04001294
Clemens Buchacheref7e93d2012-02-13 21:17:12 +01001295 for (cmd = commands; cmd; cmd = cmd->next) {
1296 if (!cmd->error_string)
1297 check_aliased_update(cmd, &ref_list);
1298 }
Jay Soffianda3efdb2010-04-19 18:19:18 -04001299
1300 string_list_clear(&ref_list, 0);
1301}
1302
brian m. carlson6ccac9e2017-10-15 22:06:54 +00001303static int command_singleton_iterator(void *cb_data, struct object_id *oid)
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001304{
1305 struct command **cmd_list = cb_data;
1306 struct command *cmd = *cmd_list;
1307
brian m. carlson9c44ea42017-03-26 16:01:29 +00001308 if (!cmd || is_null_oid(&cmd->new_oid))
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001309 return -1; /* end of list */
1310 *cmd_list = NULL; /* this returns only one */
brian m. carlson6ccac9e2017-10-15 22:06:54 +00001311 oidcpy(oid, &cmd->new_oid);
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001312 return 0;
1313}
1314
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001315static void set_connectivity_errors(struct command *commands,
1316 struct shallow_info *si)
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001317{
1318 struct command *cmd;
1319
1320 for (cmd = commands; cmd; cmd = cmd->next) {
1321 struct command *singleton = cmd;
Jeff King722ff7f2016-10-03 16:49:14 -04001322 struct check_connected_options opt = CHECK_CONNECTED_INIT;
1323
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001324 if (shallow_update && si->shallow_ref[cmd->index])
1325 /* to be checked in update_shallow_ref() */
1326 continue;
Jeff King722ff7f2016-10-03 16:49:14 -04001327
1328 opt.env = tmp_objdir_env(tmp_objdir);
Jeff King7043c702016-07-15 06:30:40 -04001329 if (!check_connected(command_singleton_iterator, &singleton,
Jeff King722ff7f2016-10-03 16:49:14 -04001330 &opt))
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001331 continue;
Jeff King722ff7f2016-10-03 16:49:14 -04001332
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001333 cmd->error_string = "missing necessary objects";
1334 }
1335}
1336
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001337struct iterate_data {
1338 struct command *cmds;
1339 struct shallow_info *si;
1340};
1341
brian m. carlson6ccac9e2017-10-15 22:06:54 +00001342static int iterate_receive_command_list(void *cb_data, struct object_id *oid)
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001343{
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001344 struct iterate_data *data = cb_data;
1345 struct command **cmd_list = &data->cmds;
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001346 struct command *cmd = *cmd_list;
1347
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001348 for (; cmd; cmd = cmd->next) {
1349 if (shallow_update && data->si->shallow_ref[cmd->index])
1350 /* to be checked in update_shallow_ref() */
1351 continue;
brian m. carlson9c44ea42017-03-26 16:01:29 +00001352 if (!is_null_oid(&cmd->new_oid) && !cmd->skip_update) {
brian m. carlson6ccac9e2017-10-15 22:06:54 +00001353 oidcpy(oid, &cmd->new_oid);
Junio C Hamanoee6dfb22011-11-03 12:15:08 -07001354 *cmd_list = cmd->next;
1355 return 0;
1356 }
Junio C Hamanoee6dfb22011-11-03 12:15:08 -07001357 }
1358 *cmd_list = NULL;
1359 return -1; /* end of list */
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001360}
1361
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001362static void reject_updates_to_hidden(struct command *commands)
1363{
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001364 struct strbuf refname_full = STRBUF_INIT;
1365 size_t prefix_len;
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001366 struct command *cmd;
1367
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001368 strbuf_addstr(&refname_full, get_git_namespace());
1369 prefix_len = refname_full.len;
1370
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001371 for (cmd = commands; cmd; cmd = cmd->next) {
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001372 if (cmd->error_string)
1373 continue;
1374
1375 strbuf_setlen(&refname_full, prefix_len);
1376 strbuf_addstr(&refname_full, cmd->ref_name);
1377
1378 if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001379 continue;
brian m. carlson9c44ea42017-03-26 16:01:29 +00001380 if (is_null_oid(&cmd->new_oid))
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001381 cmd->error_string = "deny deleting a hidden ref";
1382 else
1383 cmd->error_string = "deny updating a hidden ref";
1384 }
Lukas Fleischer78a766a2015-11-03 08:58:16 +01001385
1386 strbuf_release(&refname_full);
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001387}
1388
Stefan Bellera6a84312015-01-07 19:23:15 -08001389static int should_process_cmd(struct command *cmd)
1390{
1391 return !cmd->error_string && !cmd->skip_update;
1392}
1393
1394static void warn_if_skipped_connectivity_check(struct command *commands,
1395 struct shallow_info *si)
1396{
1397 struct command *cmd;
1398 int checked_connectivity = 1;
1399
1400 for (cmd = commands; cmd; cmd = cmd->next) {
1401 if (should_process_cmd(cmd) && si->shallow_ref[cmd->index]) {
1402 error("BUG: connectivity check has not been run on ref %s",
1403 cmd->ref_name);
1404 checked_connectivity = 0;
1405 }
1406 }
1407 if (!checked_connectivity)
Johannes Schindelin033abf92018-05-02 11:38:39 +02001408 BUG("connectivity check skipped???");
Stefan Bellera6a84312015-01-07 19:23:15 -08001409}
1410
Stefan Bellera1a26142015-01-07 19:23:17 -08001411static void execute_commands_non_atomic(struct command *commands,
1412 struct shallow_info *si)
1413{
1414 struct command *cmd;
Stefan Beller222368c2015-01-07 19:23:18 -08001415 struct strbuf err = STRBUF_INIT;
1416
Stefan Bellera1a26142015-01-07 19:23:17 -08001417 for (cmd = commands; cmd; cmd = cmd->next) {
1418 if (!should_process_cmd(cmd))
1419 continue;
1420
Stefan Beller222368c2015-01-07 19:23:18 -08001421 transaction = ref_transaction_begin(&err);
1422 if (!transaction) {
1423 rp_error("%s", err.buf);
1424 strbuf_reset(&err);
1425 cmd->error_string = "transaction failed to start";
1426 continue;
1427 }
1428
Stefan Bellera1a26142015-01-07 19:23:17 -08001429 cmd->error_string = update(cmd, si);
Stefan Beller222368c2015-01-07 19:23:18 -08001430
1431 if (!cmd->error_string
1432 && ref_transaction_commit(transaction, &err)) {
1433 rp_error("%s", err.buf);
1434 strbuf_reset(&err);
1435 cmd->error_string = "failed to update ref";
1436 }
1437 ref_transaction_free(transaction);
Stefan Bellera1a26142015-01-07 19:23:17 -08001438 }
Stefan Beller68deed22015-01-07 19:23:19 -08001439 strbuf_release(&err);
1440}
Stefan Beller222368c2015-01-07 19:23:18 -08001441
Stefan Beller68deed22015-01-07 19:23:19 -08001442static void execute_commands_atomic(struct command *commands,
1443 struct shallow_info *si)
1444{
1445 struct command *cmd;
1446 struct strbuf err = STRBUF_INIT;
1447 const char *reported_error = "atomic push failure";
1448
1449 transaction = ref_transaction_begin(&err);
1450 if (!transaction) {
1451 rp_error("%s", err.buf);
1452 strbuf_reset(&err);
1453 reported_error = "transaction failed to start";
1454 goto failure;
1455 }
1456
1457 for (cmd = commands; cmd; cmd = cmd->next) {
1458 if (!should_process_cmd(cmd))
1459 continue;
1460
1461 cmd->error_string = update(cmd, si);
1462
1463 if (cmd->error_string)
1464 goto failure;
1465 }
1466
1467 if (ref_transaction_commit(transaction, &err)) {
1468 rp_error("%s", err.buf);
1469 reported_error = "atomic transaction failed";
1470 goto failure;
1471 }
1472 goto cleanup;
1473
1474failure:
1475 for (cmd = commands; cmd; cmd = cmd->next)
1476 if (!cmd->error_string)
1477 cmd->error_string = reported_error;
1478
1479cleanup:
1480 ref_transaction_free(transaction);
Stefan Beller222368c2015-01-07 19:23:18 -08001481 strbuf_release(&err);
Stefan Bellera1a26142015-01-07 19:23:17 -08001482}
1483
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001484static void execute_commands(struct command *commands,
1485 const char *unpacker_error,
Stefan Beller77a97452016-07-14 14:49:45 -07001486 struct shallow_info *si,
1487 const struct string_list *push_options)
Linus Torvalds575f4972005-06-29 17:52:11 -07001488{
Jeff Kingd4150922016-07-15 06:36:14 -04001489 struct check_connected_options opt = CHECK_CONNECTED_INIT;
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001490 struct command *cmd;
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001491 struct iterate_data data;
Jeff Kingd4150922016-07-15 06:36:14 -04001492 struct async muxer;
1493 int err_fd = 0;
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001494
1495 if (unpacker_error) {
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001496 for (cmd = commands; cmd; cmd = cmd->next)
Jeff King74eb32d2012-09-21 01:38:46 -04001497 cmd->error_string = "unpacker error";
Shawn O. Pearce8aaf7d62007-03-07 16:51:59 -05001498 return;
1499 }
1500
Jeff Kingd4150922016-07-15 06:36:14 -04001501 if (use_sideband) {
1502 memset(&muxer, 0, sizeof(muxer));
1503 muxer.proc = copy_to_sideband;
1504 muxer.in = -1;
1505 if (!start_async(&muxer))
1506 err_fd = muxer.in;
1507 /* ...else, continue without relaying sideband */
1508 }
1509
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001510 data.cmds = commands;
1511 data.si = si;
Jeff Kingd4150922016-07-15 06:36:14 -04001512 opt.err_fd = err_fd;
Jeff King6b4cd2f2016-07-15 06:36:35 -04001513 opt.progress = err_fd && !quiet;
Jeff King722ff7f2016-10-03 16:49:14 -04001514 opt.env = tmp_objdir_env(tmp_objdir);
Jeff Kingd4150922016-07-15 06:36:14 -04001515 if (check_connected(iterate_receive_command_list, &data, &opt))
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001516 set_connectivity_errors(commands, si);
Junio C Hamano52fed6e2011-09-02 16:52:08 -07001517
Jeff Kingd4150922016-07-15 06:36:14 -04001518 if (use_sideband)
1519 finish_async(&muxer);
1520
Junio C Hamanodaebaa72013-01-18 16:08:30 -08001521 reject_updates_to_hidden(commands);
1522
Stefan Beller77a97452016-07-14 14:49:45 -07001523 if (run_receive_hook(commands, "pre-receive", 0, push_options)) {
Clemens Buchacheref7e93d2012-02-13 21:17:12 +01001524 for (cmd = commands; cmd; cmd = cmd->next) {
1525 if (!cmd->error_string)
1526 cmd->error_string = "pre-receive hook declined";
1527 }
Shawn O. Pearce05ef58e2007-03-07 16:52:05 -05001528 return;
1529 }
1530
Jeff King722ff7f2016-10-03 16:49:14 -04001531 /*
1532 * Now we'll start writing out refs, which means the objects need
1533 * to be in their final positions so that other processes can see them.
1534 */
1535 if (tmp_objdir_migrate(tmp_objdir) < 0) {
1536 for (cmd = commands; cmd; cmd = cmd->next) {
1537 if (!cmd->error_string)
1538 cmd->error_string = "unable to migrate objects to permanent storage";
1539 }
1540 return;
1541 }
1542 tmp_objdir = NULL;
1543
Jay Soffianda3efdb2010-04-19 18:19:18 -04001544 check_aliased_updates(commands);
1545
Nguyễn Thái Ngọc Duy96ec7b12011-12-13 21:17:48 +07001546 free(head_name_to_free);
René Scharfeefbd4fd2017-10-01 09:29:03 +02001547 head_name = head_name_to_free = resolve_refdup("HEAD", 0, NULL, NULL);
Junio C Hamano747ca242009-02-08 22:31:21 -08001548
Stefan Beller68deed22015-01-07 19:23:19 -08001549 if (use_atomic)
1550 execute_commands_atomic(commands, si);
1551 else
1552 execute_commands_non_atomic(commands, si);
Clemens Buchacheref7e93d2012-02-13 21:17:12 +01001553
Stefan Bellera6a84312015-01-07 19:23:15 -08001554 if (shallow_update)
1555 warn_if_skipped_connectivity_check(commands, si);
Linus Torvalds575f4972005-06-29 17:52:11 -07001556}
1557
Junio C Hamano39895c72014-08-15 14:28:28 -07001558static struct command **queue_command(struct command **tail,
1559 const char *line,
1560 int linelen)
1561{
brian m. carlson9c44ea42017-03-26 16:01:29 +00001562 struct object_id old_oid, new_oid;
Junio C Hamano39895c72014-08-15 14:28:28 -07001563 struct command *cmd;
1564 const char *refname;
1565 int reflen;
brian m. carlson9c44ea42017-03-26 16:01:29 +00001566 const char *p;
Junio C Hamano39895c72014-08-15 14:28:28 -07001567
brian m. carlson9c44ea42017-03-26 16:01:29 +00001568 if (parse_oid_hex(line, &old_oid, &p) ||
1569 *p++ != ' ' ||
1570 parse_oid_hex(p, &new_oid, &p) ||
1571 *p++ != ' ')
Junio C Hamano39895c72014-08-15 14:28:28 -07001572 die("protocol error: expected old/new/ref, got '%s'", line);
1573
brian m. carlson9c44ea42017-03-26 16:01:29 +00001574 refname = p;
1575 reflen = linelen - (p - line);
René Scharfeddd0bfa2016-08-13 17:38:56 +02001576 FLEX_ALLOC_MEM(cmd, ref_name, refname, reflen);
brian m. carlson9c44ea42017-03-26 16:01:29 +00001577 oidcpy(&cmd->old_oid, &old_oid);
1578 oidcpy(&cmd->new_oid, &new_oid);
Junio C Hamano39895c72014-08-15 14:28:28 -07001579 *tail = cmd;
1580 return &cmd->next;
1581}
1582
Junio C Hamano4adf5692014-08-18 14:38:45 -07001583static void queue_commands_from_cert(struct command **tail,
1584 struct strbuf *push_cert)
1585{
1586 const char *boc, *eoc;
1587
1588 if (*tail)
1589 die("protocol error: got both push certificate and unsigned commands");
1590
1591 boc = strstr(push_cert->buf, "\n\n");
1592 if (!boc)
1593 die("malformed push certificate %.*s", 100, push_cert->buf);
1594 else
1595 boc += 2;
1596 eoc = push_cert->buf + parse_signature(push_cert->buf, push_cert->len);
1597
1598 while (boc < eoc) {
1599 const char *eol = memchr(boc, '\n', eoc - boc);
brian m. carlsonf2214de2017-03-26 16:01:28 +00001600 tail = queue_command(tail, boc, eol ? eol - boc : eoc - boc);
Junio C Hamano4adf5692014-08-18 14:38:45 -07001601 boc = eol ? eol + 1 : eoc;
1602 }
1603}
1604
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001605static struct command *read_head_info(struct packet_reader *reader,
1606 struct oid_array *shallow)
Linus Torvalds575f4972005-06-29 17:52:11 -07001607{
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001608 struct command *commands = NULL;
Linus Torvaldseb1af2d2005-06-29 23:01:14 -07001609 struct command **p = &commands;
Linus Torvalds575f4972005-06-29 17:52:11 -07001610 for (;;) {
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001611 int linelen;
Linus Torvaldseb1af2d2005-06-29 23:01:14 -07001612
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001613 if (packet_reader_read(reader) != PACKET_READ_NORMAL)
Linus Torvalds575f4972005-06-29 17:52:11 -07001614 break;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001615
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001616 if (reader->pktlen > 8 && starts_with(reader->line, "shallow ")) {
brian m. carlson9c44ea42017-03-26 16:01:29 +00001617 struct object_id oid;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001618 if (get_oid_hex(reader->line + 8, &oid))
Junio C Hamanoc09b71c2014-08-15 14:26:17 -07001619 die("protocol error: expected shallow sha, got '%s'",
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001620 reader->line + 8);
brian m. carlson910650d2017-03-31 01:40:00 +00001621 oid_array_append(shallow, &oid);
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001622 continue;
1623 }
1624
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001625 linelen = strlen(reader->line);
1626 if (linelen < reader->pktlen) {
1627 const char *feature_list = reader->line + linelen + 1;
brian m. carlsonbb095d02020-05-25 19:59:01 +00001628 const char *hash = NULL;
1629 int len = 0;
Junio C Hamanof47182c2012-01-08 22:06:19 +01001630 if (parse_feature_request(feature_list, "report-status"))
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001631 report_status = 1;
Junio C Hamanof47182c2012-01-08 22:06:19 +01001632 if (parse_feature_request(feature_list, "side-band-64k"))
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001633 use_sideband = LARGE_PACKET_MAX;
Clemens Buchacherc207e342012-01-08 22:06:20 +01001634 if (parse_feature_request(feature_list, "quiet"))
1635 quiet = 1;
Ronnie Sahlberg1b70fe52015-01-07 19:23:20 -08001636 if (advertise_atomic_push
1637 && parse_feature_request(feature_list, "atomic"))
1638 use_atomic = 1;
Stefan Bellerc714e452016-07-14 14:49:46 -07001639 if (advertise_push_options
1640 && parse_feature_request(feature_list, "push-options"))
1641 use_push_options = 1;
brian m. carlsonbb095d02020-05-25 19:59:01 +00001642 hash = parse_feature_value(feature_list, "object-format", &len, NULL);
1643 if (!hash) {
1644 hash = hash_algos[GIT_HASH_SHA1].name;
1645 len = strlen(hash);
1646 }
1647 if (xstrncmpz(the_hash_algo->name, hash, len))
1648 die("error: unsupported object format '%s'", hash);
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001649 }
Junio C Hamano0e3c3392014-08-15 14:11:33 -07001650
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001651 if (!strcmp(reader->line, "push-cert")) {
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001652 int true_flush = 0;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001653 int saved_options = reader->options;
1654 reader->options &= ~PACKET_READ_CHOMP_NEWLINE;
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001655
1656 for (;;) {
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001657 packet_reader_read(reader);
1658 if (reader->status == PACKET_READ_FLUSH) {
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001659 true_flush = 1;
1660 break;
1661 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001662 if (reader->status != PACKET_READ_NORMAL) {
1663 die("protocol error: got an unexpected packet");
1664 }
1665 if (!strcmp(reader->line, "push-cert-end\n"))
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001666 break; /* end of cert */
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001667 strbuf_addstr(&push_cert, reader->line);
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001668 }
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001669 reader->options = saved_options;
Junio C Hamanoa85b3772014-09-12 11:17:07 -07001670
1671 if (true_flush)
1672 break;
1673 continue;
1674 }
1675
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001676 p = queue_command(p, reader->line, linelen);
Linus Torvalds575f4972005-06-29 17:52:11 -07001677 }
Junio C Hamano4adf5692014-08-18 14:38:45 -07001678
1679 if (push_cert.len)
1680 queue_commands_from_cert(p, &push_cert);
1681
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001682 return commands;
Linus Torvalds575f4972005-06-29 17:52:11 -07001683}
1684
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001685static void read_push_options(struct packet_reader *reader,
1686 struct string_list *options)
Stefan Bellerc714e452016-07-14 14:49:46 -07001687{
1688 while (1) {
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001689 if (packet_reader_read(reader) != PACKET_READ_NORMAL)
Stefan Bellerc714e452016-07-14 14:49:46 -07001690 break;
1691
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001692 string_list_append(options, reader->line);
Stefan Bellerc714e452016-07-14 14:49:46 -07001693 }
1694}
1695
Shawn Pearcefc04c412006-11-01 17:06:21 -05001696static const char *parse_pack_header(struct pack_header *hdr)
1697{
Junio C Hamanoa69e5422007-01-22 21:55:18 -08001698 switch (read_pack_header(0, hdr)) {
1699 case PH_ERROR_EOF:
1700 return "eof before pack header was fully read";
1701
1702 case PH_ERROR_PACK_SIGNATURE:
Shawn Pearcefc04c412006-11-01 17:06:21 -05001703 return "protocol error (pack signature mismatch detected)";
Junio C Hamanoa69e5422007-01-22 21:55:18 -08001704
1705 case PH_ERROR_PROTOCOL:
Shawn Pearcefc04c412006-11-01 17:06:21 -05001706 return "protocol error (pack version unsupported)";
Junio C Hamanoa69e5422007-01-22 21:55:18 -08001707
1708 default:
1709 return "unknown error in parse_pack_header";
1710
1711 case 0:
1712 return NULL;
1713 }
Shawn Pearcefc04c412006-11-01 17:06:21 -05001714}
1715
Nicolas Pitre576162a2006-11-01 17:06:25 -05001716static const char *pack_lockfile;
1717
Jeff King22f9b7f2020-07-28 16:24:27 -04001718static void push_header_arg(struct strvec *args, struct pack_header *hdr)
Jeff King446d5d92017-03-28 15:46:47 -04001719{
Jeff King22f9b7f2020-07-28 16:24:27 -04001720 strvec_pushf(args, "--pack_header=%"PRIu32",%"PRIu32,
Jeff Kingf6d89422020-07-28 16:26:31 -04001721 ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries));
Jeff King446d5d92017-03-28 15:46:47 -04001722}
1723
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001724static const char *unpack(int err_fd, struct shallow_info *si)
Linus Torvalds575f4972005-06-29 17:52:11 -07001725{
Shawn Pearcefc04c412006-11-01 17:06:21 -05001726 struct pack_header hdr;
1727 const char *hdr_err;
Nguyễn Thái Ngọc Duy31c42bf2013-12-05 20:02:43 +07001728 int status;
René Scharfed3180272014-08-19 21:09:35 +02001729 struct child_process child = CHILD_PROCESS_INIT;
Junio C Hamanodab76d32011-09-04 12:37:45 -07001730 int fsck_objects = (receive_fsck_objects >= 0
1731 ? receive_fsck_objects
1732 : transfer_fsck_objects >= 0
1733 ? transfer_fsck_objects
1734 : 0);
Shawn Pearcefc04c412006-11-01 17:06:21 -05001735
1736 hdr_err = parse_pack_header(&hdr);
Jeff King49ecfa12013-04-19 17:24:29 -04001737 if (hdr_err) {
1738 if (err_fd > 0)
1739 close(err_fd);
Shawn Pearcefc04c412006-11-01 17:06:21 -05001740 return hdr_err;
Jeff King49ecfa12013-04-19 17:24:29 -04001741 }
Shawn Pearcefc04c412006-11-01 17:06:21 -05001742
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001743 if (si->nr_ours || si->nr_theirs) {
1744 alt_shallow_file = setup_temporary_shallow(si->shallow);
Jeff King22f9b7f2020-07-28 16:24:27 -04001745 strvec_push(&child.args, "--shallow-file");
1746 strvec_push(&child.args, alt_shallow_file);
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001747 }
1748
Jeff King722ff7f2016-10-03 16:49:14 -04001749 tmp_objdir = tmp_objdir_create();
Jeff King6cdad1f2017-03-07 08:35:34 -05001750 if (!tmp_objdir) {
1751 if (err_fd > 0)
1752 close(err_fd);
Jeff King722ff7f2016-10-03 16:49:14 -04001753 return "unable to create temporary object directory";
Jeff King6cdad1f2017-03-07 08:35:34 -05001754 }
Jeff King722ff7f2016-10-03 16:49:14 -04001755 child.env = tmp_objdir_env(tmp_objdir);
1756
1757 /*
1758 * Normally we just pass the tmp_objdir environment to the child
1759 * processes that do the heavy lifting, but we may need to see these
1760 * objects ourselves to set up shallow information.
1761 */
1762 tmp_objdir_add_as_alternate(tmp_objdir);
1763
Shawn Pearcefc04c412006-11-01 17:06:21 -05001764 if (ntohl(hdr.hdr_entries) < unpack_limit) {
Jeff King22f9b7f2020-07-28 16:24:27 -04001765 strvec_push(&child.args, "unpack-objects");
Jeff King446d5d92017-03-28 15:46:47 -04001766 push_header_arg(&child.args, &hdr);
Clemens Buchacherc207e342012-01-08 22:06:20 +01001767 if (quiet)
Jeff King22f9b7f2020-07-28 16:24:27 -04001768 strvec_push(&child.args, "-q");
Junio C Hamanodab76d32011-09-04 12:37:45 -07001769 if (fsck_objects)
Jeff King22f9b7f2020-07-28 16:24:27 -04001770 strvec_pushf(&child.args, "--strict%s",
Jeff Kingf6d89422020-07-28 16:26:31 -04001771 fsck_msg_types.buf);
Jeff Kingc08db5a2016-08-24 20:41:57 +02001772 if (max_input_size)
Jeff King22f9b7f2020-07-28 16:24:27 -04001773 strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
Jeff Kingf6d89422020-07-28 16:26:31 -04001774 (uintmax_t)max_input_size);
Jeff King59bfdfb2012-09-21 01:32:52 -04001775 child.no_stdout = 1;
Jeff Kinga22e6f82012-09-21 01:34:55 -04001776 child.err = err_fd;
Jeff King59bfdfb2012-09-21 01:32:52 -04001777 child.git_cmd = 1;
Nguyễn Thái Ngọc Duy31c42bf2013-12-05 20:02:43 +07001778 status = run_command(&child);
1779 if (status)
1780 return "unpack-objects abnormal exit";
Nicolas Pitre576162a2006-11-01 17:06:25 -05001781 } else {
René Scharfeda25bdb2017-04-18 17:57:42 -04001782 char hostname[HOST_NAME_MAX + 1];
Nicolas Pitre576162a2006-11-01 17:06:25 -05001783
Jeff King22f9b7f2020-07-28 16:24:27 -04001784 strvec_pushl(&child.args, "index-pack", "--stdin", NULL);
Jeff King446d5d92017-03-28 15:46:47 -04001785 push_header_arg(&child.args, &hdr);
Jeff Kingb26cb7c2015-09-24 17:08:14 -04001786
David Turner5781a9a2017-04-18 17:57:43 -04001787 if (xgethostname(hostname, sizeof(hostname)))
Jeff Kingb26cb7c2015-09-24 17:08:14 -04001788 xsnprintf(hostname, sizeof(hostname), "localhost");
Jeff King22f9b7f2020-07-28 16:24:27 -04001789 strvec_pushf(&child.args,
Jeff Kingf6d89422020-07-28 16:26:31 -04001790 "--keep=receive-pack %"PRIuMAX" on %s",
1791 (uintmax_t)getpid(),
1792 hostname);
Jeff Kingb26cb7c2015-09-24 17:08:14 -04001793
Jeff Kingd06303b2016-07-15 06:35:28 -04001794 if (!quiet && err_fd)
Jeff King22f9b7f2020-07-28 16:24:27 -04001795 strvec_push(&child.args, "--show-resolving-progress");
Jeff King83558682016-07-15 06:43:47 -04001796 if (use_sideband)
Jeff King22f9b7f2020-07-28 16:24:27 -04001797 strvec_push(&child.args, "--report-end-of-input");
Junio C Hamanodab76d32011-09-04 12:37:45 -07001798 if (fsck_objects)
Jeff King22f9b7f2020-07-28 16:24:27 -04001799 strvec_pushf(&child.args, "--strict%s",
Jeff Kingf6d89422020-07-28 16:26:31 -04001800 fsck_msg_types.buf);
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +05301801 if (!reject_thin)
Jeff King22f9b7f2020-07-28 16:24:27 -04001802 strvec_push(&child.args, "--fix-thin");
Jeff Kingc08db5a2016-08-24 20:41:57 +02001803 if (max_input_size)
Jeff King22f9b7f2020-07-28 16:24:27 -04001804 strvec_pushf(&child.args, "--max-input-size=%"PRIuMAX,
Jeff Kingf6d89422020-07-28 16:26:31 -04001805 (uintmax_t)max_input_size);
Nguyễn Thái Ngọc Duy31c42bf2013-12-05 20:02:43 +07001806 child.out = -1;
1807 child.err = err_fd;
1808 child.git_cmd = 1;
1809 status = start_command(&child);
1810 if (status)
Nicolas Pitre576162a2006-11-01 17:06:25 -05001811 return "index-pack fork failed";
Nguyễn Thái Ngọc Duy31c42bf2013-12-05 20:02:43 +07001812 pack_lockfile = index_pack_lockfile(child.out);
1813 close(child.out);
1814 status = finish_command(&child);
1815 if (status)
1816 return "index-pack abnormal exit";
Stefan Bellera49d2832018-03-23 18:45:21 +01001817 reprepare_packed_git(the_repository);
Linus Torvalds575f4972005-06-29 17:52:11 -07001818 }
Nguyễn Thái Ngọc Duy31c42bf2013-12-05 20:02:43 +07001819 return NULL;
Linus Torvalds575f4972005-06-29 17:52:11 -07001820}
1821
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001822static const char *unpack_with_sideband(struct shallow_info *si)
Jeff Kinga22e6f82012-09-21 01:34:55 -04001823{
1824 struct async muxer;
1825 const char *ret;
1826
1827 if (!use_sideband)
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001828 return unpack(0, si);
Jeff Kinga22e6f82012-09-21 01:34:55 -04001829
Jeff King83558682016-07-15 06:43:47 -04001830 use_keepalive = KEEPALIVE_AFTER_NUL;
Jeff Kinga22e6f82012-09-21 01:34:55 -04001831 memset(&muxer, 0, sizeof(muxer));
1832 muxer.proc = copy_to_sideband;
1833 muxer.in = -1;
1834 if (start_async(&muxer))
1835 return NULL;
1836
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001837 ret = unpack(muxer.in, si);
Jeff Kinga22e6f82012-09-21 01:34:55 -04001838
1839 finish_async(&muxer);
1840 return ret;
1841}
1842
Jeff Kingc95fc722019-05-09 17:31:39 -04001843static void prepare_shallow_update(struct shallow_info *si)
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001844{
René Scharfe42c78a22017-07-08 12:35:35 +02001845 int i, j, k, bitmap_size = DIV_ROUND_UP(si->ref->nr, 32);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001846
Jeff Kingb32fa952016-02-22 17:44:25 -05001847 ALLOC_ARRAY(si->used_shallow, si->shallow->nr);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001848 assign_shallow_commits_to_refs(si, si->used_shallow, NULL);
1849
1850 si->need_reachability_test =
1851 xcalloc(si->shallow->nr, sizeof(*si->need_reachability_test));
1852 si->reachable =
1853 xcalloc(si->shallow->nr, sizeof(*si->reachable));
1854 si->shallow_ref = xcalloc(si->ref->nr, sizeof(*si->shallow_ref));
1855
1856 for (i = 0; i < si->nr_ours; i++)
1857 si->need_reachability_test[si->ours[i]] = 1;
1858
1859 for (i = 0; i < si->shallow->nr; i++) {
1860 if (!si->used_shallow[i])
1861 continue;
1862 for (j = 0; j < bitmap_size; j++) {
1863 if (!si->used_shallow[i][j])
1864 continue;
1865 si->need_reachability_test[i]++;
1866 for (k = 0; k < 32; k++)
Jeff King9a93c662015-12-29 01:35:46 -05001867 if (si->used_shallow[i][j] & (1U << k))
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001868 si->shallow_ref[j * 32 + k]++;
1869 }
1870
1871 /*
1872 * true for those associated with some refs and belong
1873 * in "ours" list aka "step 7 not done yet"
1874 */
1875 si->need_reachability_test[i] =
1876 si->need_reachability_test[i] > 1;
1877 }
1878
1879 /*
1880 * keep hooks happy by forcing a temporary shallow file via
1881 * env variable because we can't add --shallow-file to every
Jeff King7987d222018-09-21 19:04:45 -04001882 * command. check_connected() will be done with
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001883 * true .git/shallow though.
1884 */
1885 setenv(GIT_SHALLOW_FILE_ENVIRONMENT, alt_shallow_file, 1);
1886}
1887
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001888static void update_shallow_info(struct command *commands,
1889 struct shallow_info *si,
brian m. carlson910650d2017-03-31 01:40:00 +00001890 struct oid_array *ref)
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001891{
1892 struct command *cmd;
1893 int *ref_status;
1894 remove_nonexistent_theirs_shallow(si);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001895 if (!si->nr_ours && !si->nr_theirs) {
1896 shallow_update = 0;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001897 return;
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001898 }
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001899
1900 for (cmd = commands; cmd; cmd = cmd->next) {
brian m. carlson9c44ea42017-03-26 16:01:29 +00001901 if (is_null_oid(&cmd->new_oid))
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001902 continue;
brian m. carlson910650d2017-03-31 01:40:00 +00001903 oid_array_append(ref, &cmd->new_oid);
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001904 cmd->index = ref->nr - 1;
1905 }
1906 si->ref = ref;
1907
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001908 if (shallow_update) {
Jeff Kingc95fc722019-05-09 17:31:39 -04001909 prepare_shallow_update(si);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07001910 return;
1911 }
1912
Jeff Kingb32fa952016-02-22 17:44:25 -05001913 ALLOC_ARRAY(ref_status, ref->nr);
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001914 assign_shallow_commits_to_refs(si, NULL, ref_status);
1915 for (cmd = commands; cmd; cmd = cmd->next) {
brian m. carlson9c44ea42017-03-26 16:01:29 +00001916 if (is_null_oid(&cmd->new_oid))
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001917 continue;
1918 if (ref_status[cmd->index]) {
1919 cmd->error_string = "shallow update not allowed";
1920 cmd->skip_update = 1;
1921 }
1922 }
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001923 free(ref_status);
1924}
1925
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001926static void report(struct command *commands, const char *unpack_status)
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001927{
1928 struct command *cmd;
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001929 struct strbuf buf = STRBUF_INIT;
1930
1931 packet_buf_write(&buf, "unpack %s\n",
1932 unpack_status ? unpack_status : "ok");
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001933 for (cmd = commands; cmd; cmd = cmd->next) {
1934 if (!cmd->error_string)
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001935 packet_buf_write(&buf, "ok %s\n",
1936 cmd->ref_name);
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001937 else
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001938 packet_buf_write(&buf, "ng %s %s\n",
1939 cmd->ref_name, cmd->error_string);
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001940 }
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001941 packet_buf_flush(&buf);
1942
1943 if (use_sideband)
1944 send_sideband(1, 1, buf.buf, buf.len, use_sideband);
1945 else
Jeff Kingcdf4fb82013-02-20 15:01:56 -05001946 write_or_die(1, buf.buf, buf.len);
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08001947 strbuf_release(&buf);
Junio C Hamanocfee10a2005-12-25 23:18:37 -08001948}
1949
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001950static int delete_only(struct command *commands)
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001951{
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001952 struct command *cmd;
1953 for (cmd = commands; cmd; cmd = cmd->next) {
brian m. carlson9c44ea42017-03-26 16:01:29 +00001954 if (!is_null_oid(&cmd->new_oid))
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001955 return 0;
Junio C Hamanod4f694b2006-11-24 00:26:49 -08001956 }
1957 return 1;
1958}
1959
Junio C Hamanobe5908a2008-09-09 01:27:08 -07001960int cmd_receive_pack(int argc, const char **argv, const char *prefix)
Linus Torvalds575f4972005-06-29 17:52:11 -07001961{
Shawn O. Pearce42526b42009-10-30 17:47:33 -07001962 int advertise_refs = 0;
Jay Soffian5e1c71f2010-04-19 18:08:30 -04001963 struct command *commands;
brian m. carlson910650d2017-03-31 01:40:00 +00001964 struct oid_array shallow = OID_ARRAY_INIT;
1965 struct oid_array ref = OID_ARRAY_INIT;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07001966 struct shallow_info si;
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08001967 struct packet_reader reader;
Linus Torvalds575f4972005-06-29 17:52:11 -07001968
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +05301969 struct option options[] = {
1970 OPT__QUIET(&quiet, N_("quiet")),
1971 OPT_HIDDEN_BOOL(0, "stateless-rpc", &stateless_rpc, NULL),
1972 OPT_HIDDEN_BOOL(0, "advertise-refs", &advertise_refs, NULL),
1973 OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
1974 OPT_END()
1975 };
1976
Jeff Kingbbc30f92011-02-24 09:30:19 -05001977 packet_trace_identity("receive-pack");
1978
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +05301979 argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
Linus Torvalds575f4972005-06-29 17:52:11 -07001980
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +05301981 if (argc > 1)
1982 usage_msg_opt(_("Too many arguments."), receive_pack_usage, options);
1983 if (argc == 0)
1984 usage_msg_opt(_("You must specify a directory."), receive_pack_usage, options);
Clemens Buchacherc207e342012-01-08 22:06:20 +01001985
Sidhant Sharma [:tk]1b683872016-03-02 01:51:01 +05301986 service_dir = argv[0];
Linus Torvalds575f4972005-06-29 17:52:11 -07001987
Johannes Sixte1464ca2008-07-21 21:19:52 +02001988 setup_path();
Björn Steinbrink5c09f322008-03-03 05:08:43 +01001989
Junio C Hamano57323732014-09-05 10:46:04 -07001990 if (!enter_repo(service_dir, 0))
1991 die("'%s' does not appear to be a git repository", service_dir);
Linus Torvalds575f4972005-06-29 17:52:11 -07001992
Johannes Schindelinef90d6d2008-05-14 18:46:53 +01001993 git_config(receive_pack_config, NULL);
Junio C Hamanob89363e2014-08-21 16:45:30 -07001994 if (cert_nonce_seed)
Junio C Hamano57323732014-09-05 10:46:04 -07001995 push_cert_nonce = prepare_push_cert_nonce(service_dir, time(NULL));
Shawn Pearce6fb75be2006-10-30 17:35:18 -05001996
Junio C Hamanoe28714c2007-01-24 17:02:15 -08001997 if (0 <= transfer_unpack_limit)
1998 unpack_limit = transfer_unpack_limit;
1999 else if (0 <= receive_unpack_limit)
2000 unpack_limit = receive_unpack_limit;
2001
Brandon Williamsaa9bab22017-10-16 10:55:26 -07002002 switch (determine_protocol_version_server()) {
Brandon Williams8f6982b2018-03-14 11:31:47 -07002003 case protocol_v2:
2004 /*
2005 * push support for protocol v2 has not been implemented yet,
2006 * so ignore the request to use v2 and fallback to using v0.
2007 */
2008 break;
Brandon Williamsaa9bab22017-10-16 10:55:26 -07002009 case protocol_v1:
2010 /*
2011 * v1 is just the original protocol with a version string,
2012 * so just fall through after writing the version string.
2013 */
2014 if (advertise_refs || !stateless_rpc)
2015 packet_write_fmt(1, "version 1\n");
2016
2017 /* fallthrough */
2018 case protocol_v0:
2019 break;
2020 case protocol_unknown_version:
2021 BUG("unknown protocol version");
2022 }
2023
Shawn O. Pearce42526b42009-10-30 17:47:33 -07002024 if (advertise_refs || !stateless_rpc) {
Shawn O. Pearce42526b42009-10-30 17:47:33 -07002025 write_head_info();
Shawn O. Pearce42526b42009-10-30 17:47:33 -07002026 }
2027 if (advertise_refs)
2028 return 0;
Linus Torvalds575f4972005-06-29 17:52:11 -07002029
Masaya Suzuki2d103c32018-12-29 13:19:15 -08002030 packet_reader_init(&reader, 0, NULL, 0,
2031 PACKET_READ_CHOMP_NEWLINE |
2032 PACKET_READ_DIE_ON_ERR_PACKET);
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08002033
2034 if ((commands = read_head_info(&reader, &shallow)) != NULL) {
Junio C Hamanod4f694b2006-11-24 00:26:49 -08002035 const char *unpack_status = NULL;
Stefan Beller77a97452016-07-14 14:49:45 -07002036 struct string_list push_options = STRING_LIST_INIT_DUP;
Junio C Hamanod4f694b2006-11-24 00:26:49 -08002037
Stefan Bellerc714e452016-07-14 14:49:46 -07002038 if (use_push_options)
Masaya Suzuki01f9ec62018-12-29 13:19:14 -08002039 read_push_options(&reader, &push_options);
Jonathan Tancbaf82c2017-05-09 12:23:53 -07002040 if (!check_cert_push_options(&push_options)) {
2041 struct command *cmd;
2042 for (cmd = commands; cmd; cmd = cmd->next)
2043 cmd->error_string = "inconsistent push options";
2044 }
Stefan Bellerc714e452016-07-14 14:49:46 -07002045
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07002046 prepare_shallow_info(&si, &shallow);
Nguyễn Thái Ngọc Duy0a1bc122013-12-05 20:02:47 +07002047 if (!si.nr_ours && !si.nr_theirs)
2048 shallow_update = 0;
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07002049 if (!delete_only(commands)) {
2050 unpack_status = unpack_with_sideband(&si);
2051 update_shallow_info(commands, &si, &ref);
2052 }
Jeff King83558682016-07-15 06:43:47 -04002053 use_keepalive = KEEPALIVE_ALWAYS;
Stefan Beller77a97452016-07-14 14:49:45 -07002054 execute_commands(commands, unpack_status, &si,
2055 &push_options);
Nicolas Pitre576162a2006-11-01 17:06:25 -05002056 if (pack_lockfile)
Alex Riesen691f1a22009-04-29 23:22:56 +02002057 unlink_or_warn(pack_lockfile);
Junio C Hamanocfee10a2005-12-25 23:18:37 -08002058 if (report_status)
Jay Soffian5e1c71f2010-04-19 18:08:30 -04002059 report(commands, unpack_status);
Stefan Beller77a97452016-07-14 14:49:45 -07002060 run_receive_hook(commands, "post-receive", 1,
2061 &push_options);
Shawn O. Pearce8e663d92007-03-07 16:50:24 -05002062 run_update_post_hook(commands);
René Scharfe4432dd62017-01-29 14:09:46 +01002063 string_list_clear(&push_options, 0);
Junio C Hamano77e3efb2009-10-20 14:56:40 -07002064 if (auto_gc) {
2065 const char *argv_gc_auto[] = {
2066 "gc", "--auto", "--quiet", NULL,
2067 };
Lukas Fleischer860a2eb2016-06-05 11:36:38 +02002068 struct child_process proc = CHILD_PROCESS_INIT;
2069
2070 proc.no_stdin = 1;
2071 proc.stdout_to_stderr = 1;
2072 proc.err = use_sideband ? -1 : 0;
2073 proc.git_cmd = 1;
2074 proc.argv = argv_gc_auto;
2075
Derrick Stolee2d511cf2019-05-17 11:41:49 -07002076 close_object_store(the_repository->objects);
Lukas Fleischer860a2eb2016-06-05 11:36:38 +02002077 if (!start_command(&proc)) {
2078 if (use_sideband)
2079 copy_to_sideband(proc.err, -1, NULL);
2080 finish_command(&proc);
2081 }
Junio C Hamano77e3efb2009-10-20 14:56:40 -07002082 }
2083 if (auto_update_server_info)
2084 update_server_info(0);
Nguyễn Thái Ngọc Duy5dbd7672013-12-05 20:02:44 +07002085 clear_shallow_info(&si);
Linus Torvalds7f8e9822005-06-29 22:50:48 -07002086 }
Shawn O. Pearce38a81b42010-02-05 12:57:41 -08002087 if (use_sideband)
2088 packet_flush(1);
brian m. carlson910650d2017-03-31 01:40:00 +00002089 oid_array_clear(&shallow);
2090 oid_array_clear(&ref);
Junio C Hamanob89363e2014-08-21 16:45:30 -07002091 free((void *)push_cert_nonce);
Linus Torvalds575f4972005-06-29 17:52:11 -07002092 return 0;
2093}