@matheusbsbs / matheus-bagliano / commits / a240de1137
Fork 0

Introduce receive.denyDeletes

Occasionally, it may be useful to prevent branches from getting deleted from a centralized repository, particularly when no administrative access to the server is available to undo it via reflog. It also makes receive.denyNonFastForwards more useful if it is used for access control since it prevents force-updating by deleting and re-creating a ref. Signed-off-by: Jan Krüger <jk@jk.gs> Acked-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jan Krüger committed Nov 1, 2008 at 15:42 UTC a240de1137bd63a969c6bd56ab5186d7216e28ca
3 files changed +27
Documentation/config.txt
+4
@@ -1188,6 +1188,10 @@ receive.unpackLimit::
1188 especially on slow filesystems. If not set, the value of
1189 `transfer.unpackLimit` is used instead.
1190
1191 +receive.denyDeletes::
1192 + If set to true, git-receive-pack will deny a ref update that deletes
1193 + the ref. Use this to prevent such a ref deletion via a push.
1194 +
1195 receive.denyNonFastForwards::
1196 If set to true, git-receive-pack will deny a ref update which is
1197 not a fast forward. Use this to prevent such an update via a push,
builtin-receive-pack.c
+12
@@ -11,6 +11,7 @@
11
12 static const char receive_pack_usage[] = "git-receive-pack <git-dir>";
13
14 +static int deny_deletes = 0;
15 static int deny_non_fast_forwards = 0;
16 static int receive_fsck_objects;
17 static int receive_unpack_limit = -1;
@@ -23,6 +24,11 @@ static int capabilities_sent;
24
25 static int receive_pack_config(const char *var, const char *value, void *cb)
26 {
27 + if (strcmp(var, "receive.denydeletes") == 0) {
28 + deny_deletes = git_config_bool(var, value);
29 + return 0;
30 + }
31 +
32 if (strcmp(var, "receive.denynonfastforwards") == 0) {
33 deny_non_fast_forwards = git_config_bool(var, value);
34 return 0;
@@ -185,6 +191,12 @@ static const char *update(struct command *cmd)
191 "but I can't find it!", sha1_to_hex(new_sha1));
192 return "bad pack";
193 }
194 + if (deny_deletes && is_null_sha1(new_sha1) &&
195 + !is_null_sha1(old_sha1) &&
196 + !prefixcmp(name, "refs/heads/")) {
197 + error("denying ref deletion for %s", name);
198 + return "deletion prohibited";
199 + }
200 if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
201 !is_null_sha1(old_sha1) &&
202 !prefixcmp(name, "refs/heads/")) {
t/t5400-send-pack.sh
+11
@@ -103,6 +103,17 @@ unset GIT_CONFIG GIT_CONFIG_LOCAL
103 HOME=`pwd`/no-such-directory
104 export HOME ;# this way we force the victim/.git/config to be used.
105
106 +test_expect_failure \
107 + 'pushing a delete should be denied with denyDeletes' '
108 + cd victim &&
109 + git config receive.denyDeletes true &&
110 + git branch extra master &&
111 + cd .. &&
112 + test -f victim/.git/refs/heads/extra &&
113 + test_must_fail git send-pack ./victim/.git/ :extra master
114 +'
115 +rm -f victim/.git/refs/heads/extra
116 +
117 test_expect_success \
118 'pushing with --force should be denied with denyNonFastforwards' '
119 cd victim &&