我设置了一些 git hooks 在预提交时运行一些
gulp
命令。我基本上运行jshint
/plato
。我基本上想在两种情况下绕过这些:
plato gulp 命令对源运行分析并生成一个 /reports/ 目录,用于跟踪一段时间内的复杂性。如果我们在修补程序分支上执行此操作,则在将它们合并回开发时会导致合并冲突。这里说得够多了,简单的钩子:
#!/bin/sh
if git diff --cached --name-only --diff-filter=ACM | grep '.js$' >/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
现在的问题是,如果我在“报告”上存在合并冲突,并且我解决了合并
All conflicts fixed but you are still merging.
,然后提交,它再次运行分析并暂存提交,当它提交时,它会抛出错误:
/Users/Nix/work/project/.git/modules/somesubmodule/MERGE_HEAD'供阅读:没有这样的文件或目录。
目录确实存在,但没有合并头...
所以我刚刚找到了一个我认为可以用来检测“merge_head”的命令
git rev-parse -q --verify MERGE_HEAD
如果 rev-parse 返回一个哈希值,则意味着我们当前处于合并状态。我可以用它来绕过这个逻辑。但会等待更有经验的人提供更好的建议。
正如这个相关答案中提到的,您可以测试
$GIT_DIR/MERGE_HEAD
是否存在来检测合并提交:
这就是你得到的:
如果您使用
修改合并提交,则预提交挂钩会照常运行,但它无法真正检测到此 正在发生。新的提交将是合并,但你无法判断。git commit --amend
如果您使用常规旧
来创建非合并提交,则文件git commit
将不存在于git目录中,并且 你可以看出这不会创建合并提交。MERGE_HEAD
如果您使用
来完成冲突的合并,则文件git commit
将存在,您可以知道这将 创建合并提交。MERGE_HEAD
如果你正在运行
并且它自己成功了,它会在不使用预提交钩子的情况下进行新的提交,所以你甚至不会得到 在这里调用。git merge
因此,如果您愿意允许
合并到 失火,你可以接近你想要的:只需测试 是否存在git commit --amend
来看看这是否是一个$GIT_DIR/MERGE_HEAD
正在完成冲突的合并。 (使用git commit
是一个技巧 即使命令在 git 树之外运行,也能使其正常工作。 Git 设置$GIT_DIR
以便挂钩 git 命令能够正常工作。)$GIT_DIR
########################
# Setup Some Variables #
########################
REPO_ROOT_REL=$( git rev-parse --show-toplevel )
REPO_ROOT="$( cd "$REPO_ROOT_REL" >/dev/null 2>&1 ; pwd -P )"
####################################################
# Check for merge or rebase commit and abort if so #
####################################################
set +e
MERGE_HASH=$( git rev-parse -q --verify MERGE_HEAD 2> /dev/null)
set -e
if [ ! -z "$MERGE_HASH" ]; then
echo "This appears to be a merge commit ($MERGE_HASH). Avoiding pre-commit steps."
echo ""
echo "EXITING ${0##*/}"
exit 1
fi
REBASE_APPLY_PATH="${REPO_ROOT}/.git/rebase-apply"
REBASE_MERGE_PATH="${REPO_ROOT}/.git/rebase-merge"
if [ -e "${REBASE_APPLY_PATH}" ] || [ -e "${REBASE_MERGE_PATH}" ]; then
echo "This appears to be a rebase commit (.git/rebase-apply or .git/rebase-merge exists). Avoiding pre-commit steps."
echo ""
echo "EXITING ${0##*/}"
exit 1
fi