是否有可能确定两个git分支是否会干净地合并而不影响工作目录?

And*_*rew 25 git

如果可以快进,你可以用git merge-base来确定,但是有没有一些git技巧来确定两个分支是否会与一些策略完全合并而不实际进行合并?我知道git merge --no-commit --no-ff $BRANCH但这影响了工作目录,我想避免,因为这是webservice的一部分.

kra*_*lyk 29

我是通过创建第三个临时分支来实现的.假设您要将分支合并branchFrombranchTo.它会像这样:

git checkout branchTo    #only if not already at branchTo
git checkout -b branchTmp
git merge branchFrom
# see what happens
git checkout branchTo
git branch -d branchTmp
# act accordingly
Run Code Online (Sandbox Code Playgroud)

这样,您可以获得准确的结果,而无需拧紧任何分支.

  • 这肯定会影响工作目录。 (2认同)

Cas*_*bel 9

没有内置的方式; 执行合并需要工作树.看看合并是否有效(在一般情况下)意味着尝试策略并看看会发生什么.

但是,您可以检查一些简单的情况:两个分支不会触及相同的文件.找到合并基础,然后检查是否git diff --name-only $merge_base branchAgit diff --name-only $merge_base branchB什么共同点.

否则,您将需要一个工作树来尝试合并.您可以轻松地创建第二个 - 克隆存储库,或者为了节省空间,只需创建一个工作树.将git-new-workdir(从git.git的的contrib目录)脚本可以在这方面帮助; 它创建一个新的repo,其.git目录中充满了符号链接,返回原始的符号链接.请注意,在新的工作目录中,您不会修改原始仓库已检出的分支 - 它们将不同步,就像推入当前已检出的分支一样混乱.

  • 另一个微不足道的情况是其中一个分支包含另一个分支.您可以使用`git branch --contains branchB'来检查当前分支是否完全包含`branchB`分支. (3认同)

Idr*_*ada 7

TLDR

假设您的合并'目标'已签出,即HEAD您的合并'来源'是$BRANCH:

git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
Run Code Online (Sandbox Code Playgroud)

细节

假设您的合并'目标'已签出,即HEAD您的合并'来源'是$BRANCH,首先"找到合并时尽可能好的共同祖先":

git merge-base $BRANCH HEAD
Run Code Online (Sandbox Code Playgroud)

以上应该输出提交的哈希值; 称之为价值$merge_base.

接下来,"显示三向合并而不触及索引":

git merge-tree $merge_base HEAD $BRANCH
Run Code Online (Sandbox Code Playgroud)

上面应该输出"平凡的合并结果和标准输出的冲突阶段".

如果HEAD已经是最新的,$BRANCH则应该没有输出.

如果存在合并冲突,则输出应包含Git冲突标记.您可以使用以下命令确定是否有任何命令:

git merge-tree $merge_base HEAD $BRANCH | grep "^<<<<<<<"
Run Code Online (Sandbox Code Playgroud)

您还可以查找"两者都已更改"的文本:

git merge-tree $merge_base HEAD $BRANCH | grep "changed in both"
Run Code Online (Sandbox Code Playgroud)

所有上述命令都作为(Bash)单行:

git merge-tree `git merge-base $BRANCH HEAD` HEAD $BRANCH | grep "^<<<<<<<\|changed in both"
Run Code Online (Sandbox Code Playgroud)

这是根据这个问题的答案改编的:

  • 上面的答案可以引导你到一个非常强大的单行,在这里我通过jakub.g提供关于答案的一个评论摘要.假设你在分支`master`上,你想检查`git merge origin/devel`是否有效.然后就做:`git merge-tree \`git merge-base origin/devel master \`master origin/devel`.但是这一行比它看起来更强大,因为你也可以在未检出的分支上执行此操作.强大! (2认同)