1009

I'm looking at a Git hook which looks for print statements in Python code. If a print statement is found, it prevents the Git commit.

I want to override this hook and I was told that there is a command to do so. I haven't been able to find it. Any thoughts?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben
  • 15,010
  • 11
  • 58
  • 90
  • 2
    A solution that is more generic (also work for git commands different than `commit`): https://stackoverflow.com/questions/58337861/disable-hooks-for-a-single-git-command – Gabriel Devillers Oct 11 '19 at 09:15
  • Related config: https://stackoverflow.com/questions/54751668/git-pre-commit-hook-configuration - Modify your project root's `.pre-commit-config.yaml` – Cees Timmerman Nov 25 '21 at 23:27

7 Answers7

1656

Maybe (from git commit man page):

git commit --no-verify -m "commit message"
           ^^^^^^^^^^^
-n  
--no-verify

This option bypasses the pre-commit and commit-msg hooks. See also githooks(5).

As commented by Blaise, -n can have a different role for certain commands.
For instance, git push -n is actually a dry-run push.
Only git push --no-verify would skip the hook.


Note: Git 2.14.x/2.15 improves the --no-verify behavior:

See commit 680ee55 (14 Aug 2017) by Kevin Willford (``).
(Merged by Junio C Hamano -- gitster -- in commit c3e034f, 23 Aug 2017)

commit: skip discarding the index if there is no pre-commit hook

"git commit" used to discard the index and re-read from the filesystem just in case the pre-commit hook has updated it in the middle; this has been optimized out when we know we do not run the pre-commit hook.


Davi Lima points out in the comments the git cherry-pick does not support --no-verify.
So if a cherry-pick triggers a pre-commit hook, you might, as in this blog post, have to comment/disable somehow that hook in order for your git cherry-pick to proceed.

The same process would be necessary in case of a git rebase --continue, after a merge conflict resolution.


With Git 2.36 (Q2 2022), the callers of run_commit_hook() to learn if it got "success" because the hook succeeded or because there wasn't any hook.

See commit a8cc594 (fixed with commit 4369e3a1), commit 9f6e63b (07 Mar 2022) by Ævar Arnfjörð Bjarmason (avar).
(Merged by Junio C Hamano -- gitster -- in commit 7431379, 16 Mar 2022)

hooks: fix an obscure TOCTOU "did we just run a hook?" race

Signed-off-by: Ævar Arnfjörð Bjarmason

