本地Git裸仓库权限管控:限制用户分支推送至Code_bare
Got it, let's break down how to enforce push permissions on your self-hosted bare Git repo without relying on SaaS platforms like GitHub or paid GitLab. The most straightforward, no-cost solution here is using Git server-side hooks—specifically the pre-receive hook—to gate pushes before they're accepted into the bare repo.
Step 1: Understand the pre-receive Hook
This hook runs on the server before any changes are applied from a push. It gets fed details about every branch/tag being pushed, and if it exits with a non-zero code, the entire push is rejected. Perfect for enforcing permissions.
Step 2: Create the Hook Script
Head into the hooks directory of your bare repo first:
cd /path/to/Code_bare/hooks
By default, Git comes with sample hooks (like pre-receive.sample). We'll create a new executable pre-receive file:
touch pre-receive chmod +x pre-receive
Open the file with your favorite editor (e.g., nano pre-receive) and paste this script, tailored to your setup:
#!/bin/sh # Grab the SSH username of the user pushing (works for SSH-based Git access, the most common multi-user setup) CURRENT_USER="$USER" # Loop through every branch/tag being pushed while read OLD_COMMIT NEW_COMMIT REF_NAME; do # Extract the branch name (strip off the "refs/heads/" prefix) BRANCH=$(echo "$REF_NAME" | sed 's/refs\/heads\///') # Rule 1: Users can only push to their own dedicated branches EXPECTED_BRANCH="Code_$CURRENT_USER" if [ "$BRANCH" != "$EXPECTED_BRANCH" ]; then echo "❌ Permission denied: You can only push to your dedicated branch '$EXPECTED_BRANCH'." exit 1 fi # Rule 2: Block non-admin users from pushing to the stable branch STABLE_BRANCH="Code_stable" if [ "$BRANCH" = "$STABLE_BRANCH" ] && [ "$CURRENT_USER" != "admin" ]; then echo "❌ Permission denied: Only the 'admin' user can push to the stable branch '$STABLE_BRANCH'." exit 1 fi done # All checks passed—allow the push exit 0
Customize the Rules to Your Needs
- If users need to push multiple branches under their prefix (e.g.,
Code_UserA/feature1,Code_UserA/bugfix), change the branch check to use a wildcard match:if [[ ! "$BRANCH" == "Code_$CURRENT_USER"* ]]; then - To add more admins for the stable branch, modify the check like this:
ALLOWED_STABLE_USERS="admin devlead" if [ "$BRANCH" = "$STABLE_BRANCH" ] && [[ ! " $ALLOWED_STABLE_USERS " =~ " $CURRENT_USER " ]]; then
Step 3: Ensure the Hook Works
Double-check the script has executable permissions (we ran chmod +x earlier, but it never hurts to verify):
ls -l pre-receive
You should see an x in the permission string (e.g., -rwxr-xr-x).
Step 4: Test the Permissions
Have UserA try pushing to Code_UserB—they should get an error. Have a non-admin user try pushing to Code_stable—same thing. Only admin should be able to push to the stable branch, and each user only to their own dedicated branch.
Optional: For More Complex Permissions
If you outgrow simple hooks and need granular permissions (like repo-level access, branch patterns, etc.), check out Gitolite—it's a free, lightweight tool that runs on your server, uses SSH keys for authentication, and lets you define permissions in a simple config file. No need for paid services, and it's perfect for multi-user Git setups.
内容的提问来源于stack exchange,提问作者ALollz

