我想获得Git存储库中所有分支的列表,其中“最新”分支位于顶部,“最新的”分支是最近提交的分支(因此,更可能是我想关注的分支)。
有没有一种方法可以使用Git(a)按最新提交对分支列表进行排序,或者(b)以某种机器可读格式将分支列表与每个分支的最后提交日期一起获取?
最坏的情况是,我总是可以运行gitbranch获取所有分支的列表,解析其输出,然后运行git-log-n 1 branchname--format=format:%ci获取每个分支的提交日期。但这将在Windows环境下运行,在那里启动一个新进程相对昂贵,因此如果有很多分支,每个分支启动一次Git可执行文件可能会很慢。有没有一种方法可以用一个命令完成所有这些?
其他答案似乎不允许传递-vv来获得详细的输出。
所以这里有一个单行程序,按照提交日期、保存颜色等对gitbranch-vv进行排序:
git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ct $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ct)"\t$REPLY"; done | sort -r | cut -f 2
如果您还想打印提交日期,可以使用以下版本:
git branch -vv --color=always | while read; do echo -e $(git log -1 --format=%ci $(echo "_$REPLY" | awk '{print $2}' | perl -pe 's/\e\[?.*?[\@-~]//g') 2> /dev/null || git log -1 --format=%ci)" $REPLY"; done | sort -r | cut -d ' ' -f -1,4-
样本输出:
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
拆分成多行可能更易读:
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 $2}' | 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-
这也应该与git分支的其他参数一起使用,例如-vvr列出远程跟踪分支,或-vva列出远程跟踪和本地分支。
另一种变化:
git branch -r --sort=-committerdate --format='%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)' --color=always | column -ts'|'
值得注意的是,尽管它正在查看远程分支中的更改,但在运行命令之前还是值得与origin同步(您可以使用Git fetch),因为我发现如果您的本地Git文件夹有一段时间没有更新,它可能会返回过期信息。
此外,这是一个在Windows cmd和PowerShell中工作的版本:
git branch -r --sort=-committerdate --format="%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)" --color=always
我也有同样的问题,所以我写了一个Ruby宝石,叫做Twig。它按时间顺序列出分支(最新的第一个),还可以让您设置最大年龄,这样您就不会列出所有分支(如果您有很多分支)。例如:
$ twig
issue status todo branch
----- ------ ---- ------
2013-01-26 18:00:21 (7m ago) 486 In progress Rebase optimize-all-the-things
2013-01-26 16:49:21 (2h ago) 268 In progress - whitespace-all-the-things
2013-01-23 18:35:21 (3d ago) 159 Shipped Test in prod * refactor-all-the-things
2013-01-22 17:12:09 (4d ago) - - - development
2013-01-20 19:45:42 (6d ago) - - - master
它还允许您存储每个分支的自定义财产,例如票证id、状态、todos,并根据这些财产筛选分支列表。更多信息:http://rondevera.github.io/twig/
对每个ref使用git的--sort=-committendate选项;
从Git 2.7.0开始,Git分支也可用:
基本用法:
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
结果:
高级用法:
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))'
结果:
Pro用法(Unix):
您可以在~/.gitconfig中放入以下代码段。recentb别名接受两个参数:
refbranch:前面和后面的列是根据哪个分支计算的。默认主机计数:显示最近的分支。默认值20
[alias]
# ATTENTION: All aliases prefixed with ! run in /bin/sh make sure you use sh syntax, not bash/zsh or whatever
recentb = "!r() { refbranch=$1 count=$2; git for-each-ref --sort=-committerdate refs/heads --format='%(refname:short)|%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)' --color=always --count=${count:-20} | while read line; do branch=$(echo \"$line\" | awk 'BEGIN { FS = \"|\" }; { print $1 }' | tr -d '*'); ahead=$(git rev-list --count \"${refbranch:-origin/master}..${branch}\"); behind=$(git rev-list --count \"${branch}..${refbranch:-origin/master}\"); colorline=$(echo \"$line\" | sed 's/^[^|]*|//'); echo \"$ahead|$behind|$colorline\" | awk -F'|' -vOFS='|' '{$5=substr($5,1,70)}1' ; done | ( echo \"ahead|behind||branch|lastcommit|message|author\\n\" && cat) | column -ts'|';}; r"
结果: