如何获取按最近提交排序的 Git 分支列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5188320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get a list of Git branches, ordered by most recent commit?
提问by Joe White
I want to get a list of all the branches in a Git repository with the "freshest" branches at the top, where the "freshest" branch is the one that's been committed to most recently (and is, therefore, more likely to be one I want to pay attention to).
我想获取 Git 存储库中所有分支的列表,其中“最新鲜”的分支位于顶部,其中“最新鲜”的分支是最近提交的分支(因此,更有可能是一个分支)我要注意)。
Is there a way I can use Git to either (a) sort the list of branches by latest commit, or (b) get a list of branches together with each one's last-commit date, in some kind of machine-readable format?
有没有一种方法可以使用 Git 来 (a) 按最新提交对分支列表进行排序,或者 (b) 以某种机器可读的格式获取分支列表以及每个人的最后提交日期?
Worst case, I could always run git branch
to get a list of all the branches, parse its output, and then git log -n 1 branchname --format=format:%ci
for each one, to get each branch's commit date. But this will run on a Windows box, where spinning up a new process is relatively expensive, so launching the Git executable once per branch could get slow if there are a lot of branches. Is there a way to do all this with a single command?
最坏的情况是,我总是可以运行git branch
以获取所有分支的列表,解析其输出,然后git log -n 1 branchname --format=format:%ci
为每个分支获取每个分支的提交日期。但这将在 Windows 机器上运行,在那里启动一个新进程相对昂贵,因此如果有很多分支,每个分支启动一次 Git 可执行文件可能会变慢。有没有办法用一个命令来完成所有这些?
回答by Jakub Nar?bski
Use the --sort=-committerdate
option of git for-each-ref
;
使用--sort=-committerdate
选项git for-each-ref
;
Also available since Git 2.7.0for git branch
:
Basic Usage:
基本用法:
git for-each-ref --sort=-committerdate refs/heads/
# Or using git branch (since version 2.7.0)
git branch --sort=-committerdate # DESC
git branch --sort=committerdate # ASC
Result:
结果:
Advanced Usage:
高级用法:
git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
Result:
结果:
回答by Beau Smith
List of Git branch names, ordered by most recent commit…
Git 分支名称列表,按最近提交排序...
Expanding on Jakub's answerand Joe's tip, the following will strip out the "refs/heads/" so the output only displays the branch names:
扩展Jakub's answer和Joe's tip,以下内容将删除“refs/heads/”,因此输出仅显示分支名称:
Command:
命令:
git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'
Result:
结果:
回答by nikolay
Here's the optimal code, which combines the other two answers:
这是最佳代码,它结合了其他两个答案:
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'
回答by user1682406
Here is a simple command that lists all branches with latest commits:
这是一个简单的命令,它列出了具有最新提交的所有分支:
git branch -v
To order by most recent commit, use
要按最近的提交排序,请使用
git branch -v --sort=committerdate
Source: http://git-scm.com/book/en/Git-Branching-Branch-Management
来源:http: //git-scm.com/book/en/Git-Branching-Branch-Management
回答by dimid
I use the following alias:
我使用以下别名:
recent = "!r(){git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'}; r"
recent = "!r(){git for-each-ref --sort=-committerdate refs/heads --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)'|column -ts'|'}; r"
which produces:
它产生:
Use '|' to separate.
使用“|” 分开。
回答by Andy
I was able to reference the previous examples to create something that works best for me.
我能够参考之前的示例来创建最适合我的东西。
git for-each-ref --sort=-committerdate refs/heads/ --format='%(authordate:short) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))'
git for-each-ref --sort=-committerdate refs/heads/ --format='%(authordate:short) %(color:red)%(objectname:short) %(color:yellow)%(refname:short) )%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))'
回答by estani
I also needed colors, tags and remote references without any duplicates:
我还需要没有任何重复的颜色、标签和远程引用:
for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '! a[alias glist='for ref in $(git for-each-ref --sort=-committerdate --format="%(refname)" refs/heads/ refs/remotes ); do git log -n1 $ref --pretty=format:"%Cgreen%cr%Creset %C(yellow)%d%Creset %C(bold blue)<%an>%Creset%n" | cat ; done | awk '"'! a["'git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ct)"\t$REPLY"; done | sort -r | cut -f 2
'"]++'"
]++'
Because quoting can be hard, here is the alias for Bash:
因为引用可能很难,这里是 Bash 的别名:
git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ci $(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ci)" $REPLY"; done | sort -r | cut -d ' ' -f -1,4-
回答by John Mellor
The other answers don't seem to allow passing -vv
to get verbose output.
其他答案似乎不允许传递-vv
以获得详细输出。
So here's a one-liner that sorts git branch -vv
by commit date, preserving color etc:
所以这是一个git branch -vv
按提交日期、保留颜色等排序的单行:
2013-09-15 master da39a3e [origin/master: behind 7] Some patch
2013-09-11 * (detached from 3eba4b8) 3eba4b8 Some other patch
2013-09-09 my-feature e5e6b4b [master: ahead 2, behind 25] WIP
If you additionally want to print the commit date, you can use this version instead:
如果您还想打印提交日期,则可以改用此版本:
git branch -vv --color=always | while read; do
# The underscore is because the active branch is preceded by a '*', and
# for awk I need the columns to line up. The perl call is to strip out
# ansi colors; if you don't pass --color=always above you can skip this
local branch=$(echo "_$REPLY" | awk '{print }' | perl -pe 's/\e\[?.*?[\@-~]//g')
# git log fails when you pass a detached head as a branch name.
# Hide the error and get the date of the current head.
local branch_modified=$(git log -1 --format=%ci "$branch" 2> /dev/null || git log -1 --format=%ci)
echo -e "$branch_modified $REPLY"
# cut strips the time and timezone columns, leaving only the date
done | sort -r | cut -d ' ' -f -1,4-
Sample output:
示例输出:
git branch --sort=-committerdate
It's probably more readable split into multiple lines:
分成多行可能更易读:
# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch
This should also work with other arguments to git branch
, e.g. -vvr
to list remote-tracking branches, or -vva
to list both remote-tracking and local branches.
这也应该与 的其他参数一起使用git branch
,例如-vvr
列出远程跟踪分支,或-vva
同时列出远程跟踪和本地分支。
回答by VonC
git 2.7 (Q4 2015) will introduce branch sorting using directly git branch
:
See commit aa3bc55, commit aedcb7d, commit 1511b22, commit f65f139, ... (23 Sep 2015), commit aedcb7d, commit 1511b22, commit ca41799(24 Sep 2015), and commit f65f139, ... (23 Sep 2015) by Karthik Nayak (KarthikNayak
).
(Merged by Junio C Hamano -- gitster
--in commit 7f11b48, 15 Oct 2015)
git的2.7(2015年第4季度)将介绍分支直接使用排序git branch
:
见犯aa3bc55,提交aedcb7d,提交1511b22,提交f65f139,...(2015年9月23日),提交aedcb7d,提交1511b22,提交ca41799(2015年9月24日),和提交 f65f139,...(2015 年 9 月 23 日)由Karthik Nayak ( KarthikNayak
)。
(由Junio C gitster
Hamano合并-- --在提交 7f11b48 中,2015 年 10 月 15 日)
In particular, commit aedcb7d:
特别是,提交 aedcb7d:
branch.c
: use 'ref-filter
' APIs
branch.c
: 使用“ref-filter
” API
Make 'branch.c
' use 'ref-filter
' APIs for iterating through refs sorting. This removes most of the code used in 'branch.c
' replacing it
with calls to the 'ref-filter
' library.
使 ' branch.c
' 使用 ' ref-filter
' API 来迭代 refs 排序。这将删除“ branch.c
”中使用的大部分代码,将其替换为对“ ref-filter
”库的调用。
It adds the option --sort=<key>
:
Sort based on the key given.
Prefix-
to sort in descending order of the value.You may use the
--sort=<key>
option multiple times, in which case the last key becomes the primary key.The keys supported are the same as those in
git for-each-ref
.
Sort order defaults to sorting based on the full refname (includingrefs/...
prefix). This lists detached HEAD (if present) first, then local branches and finally remote-tracking branches.
根据给定的键排序。按值的降序排序的
前缀-
。您可以
--sort=<key>
多次使用该选项,在这种情况下,最后一个键将成为主键。支持的密钥与
git for-each-ref
.
排序顺序默认为基于完整引用名称(包括refs/...
前缀)进行排序。这首先列出分离的 HEAD(如果存在),然后是本地分支,最后是远程跟踪分支。
Here:
这里:
$ git branch --sort=objectsize
* (HEAD detached from fromtag)
branch-two
branch-one
master
Or (see below with Git 2.19)
或者(参见下面的 Git 2.19)
branch.sort:
See also commit 9e46833(30 Oct 2015) by Karthik Nayak (KarthikNayak
).
Helped-by: Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
--in commit 415095f, 03 Nov 2015)
另请参阅Karthik Nayak ( )提交的 9e46833(2015 年 10 月 30 日)。
帮助者:Junio C Hamano ( )。(由Junio C Hamano合并-- --在提交 415095f 中,2015 年 11 月 3 日)KarthikNayak
gitster
gitster
When sorting as per numerical values (e.g.
--sort=objectsize
) there is no fallback comparison when both refs hold the same value. This can cause unexpected results (i.e. the order of listing refs with equal values cannot be pre-determined) as pointed out by Johannes Sixt ($gmane/280117).Hence, fallback to alphabetical comparison based on the refname whenever the other criterion is equal.
当按数值排序时(例如
--sort=objectsize
),当两个 refs 保持相同的值时,没有后备比较。正如 Johannes Sixt ( $gmane/280117)所指出的那样,这可能会导致意外的结果(即无法预先确定具有相同值的引用的列表顺序)。因此,只要其他标准相等,就回退到基于 refname 的字母顺序比较。
branch.sort:
With Git 2.19, the sort order can be set by default.git branch
supports a config branch.sort
, like git tag
, which already had a config tag.sort
.
See commit 560ae1c(16 Aug 2018) by Samuel Maftoul (``).
(Merged by Junio C Hamano -- gitster
--in commit d89db6f, 27 Aug 2018)
在 Git 2.19 中,可以默认设置排序顺序。git branch
支持 config branch.sort
,例如git tag
,它已经有一个 config tag.sort
。
请参阅Samuel Maftoul (``) 的提交 560ae1c(2018 年 8 月 16 日)。
(由Junio C gitster
Hamano合并-- --在d89db6f 提交中,2018 年 8 月 27 日)
git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads
This variable controls the sort ordering of branches when displayed by
git-branch
.
Without the "--sort=<value>
" option provided, the value of this variable will be used as the default.
21 minutes ago nathan/a_recent_branch 6 hours ago master 27 hours ago nathan/some_other_branch 29 hours ago branch_c 6 days ago branch_d
当由 显示时,此变量控制分支的排序顺序
git-branch
。
如果不--sort=<value>
提供" " 选项,则此变量的值将用作默认值。
To list remote branches, use git branch -r --sort=objectsize
. The -r
flag causes it to list remote branches instead of local branches.
要列出远程分支,请使用git branch -r --sort=objectsize
. 该-r
标志导致它列出远程分支而不是本地分支。
With Git 2.27 (Q2 2020), "git branch
" and other "for-each-ref
" variants accepted multiple --sort=<key>
options in the increasing order of precedence, but it had a few breakages around "--ignore-case
" handling, and tie-breaking with the refname, which have been fixed.
在 Git 2.27(2020 年第 2 季度)中,“ git branch
” 和其他“ for-each-ref
” 变体--sort=<key>
以优先级递增的顺序接受了多个选项,但它在“ --ignore-case
”处理方面存在一些问题,并与 refname 打了平局,这些问题已得到修复。
See commit 7c5045f, commit 76f9e56(03 May 2020) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
--in commit 6de1630, 08 May 2020)
请参阅Jeff King ( ) 的commit 7c5045f和commit 76f9e56(2020 年 5 月 3 日)。(由Junio C Hamano合并-- --在6de1630 提交中,2020 年 5 月 8 日)peff
gitster
ref-filter
: apply fallback refname sort only after all user sortsSigned-off-by: Jeff King
Commit 9e468334b4("
ref-filter
: fallback on alphabetical comparison", 2015-10-30, Git v2.7.0-rc0 -- mergelisted in batch #10) taught ref-filter's sort to fallback to comparing refnames.
But it did it at the wrong level, overriding the comparison result for a single "--sort
" key from the user, rather than after all sort keys have been exhausted.This worked correctly for a single "
--sort
" option, but not for multiple ones.
We'd break any ties in the first key with the refname and never evaluate the second key at all.To make matters even more interesting, we only applied this fallback sometimes!
For a field like "taggeremail
" which requires a string comparison, we'd truly return the result ofstrcmp()
, even if it was 0.
But for numerical "value
" fields like "taggerdate
", we did apply the fallback. And that's why our multiple-sort test missed this: it usestaggeremail
as the main comparison.So let's start by adding a much more rigorous test. We'll have a set of commits expressing every combination of two tagger emails, dates, and refnames. Then we can confirm that our sort is applied with the correct precedence, and we'll be hitting both the string and value comparators.
That does show the bug, and the fix is simple: moving the fallback to the outer
compare_refs()
function, after allref_sorting
keys have been exhausted.Note that in the outer function we don't have an
"ignore_case"
flag, as it's part of each individualref_sorting
element. It's debatable what such a fallback should do, since we didn't use the user's keys to match.
But until now we have been trying to respect that flag, so the least-invasive thing is to try to continue to do so.
Since all callers in the current code either set the flag for all keys or for none, we can just pull the flag from the first key. In a hypothetical world where the user really can flip the case-insensitivity of keys separately, we may want to extend the code to distinguish that case from a blanket "--ignore-case
".
ref-filter
: 仅在所有用户排序后应用回退引用名排序签字人:Jeff King
提交9e468334b4(“
ref-filter
:按字母顺序比较的后备”,2015 年10 月 30 日,Git v2.7.0-rc0 --合并在第 10 批中列出)教导 ref-filter 的排序后备到比较 refnames。
但是它在错误的级别上做到了,覆盖了--sort
来自用户的单个“ ”键的比较结果,而不是在所有排序键都用完之后。这适用于单个“
--sort
”选项,但不适用于多个选项。
我们会打破第一个键与 refname 的任何联系,并且根本不评估第二个键。为了让事情变得更有趣,我们有时只应用这种回退!
对于像“taggeremail
”这样需要字符串比较的字段,我们会真正返回 的结果strcmp()
,即使它是 0。
但是对于value
像“taggerdate
”这样的数字“ ”字段,我们确实应用了回退。这就是为什么我们的多重排序测试忽略了这一点:它taggeremail
用作主要比较。因此,让我们从添加一个更严格的测试开始。我们将有一组提交来表达两个标记电子邮件、日期和引用名称的每种组合。然后我们可以确认我们的排序应用了正确的优先级,我们将同时命中字符串和值比较器。
这确实显示了错误,修复很简单:
compare_refs()
在所有ref_sorting
键都用完后,将回退移动到外部函数。请注意,在外部函数中我们没有
"ignore_case"
标志,因为它是每个单独ref_sorting
元素的一部分。这种回退应该做什么是有争议的,因为我们没有使用用户的密钥来匹配。
但到目前为止,我们一直在努力尊重这面旗帜,因此侵入性最小的事情是尝试继续这样做。
由于当前代码中的所有调用者要么为所有键设置标志,要么为无,我们可以从第一个键中提取标志。在一个假设的世界中,用户真的可以单独翻转不区分大小写的键,我们可能希望扩展代码以将这种情况与笼统的“--ignore-case
”区分开来。
回答by n8tr
I like using a relative date and shortening the branch name like this:
我喜欢使用相对日期并像这样缩短分支名称:
#!/bin/sh
git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"
Which gives you output:
这给你输出:
git branches
I recommend making a Bash file for adding all your favorite aliases and then sharing the script out to your team. Here's an example to add just this one:
我建议制作一个 Bash 文件来添加所有您喜欢的别名,然后将脚本分享给您的团队。这是一个仅添加此示例的示例:
#!/bin/sh
#
(echo ' ------------------------------------------------------------??' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------??') | grep --color -E "$(git rev-parse --abbrev-ref HEAD)$|$"
Then you can just do this to get a nicely formatted and sorted local branch list:
然后你可以这样做来获得一个格式化和排序的本地分支列表:
##代码##Update: Do this if you want coloring:
更新:如果您想着色,请执行以下操作:
##代码##