Search code examples
gitmergefast-forward

Prevent commits in master branch


(For simplicity) I have a master branch and a dev in my Git repository. I want to ensure the master branch is always working, so all work I do should be in the dev branch.

However, when I merge my changes in with a --no-ff merge, I tend to stay in the master branch, and just continue working in it (because I forget to checkout my dev branch).

Can I put up a rule for the master branch, which states I can't do commits, and fast-forward merges, but only --no-ff merges from another branch?

This must work for private hosted repositories (ergo, not GitHub or Bitbucket).


Solution

  • Yes, it is possible. You must create a pre-commit hook which rejects commits to the master branch. Git doesn't call a pre-commit hook when you call the merge command, so this hook will be rejecting only regular commits.

    1. Go to your repository.

    2. Create a file, .git/hooks/pre-commit, with the following content:

      #!/bin/bash
      
      branch="$(git rev-parse --abbrev-ref HEAD)"
      
      if [ "$branch" = "master" ]; then
        echo "You can't commit directly to master branch"
        exit 1
      fi
      
    3. Make it executable (not required on Windows):

      chmod +x .git/hooks/pre-commit
      

    To disable fast-forward merges, you must also add the following option to your .git/config file:

    [branch "master"]
        mergeoptions = --no-ff
    

    If you want also protect the master branch on your remote, check this answer: How to restrict access to master branch in Git