11
12
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
13
14
+enum deny_action {
15
+ DENY_IGNORE,
16
+ DENY_WARN,
17
+ DENY_REFUSE,
18
+};
19
+
20
static int deny_deletes = 0;
21
static int deny_non_fast_forwards = 0;
22
+static enum deny_action deny_current_branch = DENY_WARN;
23
static int receive_fsck_objects;
24
static int receive_unpack_limit = -1;
25
static int transfer_unpack_limit = -1;
29
static char capabilities[] = " report-status delete-refs ";
30
static int capabilities_sent;
31
32
+static enum deny_action parse_deny_action(const char *var, const char *value)
33
+{
34
+ if (value) {
35
+ if (!strcasecmp(value, "ignore"))
36
+ return DENY_IGNORE;
37
+ if (!strcasecmp(value, "warn"))
38
+ return DENY_WARN;
39
+ if (!strcasecmp(value, "refuse"))
40
+ return DENY_REFUSE;
41
+ }
42
+ if (git_config_bool(var, value))
43
+ return DENY_REFUSE;
44
+ return DENY_IGNORE;
45
+}
46
+
47
static int receive_pack_config(const char *var, const char *value, void *cb)
48
{
49
if (strcmp(var, "receive.denydeletes") == 0) {
71
return 0;
72
}
73
74
+ if (!strcmp(var, "receive.denycurrentbranch")) {
75
+ deny_current_branch = parse_deny_action(var, value);
76
+ return 0;
77
+ }
78
+
79
return git_default_config(var, value, cb);
80
}
81
200
return hook_status(run_command(&proc), update_hook);
201
}
202
203
+static int is_ref_checked_out(const char *ref)
204
+{
205
+ unsigned char sha1[20];
206
+ const char *head;
207
+
208
+ if (is_bare_repository())
209
+ return 0;
210
+
211
+ head = resolve_ref("HEAD", sha1, 0, NULL);
212
+ if (!head)
213
+ return 0;
214
+ return !strcmp(head, ref);
215
+}
216
+
217
static const char *update(struct command *cmd)
218
{
219
const char *name = cmd->ref_name;
227
return "funny refname";
228
}
229
230
+ switch (deny_current_branch) {
231
+ case DENY_IGNORE:
232
+ break;
233
+ case DENY_WARN:
234
+ if (!is_ref_checked_out(name))
235
+ break;
236
+ warning("updating the currently checked out branch; this may"
237
+ " cause confusion,\n"
238
+ "as the index and working tree do not reflect changes"
239
+ " that are now in HEAD.");
240
+ break;
241
+ case DENY_REFUSE:
242
+ if (!is_ref_checked_out(name))
243
+ break;
244
+ error("refusing to update checked out branch: %s", name);
245
+ return "branch is currently checked out";
246
+ }
247
+
248
if (!is_null_sha1(new_sha1) && !has_sha1_file(new_sha1)) {
249
error("unpack should have generated %s, "
250
"but I can't find it!", sha1_to_hex(new_sha1));