如果存在合并冲突,如何让 git 自动打开合并工具?
Posted
技术标签:
【中文标题】如果存在合并冲突,如何让 git 自动打开合并工具?【英文标题】:How do I make git automatically open the mergetool if there is a merge conflict? 【发布时间】:2012-04-19 09:49:19 【问题描述】:如何让 git 针对任何合并冲突自动运行 git mergetool
?这应该适用于所有合并,使用 merge
、rebase
、pull
等。
【问题讨论】:
也许你可以使用githook,例如post-checkout
(不知道是不是真的在合并的时候调用了。post-merge
需要合并成功)
@TobiasKienzler 您可能正在做某事。如果你能找到一个可行的解决方案,我会给你这个问题的赏金。
@QuinnStrahl 我认为目前不存在一个在导致合并的各种命令之前执行的钩子,因此rospov's wrapper 可能是最简单的解决方案。或者修改 git 源以实现 pre-merge
钩子功能,在这种情况下,您当然可以简单地让 git run mergetool 发生冲突,这取决于配置设置......
嗯,好的。谢谢您的帮助。我想我会提交一个补丁。
@QuinnStrahl 如果你现在已经提交了补丁,我会很感激这里的链接:)
【参考方案1】:
你不能(还)让 git 这样做。
这可能是也可能不是可接受的解决方法。
在您的~/.bashrc
中创建一个函数:
git()
if [[ $1 == "merge" ]] || [[ $1 == "rebase" ]] || [[ $1 == "pull" ]]; then
command git "$@"
rc=$?
if [[ $rc == 1 ]]; then
echo "There are conflicts, better run git-mergetool!!!"
# There might be some other condition that returns a '1',
# if so you can add another check like this:
# if grep Conflicts $(git --git-dir)/MERGE_MSG;
command git mergetool
fi
else
command git "$@"
fi
合并时不调用 Mergetool:
$ git merge non_conflicting_branch
Merge made by the 'recursive' strategy.
bar | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 bar
发生冲突时调用Mergetool:
$ git merge conflicting_branch
Auto-merging foo
CONFLICT (content): Merge conflict in foo
Automatic merge failed; fix conflicts and then commit the result.
There are Conflicts, better run git-mergetool!!!
Mergetool 不会因其他错误而被调用:
$ git merge adasds
fatal: adasds - not something we can merge
【讨论】:
这不是让git自动打开mergetool,而是让shell来做。 为什么投反对票?这本质上是实现 rosipov 答案的一种更简洁的方式。 如何清洁?您缺少某些类型的冲突(例如git stash pop
)。因为他不按命令过滤,所以这不是问题。正如您自己注意到的那样,当前代码将在任何状态为 1 的错误上启动 git mergetool
。
我不能确定是否有任何其他错误,返回值为 1 的命令,因为 git 返回值通常没有记录。不过,我还没有找到一个不是合并冲突的。
@QuinnStrahl git (还)不能做到这一点,那么通过 shell 完成它是一个错误的答案吗?【参考方案2】:
你总是可以使用别名
alias 'git-merge'='git merge && git mergetool'
alias 'git-rebase'='git rebase && git mergetool'
alias 'git-pull'='git pull && git mergetool'
和/或按照这些思路编写一个帮助脚本
#/bin/bash
git $*
[ "$(git ls-files –abbrev –unmerged | wc -l)" -gt 0 ] && git mergetool
然后
alias git='~/.git/git-script'
没有直接调用mergetool的方法,因为它只是几种合并方法中的一种(参见man 1 git-merge中的“HOW TO RESOLVE CONFLICTS”)。
【讨论】:
正如我所提到的,如果有冲突,我只想打电话给mergetool
。 “合并的几种方法中只有一种”的论点没有说服力。是的,有多种方式,但选择一种作为默认方式是很合理的。
如果没有冲突,git mergetool 不会做任何事情。【参考方案3】:
据我所知,没有瓷器可以做到这一点。
您可以像这样围绕 git 进行包装(文件 git_mergetool.sh
,在您的路径上,+x
):
#!/bin/bash
SEARCH="CONFLICT"
OUTPUT=$(git "$@" 2>&1 | tee /dev/tty)
if `echo $OUTPUT | grep -i "$SEARCH" 1>/dev/null 2>&1`
then
git mergetool
fi
然后添加别名:
echo alias git=\"git_mergetool.sh\" >> ~/.bashrc
每次调用 git 时,包装器都会检查是否弹出“冲突”一词。如果是 - 包装器启动合并工具。
这可以通过向$SEARCH
添加更精确的短语来改进(例如“自动合并失败;修复冲突然后提交结果。”)以及检查第一个参数 ($1
) 是否在列表中导致合并冲突的命令(pull
、merge
等...)。否则如果 git 命令输出太长,你最终会解析很多不必要的数据。
【讨论】:
是否可以不有效地给 git 起别名? @QuinnStrahl 您可以将脚本命名为git
(不带文件扩展名)并在实际 git 可执行文件之前放入您的路径。但这几乎只是另一种混叠方式。所以不,我不知道没有别名 git 的方法。
应该有点可行,但 CONFLICT 正则表达式需要改进。我认为它目前会在任何地方捡起它,即使在例如差异输出。至少您可以按行位置(例如锚点)进行过滤,并且可以扩展文本。以上是关于如果存在合并冲突,如何让 git 自动打开合并工具?的主要内容,如果未能解决你的问题,请参考以下文章