确定两个Git分支是否已经分叉。

5
我想确定两个Git分支是否已经发生了分歧,或者其中一个分支是否可以简单地快速向另一个分支合并。
换句话说,我想检查其中一个分支的当前HEAD是否在某个时刻被合并到另一个分支中,或者它是否包含在另一个分支中不存在的提交。
是否有方法在不实际合并两个分支的情况下完成这个操作?在这种情况下,简单的git diff无法帮助。
4个回答

6
你可以使用git merge-base命令。
这个命令的详细说明可以在这里找到。

1
并完成它:m="$(git merge-base b1 b2)"; test "$m" = "$(git rev-parse b1)" -o "$m" = "$(git rev-parse b2)"; - jørgensen
还可以尝试执行命令 git merge-base --is-ancestor origin/main main; echo $? 来判断 origin/main 是否为 main 的祖先(即主分支是否已经发生了分叉)。 - Hritik

4
我正在使用以下Shell脚本片段实现这个目的:
git_is_merged () {
    local revlist
    if revlist=$(git rev-list -1 "$1" --not "$2"); then
        if [ "$revlist" = "" ]; then
            echo "'$1' IS merged into '$2'."
        else
            echo "'$1' is NOT merged into '$2'."
        fi
    fi
}

alias gim='git_is_merged'

使用像gim origin/devel origin/master这样的命令来确定是否将origin/devel合并到origin/master中。

编辑:为了完整起见,如果您只使用命名分支,则还可以使用以下命令:

git branch --contains origin/devel | grep -q origin/master && echo "Merged" || echo "Not merged"

或者

git branch --merged origin/master | grep -q origin/devel && echo "Merged" || echo "Not merged"

为了相同的目的。

非常好 :) 我正在尝试使用 git for-each-ref | grep $(git merge-base <branch1> <branch2>),并考虑编写一个 shell 函数,但是您的解决方案肯定更加简洁。 - Danilo Bargen
@sschuberth 抱歉,我不是故意在建议编辑时踩你的脚。当你已经有一个函数时,就没有必要再创建别名了。在函数内部不使用local关键字意味着revlist变量在执行后仍然存在于环境中。而且,如果不对$1/$2参数进行引用,可能会导致出现奇怪的分支名称,这些名称仍然是有效的,并且被Git允许;包括分号、引号等。我想这些都是审稿人批准此次编辑的原因。 - ReenignE
@ReenignE 不用担心。我很感激那些能够带来明显价值的编辑,但在这种情况下,价值对我来说并不清晰(这一次是我不想踩你的脚了)。也许这只是因为我对Bash的中级知识。我故意使用这个“多余”的别名来强调gim的含义。但现在我看到了引用参数和有一个本地变量的价值,并已相应地调整了我的答案。谢谢。 - sschuberth
@sschuberth 我的想法是,从这样的代码中学习的人可能不会意识到函数可以直接调用。我同意仅仅将函数命名为gim并不容易阅读。你认为在函数上方加上描述性文本的注释会更好吗? - ReenignE
@sschuberth 对不起,它对你有用吗?对我来说似乎仍然有效。对于你来说,它的archive.org链接是否有效?https://web-beta.archive.org/web/20170115010427/http://mywiki.wooledge.org/BashPitfalls#function_foo.28.29 - ReenignE
显示剩余3条评论

4
如果可以简单快速地合并,git merge --ff-only otherbranch 将会成功。(如果不行,它将被拒绝而不是创建一个合并提交。)

0
如果你想要一个图形界面工具,可以使用 gitk branch1 branch2。这样你也可以检查需要的不同提交记录。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接