如何获得最近提交的Git分支列表?

时间:2011-03-04 00:26:35

标签: git version-control branch

我想得到一个Git存储库中所有分支的列表,顶部有“最新鲜”的分支,其中“最新鲜”的分支是最近承诺的分支(因此,更有可能成为一个我想要注意的人。)

有没有办法可以使用Git来(a)按最新提交对分支列表进行排序,或者(b)在某种机器可读的情况下获取分支列表以及每个分支的最后提交日期格式?

最坏的情况是,我总是可以运行git branch来获取所有分支的列表,解析其输出,然后为每个分支git log -n 1 branchname --format=format:%ci获取每个分支的提交日期。但是这将在Windows机器上运行,其中启动新进程相对昂贵,因此如果有很多分支,每个分支启动Git可执行文件可能会变慢。有没有办法用一个命令完成所有这些?

31 个答案:

答案 0 :(得分:1513)

使用git for-each-ref;

--sort=-committerdate 选项

since 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

结果:

Result

高级用法:

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

答案 1 :(得分:114)

git分支名称列表,按最近提交的顺序排序......

扩展Jakub的回答和Joe的提示,以下将删除“refs / heads /”,因此输出只显示分支名称:


命令:

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

结果:

recent git branches

答案 2 :(得分:80)

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

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

答案 3 :(得分:72)

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

git branch -v

要按最近提交的顺序排序,请使用

git branch -v --sort=committerdate

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

答案 4 :(得分:44)

我使用以下别名:

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"

产生: result

修改:使用' |'分开,感谢@Björn Lindqvist

更新:在当前分支之前添加*,感谢@elhadi
编辑:修复了当前分支是另一个分支的子字符串

的情况

编辑:感谢 @Joshua Skrzypek

,为当前分支使用更简单的语法

答案 5 :(得分:36)

我还需要颜色,标签和远程参考,没有任何重复:

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

答案 6 :(得分:29)

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

  

git for-each-ref --sort = -committerdate refs / heads /   --format =&#39;%(authordate:short)%(color:red)%(objectname:short)%(color:yellow)%(refname:short)%(color:reset)   (%(颜色:绿色)%(committerdate:相对)%(颜色:复位))&#39;

Screenshot of Output

答案 7 :(得分:24)

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

所以这是一个单行,按提交日期排序git 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

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

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列出远程跟踪和本地分支。

答案 8 :(得分:22)

git 2.7(2015年第4季度)将直接使用git branch引入分支排序:
请参阅commit aa3bc55commit aedcb7dcommit 1511b22commit f65f139,...(2015年9月23日),commit aedcb7dcommit 1511b22,{{3} (2015年9月24日)和commit ca41799,...(2015年9月23日)commit f65f139 Karthik Nayak (KarthikNayak)Junio C Hamano -- gitster --合并,2015年10月15日)

特别是commit 7f11b48

  

branch.c:使用&#39; ref-filter&#39;的API

制作&#39; branch.c&#39;使用&#39; ref-filter&#39;用于迭代refs排序的API。这会删除&#39; branch.c&#39;中使用的大部分代码。替换它 打电话给&#39; ref-filter&#39;库。

commit aedcb7d

  

根据给定的密钥排序。
  前缀-按值的降序排序。

     

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

     

支持的密钥是adds the option --sort=<key>   排序顺序默认为基于完整refname(包括refs/...前缀)的排序。这首先列出了分离的HEAD(如果存在),然后是本地分支,最后是远程跟踪分支。

下面:

git branch --sort=-committerdate 

或(见下文Git 2.19)

# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch

另见same as those in git for-each-ref(2015年10月30日)commit 9e46833 帮助:Karthik Nayak (KarthikNayak)
(由Junio C Hamano (gitster)合并于Junio C Hamano -- gitster --,2015年11月3日)

  

按数值排序时(例如--sort=objectsize),当两个refs保持相同的值时,没有后备比较。如Johannes Sixt(commit 415095f)所指出的那样,这可能会导致意想不到的结果(即无法预先确定具有相同值的列表引用的顺序)。

     

因此,基于refname回退到字母比较   只要其他标准相等

$ git branch --sort=objectsize

*  (HEAD detached from fromtag)
      branch-two
      branch-one
      master

