Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save zubaer-ahammed/73e0ea67f7dcb5659e902a07c6cafe8a to your computer and use it in GitHub Desktop.
Save zubaer-ahammed/73e0ea67f7dcb5659e902a07c6cafe8a to your computer and use it in GitHub Desktop.
Git Pre-Commit Hook for Protecting Master, Main and Production Branches

πŸš€ Git Pre-Commit Hook for Protecting Master & Main Branches

A Git pre-commit hook that prevents accidental commits on protected branches (master, main, production).

πŸ”₯ Features

βœ… πŸ”΄ Warning when committing on a protected branch.
βœ… 🟒 Option to proceed (yes) or discard uncommitted changes (discard).
βœ… 🟑 Default is no (commit aborted unless explicitly confirmed).
βœ… πŸ“œ Logs commit attempts in ~/.git_commit_log.txt for auditing.
βœ… 🎨 Color-coded output for better readability.


πŸ“Œ How It Works

  • If you attempt to commit on a protected branch (master, main, production), a warning appears.
  • You can:
    • Type yes β†’ Proceed with the commit.
    • Type discard β†’ Discard all uncommitted changes (tracked & untracked).
    • Press Enter (no) β†’ Abort the commit (default action).
  • All commit attempts are logged in ~/.git_commit_log.txt.

βš™οΈ Installation

Option 1: Per-Repository Setup

  1. Navigate to your repository:

    cd /path/to/your/repository
  2. Place the script inside .git/hooks/pre-commit:

nano .git/hooks/pre-commit
  1. Paste the pre-commit script and save.

  2. Make it executable:

chmod +x .git/hooks/pre-commit

Option 2: Global Setup (For All Repositories)

  1. Create a global hooks directory:
mkdir -p ~/.git_hooks
  1. Tell Git to use this hooks directory globally:
git config --global core.hooksPath ~/.git_hooks
  1. Create the pre-commit hook:
nano ~/.git_hooks/pre-commit
  1. Paste the script, save, and make it executable:
chmod +x ~/.git_hooks/pre-commit
#!/bin/bash
# Define color codes
RED='\033[1;31m' # Bold Red
YELLOW='\033[1;33m' # Bold Yellow
GREEN='\033[1;32m' # Bold Green
CYAN='\033[1;36m' # Bold Cyan
NC='\033[0m' # Reset color
# List of protected branches
protected_branches=("master" "main" "production")
# Get the current branch name
branch=$(git rev-parse --abbrev-ref HEAD)
# Check if the branch is in the protected list
if [[ " ${protected_branches[@]} " =~ " ${branch} " ]]; then
echo -e "${RED}⚠️ WARNING: You are attempting to commit on the '${branch}' branch!${NC}"
echo -e "${YELLOW}You should only update the '${branch}' branch via pull requests.${NC}"
echo -e "${CYAN}Options:${NC}"
echo -e " - Type ${GREEN}'yes'${NC} to continue with the commit."
echo -e " - Type ${RED}'discard'${NC} to **discard all uncommitted changes**."
echo -e " - Press Enter or type ${RED}'no'${NC} to abort. ${YELLOW}[default: no]${NC}"
# Ensure the prompt works in Git hooks
exec < /dev/tty
echo -ne "${CYAN}Input: ${NC}" # Prompt text
read -r response
# Default to "no" if no input is provided
response=${response:-no}
# Convert response to lowercase for comparison
response=$(echo "$response" | tr '[:upper:]' '[:lower:]')
if [[ "$response" == "discard" ]]; then
echo -e "${RED}⚠️ Discarding all uncommitted changes on '${branch}'...${NC}"
git reset --hard HEAD # Discard changes in tracked files
git clean -fd # Remove untracked files and folders
echo -e "${GREEN}βœ… Uncommitted changes have been discarded.${NC}"
exit 1 # Abort the commit to prevent partial commits
fi
if [[ "$response" != "yes" ]]; then
echo -e "${RED}❌ Commit aborted. Please switch to another branch.${NC}"
echo -e "${CYAN}Run the following to create a new branch:${NC}"
echo -e "${GREEN} git checkout -b <branch-name>${NC}"
exit 1
fi
# Log commit attempts on protected branches
log_file=~/.git_commit_log.txt
echo "$(date): Commit allowed on ${branch} by $(git config user.name) (email: $(git config user.email))" >> "$log_file"
echo -e "${GREEN}βœ… Proceeding with the commit on the '${branch}' branch...${NC}"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment