Setup pre-push hook with Husky to prevent pushing to master branch
Asked Answered
L

2

5

Is it possible to setup pre-push hook with Husky to prevent pushing to master by mistake?? Husky documentation is very poor so I couldn't find the answer.

Right now I have husky set for committing and pushing like this:

 "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "pre-push": "npm run lint"
    }
  },
  "lint-staged": {
    "linters": {
      "*.{js,json,scss,md}": [
        "prettier --write",
        "git add"
      ],
      "*.js": [
        "eslint -c .eslintrc --fix",
        "echo test",
        "git add"
      ]
    }
  }
Lukas answered 11/12, 2018 at 15:8 Comment(1)
Depending on what you are trying to do, Protected Branches (help.github.com/articles/about-protected-branches) might help. – Ind
R
4

What I did was making 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 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

Ringnecked answered 9/8, 2020 at 5:42 Comment(1)
Thank you for your work, but that doesn't work anymore with Husky v5. Would you be able to update it for the community? – Unsettle
R
6

Try changing your pre-push hook to: "npm run lint && git branch | grep \"*\" | egrep -v \"^* master$\""

This will cause git push to fail when the current branch is master

Refugee answered 11/12, 2018 at 17:24 Comment(3)
but what about the case, when I am on a different branch than master and by mistake, I do git push origin master ?? – Lukas
I'm afraid I don't know how to prevent that through git hooks. Look into setting up master as a 'protected branch' on whatever remote you are pushing to. Github, Gitlab etc. probably make this pretty easy to do. – Refugee
yea, however that won't work either with auto-merging bots. Cannot find a solution to this – Unattended
R
4

What I did was making 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 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

Ringnecked answered 9/8, 2020 at 5:42 Comment(1)
Thank you for your work, but that doesn't work anymore with Husky v5. Would you be able to update it for the community? – Unsettle

© 2022 - 2024 β€” McMap. All rights reserved.