Jan Krrrger <jk@xxxxx> wrote: > 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@xxxxx> > --- > Like this, then? Acked-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> > Documentation/config.txt | 4 ++++ > builtin-receive-pack.c | 12 ++++++++++++ > t/t5400-send-pack.sh | 11 +++++++++++ > 3 files changed, 27 insertions(+), 0 deletions(-) > > diff --git a/Documentation/config.txt b/Documentation/config.txt > index 29369d0..965ed74 100644 > --- a/Documentation/config.txt > +++ b/Documentation/config.txt > @@ -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, > diff --git a/builtin-receive-pack.c b/builtin-receive-pack.c > index 9f60f31..2c0225c 100644 > --- a/builtin-receive-pack.c > +++ b/builtin-receive-pack.c > @@ -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; > @@ -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; > @@ -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/")) { > diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh > index 544771d..6fe2f87 100755 > --- a/t/t5400-send-pack.sh > +++ b/t/t5400-send-pack.sh > @@ -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 && > -- > 1.6.0.3.524.g86cf.dirty -- Shawn. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html