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?
git for-each-ref
from Jakub Narębski: you can get remote branches passing refs/remotes/
instead of refs/heads/
(or you can pass both, whitespace-separated); refs/tags/
for tags, or just refs/
for all three kinds. - anyone for-each-ref
! You will use directly git branch --sort=-committerdate
: see my answer below - anyone Use the --sort=-committerdate
option of git for-each-ref
;
Also available since Git 2.7.0 for 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))'
You can put the following snippet in your ~/.gitconfig
. The recentb alias accepts two arguments:
refbranch
: which branch the ahead and behind columns are calculated against. Default mastercount
: how many recent branches to show. Default 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"
Answered 2023-09-21 08:07:32
--format=%(refname)
. - anyone git for-each-ref --sort=-committerdate refs/heads/ --format='%(refname) %(committerdate) %(authorname)' | sed 's/refs\/heads\///g'
- anyone :shortname
? - anyone git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads/
. git-for-each-ref(1) manpage says: For a non-ambiguous short name of the ref append :short
. - anyone [alias]
section and I love it. br = 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))'
- anyone Expanding on Jakub’s answer and Joe’s tip, the following will strip out the "refs/heads/" so the output only displays the branch names:
git for-each-ref --count=30 --sort=-committerdate refs/heads/ --format='%(refname:short)'
Answered 2023-09-21 08:07:32
git rb
remember to surround the command in quotes: git config --global alias.rb "for-each-ref --count=20 --sort=-committerdate refs/heads/ --format=\'%(refname:short)\'"
- anyone git branch
, so getting local, remote or all branches works like on git-branch (i.e. -r, -a). git branch -r --sort=committerdate --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
- anyone git branch -va --sort=committerdate | tail -5
. Perhaps that's an alternative to what you were asking and discovered. - anyone Here is a simple command that lists all branches with latest commits:
git branch -v
To order by most recent commit, use
git branch -v --sort=committerdate
Source: http://git-scm.com/book/en/Git-Branching-Branch-Management
Answered 2023-09-21 08:07:32
git branch -av
if you want to see non-local branches too. - anyone git branch -v
to include the date of each commit listed? - anyone git branch -va --sort=-committerdate
to show non-local branches, with the most recently changed branches at the top. - anyone git branch -v --format='%(committerdate:short) %(refname:short)'
will include the date. - anyone committerdate
will catch the last time that you amended or rebased. (The other possibility is authordate
, which amend
or rebase
will not change by default.) - anyone Here's the optimal code, which combines the other two answers:
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'
Answered 2023-09-21 08:07:32
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(authorname) %(refname:short)'
- anyone I use the following alias:
recent = "!r() { count=$1; 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)' --color=always --count=${count:=10} | column -ts'|';}; r"
which produces:
We can also give a custom count, e.g.,
git recent 20
(the default is 10).
Answered 2023-09-21 08:07:32
'%(HEAD) ...'
at the start of the format string to get the same effect without piping throught the sed
command - anyone [alias] recent = !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'|'
- anyone 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)' --color=always|column -ts'|'}
- anyone !r(){git for-each-ref ... ;}; r
- anyone -ts'|'
i.e. "!r(){ git ... -ts'|'; }; r"
- anyone I was able to reference the previous examples to create something that works best for me.
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))'
As suggested in the comments below you can also include remote branches and the author's name.
git for-each-ref --sort=-committerdate refs/heads refs/remotes --format='%(authordate:short) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset)) %(authorname)'
Here are both commands as shell aliases that you can easily add to your shell profile.
# show a list of local git branches sorted by the commit date
alias git.branches='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))"'
# show a list of local and remote git branches sorted by the commit date
alias git.branches.remote='git for-each-ref --sort=-committerdate refs/heads refs/remotes --format="%(authordate:short) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset)) %(authorname)"'
Answered 2023-09-21 08:07:32
git for-each-ref --sort=-committerdate refs/heads/ refs/remotes --format='%(authordate:short) %(authorname) %(color:red)%(objectname:short) %(color:yellow)%(refname:short)%(color:reset) (%(color:green)%(committerdate:relative)%(color:reset))'
- anyone git 2.7 (Q4 2015) will introduce branch sorting using directly git branch
:
See commit aa3bc55, commit aedcb7d, commit 1511b22, commit f65f139, ... (23 Sep 2015), commit aedcb7d, commit 1511b22, commit ca41799 (24 Sep 2015), and commit f65f139, ... (23 Sep 2015) by Karthik Nayak (KarthikNayak
).
(Merged by Junio C Hamano -- gitster
-- in commit 7f11b48, 15 Oct 2015)
In particular, commit aedcb7d:
branch.c
: use 'ref-filter
' APIs
Make '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
' library.
It adds the option --sort=<key>
:
Sort based on the key given.
Prefix-
to sort in descending order of the value.You may use the
--sort=<key>
option multiple times, in which case the last key becomes the primary key.The keys supported are the same as those in
git for-each-ref
.
Sort order defaults to sorting based on the full refname (includingrefs/...
prefix). This lists detached HEAD (if present) first, then local branches and finally remote-tracking branches.
Here:
git branch --sort=-committerdate
Or (see below with Git 2.19)
# if you are sure to /always/ want to see branches ordered by commits:
git config --global branch.sort -committerdate
git branch
See also commit 9e46833 (30 Oct 2015) by Karthik Nayak (KarthikNayak
).
Helped-by: Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 415095f, 03 Nov 2015)
When sorting as per numerical values (e.g.
--sort=objectsize
) there is no fallback comparison when both refs hold the same value. This can cause unexpected results (i.e. the order of listing refs with equal values cannot be pre-determined) as pointed out by Johannes Sixt ($gmane/280117).Hence, fallback to alphabetical comparison based on the refname whenever the other criterion is equal.
$ git branch --sort=objectsize * (HEAD detached from fromtag) branch-two branch-one master
With Git 2.19, the sort order can be set by default.
git branch
supports a config branch.sort
, like git tag
, which already had a config tag.sort
.
See commit 560ae1c (16 Aug 2018) by Samuel Maftoul (``).
(Merged by Junio C Hamano -- gitster
-- in commit d89db6f, 27 Aug 2018)
branch.sort:
This variable controls the sort ordering of branches when displayed by
git-branch
.
Without the "--sort=<value>
" option provided, the value of this variable will be used as the default.
To list remote branches, use git branch -r --sort=objectsize
. The -r
flag causes it to list remote branches instead of local branches.
With Git 2.27 (Q2 2020), "git branch
" and other "for-each-ref
" variants accepted multiple --sort=<key>
options in the increasing order of precedence, but it had a few breakages around "--ignore-case
" handling, and tie-breaking with the refname, which have been fixed.
See commit 7c5045f, commit 76f9e56 (03 May 2020) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit 6de1630, 08 May 2020)
ref-filter
: apply fallback refname sort only after all user sortsSigned-off-by: Jeff King
Commit 9e468334b4 ("
ref-filter
: fallback on alphabetical comparison", 2015-10-30, Git v2.7.0-rc0 -- merge listed in batch #10) taught ref-filter's sort to fallback to comparing refnames.
But it did it at the wrong level, overriding the comparison result for a single "--sort
" key from the user, rather than after all sort keys have been exhausted.This worked correctly for a single "
--sort
" option, but not for multiple ones.
We'd break any ties in the first key with the refname and never evaluate the second key at all.To make matters even more interesting, we only applied this fallback sometimes!
For a field like "taggeremail
" which requires a string comparison, we'd truly return the result ofstrcmp()
, even if it was 0.
But for numerical "value
" fields like "taggerdate
", we did apply the fallback. And that's why our multiple-sort test missed this: it usestaggeremail
as the main comparison.So let's start by adding a much more rigorous test. We'll have a set of commits expressing every combination of two tagger emails, dates, and refnames. Then we can confirm that our sort is applied with the correct precedence, and we'll be hitting both the string and value comparators.
That does show the bug, and the fix is simple: moving the fallback to the outer
compare_refs()
function, after allref_sorting
keys have been exhausted.Note that in the outer function we don't have an
"ignore_case"
flag, as it's part of each individualref_sorting
element. It's debatable what such a fallback should do, since we didn't use the user's keys to match.
But until now we have been trying to respect that flag, so the least-invasive thing is to try to continue to do so.
Since all callers in the current code either set the flag for all keys or for none, we can just pull the flag from the first key. In a hypothetical world where the user really can flip the case-insensitivity of keys separately, we may want to extend the code to distinguish that case from a blanket "--ignore-case
".
The implementation of "git branch --sort
"(man) wrt the detached HEAD display has always been hacky, which has been cleaned up with Git 2.31 (Q1 2021).
See commit 4045f65, commit 2708ce6, commit 7c269a7, commit d094748, commit 75c50e5 (07 Jan 2021), and commit 08bf6a8, commit ffdd02a (06 Jan 2021) by Ævar Arnfjörð Bjarmason (avar
).
(Merged by Junio C Hamano -- gitster
-- in commit 9e409d7, 25 Jan 2021)
branch
: show "HEAD detached" first under reverse sortSigned-off-by: Ævar Arnfjörð Bjarmason
Change the output of the likes of "
git branch -l --sort=-objectsize
"(man) to show the "(HEAD detached at <hash>)
" message at the start of the output.
Before thecompare_detached_head()
function added in a preceding commit we'd emit this output as an emergent effect.It doesn't make any sense to consider the objectsize, type or other non-attribute of the "
(HEAD detached at <hash>)
" message for the purposes of sorting.
Let's always emit it at the top instead.
The only reason it was sorted in the first place is because we're injecting it into the ref-filter machinery sobuiltin/branch.c
doesn't need to do its own "am I detached?" detection.
With Git 2.35 (Q1 2022), things like "git -c branch.sort=bogus branch new HEAD
"(man), i.e.
the operation modes of the "git branch
"(man) command that do not need the sort key information, no longer errors out by seeing a bogus sort key.
See commit 98e7ab6, commit 1a89796 (20 Oct 2021) by Junio C Hamano (gitster
).
(Merged by Junio C Hamano -- gitster
-- in commit 5126145, 29 Nov 2021)
for-each-ref
: delay parsing of--sort=<atom>
options
The
for-each-ref
family of commands invoke parsers immediately when it sees each--sort=<atom>
option, and die before even seeing the other options on the command line when the<atom>
is unrecognised.Instead, accumulate them in a string list, and have them parsed into a
ref_sorting
structure after the command line parsing is done.
As a consequence, "git branch --sort=bogus -h
"(man) used to fail to give the brief help, which arguably may have been a feature, now does so, which is more consistent with how other options work.
Answered 2023-09-21 08:07:32
-r
- anyone I also needed colors, tags and remote references without any duplicates:
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]++'
Because quoting can be hard, here is the alias for 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'"]++'"
Answered 2023-09-21 08:07:32
| head -n20
at the end. If you are using the alias, be sure this goes within the quotes. - anyone Another variation:
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'|'
It is worth noting that even though it's looking at changes in remote branches, it's worth synchronising with origin before running the command (you can use Git fetch), as I found it can return out of date information if your local Git folder hasn't been updated in a while.
Also, this is a version that works in Windows cmd and 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
Answered 2023-09-21 08:07:32
-r
ifi you want your local branches, and not just what's been pushed/synced to your remote(s). - anyone As of Git 2.19 you can simply:
git branch --sort=-committerdate
You can also:
git config branch.sort -committerdate
So whenever you list branches in the current repository, it will be listed sorted by committerdate.
If whenever you list branches, you want them sorted by comitterdate:
git config --global branch.sort -committerdate
Disclaimer: I'm the author of this feature in Git, and I implemented it when I saw this question.
Answered 2023-09-21 08:07:32
The other answers don't seem to allow passing -vv
to get verbose output.
So here's a one-liner that sorts git branch -vv
by commit date, preserving color etc:
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
If you additionally want to print the commit date, you can use this version instead:
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-
Sample output:
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
It's probably more readable split into multiple lines:
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-
This should also work with other arguments to git branch
, e.g. -vvr
to list remote-tracking branches, or -vva
to list both remote-tracking and local branches.
Answered 2023-09-21 08:07:32
-vv
can be useful indeed, thanks. However, this solution still spawns new processes for each branch, which the OP wanted to avoid. - anyone git branch
doesn't specifically define the meaning of -vv
, but only of -v
, so -vv
should have the same as -v
. - anyone -v, -vv, --verbose
contains the following: If given twice, print the name of the upstream branch, as well
- anyone I find the following command helpful for my purposes.
git branch --sort=-committerdate | head -n 10
This will list the latest 10 branches. It is short and can be used without an alias as well.
Answered 2023-09-21 08:07:32
git config --global alias.br "! git branch --sort=-committerdate | head -n 10"
- anyone I like using a relative date and shortening the branch name like this:
git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads
Which gives you output:
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
I recommend making a Bash file for adding all your favorite aliases and then sharing the script out to your team. Here's an example to add just this one:
#!/bin/sh
git config --global alias.branches "!echo ' ------------------------------------------------------------' && git for-each-ref --sort='-authordate:iso8601' --format=' %(authordate:relative)%09%(refname:short)' refs/heads && echo ' ------------------------------------------------------------'"
Then you can just do this to get a nicely formatted and sorted local branch list:
git branches
Update: Do this if you want coloring:
#!/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)$|$"
Answered 2023-09-21 08:07:32
fatal: unknown field name: '-authordate:iso8601'
- anyone refs/heads
with refs/remotes
to have a look at remote branches. - anyone expansion of alias 'branches' failed; 'echo' is not a git command
- anyone (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)$|$"
- anyone Getting just the top five branch names sorted based on committer date:
git branch --sort=-committerdate | head -5
Answered 2023-09-21 08:07:32
Adds some color (since pretty-format
isn't available)
[alias]
branchdate = for-each-ref --sort=-committerdate refs/heads/ --format="%(authordate:short)%09%(objectname:short)%09%1B[0;33m%(refname:short)%1B[m%09"
Answered 2023-09-21 08:07:32
I came up with the following command (for Git 2.13 and later):
git branch -r --sort=creatordate \
--format "%(creatordate:relative);%(committername);%(refname:lstrip=-1)" \
| grep -v ";HEAD$" \
| column -s ";" -t
If you don’t have column
you can replace the last line with
| sed -e "s/;/\t/g"
The output looks like
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
I wrote a blog post about how the various pieces work.
Answered 2023-09-21 08:07:32
git branch --sort
I mentioned in stackoverflow.com/a/33163401/6309. - anyone I had the same problem, so I wrote a Ruby gem called Twig. It lists branches in chronological order (newest first), and can also let you set a max age so that you don't list all branches (if you have a lot of them). For example:
$ 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
It also lets you store custom properties for each branch, e.g., ticket id, status, todos, and filter the list of branches according to these properties. More info: http://rondevera.github.io/twig/
Answered 2023-09-21 08:07:32
FYI, if you'd like to get a list of recently checked out branches (as opposed to recently committed) you can use Git's reflog:
$ git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | head -n5
master
stable
master
some-cool-feature
feature/improve-everything
See also: How can I get a list of Git branches that I've recently checked out?
Answered 2023-09-21 08:07:32
Git v2.19 introduces branch.sort
configuration option (see branch.sort).
So git branch
will sort by committer date (descending) by default with
# gitconfig
[branch]
sort = -committerdate # Descending
Script:
git config --global branch.sort -committerdate
So,
git branch
Output:
* dev
master
_
And
git branch -v
Output:
* dev 0afecf5 Merge branch 'oc' into dev
master 652428a Merge branch 'dev'
_ 7159cf9 Merge branch 'bashrc' into dev
Answered 2023-09-21 08:07:32
Here's a little script that I use to switch between recent branches:
#!/bin/bash
# sudo bash
re='^[0-9]+$'
if [[ "$1" =~ $re ]]; then
lines="$1"
else
lines=10
fi
branches="$(git recent | tail -n $lines | nl)"
branches_nf="$(git recent-nf | tail -n $lines | nl)"
echo "$branches"
# Prompt which server to connect to
max="$(echo "$branches" | wc -l)"
index=
while [[ ! ( "$index" =~ ^[0-9]+$ && "$index" -gt 0 && "$index" -le "$max" ) ]]; do
echo -n "Checkout to: "
read index
done
branch="$( echo "$branches_nf" | sed -n "${index}p" | awk '{ print $NF }' )"
git co $branch
clear
Using those two aliases:
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)'
Just call that in a Git repository, and it will show you the last N branches (10 by default) and a number aside each. Input the number of the branch, and it checks out:
Answered 2023-09-21 08:07:32
Normally we consider the remote branches recently. So try this
git fetch
git for-each-ref --sort=-committerdate refs/remotes/origin
Answered 2023-09-21 08:07:32
Here is another script that does what all the other scripts do. In fact, it provides a function for your shell.
Its contribution is that it pulls some colours from your Git configuration (or uses defaults).
# 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}"
}
Answered 2023-09-21 08:07:32
This is based on saeedgnu's version, but with the current branch shown with a star and in color, and only showing anything that is not described as "months" or "years" ago:
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
Answered 2023-09-21 08:07:32
My best result as a script:
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
Answered 2023-09-21 08:07:32
The accepted command-line answer rocks, but if you want something prettier, like a GUI, and your origin === "github".
You can click "Branches" in the repository. Or hit the URL directly: https://github.com/ORGANIZATION_NAME/REPO_NAME/branches
Answered 2023-09-21 08:07:32
The simplest one to print along with the last commit date:
git branch --all --format='%(committerdate:short) %(refname:short)'|sort
Answered 2023-09-21 08:07:32
git for-each-ref --sort=-committerdate refs/heads/
# Or using Git branch (since version 2.7.0)
git branch --sort=-committerdate # Descending
git branch --sort=committerdate # Ascending
Answered 2023-09-21 08:07:32
Here's the variation I was looking for:
git for-each-ref --sort=-committerdate --format='%(committerdate)%09%(refname:short)' refs/heads/ | tail -r
That tail -r
reverses the list so the most-recent commiterdate
is last.
Answered 2023-09-21 08:07:32
tail
has -r
? - anyone I know there are a lot of answers already, but here are my two cents for a simple alias (I like to have my most recent branch at the bottom):
[alias]
br = !git branch --sort=committerdate --color=always | tail -n15
[color "branch"]
current = yellow
local = cyan
remote = red
This will give you a nice overview of your latest 15 branches, in color, with your current branch highlighted (and it has an asterisk).
Answered 2023-09-21 08:07:32
I pipe the output from the accepted answer into dialog
, to give me an interactive list:
#!/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
Save as (e.g.) ~/bin/git_recent_branches.sh
and chmod +x
it. Then git config --global alias.rb '!git_recent_branches.sh'
to give me a new git rb
command.
Answered 2023-09-21 08:07:32