Description
Branch protection rules are completely ineffective on our Gitea instance running on Windows. Any user, including non-admin users, can push directly to protected branches without any error or rejection.
Environment
-
Gitea version: 1.25.4 (upgraded from 1.22.6)
-
OS: Windows Server (Windows binary installation, not Docker)
-
Git client: Visual Studio built-in Git client + GitHub Desktop
-
Protocol: HTTP
Configuration
Branch protection rule on main:
-
Push: Disabled (no direct push allowed)
-
Required approvals: 1
-
Revoke stale approvals: enabled
-
Block merge on rejected reviews: enabled
-
Administrators must follow branch protection rules: enabled
Steps to reproduce
-
Create a branch protection rule on
mainwith push disabled -
Push directly to
mainfrom any Git client (Visual Studio, GitHub Desktop) as any user (admin or non-admin) -
Push succeeds with no error message whatsoever
Investigation
We inspected the hooks directory at: C:\gitea\data\gitea-repositories\<org>\<repo>.git\hooks\
The hooks are present (pre-receive, post-receive, proc-receive, update) and were regenerated via the “Resync git hooks” admin task. The pre-receive.d\gitea file contains the correct auto-generated content:
bash
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
C:/gitea/gitea.exe hook --config="C:\\gitea\\custom\\conf\\app.ini" pre-receive
The root pre-receive file contains:
bash
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
data=$(cat)
exitcodes=""
hookname=$(basename $0)
GIT_DIR=${GIT_DIR:-$(dirname $0)/..}
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
test -x "${hook}" && test -f "${hook}" || continue
echo "${data}" | "${hook}"
exitcodes="${exitcodes} $?"
done
for i in ${exitcodes}; do
[ ${i} -eq 0 ] || exit ${i}
done
We noticed that test -x fails on Windows because files do not have Unix executable bits. We ran chmod +x on all hook files via Git Bash:
bash
chmod +x pre-receive pre-receive.d/gitea
chmod +x post-receive post-receive.d/gitea
chmod +x proc-receive proc-receive.d/gitea
chmod +x update update.d/gitea
This did not resolve the issue. Pushes to protected branches are still accepted silently.
Expected behavior
Any direct push to a protected branch should be rejected with an error message such as: remote: Gitea: branch main is protected
Actual behavior
Push succeeds silently. No error, no rejection, no hook output visible on the client side.
Additional notes
-
ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SETis not set inapp.ini(default value applies) -
DISABLE_GIT_HOOKSis not set inapp.ini(default value applies) -
The issue affects all users regardless of admin status
-
Branch protection rules are correctly saved and visible in the repository settings UI
-
The problem appeared to exist on 1.22.6 as well (we upgraded hoping it would fix it)
Question
Is branch protection via server-side hooks fully supported on Windows binary installations? Is there a known workaround or required configuration for Windows environments?