Fix a Time-of-check to time-of-use (TOCTOU) race in code added in 680ee55 ("commit: skip discarding the index if there is no pre-commit hook", 2017-08-14, Git v2.15.0-rc0 -- merge listed in batch #3).

This obscure race condition can occur if we e.g. ran the "pre-commit" hook and it modified the index, but hook_exists() returns false later on (e.g., because the hook itself went away, the directory became unreadable, etc.).
Then we won't call discard_cache() when we should have.

The race condition itself probably doesn't matter, and users would have been unlikely to run into it in practice.
This problem has been noted on-list when 680ee55 was discussed, but had not been fixed.

Let's also change this for the push-to-checkout hook.
Now instead of checking if the hook exists and either doing a push to checkout or a push to deploy we'll always attempt a push to checkout.
If the hook doesn't exist we'll fall back on push to deploy.
The same behavior as before, without the TOCTOU race.
See 0855331 ("receive-pack: support push-to-checkout hook", 2014-12-01, Git v2.4.0-rc0 -- merge) for the introduction of the previous behavior.

This leaves uses of hook_exists() in two places that matter.
The "reference-transaction" check in refs.c, see 6754159 ("refs: implement reference transaction hook", 2020-06-19, Git v2.28.0-rc0 -- merge listed in batch #7), and the "prepare-commit-msg" hook, see 66618a5 ("sequencer: run 'prepare-commit-msg' hook", 2018-01-24, Git v2.17.0-rc0 -- merge listed in batch #2).

In both of those cases we're saving ourselves CPU time by not preparing data for the hook that we'll then do nothing with if we don't have the hook.
So using this "invoked_hook" pattern doesn't make sense in those cases.

The "reference-transaction" and "prepare-commit-msg" hook also aren't racy.
In those cases we'll skip the hook runs if we race with a new hook being added, whereas in the TOCTOU races being fixed here we were incorrectly skipping the required post-hook logic.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    For cherry-pick see http://web-dev.wirt.us/info/git-drupal/git-continue-vs-no-verify – Davi Lima Sep 01 '19 at 12:31
  • 1
    @DaviLima Thank you. I have included your comment in the answer for visibility. – VonC Sep 01 '19 at 13:39
  • 1
    thanks, @Vonc. same happens for `git rebase --continue` btw – Davi Lima Sep 02 '19 at 14:26
  • Hi, in my case, someone in my team keep updating my `hook` folder with some pre-commit scripts, it is so annoying, is there a way I can prevent my `hook` folder to be overriden by git pull? – Zennichimaro May 21 '20 at 10:49
  • @Zennichimaro Maybe you can copy that repo hook folder elsewhere, and setup a post-merge hook (https://git-scm.com/docs/githooks#_post_merge) which will detect if the pull affect the repo hook folder, and will propose to copy its content to your local hook folder (outside of the repo): that way, you can at least control if you want your hooks overridden or not by what is pushed by your colleagues. – VonC May 21 '20 at 16:36
  • How to disable the hooks permanently for one specific repository? – aagjalpankaj Jun 21 '20 at 04:48
  • @aagjalpankaj You could simply make sure it is not executable. Or rename it. In both cases, that would be done in the `specific repo/.git/hooks` – VonC Jun 21 '20 at 09:22
  • @VonC - I tried that but still facing the issue. Can you please look into this question - https://stackoverflow.com/questions/62494323/npm-run-deploy-ignore-hooks – aagjalpankaj Jun 21 '20 at 13:45
  • 1
    yep. Had to rename .git\hooks\pre-commit and rename it back afterwards. I'm surprised there isn't a flag to pass flags to commit – TamusJRoyce Jun 09 '21 at 20:51
68

With both comment and no verify without any further issue:

git commit -m "Some comments" --no-verify
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Moumit
  • 8,314
  • 9
  • 55
  • 59
  • 1
    @Moumit The command just works fine. You might want to rephrase the sentence as this is little confusing. – Pramod Itagi Nov 29 '21 at 09:09
  • Understood the concern changed it @PramodItagi – Moumit Nov 29 '21 at 10:59
  • What do you mean by *"with no further issue"*? Can you elaborate? And what do you mean by *"with both comment and no verify"*? It would be fine to elaborate here in comments. And/or by editing your answer. – Peter Mortensen Dec 02 '21 at 15:05
  • ["-m" is *"Use the given as the commit message."*](https://linux.die.net/man/1/git-commit). By comment, do you mean the (commit) message? – Peter Mortensen Jul 05 '22 at 20:23
46

--no-verify works, but in my case, I didn't want to put the parameter all the time on the terminal. So I opted for something a little more aggressive.

If you want to disable git hooks globally, you could try running this:

git config --global core.hooksPath /dev/null

But, if you want to leave it as it was before, just run the following command in your terminal:

git config --global --unset core.hooksPath

If you do not want it to be global, just remove the argument: --global

I tested it with Git 2.16.3.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    Thanks Francisco! Works like a charm! I ended up adding the following aliases to my `$HOME/.gitconfig` -> `disable-hooks = config core.hooksPath /dev/null` and `enable-hooks = config --unset core.hooksPath`. – jweyrich May 03 '22 at 18:41
33

From man githooks:

pre-commit
This hook is invoked by git commit, and can be bypassed with --no-verify option. It takes no parameter, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with non-zero status from this script causes the git commit to abort.

Chris Eberle
  • 47,994
  • 12
  • 82
  • 119
16

-n or --no-verify does not work for a commit after 'git merge --continue' for example.

So here is another rougher idea.

  1. Just comment lines in file .git/hooks/pre-commit with symbol '#'.
  2. Run single or many commands
  3. Uncomment
  4. Profit.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
10

For some reason, --no-verify does not work for me with this particular hook: prepare-commit-msg

If you too are running into this issue, try:

SKIP=prepare-commit-msg git commit
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike Lyons
  • 22,575
  • 2
  • 16
  • 19
  • 1
    This didn't work for me. Is the `SKIP` env var documented by git? Or is this some special control flow implemented by your `prepare-commit-msg` script? – Jasha Jun 11 '22 at 21:32
  • 3
    @Jasha: it's not a Git standard thing. – torek Jun 15 '22 at 11:17
  • I think this `SKIP` is part of the [pre-commit](https://pre-commit.com) tool and not part of core Git. See: https://pre-commit.com/index.html#temporarily-disabling-hooks – Gino Mempin May 09 '23 at 10:58
-2

SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^(.>).$/- signed-off-by: \1/p') grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

sColpx
  • 1
  • 1
  • This “signed-off-by” stuff is irrelevant. Did you reply to the wrong answer? Although it’s been half a week since I first saw this answer so you should have noticed by now. – Guildenstern May 12 '23 at 18:23