使用Git 2.19,默认情况下可以设置排序顺序 git branch支持配置branch.sort,例如git tag,已配置tag.sort
$gmane/280117commit 560ae1c(2018年8月16日) (由Samuel Maftoul (``)合并于Junio C Hamano -- gitster --,2018年8月27日)

branch.sort:
     

此变量控制git-branch显示时分支的排序顺序   没有&#34; --sort=<value>&#34;提供的选项,此变量的值将用作默认值。

要列出远程分支,请使用git branch -r --sort=objectsize-r标志使其列出远程分支而不是本地分支。

答案 9 :(得分:19)

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

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

我建议制作一个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 ' ------------------------------------------------------------'"

然后你可以这样做以获得一个格式良好和排序的本地分支列表:

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)$|$"

答案 10 :(得分:11)

添加一些颜色(因为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"

答案 11 :(得分:10)

从git 2.19开始,您可以简单地:

git branch --sort=-committerdate

您还可以:

git config branch.sort -committerdate

因此,只要您在当前存储库中列出分支,就会按committerdate对其进行排序。

如果每当您列出分支机构时,都希望它们按comitterdate排序:

git config --global branch.sort -committerdate

免责声明:我是git中此功能的作者,当我看到这个问题时便实现了它。

答案 12 :(得分:8)

我想出了以下命令(适用于Git 2.13及更高版本):

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

我写了a blog post关于各个部分是如何工作的。

答案 13 :(得分:8)

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

$ 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/

答案 14 :(得分:7)

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

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

另请参阅:How can I get a list of git branches that I've recently checked out?

答案 15 :(得分:5)

另一种变体:

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

答案 16 :(得分:4)

这是另一个执行所有其他脚本操作的脚本。实际上,它为你的shell提供了一个函数。

它的贡献在于它从你的git配置中提取了一些颜色(或使用默认值)。

# 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}"
}

答案 17 :(得分:3)

基于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

答案 18 :(得分:3)

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

#!/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 repo中调用它,它会显示最后N个分支(默认为10个)和每个分支旁边的数字。输入分支的编号并检出:

enter image description here

答案 19 :(得分:2)

git branch --sort=-committerdate | head -5

对于任何有兴趣仅获得基于提交者日期排序的前5个分支名称的人。

答案 20 :(得分:2)

与上次提交日期一起打印的最简单的:

git branch --all  --format='%(committerdate:short) %(refname:short)'|sort

答案 21 :(得分:2)

我作为剧本的最佳结果:

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

答案 22 :(得分:2)

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

答案 23 :(得分:1)

我将接受的答案的输出传输到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命令。

答案 24 :(得分:1)

这里的派对迟到了。接受的CML答案很明显,但如果你想要更漂亮的东西,比如GUI,你的起源===&#34; github&#34;。

您可以点击&#34;分支&#34;在回购中。或直接点击网址:https://github.com/ORGANIZATION_NAME/REPO_NAME/branches

答案 25 :(得分:1)

这是我正在寻找的变化:

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

tail -r会反转列表,因此最近的commiterdate是最后一次。

答案 26 :(得分:1)

我知道已经有很多答案了,但是这是我的两个美分,一个简单的别名(我喜欢在底部有我最近的分支):

[alias]
        br = !git branch --sort=committerdate --color=always | tail -n15
[color "branch"]
        current = yellow
        local = cyan
        remote = red

这将为您提供最新的15个彩色分支的概览,并突出显示当前分支(并带有星号)。

答案 27 :(得分:1)

通常我们最近会考虑远程分支。所以试试这个

git fetch
git for-each-ref --sort=-committerdate refs/remotes/origin

答案 28 :(得分:0)

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))'这就是你需要的

答案 29 :(得分:0)

Git v2.19引入了branch.sort配置选项(请参见branch.sort)。

因此git branch将默认使用提交者日期(desc)进行排序

# gitconfig
[branch]
    sort = -committerdate     # desc

脚本:

$ git config --global branch.sort -committerdate

更新

所以

$ git branch
* dev
  master
  _

$ git branch -v
* dev    0afecf5 Merge branch 'oc' into dev
  master 652428a Merge branch 'dev'
  _      7159cf9 Merge branch 'bashrc' into dev

答案 30 :(得分:0)

在尝试设置别名时,在Mac上的bash_profile中处理单引号时遇到了一些麻烦。此答案有助于解决它“ How to escape single quotes within single quoted strings

工作解决方案:

alias gb='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))'"'"''

P.S。由于我的声誉而无法发表评论