Skip to content

Instantly share code, notes, and snippets.

@rakeshtembhurne
Created October 6, 2025 12:13
Show Gist options
  • Save rakeshtembhurne/7ca7383df22e9d43fda4fcc59da8d75d to your computer and use it in GitHub Desktop.
Save rakeshtembhurne/7ca7383df22e9d43fda4fcc59da8d75d to your computer and use it in GitHub Desktop.
GitLab Protect Banches Script to avoid merging by developers
#!/bin/bash
# Script name: gitlab-protect-branches
# Description: Protect main and develop branches in any GitLab project
# Usage: gitlab-protect-branches [options]
# sudo vim /usr/local/bin/gitlab-protect-branches
# sudo chmod +x /usr/local/bin/gitlab-protect-branches
# gitlab-protect-branches --help
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to display usage
usage() {
echo "Usage: $(basename $0) [OPTIONS]"
echo ""
echo "Options:"
echo " -b, --branches Comma-separated list of branches (default: main,develop)"
echo " -l, --level Access level (default: 40 for Maintainer)"
echo " -h, --help Show this help message"
echo ""
echo "Access Levels:"
echo " 30 = Developer"
echo " 40 = Maintainer"
echo " 50 = Owner"
echo ""
echo "Examples:"
echo " $(basename $0)"
echo " $(basename $0) -b main,develop,staging"
echo " $(basename $0) -b master -l 50"
exit 1
}
# Default values
BRANCHES="main,develop"
ACCESS_LEVEL=40
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-b|--branches)
BRANCHES="$2"
shift 2
;;
-l|--level)
ACCESS_LEVEL="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
usage
;;
esac
done
# Check if we're in a git repository
if ! git rev-parse --git-dir > /dev/null 2>&1; then
echo -e "${RED}❌ Error: Not in a git repository${NC}"
exit 1
fi
# Check if glab is installed
if ! command -v glab &> /dev/null; then
echo -e "${RED}❌ Error: glab CLI is not installed${NC}"
echo "Install it from: https://gitlab.com/gitlab-org/cli"
exit 1
fi
# Extract GitLab project path from any GitLab instance
get_project_path() {
local origin_url=$(git remote get-url origin 2>/dev/null)
if [ -z "$origin_url" ]; then
echo -e "${RED}❌ Error: No git remote 'origin' found${NC}"
exit 1
fi
# Handle both SSH and HTTPS URLs
local project_path
if [[ $origin_url == git@* ]]; then
# SSH URL: [email protected]:namespace/project.git
project_path=$(echo "$origin_url" | sed 's/.*@[^:]*://' | sed 's/\.git$//')
elif [[ $origin_url == https://* ]] || [[ $origin_url == http://* ]]; then
# HTTPS URL: https://gitlab.example.com/namespace/project.git
project_path=$(echo "$origin_url" | sed 's|.*://[^/]*/||' | sed 's/\.git$//')
else
echo -e "${RED}❌ Error: Unrecognized git remote URL format${NC}"
exit 1
fi
# URL encode the path (replace / with %2F)
echo "$project_path" | sed 's/\//%2F/g'
}
# Main execution
echo "🔐 GitLab Branch Protection Tool"
echo "================================"
REPO_PATH=$(get_project_path)
echo -e "📦 Project: ${GREEN}$(echo $REPO_PATH | sed 's/%2F/\//g')${NC}"
# Check current protected branches
echo -e "\n🔍 Current protected branches:"
CURRENT_PROTECTED=$(glab api "projects/$REPO_PATH/protected_branches" 2>/dev/null || echo "[]")
if [ "$CURRENT_PROTECTED" = "[]" ]; then
echo " No protected branches found"
else
echo "$CURRENT_PROTECTED" | jq -r '.[] | " - \(.name)"' 2>/dev/null || echo "$CURRENT_PROTECTED"
fi
# Protect specified branches
echo -e "\n🛡️ Protecting branches with access level $ACCESS_LEVEL..."
IFS=',' read -ra BRANCH_ARRAY <<< "$BRANCHES"
for branch in "${BRANCH_ARRAY[@]}"; do
branch=$(echo "$branch" | xargs) # Trim whitespace
echo -n " Protecting '$branch'... "
# Check if branch already protected
if echo "$CURRENT_PROTECTED" | jq -e ".[] | select(.name == \"$branch\")" > /dev/null 2>&1; then
echo -e "${YELLOW}already protected (skipping)${NC}"
continue
fi
# Protect the branch
if glab api "projects/$REPO_PATH/protected_branches" \
-X POST \
-f name="$branch" \
-f push_access_level=$ACCESS_LEVEL \
-f merge_access_level=$ACCESS_LEVEL \
-f unprotect_access_level=$ACCESS_LEVEL \
-f allow_force_push=false \
--silent > /dev/null 2>&1; then
echo -e "${GREEN}✓ protected${NC}"
else
echo -e "${RED}✗ failed${NC}"
fi
done
echo -e "\n✅ Branch protection complete!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment