我怎样才能得到最近提交sorting的git分支列表?

我想得到一个Git仓库中所有分支的列表,其中“最新鲜的”分支在最上面,“最新鲜的”分支是最近被承诺的分支(并且因此更可能是我想要注意)。

有没有一种方法可以使用Git来(a)通过最新的提交对分支列表进行sorting,或者(b)以某种机器可读的格式获取分支列表以及每个分支的最后提交date?

最糟糕的情况是,我总是可以运行git branch来获取所有分支的列表,parsing它的输出,然后对每个分支的git log -n 1 branchname --format=format:%ci来获取每个分支的提交date。 但是这会在一个Windows机器上运行,在这个机器上启动一个新的进程相对比较昂贵,所以如果有很多分支机构,每个分支启动一次git可执行文件就会变慢。 有一种方法可以用一个命令完成所有这些吗?

使用--sort=-committerdate选项的git for-each-ref ;
也可以从Git 2.7.0的git branch

基本用法:

 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))' 

结果:

结果

为了扩展Jakub的答案和Joe的提示,下面的内容将去掉“refs / heads /”,所以输出只显示分支名称:

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

经testing!

这是最优的代码,它结合了另外两个答案:

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

这是一个简单的命令,列出所有最新提交的分支:

 git branch -v 

要按最近的提交进行sorting,请使用

 git branch -v --sort=committerdate 

资料来源: http : //git-scm.com/book/en/Git-Branching-Branch-Management

我也需要颜色,标签和远程引用,没有任何重复:

 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[$0]++' 

因为引用可以很难,这里是bash的别名:

 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["'$0'"]++'" 

我使用以下别名:

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"

这产生: 结果

编辑:使用'|' 分享 ,感谢@BjörnLindqvist

更新:在当前分支之前添加*,感谢@elhadi
编辑:修复当前分支是另一个分支的子string的情况

编辑:使用更简单的语法为当前分支,感谢@Joshua Skrzypek

其他的答案似乎不允许传递-vv来获得详细的输出。

所以这里是一个git branch -vv按提交datesortinggit branch -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 

如果您还想打印提交date,则可以使用此版本:

 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 branch ,例如-vvr列出远程跟踪分支,或-vva列出远程跟踪和本地分支。

git 2.7(2015年第四季度)将直接使用git branch引入分支sorting:
请参阅提交aa3bc55 , 提交aedcb7d , 提交1511b22 , 提交f65f139 ,…(2015年9月23日), 提交aedcb7d , 提交1511b22 , 提交ca41799 (2015年9月24日),并提交f65f139 ,…(2015年9月23日) 纳亚克( KarthikNayak ) 。
(由Junio C gitster合并- gitster -在2015年10月15日的gitster 提交 )

特别是提交aedcb7d :

branch.c :使用' ref-filter branch.c

使' branch.c '使用' ref-filter branch.c来迭代refssorting。 这删除了“ branch.c ”中使用的大部分代码,并将其replace为对“ ref-filter ”库的调用。

它添加了选项--sort=<key>

根据给定的关键字进行sorting。
前缀-按值的降序sorting。

您可以--sort=<key>使用--sort=<key>选项,在这种情况下,最后一个键变为主键。

所支持的密钥与git for-each-ref的密钥相同 。
sorting顺序默认为基于完整的refnamesorting(包括refs/...前缀)。 这列出了分离的HEAD(如果存在),然后是本地分支,最后是远程跟踪分支。

这里:

 git branch --sort=-committerdate 

另请参见由Karthik Nayak( KarthikNayak ) 提交的9e46833 (2015年10月30日) 。
帮助: Junio C gitstergitster ) 。
(由Junio C gitster合并- gitster -在承诺415095f ,2015年11月3日)

当按照数值进行sorting时(例如--sort=objectsize ),当两个ref都保持相同的值时,不存在回退比较。 如Johannes Sixt( $ gmane / 280117 )所指出的,这可能会导致意想不到的结果(即无法预先确定具有相同值的上市参考订单 )。

因此, 只要其他标准相同,则基于refname的字母比较可以回退

 $ git branch --sort=objectsize * (HEAD detached from fromtag) branch-two branch-one master 

我喜欢使用相对date并缩短分支名称,如下所示:

 git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads 

哪个给你输出:

 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 

我build议创build一个bash文件来添加所有你喜欢的别名,然后把脚本分享给你的团队。 以下是添加这个的一个例子:

 #!/bin/sh git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'" 

然后你可以做到这一点,以获得一个很好的格式和sorting的本地分支列表:

 git branches 

更新:如果您想着色,请执行此操作:

 #!/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)$|$" 

