Prevent pushing to master on GitHub?

GitGithubBranchAccess ControlPull Request

Git Problem Overview


GitHub allows you to configure your repository so that users can't force push to master, but is there a way to prevent pushing to master entirely? I'm hoping to make it so that the only way of adding to commits to master is through the GitHub pull request UI.

Git Solutions


Solution 1 - Git

Since the original question / answer, Github has added a new option for this to the restricted branches UI which allows you to set this up.

> Require pull request reviews before merging When enabled, all commits must be made to a non-protected branch and submitted via a > pull request with the required number of approving reviews and no > changes requested before it can be merged into a branch that matches > this rule.

To find it go to Settings > Branches > Branch Protection Rules and click 'Add Rule'. Github UI after following instructions Then, enter the name of the branch you want to protect and click the checkbox to require pull request reviews before merging. Github UI with the button to click By default, this only stops people who are not moderators. There is also another checkbox later down for ensuring that even moderators cannot merge. Github UI with the other button to click

Solution 2 - Git

The current accepted answer is actually correct but if you are an organization owner or have admin privileges, which is the case if you created the repo, you can still push to protected branches. From Github documentation at https://help.github.com/en/articles/about-branch-restrictions:

> Organization owners and people with admin permissions for a repository are always able to push to a protected branch.

For any other type of collaborator, git push will fail.

If you really want to disable pushing at all, then you have to set that up locally either by configuring an invalid pushRemote for a branch as mentioned before:

git config branch.master.pushRemote no_push

or by creating a pre-push hook as shown here: https://gist.github.com/vlucas/8009a5edadf8d0ff7430

Solution 3 - Git

Directly pushing to remote's master is rejected when status checks are enabled, meaning that the only way to add commits on remote's master is merging pull requests (which pass the status checks) on GitHub.

Here is my experiment result for the master branch requiring status checks:

  1. Create a commit on the master branch on my PC.
  2. Push to remote's master.
  3. A rejection message appears. The commit is not pushed to remote in the end.
C:\GitRepo\GitHub\TomoyukiAota\photo-location-map [master ↑1]> git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 305 bytes | 305.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: error: GH006: Protected branch update failed for refs/heads/master.
remote: error: 3 of 3 required status checks are expected.
To https://github.com/TomoyukiAota/photo-location-map.git
 ! [remote rejected] master -> master (protected branch hook declined)
error: failed to push some refs to 'https://github.com/TomoyukiAota/photo-location-map.git'
C:\GitRepo\GitHub\TomoyukiAota\photo-location-map [master ↑1]>

Solution 4 - Git

You can enable branch restrictions and decide who (in terms of users and teams of the organization) are allowed to push.

https://help.github.com/articles/about-branch-restrictions/

«Note: If the "Include administrators" is checked and you've enabled required status checks on the branch and they fail, any attempt to push changes to the base branch will also fail, regardless of a user or team's permission status.»

Solution 5 - Git

> I'm hoping to make it so that the only way of adding to commits to master is through the GitHub pull request UI.

I have a solution that prevents pushing to the main branch and doesn't require approvals or long status checks to pass in the pull request.

The trick is to create a status check that passes immediately.

Create the following GitHub Action in .github/workflows/requirePullRequest.yml.

name: require pull request

on:
  pull_request:
    branches:
      - master

jobs:
  job:
    name: require pull request
    runs-on: ubuntu-latest
    steps:
      - run: echo hello

Next, update repository settings to require require pull request status check to pass.

If you want administrators to follow the same rule, then you have to check include administrators rule.

This way, GitHub will reject all direct pushes to the main branch and pull requests won't be delayed by anything.

Solution 6 - Git

If you are using free-plan on private repo in Github, you may not be able to use protected branch feature. So you need to block any push / commit from local.

This is what I did to make it work locally and distributed to all repo's members.

First of all, you need to install husky to control pre-commit and pre-push hook. Then, I made a pre-push bash script and commit it inside the repository. Then call this script from husky pre-push hook with husky parameter.

This is my husky configuration inside package.json (you can set separated config if you want)

"husky": {
    "hooks": {
        "pre-commit": "./commands/pre-commit",
        "pre-push": "./commands/pre-push $HUSKY_GIT_STDIN"
    }
},

as you can see I have 2 scripts, one for pre-push and one for pre-commit.

And this is my commands/pre-push bash script

#!/bin/bash

echo -e "===\n>> Talenavi Pre-push Hook: Checking branch name / Mengecek nama branch..."

BRANCH=`git rev-parse --abbrev-ref HEAD`
PROTECTED_BRANCHES="^(master|develop)"

if [[ $1 != *"$BRANCH"* ]]
then
  echo -e "\n🚫 You must use (git push origin $BRANCH) / Anda harus menggunakan (git push origin $BRANCH).\n" && exit 1
fi

if [[ "$BRANCH" =~ $PROTECTED_BRANCHES ]]
then
  echo -e "\n🚫 Cannot push to remote $BRANCH branch, please create your own branch and use PR."
  echo -e "🚫 Tidak bisa push ke remote branch $BRANCH, silahkan buat branch kamu sendiri dan gunakan pull request.\n" && exit 1
fi

echo -e ">> Finish checking branch name / Selesai mengecek nama branch.\n==="

exit 0

The script basically will do 2 things:

  • This script will block anybody who tries to push to a certain branch (in my case I don't want anybody -including myself- to push directly to master and develop branch). They need to work in their own branch and then create a pull request.
  • This script will block anybody who tries to push to a branch that is different from their current active branch. For example you are in branch fix/someissue but then you mistakenly type git push origin master.

For more detailed instructions you can follow from this article:
https://github.com/talenavi/husky-precommit-prepush-githooks

Solution 7 - Git

If You are using Node, You can use husky to create a pre-push validation that a direct push to master does not happen. That way, You can still use your administrator privileges to merge PRs. I guess other languages have similar solutions to husky.

  1. npm install husky --save-dev
  2. In /.huskyrc.js:
const preventPushToMaster = `branch=\`git symbolic-ref HEAD\`
if [ "$branch" = "refs/heads/master" ]; then
    echo "\\033[31mDirect push to master is not allowed.\\033[0m"
    exit 1
fi`;

module.exports = {
  hooks: {
    'pre-push': preventPushToMaster,
  },
};

Solution 8 - Git

I needed to avoid to accidentally push any commits to master branch. It is a similar solution like @christian-chandra's but more simple.

go to your local working copy and

$ cd .git/hooks
echo '' > pre-commit
$ chmod +x pre-commit

Add this content to the file (pre-commit)

#!/bin/sh

branch="$(git rev-parse --abbrev-ref HEAD)"

if [ "$branch" = "master" ]; then
  echo "Master Branch commit is blocked"
  exit 1
fi

done!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjoshlfView Question on Stackoverflow
Solution 1 - GitCoryView Answer on Stackoverflow
Solution 2 - GitIgnacio ArcesView Answer on Stackoverflow
Solution 3 - GitTomoyuki AotaView Answer on Stackoverflow
Solution 4 - GitphdView Answer on Stackoverflow
Solution 5 - GitMichał PietraszkoView Answer on Stackoverflow
Solution 6 - GitChristian ChandraView Answer on Stackoverflow
Solution 7 - Gittal952View Answer on Stackoverflow
Solution 8 - GitZoltán SüleView Answer on Stackoverflow