Navigation Menu

Skip to content

Commit

Permalink
Introduce receive.denyDeletes
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jast authored and gitster committed Nov 2, 2008
1 parent aebd173 commit a240de1
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Documentation/config.txt
Expand Up @@ -1188,6 +1188,10 @@ receive.unpackLimit::
especially on slow filesystems. If not set, the value of
`transfer.unpackLimit` is used instead.

receive.denyDeletes::
If set to true, git-receive-pack will deny a ref update that deletes
the ref. Use this to prevent such a ref deletion via a push.

receive.denyNonFastForwards::
If set to true, git-receive-pack will deny a ref update which is
not a fast forward. Use this to prevent such an update via a push,
Expand Down
12 changes: 12 additions & 0 deletions builtin-receive-pack.c
Expand Up @@ -11,6 +11,7 @@

static const char receive_pack_usage[] = "git-receive-pack <git-dir>";

static int deny_deletes = 0;
static int deny_non_fast_forwards = 0;
static int receive_fsck_objects;
static int receive_unpack_limit = -1;
Expand All @@ -23,6 +24,11 @@ static int capabilities_sent;

static int receive_pack_config(const char *var, const char *value, void *cb)
{
if (strcmp(var, "receive.denydeletes") == 0) {
deny_deletes = git_config_bool(var, value);
return 0;
}

if (strcmp(var, "receive.denynonfastforwards") == 0) {
deny_non_fast_forwards = git_config_bool(var, value);
return 0;
Expand Down Expand Up @@ -185,6 +191,12 @@ static const char *update(struct command *cmd)
"but I can't find it!", sha1_to_hex(new_sha1));
return "bad pack";
}
if (deny_deletes && is_null_sha1(new_sha1) &&
!is_null_sha1(old_sha1) &&
!prefixcmp(name, "refs/heads/")) {
error("denying ref deletion for %s", name);
return "deletion prohibited";
}
if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
!is_null_sha1(old_sha1) &&
!prefixcmp(name, "refs/heads/")) {
Expand Down
11 changes: 11 additions & 0 deletions t/t5400-send-pack.sh
Expand Up @@ -103,6 +103,17 @@ unset GIT_CONFIG GIT_CONFIG_LOCAL
HOME=`pwd`/no-such-directory
export HOME ;# this way we force the victim/.git/config to be used.

test_expect_failure \
'pushing a delete should be denied with denyDeletes' '
cd victim &&
git config receive.denyDeletes true &&
git branch extra master &&
cd .. &&
test -f victim/.git/refs/heads/extra &&
test_must_fail git send-pack ./victim/.git/ :extra master
'
rm -f victim/.git/refs/heads/extra

test_expect_success \
'pushing with --force should be denied with denyNonFastforwards' '
cd victim &&
Expand Down

0 comments on commit a240de1

Please sign in to comment.