如何快速检查哪个Git分支是最新的?

4
例如,如果在git上有4个分支,就像这样:

branch1
branch2* (current branch)
branch3 (newest commits here)
master (oldest)

我的问题是:

  • 我如何从git命令行检查当前分支是否是最新的?如果不是,哪个分支是最新的?我的意思是哪个分支包含最新的提交?

  • 如何列出此git存储库中所有比我的分支更新的提交(在任何分支中),而不必切换到其他分支?


2
“最新的分支”是指最近的提交记录所在的分支(简单),还是指最后创建的分支(较难)? - jub0bs
我的意思是包含“最新提交”的分支,而不是其创建日期。 - TaoPR
1
根据@Josue Abarca的答案,我现在找到了解决方法。我可以简单地运行git log --oneline --decorate --all 72bb..,其中72bb是当前分支的最新提交哈希值。这将列出所有其他分支中的更新提交。 :) - TaoPR
1
如果你只对可以从分支中到达的提交感兴趣,那么你应该使用 --branches 而不是 --all,因为后者还列出了可以从存储和标签中到达的提交。 - jub0bs
很有帮助。非常感谢您的建议。 - TaoPR
2个回答

5

编辑: 您可以在我的GitHub代码库中找到相关的shell脚本。

哪个分支是最新的?

[...] 哪个分支是最新的?我的意思是哪个分支包含了最新的提交?

我理解为:

在所有本地分支中,找到其端点最近(例如按提交者日期等方面)的分支。

git for-each-ref命令非常有用;阅读其手册页绝对值得您花费时间。

命令

让我们逐步构建所需的命令...

  1. This first command prints a list of the (short) names of all the local branches.

    git for-each-ref --format='%(refname:short)' \
                     refs/heads
    
  2. This next command does the same thing, but sorts the results by committer date, in descending order (note the -):

    git for-each-ref --sort='-committerdate'     \
                     --format='%(refname:short)' \
                     refs/heads
    
  3. This next command does the same as the previous one, but restrict the output to just one entry:

    git for-each-ref --count=1                   \
                     --sort='-committerdate'     \
                     --format='%(refname:short)' \
                     refs/heads
    

总之,现在我们有一个命令可以打印最近(按提交者日期计算)分支引用的(短)名称:正是我们想要的。太好了!

将其定义为别名

为了方便起见,让我们定义一个基于它的别名(下面称为newest-branch):

git config --global alias.newest-branch "for-each-ref --count=1 --sort='-committerdate' --format='%(refname:short)' refs/heads"

健全性检查

现在,让我们在Git项目仓库中运行一些测试:

$ git branch
  maint
* master
  next
  pu
$ git newest-branch
pu

# Now print the list of all branches and the committer date of their tips
$ git for-each-ref --sort='-committerdate' \
                   --format="%(refname:short)%09%(committerdate)"
                   refs/heads
pu      Tue Mar 17 16:26:47 2015 -0700
next    Tue Mar 17 16:14:11 2015 -0700
master  Tue Mar 17 16:05:12 2015 -0700
maint   Fri Mar 13 22:57:25 2015 -0700

pu确实是最新的分支。耶!


当前分支是最新的吗?

很简单,现在我们有了newest-branch的别名; 我们只需要比较当前分支的名称和最新分支的名称即可。(为了更加稳健,您可能需要使用完整的引用名称而不是短名称)。

命令

当前分支的(短)名称如下:

$ git symbolic-ref --short HEAD
master

让我们将其与最新的分支进行比较,然后打印yes如果当前分支是最新的,否则打印no

if [ $(git newest-branch) = $(git symbolic-ref --short HEAD) ]; then
    printf "yes\n"
else
    printf "no\n"
fi

将其定义为别名

太好了!为了方便起见,我们也可以将其定义为一个别名(以下称为isnewest):

git config --global alias.isnewest '! if [ $(git newest-branch) = $(git rev-parse --abbrev-ref HEAD) ]; then printf "yes\n"; else printf "no\n"; fi'

健全性检查

(我们已经知道,从之前的健全性检查中,pu是最新的分支。)

$ git branch
  maint
* master
  next
  pu
$ git isnewest 
no
$ git checkout pu
Switched to branch 'pu'
Your branch is up-to-date with 'origin/pu'.
$ git isnewest
yes
$ git checkout maint
Switched to branch 'maint'
Your branch is up-to-date with 'origin/maint'.
$ git is-newest-branch 
no

看起来可以工作 (•_•) ( •_•)>⌐■-■ (⌐■_■)


如何列出此git仓库中(在任何分支中)所有新于我的分支的提交,而不必切换到当前分支以外的其他分支?

如果您指的是某个日期之后的较新提交,则这是一个难题。在最坏的情况下,您将不得不探索整个DAG,因为Git不禁止父级具有比其子级更近的日期。如果您是按拓扑顺序排序,则要容易得多:

git log --branches HEAD..

--branches标志限制输出仅包括可从至少一个refs/heads引用到达的提交。)当然,您可以通过添加一些美化标志,如--oneline--decorate等来调整该命令的输出。

1
你的解决方案真棒。无论是shell脚本还是git别名都非常出色!在这种情况下,我更喜欢使用git别名解决方案。 - TaoPR
@TaoP.R.请看我的修改。我认为我的新方法更好。 - jub0bs
你真是个 Git 专家!这个命令非常有效,但我刚刚用一个特殊情况测试了一下:假设 [pu] 是最新的分支,我们从它创建了一个新的分支 [pu2]。显然,[pu] 和 [pu2] 在代码状态上是相同的,但只有 [pu] 被认为是最新的。听起来很奇怪,是吗?(@_@) - TaoPR
@TaoP.R. 谢谢,但我仍在每天学习Git :) 关于您的评论,如果日期相同,则词典顺序会接管。在您的示例中,pu2在词典顺序中排在pu之后,因此列出了pu。但是,如果您使用一个分支pt(在词典顺序中排在pu之前),则pt将被列为最新的分支。 - jub0bs
你的解释对我来说很有道理。对于这种情况,我认为有一个简单的解决方法。当我发现pu2不是最新的分支时,我可以通过git diff $(git newestbranch)查看它之后的更改,从而意识到它已经与最新的分支相同了。 - TaoPR

3

您可以使用:

git log --decorate --all --oneline --graph

来源: man git log

  • --decorate: 打印显示的任何提交的引用名称。
  • --all: 假装所有refs/中的引用都被列在命令行上作为<commit>。
  • --oneline: 这是--pretty=oneline --abbrev-commit的缩写,两者一起使用。
  • --graph: 在输出左侧绘制基于文本的提交历史图形表示。

如果你想从远程仓库下载最新的对象和引用,请先执行git fetch

git fetch origin

此外,以下命令:
gitk

可以帮助您在一个简单的图形界面中查看所有提交和引用。

这个命令确实非常有用,但它并没有直接回答问题。 - jub0bs
哦,我其实已经尝试过 git log --decorate --oneline --graph,但它只显示当前分支中的提交。我刚刚意识到参数 --all 能够帮助我查看所有提交,无论它们是否在当前分支上。非常有用。 - TaoPR
@TaoP.R.(您可以为您认为有用的答案投票。) - jub0bs
1
--simplify-by-decoration --date-order 添加到日志命令中,这仍然不能排除所有标签,但已经接近了。编辑:哦,还要去掉 graph,我认为那可能会影响日期排序。 - jthill
1
@jthill 你可以使用 --branches 而不是 --all 来仅考虑从分支可达的提交。 - jub0bs

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