41

I was doing a git revert (of a previous revert), which caused some merge conflicts. After resolving the conflicts my pre-commit hook threw some code sniffer issues.

Since these code sniffer notices are fixed elsewhere I wanted to bypass the pre-commit hook at this point using git revert --continue --no-verify, apparently git revert doesn't have the --no-verify subcommand.

git revert does have a --no-commit subcommand but this doesn't work in combination with --continue.

I ended up renaming the pre-commit file, but out of curiosity. Is there any better wat to bypass pre-commit hooks at that point?

Geert van Dort
  • 986
  • 8
  • 6
  • 1
    had the same issue too and resolved it like you: I created a file `hooks.sh` that takes one argument: `enable` or `disable`. When feeding `disable`, I take my pre-commit hook and rename it to `pre-commit.disabled`. Once done, I call `./hooks.sh enable` which renames the file back to `pre-commit` – eckes Sep 14 '15 at 10:27
  • Yeah, the only option is to delete the hooks directory, do the git revert --continue and then do git reset --hard HEAD. – kboom Mar 18 '18 at 15:10
  • 1
    You could also just temporarily turn off your git hooks: `git git config core.hooksPath ""` and then after you're done with the `revert --continue`, turn it back on with `git config core.hooksPath hooks/` (assuming your hooks path is `/hooks`). This won't work if you just want to turn off the precommit hook (and want your postcommit hook to still run, for example). – combinatorist Apr 13 '18 at 17:29

2 Answers2

24

Changing the hooks

If you are able to change the hooks, you can just add a toggle for each one. Or just use a script to temporarily rename a given hook, as commented.

Either way will selectively skip the problematic hook while letting the other ones run normally. This ensures that other checks occur (if they exist), such as a commit message validation with the commit-msg hook.

Committing

If that does not apply, there is an alternative:

Usually, when an operation is stopped by a conflict, after fixing it you can just run

git commit

instead of

git $operation --continue

This applies to revert, merge, cherry-pick and possibly others (although in rebase it might behave differently, since it is a sequence of operations).

So, as noted, to bypass the hooks, you can just add --no-verify:

git commit --no-verify

Note: The feature above seems to be undocumented, but it WorksForMe(tm).

From a diff of strace git commit and strace git revert --continue, the former does a lot of other things (515 vs 173 lines, respectively), such as checking if a rebase is in progress and creating some temporary files in $GIT_DIR/objects. Example:

stat(".git/MERGE_HEAD", 0x7ffefb5d0760) = -1 ENOENT (No such file or directory)
stat(".git/rebase-apply", 0x7ffefb5d0620) = -1 ENOENT (No such file or directory)
stat(".git/rebase-merge", 0x7ffefb5d0620) = -1 ENOENT (No such file or directory)
stat(".git/CHERRY_PICK_HEAD", 0x7ffefb5d0760) = -1 ENOENT (No such file or directory)
stat(".git/BISECT_LOG", 0x7ffefb5d0620) = -1 ENOENT (No such file or directory)
stat(".git/REVERT_HEAD", {st_mode=S_IFREG|0644, st_size=41, ...}) = 0
lstat(".git/REVERT_HEAD", {st_mode=S_IFREG|0644, st_size=41, ...}) = 0
openat(AT_FDCWD, ".git/REVERT_HEAD", O_RDONLY) = 4

But the result appears to be same: They open up the editor with the git-generated message (e.g.: "This reverts commit [...]") and commit after exiting. I have used the alternative form multiple times and never had any problems at least (by the way, I probably discovered it under the same scenario).

kelvin
  • 1,421
  • 13
  • 28
7

There is the possibility to check inside of your pre-commit hook, if you are in a certain state. Based on that check you can abort the script. The following commands will return a hash when they are in a state like that, respectively, inside a revert, merge and rebase:

git rev-parse -q --verify REVERT_HEAD
git rev-parse -q --verify MERGE_HEAD
git rev-parse -q --verify REBASE_HEAD

This is how I use two of them in my pre-commit hook:

#!/bin/sh

IN_MERGE=$(git rev-parse -q --verify MERGE_HEAD)
if [ "$IN_MERGE" != "" ]
then
    exit 0;
fi

IN_REBASE=$(git rev-parse -q --verify REBASE_HEAD)
if [ "$IN_REBASE" != "" ]
then
    exit 0;
fi
Daan
  • 7,685
  • 5
  • 43
  • 52