如何检查两个分支是否 "even"?

How can I check whether two branches are "even"?

GitHub 网络界面有一个很好的功能,告诉我一个分支是否与 master 分支相等。

是否有与此功能等效的命令行?我使用多个存储库,我正在寻找一种快速方法来查看分支是否均匀或需要注意。

这里是 GitHub 网络界面的截图,对于那些想知道这个功能的人:

要将位于 GitHub 上名为 branch 的分支的 文件 与同一存储库中的 master 进行比较,您可以使用 git diff:

git diff origin/branch origin/master

以下将比较两个分支之间的提交

git log --left-right --graph --cherry-pick --oneline origin/branch...origin/master

正如我在上面的评论中提到的,两个分支可能有相同的文件但有不同的提交。

比较提交哈希值

如果要检查两个分支是否完全等价,只需比较提交哈希:

-> git branch -v
  master                       0ccca51 Commencing the awesome
                               ^^^^^^^

-> git fetch
-> git branch -v -r
  origin/master                0ccca51 Commencing the awesome
                               ^^^^^^^
  origin/other                 0ccca51 Commencing the awesome
                               ^^^^^^^

如果提交哈希匹配 - 分支既不领先也不落后,它们完全相同。

Git集线器术语

Branch A and branch B are even.

是Git

的中心用语

Branch A and Branch B point to the same commit.

这两个分支是偶数吗?

如果您只对两个分支是否感兴趣,没有任何额外的细节(例如提交计数),脚本友好的方法是简单地测试他们的平等技巧的 SHA:

[ "$(git rev-parse <refA>)" = "$(git rev-parse <refB>)" ]

执行运行这条命令后,如果<ref1><ref2>是偶数,$?的值为0,否则为1 .因为此命令仅涉及管道 Git 命令 git-rev-parse,所以可以安全地以编程方式使用它。

一个分支是在另一分支之前还是之后?

如果您想模拟 GitHub 的功能,例如打印

foo is n commits ahead of bar

等,可以使用如下脚本:

#!/bin/sh

# git-checkeven.sh
#
# Check whether two revisions are even, and, otherwise, to what extent
# the first revision is ahead of / behind the second revision
#
# Usage: git checkeven <revA> <revB>
#
# To make a Git alias called 'checkeven' out of this script,
# put the latter on your search path, and run
#
#   git config --global alias.checkeven '!sh git-checkeven.sh'

if [ $# -ne 2 ]; then
    printf "usage: git checkeven <revA> <revB>\n\n"
    exit 2
fi

revA=
revB=

nA2B="$(git rev-list --count $revA..$revB)"
nB2A="$(git rev-list --count $revB..$revA)"

if [ "$nA2B" -eq 0 -a "$nB2A" -eq 0 ]; then
  printf "$revA is even with $revB\n"
  exit 0
elif [ "$nA2B" -gt 0 ]; then
  printf "$revA is $nA2B commits behind $revB\n"
  exit 1
else
  printf "$revA is $nB2A commits ahead of $revB\n"
  exit 1
fi

测试

假设玩具回购具有以下历史记录:

... -- * [release71]
        \
         * [master, develop]

然后,在定义一个名为 checkeven 的 Git 别名来调用上面的脚本之后,您会得到...

$ git checkeven release71 develop
release71 is 1 commits behind develop
$ git checkeven develop release71
develop is 1 commits ahead of release71
$ git checkeven master develop
master is even with develop

您可以使用 git branch --remotes --list --all -vv 检查本地和远程所有分支的相等性,这将向您显示所有分支及其所在位置。在我的回购协议中,您可以看到它们都是@ 1ba393b

git branch --remotes --list --all -vv

* Develop              1ba393b [origin/Develop] Merge remote-tracking branch into Master
Master                 1ba393b [origin/Master] Merge remote-tracking branch into Master
Release                1ba393b [origin/Release] Merge remote-tracking branch into Master
remotes/origin/Develop 1ba393b Merge remote-tracking branch into Master
remotes/origin/HEAD    -> origin/master
remotes/origin/Master  1ba393b Merge remote-tracking branch into Master
remotes/origin/Release 1ba393b Merge remote-tracking branch into Master

正如其他人所暗示的,您可以将其变成 git 别名。我很少使用 bash 我在 windows 命令或 PowerShell 中操作。以下在那里工作。您的环境可能需要少量的语法来执行“更多信息”link 至 SO post 下面将讨论其中的一些内容。在 git 中创建别名与脚本或批处理相比意味着无论 shell 您使用什么,别名都可用。

git config --global alias.equal '!git branch --remotes --list --all -vv' 

将使您成为通过 git equal 别名进行相等性检查的捷径。equal 可能是别名。{anyAvailable}。 More Info.

hth

简答

if [ $(git rev-parse develop) == $(git rev-parse feature/SPRINT_WSMR_UPDATES) ]; 
then 
    echo "branches are the same"
fi

说明

git rev-parse develop 将 return 分支的哈希值。

# git rev-parse develop
c400a9bfb08458f693a1cd05cf7999f6c5b523d2

您可以使用散列来比较两个分支。当您在分支相同的情况下使用子模块做一些特殊的事情时,这会很有趣。例如,如果所有子模块的特性分支都相同,你想切换到开发分支....

与子模块一起使用

git submodule foreach '[ $(git rev-parse develop) == $(git rev-parse feature/SPRINT_WSMR_UPDATES) ] && git checkout develop || : '

分解

  • git submodule foreach 'cmd' 将在每个子模块中 运行 cmd
  • [ $(git rev-parse develop) == $(git rev-parse feature/SPRINT_WSMR_UPDATES) ]检验“开发的真假” 哈希匹配特征的哈希?”。
  • && git checkout develop 只会 运行 如果事实陈述是 是的。
  • || : 确保整个命令 return 为真,这样 foreach分支不同时命令不会终止。