我如何 "resume" 一个由于合并冲突而中止的 post-merge hook?

How can I "resume" a post-merge hook that was aborted due to merge conflicts?

我有一个 post-merge git 部分基于 https://gist.github.com/sindresorhus/7996717 的挂钩。正如预期的那样,如果拉取引入合并冲突,挂钩将无法 运行。

我应该如何处理合并冲突,以便我的挂钩可以 运行 按需要进行?我的钩子依赖于差异。如果我手动解决冲突并提交更新,我将不再有任何差异,因此挂钩中的逻辑不再相关。

这是关键所在(尽管我认为如果一开始就存在冲突,这里的内容并不重要)

#!/bin/sh
echo "[post-merge] Commit done."
DIFFS="$(git diff-tree -r --name-only --no-commit-id HEAD@{1} HEAD)"
BLUE='3[0;34m'
GRN='3[0;32m'
NC='3[0m' # No Color
# Git hooks are not designed to be interactive. By default they don't have access to $stdin. 
# which meant that normal use of `read` was not working when used within the context of a git hook.
# This line restores keyboard access to stdin so that the dev can respond to the prompt that appears while the hook
# is running.
# Alternatively, we could forgo the confirmation and make package installation automatic, 
# though it seems better to allow dev to decide.

exec < /dev/tty

check_incoming() {
    #  is package.json 
    #  is handle_package_json
    echo "$DIFFS" | grep --quiet "" && eval ""
    exit 0
}

handle_package_json() {
    while true; do
    echo -e "${BLUE}[post-merge] PACKAGE.JSON UPDATED:${NC}"
    read -p "[post-merge] File may contain dependency updates. Run yarn install? (y/n) " yn
    if [ "$yn" = "" ]; then
        yn='Y'
    fi
    case $yn in
        [Yy] ) yarn install; break;;
        [Nn] ) echo "[post-merge] Installation deferred. You may need to manually update dependencies at a later point."; exit;;
        * ) echo "[post-merge] Please answer y or n for yes or no.";;
    esac
    done
}

if [[ -n "$DIFFS" ]]; then
    check_incoming package.json handle_package_json;    
fi

How might I go about handling the merge conflicts so that my hook can run as desired?

您不能通过钩子执行此操作,因为正如您所发现的那样,钩子永远不会 运行。

您需要做的是让用户调用您自己的命令而不是 运行ning git merge。让你的命令 运行 git merge 并检查结果(包括退出状态)来决定合并是否成功。

(请注意,这意味着他们也不能 运行 git pull,因为 git pull 运行 后跟 git fetch。你如果他们是喜欢 git pull 命令的那种人,可能需要为他们提供一个命令来替代 git pull。)

(顺便说一句,在 git merge 开始 package.json 之前检查 package.json 是否需要合并 似乎是有意义的:找到自己合并base,用git rev-parse提取三个hash ID,分别为HEAD:package.json<merge-base>:package.json<theirs>:package.json,如果hash ID匹配不匹配,可以甚至使用 git showgit cat-file -p 提取文件本身,以便在需要时进行合并前检查。如果所有三个哈希 ID 都匹配,则合并很简单:所有三个文件都相同并且 Git 将保持 package.json 不变。如果 merge-base 和他们的匹配,但 HEAD 不同,Git 将保持 HEAD 版本。如果 merge-base 和 HEAD匹配,但他们的不同,Git 将采用他们的版本。如果所有三个 匹配,Git 将尝试合并 json 数据作为如果它是面向行的纯文本,这很可能会产生废话。)