I unintentionally create commits on my main branch all the time. When this happens, I need to undo my changes, or delete my local main branch and checkout a fresh copy from origin.

With a Git hook, we can prevent commits being made to the main branch.

I found an example of this on Stack Overflow, which works, but I wanted a solution that I could configure with multiple branch names.

I wrote the pre-commit hook in Python, which I find easier to work with than Bash.

Use the following steps:

mkdir ~/.git-hooks
git config --global core.hooksPath ~/.git-hooks/
touch ~/.git-hooks/pre-commit
chmod +x ~/.git-hooks/pre-commit
# copy the following python code into ~/.git-hooks/pre-commit
#!/usr/bin/env python3

import subprocess
import sys
import os

PROTECTED_BRANCHES = ("master", "main")
DISABLE_KEY_PATH = "protected-main.disabled"

def main():
    disabled = bool(
        subprocess.run(
            ["git", "config", "--get", DISABLE_KEY_PATH],
            capture_output=True,
        )
        .stdout.decode()
        .strip()
    )
    if disabled:
        return
    branch = (
        subprocess.run(
            ["git", "rev-parse", "--abbrev-ref", "HEAD"],
            capture_output=True,
            check=True,
        )
        .stdout.decode()
        .strip()
    )
    if branch in PROTECTED_BRANCHES:
        print(f"You can't commit directly to the {branch!r} branch", file=sys.stderr)
        print(f"Disable with `git config --add {DISABLE_KEY_PATH} 1 ", file=sys.stderr)
        exit(1)


if __name__ == "__main__":
    main()