绕过合并提交的预提交挂钩

bypass pre-commit hook for merge commits

我设置了一些 git 挂钩以在预提交时运行一些 gulp 命令。我基本上运行jshint/plato。我基本上想在两种情况下绕过这些:

  1. 修补程序分支(主/修补程序)
  2. git 合并(或找到一种不会在合并提交情况下崩溃的方法)

plato gulp 命令对源代码运行分析并生成一个 /reports/ 目录,用于跟踪随时间变化的复杂性。如果我们在 hotfix 分支上这样做,在将它们合并回开发时会导致合并冲突。这里说的够多了,简单的钩子:

#!/bin/sh

if git diff --cached --name-only --diff-filter=ACM | grep '.js

现在的问题是,如果我在 "reports" 上有合并冲突,我解决合并 All conflicts fixed but you are still merging. 然后提交它再次运行分析并分阶段提交,当它提交时抛出一个错误:

/Users/Nix/work/project/.git/modules/somesubmodule/MERGE_HEAD' for reading: No such file or directory.

该目录确实存在但没有合并头...

>/dev/null 2>&1 then git stash -q --keep-index ./node_modules/.bin/gulp jshint RESULT=$? git stash pop -q [ $RESULT -ne 0 ] && exit 1 git stash -q --keep-index ./node_modules/.bin/gulp plato git add report/ git stash pop -q fi exit 0

现在的问题是,如果我在 "reports" 上有合并冲突,我解决合并 All conflicts fixed but you are still merging. 然后提交它再次运行分析并分阶段提交,当它提交时抛出一个错误:

/Users/Nix/work/project/.git/modules/somesubmodule/MERGE_HEAD' for reading: No such file or directory.

该目录确实存在但没有合并头...

所以我刚找到一个命令,我认为我可以用它来检测 "merge_head"

 git rev-parse -q --verify MERGE_HEAD

如果 rev-parse returns 一个散列,这意味着我们当前处于合并状态。我可以用它来绕过这个逻辑。但会等待更有经验的人提供更好的建议。

如本 中所述,您可以测试 $GIT_DIR/MERGE_HEAD 是否存在以检测合并提交:

Here's what you do get:

  • If you're using git commit --amend to amend a merge commit, the pre-commit hook is run as usual, but it can't really detect that this is happening. The new commit will be a merge, but you can't tell.

  • If you're using regular old git commit to create a non-merge commit, the file MERGE_HEAD will not exist in the git directory, and you can tell that this is not going to create a merge commit.

  • If you're using git commit to finish off a conflicted merge, the file MERGE_HEAD will exist, and you can tell that this is going to create a merge commit.

  • If you're running git merge and it succeeds on its own, it makes a new commit without using the pre-commit hook, so you don't even get invoked here.

Hence, if you're willing to allow git commit --amend on merges to misfire, you can get close to what you want: just test for the existence of $GIT_DIR/MERGE_HEAD to see if this is a git commit that is finishing off a conflicted merge. (The use of $GIT_DIR is a trick to make this work even if the commands are run outside the git tree. Git sets $GIT_DIR so that in-hook git commands will work right.)