[PATCH] optionally deny all pushes
From: Clemens Buchacher <hidden>
Date: 2016-06-15 22:52:50
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
For a mirror repository which is updated only by pulling from upstream, it is convenient to disallow all pushes. An accidental push from a downstream repository would mess up the mirror's state as well as future updates. Add a boolean configuration variable receive.denyAll. If enabled, receive-pack will deny all ref updates. Signed-off-by: Clemens Buchacher <redacted> --- Documentation/config.txt | 4 ++++ Documentation/git-push.txt | 1 + builtin/receive-pack.c | 11 +++++++++++ contrib/completion/git-completion.bash | 1 + t/t5400-send-pack.sh | 17 +++++++++++++++++ t/t5516-fetch-push.sh | 12 ++++++++++++ 6 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 04f5e19..edbddea 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt@@ -1683,6 +1683,10 @@ receive.unpackLimit:: especially on slow filesystems. If not set, the value of `transfer.unpackLimit` is used instead. +receive.denyAll:: + If set to true, git-receive-pack will deny all ref updates. + The repository can not be updated remotely. + 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.
diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index aede488..7c6cc63 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt@@ -219,6 +219,7 @@ remote rejected:: The remote end refused the update. Usually caused by a hook on the remote side, or because the remote repository has one of the following safety options in effect: + `receive.denyAll` (for all pushes), `receive.denyCurrentBranch` (for pushes to the checked out branch), `receive.denyNonFastForwards` (for forced non-fast-forward updates), `receive.denyDeletes` or
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index d2dcb7e..9cd04f9 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c@@ -22,6 +22,7 @@ enum deny_action { DENY_REFUSE }; +static int deny_all; static int deny_deletes; static int deny_non_fast_forwards; static enum deny_action deny_current_branch = DENY_UNCONFIGURED;
@@ -57,6 +58,11 @@ static enum deny_action parse_deny_action(const char *var, const char *value) static int receive_pack_config(const char *var, const char *value, void *cb) { + if (strcmp(var, "receive.denyall") == 0) { + deny_all = git_config_bool(var, value); + return 0; + } + if (strcmp(var, "receive.denydeletes") == 0) { deny_deletes = git_config_bool(var, value); return 0;
@@ -401,6 +407,11 @@ static const char *update(struct command *cmd) unsigned char *new_sha1 = cmd->new_sha1; struct ref_lock *lock; + if (deny_all) { + rp_error("denying all updates"); + return "update prohibited"; + } + /* only refs/... are allowed */ if (prefixcmp(name, "refs/") || check_refname_format(name + 5, 0)) { rp_error("refusing to create funny ref '%s' remotely", name);
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index b0062ba..9d63622 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash@@ -2250,6 +2250,7 @@ _git_config () rebase.autosquash rebase.stat receive.autogc + receive.denyAll receive.denyCurrentBranch receive.denyDeleteCurrent receive.denyDeletes
diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh
index 0eace37..e8c9be2 100755
--- a/t/t5400-send-pack.sh
+++ b/t/t5400-send-pack.sh@@ -222,4 +222,21 @@ test_expect_success 'deny pushing to delete current branch' ' ) ' +test_expect_success 'deny pushing to any branch with denyAll' ' + rewound_push_setup && + ( + cd parent && + git config receive.denyCurrentBranch false && + git config receive.denyAll true + ) && + ( + cd child && + test_must_fail git send-pack ../parent master 2>errs + ) && + ( + cd child && + test_must_fail git send-pack ../parent :refs/heads/master 2>errs + ) +' + test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b69cf57..d1117c0 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh@@ -815,6 +815,18 @@ test_expect_success 'allow push to HEAD of bare repository (bare)' ' ! grep "warning: updating the current branch" stderr ' +test_expect_success 'deny push to HEAD of bare repository (denyAll)' ' + mk_test heads/master && + ( + cd testrepo && + git checkout master && + git config receive.denyCurrentBranch false && + git config receive.denyAll true && + git config core.bare true + ) && + test_must_fail git push testrepo master +' + test_expect_success 'allow push to HEAD of non-bare repository (config)' ' mk_test heads/master && (
--
1.7.8