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

问题描述 投票:0回答:3

我设置了一些 git hooks 在预提交时运行一些

gulp
命令。我基本上运行
jshint
/
plato
。我基本上想在两种情况下绕过这些:

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

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'供阅读:没有这样的文件或目录。

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

git git-submodules githooks
3个回答
39
投票

所以我刚刚找到了一个我认为可以用来检测“merge_head”的命令

 git rev-parse -q --verify MERGE_HEAD

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


4
投票

正如这个相关答案中提到的,您可以测试

$GIT_DIR/MERGE_HEAD
是否存在来检测合并提交:

这就是你得到的:

  • 如果您使用

    git commit --amend
    修改合并提交,则预提交挂钩会照常运行,但它无法真正检测到此 正在发生。新的提交将是合并,但你无法判断。

  • 如果您使用常规旧

    git commit
    来创建非合并提交,则文件
    MERGE_HEAD
    将不存在于git目录中,并且 你可以看出这不会创建合并提交。

  • 如果您使用

    git commit
    来完成冲突的合并,则文件
    MERGE_HEAD
    将存在,您可以知道这将 创建合并提交。

  • 如果你正在运行

    git merge
    并且它自己成功了,它会在不使用预提交钩子的情况下进行新的提交,所以你甚至不会得到 在这里调用。

因此,如果您愿意允许

git commit --amend
合并到 失火,你可以接近你想要的:只需测试 是否存在
$GIT_DIR/MERGE_HEAD
来看看这是否是一个
git commit
正在完成冲突的合并。 (使用
$GIT_DIR
是一个技巧 即使命令在 git 树之外运行,也能使其正常工作。 Git 设置
$GIT_DIR
以便挂钩 git 命令能够正常工作。)


0
投票
########################
# 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
© www.soinside.com 2019 - 2024. All rights reserved.