添加一些颜色(因为pretty-format不可用)

 [alias] branchdate = for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short)%09%(objectname:short)%09%1B[0;33m%(refname:short)%1B[m%09" 

我有同样的问题,所以我写了一个叫做Twig的Rubygem。 它按时间顺序(最新的第一个)列出分支,并且还可以让您设置最大年龄,以便不列出所有分支(如果您有很多分支)。 例如:

 $ 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,状态,待办事项,并根据这些属性筛选分支列表。 更多信息: http : //rondevera.github.io/twig/

仅供参考,如果您想获得最近签出的分支机构列表(而不是最近提交的),可以使用git的reflog:

 $ git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | head -n5 master stable master some-cool-feature feature/improve-everything 

另请参阅: 如何获取最近检出的git分支列表?

我能够参考上面的例子来创build最适合我的东西。

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 branch -r --sort=creatordate \ --format "%(creatordate:relative);%(committername);%(refname:lstrip=-1)" \ | grep -v ";HEAD$" \ | column -s ";" -t 

如果你没有column你可以用最后一行代替

  | sed -e "s/;/\t/g" 

输出看起来像

 6 years ago Tom Preston-Werner book 4 years, 4 months ago Parker Moore 0.12.1-release 4 years ago Matt Rogers 1.0-branch 3 years, 11 months ago Matt Rogers 1.2_branch 3 years, 1 month ago Parker Moore v1-stable 12 months ago Ben Balter pages-as-documents 10 months ago Jordon Bedwell make-jekyll-parallel 6 months ago Pat Hawks to_integer 5 months ago Parker Moore 3.4-stable-backport-5920 4 months ago Parker Moore yajl-ruby-2-4-patch 4 weeks ago Parker Moore 3.4-stable 3 weeks ago Parker Moore rouge-1-and-2 19 hours ago jekyllbot master 

我写了一篇关于各个部分如何工作的博客文章 。

这是另外一个脚本,可以完成所有其他脚本的function。 实际上,它为你的shell提供了一个函数。

它的贡献是它从你的gitconfiguration中拉出一些颜色(或使用默认值)。

 # Git Branch by Date # Usage: gbd [ -r ] gbd() { local reset_color=`tput sgr0` local subject_color=`tput setaf 4 ; tput bold` local author_color=`tput setaf 6` local target=refs/heads local branch_color=`git config --get-color color.branch.local white` if [ "$1" = -r ] then target=refs/remotes/origin branch_color=`git config --get-color color.branch.remote red` fi git for-each-ref --sort=committerdate $target --format="${branch_color}%(refname:short)${reset_color} ${subject_color}%(subject)${reset_color} ${author_color}- %(authorname) (%(committerdate:relative))${reset_color}" } 

我最好的结果作为脚本:

 git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short)|%(committerdate:iso)|%(authorname)' | sed 's/refs\/heads\///g' | grep -v BACKUP | while IFS='|' read branch date author do printf '%-15s %-30s %s\n' "$branch" "$date" "$author" done 

基于ilius的版本,但是当前分支以星号和颜色显示,并且仅显示任何未被描述为“月”或“年”前的分支:

 current_branch="$(git symbolic-ref --short -q HEAD)" git for-each-ref --sort=committerdate refs/heads \ --format='%(refname:short)|%(committerdate:relative)' \ | grep -v '\(year\|month\)s\? ago' \ | while IFS='|' read branch date do start=' ' end='' if [[ $branch = $current_branch ]]; then start='* \e[32m' end='\e[0m' fi printf "$start%-30s %s$end\\n" "$branch" "$date" done 

这是我正在寻找的变化:

 git for-each-ref --sort=-committerdate --format='%(committerdate)%09%(refname:short)' refs/heads/ | tail -r 

tail -r反转列表,所以最近的commiterdate是最后一个。

晚会到了这里。 被接受的CML答案是岩石,但是如果你想要一些漂亮的东西,像一个GUI,你的起源===“github”。

您可以单击回购中的“分支”。 或直接点击url: https : //github.com/ORGANIZATION_NAME/REPO_NAME/branches

我把接受的答案输出到dialog ,给我一个交互式列表:

 #!/bin/bash TMP_FILE=/tmp/selected-git-branch eval `resize` dialog --title "Recent Git Branches" --menu "Choose a branch" $LINES $COLUMNS $(( $LINES - 8 )) $(git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname:short) %(committerdate:short)') 2> $TMP_FILE if [ $? -eq 0 ] then git checkout $(< $TMP_FILE) fi rm -f $TMP_FILE clear 

另存为(例如) ~/bin/git_recent_branches.shchmod +x它。 然后git config --global alias.rb '!git_recent_branches.sh'给我一个新的git rb命令。

下面是我用来在最近的分支之间切换的一个小脚本:

 #!/bin/bash # sudo bash re='^[0-9]+$' if [[ "$1" =~ $re ]]; then lines="$1" else lines=10 fi branchs="$(git recent | tail -n $lines | nl)" branchs_nf="$(git recent-nf | tail -n $lines | nl)" echo "$branchs" # Prompt which server to connect to max="$(echo "$branchs" | wc -l)" index= while [[ ! ( "$index" =~ ^[0-9]+$ && "$index" -gt 0 && "$index" -le "$max" ) ]]; do echo -n "Checkout to: " read index done branch="$( echo "$branchs_nf" | sed -n "${index}p" | awk '{ print $NF }' )" git co $branch clear 

使用这两个别名

 recent = for-each-ref --sort=committerdate refs/heads/ --format=' %(color:blue) %(authorname) %(color:yellow)%(refname:short)%(color:reset)' recent-nf = for-each-ref --sort=committerdate refs/heads/ --format=' %(authorname) %(refname:short)' 

只要在git仓库中调用它,就会显示最后N个分支(默认为10个),每个分支都有一个数字。 input分支的号码,并检出。