4

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"
      ]
    }
  }
p7adams
  • 622
  • 1
  • 9
  • 24
  • Depending on what you are trying to do, Protected Branches (https://help.github.com/articles/about-protected-branches/) might help. – bitoiu Dec 11 '18 at 15:20

2 Answers2

7

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

ack_inc
  • 1,015
  • 7
  • 13
  • but what about the case, when I am on a different branch than master and by mistake, I do `git push origin master ` ?? – p7adams Dec 12 '18 at 07:03
  • 1
    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. – ack_inc Dec 12 '18 at 17:08
  • yea, however that won't work either with auto-merging bots. Cannot find a solution to this – Matteo May 19 '20 at 02:12
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

  • Thank you for your work, but that doesn't work anymore with Husky v5. Would you be able to update it for the community? – Raphael Setin Mar 24 '22 at 00:04