gitversion-controlgit-branch

How can I get a list of Git branches, ordered by most recent commit?


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

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?

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?


Solution

  • Use the --sort=-committerdate option of git for-each-ref;

    Also available since Git 2.7.0 for 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:

    Result

    Advanced Usage:

    git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(align:35)%(color:yellow)%(refname:short)%(color:reset)%(end) - %(color:red)%(objectname:short)%(color:reset) - %(align:40)%(contents:subject)%(end) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
    

    Result:

    Result

    Pro Usage (Unix):

    You can put the following snippet in your ~/.gitconfig. The recentb alias accepts two arguments:

    [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"
    

    Result:

    Recentb alias result