首页 文章

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

提问于
浏览
954

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

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

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

24 回答

  • 3

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

    git for-each-ref --sort = -committerdate refs / heads / --format ='%(authordate:short)%(color:red)%(objectname:short)%(color:yellow)%(refname:短)%(颜色:重置)(%(颜色:绿色)%(committerdate:relative)%(颜色:重置))'

    Screenshot of Output

  • 8

    git 2.7(2015年第4季度)将直接引入分支排序 git branch
    请参阅commit aa3bc55commit aedcb7dcommit 1511b22commit f65f139,...(2015年9月23日),commit aedcb7dcommit 1511b22commit ca41799(2015年9月24日)和commit f65f139,...(2015年9月23日)Karthik Nayak (KarthikNayak) .
    (由Junio C Hamano合并 - gitster - 在提交7f11b48,2015年10月15日)

    特别是commit aedcb7d

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

    制作' 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 '图书馆 .

    adds the option --sort=<key>

    根据给定的密钥排序 . 前缀 - 按值的降序排序 . 您可以多次使用--sort = <key>选项,在这种情况下,最后一个键成为主键 . 支持的密钥与git for-each-ref中的密钥相同 . 排序顺序默认为基于完整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
    

    另见commit 9e46833(2015年10月30日)Karthik Nayak (KarthikNayak) .
    帮助:Junio C Hamano (gitster) .
    (由Junio C Hamano合并 - gitster - in commit 415095f,2015年11月3日)

    根据数值排序时(例如--sort = objectsize),当两个refs保持相同的值时,没有回退比较 . 这可能会导致意外结果(即列表refs的顺序不能相等如Johannes Sixt所指出的那样($ gmane / 280117) . 因此,只要其他标准相等,就根据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 .
    commit 560ae1c(2018年8月16日)Samuel Maftoul (``) .
    (由Junio C Hamano合并 - gitster - 在提交d89db6f,2018年8月27日)

    branch.sort:
    当git-branch显示时,此变量控制分支的排序顺序 . 如果未提供“--sort = <value>”选项,则此变量的值将用作默认值 .


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

  • 37

    使用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

  • 7

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

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


    命令:

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

    结果:

    recent git branches

  • 112

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

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

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

    git branch -v
    

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

    git branch -v --sort=committerdate
    

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

  • 19

    我使用以下别名:

    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

  • 11

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

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

    其他答案似乎不允许传递 -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 列出远程跟踪和本地分支 .

  • 1

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

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

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

    我有同样的问题,所以我写了一个名为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/

  • 1

    我想出了以下命令(适用于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 .

  • -1

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

    git branch --sort=-committerdate
    

    你也可以:

    git config branch.sort -committerdate
    

    因此,无论何时在当前存储库中列出分支,它都将按committerdate排序 .

    如果每次列出分支时,都希望它们按comitterdate排序:

    git config --global branch.sort -committerdate
    

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

  • 76

    仅供参考,如果您想获得最近签出的分支列表(而不是最近提交的分支),您可以使用git的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?

  • 20

    这是另一个执行所有其他脚本的脚本 . 实际上,它为您的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}"
    }
    
  • 8

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

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

    #!/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

  • 23

    我作为剧本的最佳结果:

    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
    
  • 8

    这是我正在寻找的变化:

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

    tail -r 反转了列表,因此最近的 commiterdate 是最后一个 .

  • 1

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

    您可以在仓库中单击"Branches" . 或者直接点击网址:https://github.com/ORGANIZATION_NAME/REPO_NAME/branches

  • 23

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

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

  • 4

    Git v2.19介绍了 branch.sort 配置选项(参见branch.sort) .

    所以 git branch 默认按提交日期(desc)排序

    # gitconfig
    [branch]
        sort = -committerdate     # desc
    

    脚本:

    $ git config --global branch.sort -committerdate
    

相关问题