49

When moving between Git branches I sometimes forget the name of a branch I was recently on. How can I display a list of recently checked out branches/tags/commits in order of checkout?

Jordan Brough
  • 6,808
  • 3
  • 31
  • 31

3 Answers3

75

Summary:

You can use Git's reflog to show recent movements in order of checkout: git reflog

Script:

Here's a script you can download and use via git recent from inside any Git repository: https://gist.github.com/jordan-brough/48e2803c0ffa6dc2e0bd

Usage:

$ (master) git recent -n 5

1) master  4) deleted-branch
2) stable  5) improve-everything
3) fun
Choose a branch: 2

$ (stable) …

See the gist for more details/options.

Details:

Here's essentially what the script does to make the reflog output more usable:

$ git reflog | egrep -io "moving from ([^[:space:]]+)" | awk '{ print $3 }' | awk ' !x[$0]++' | egrep -v '^[a-f0-9]{40}$' | head -n5
master
stable
fix-stuff
some-cool-feature
feature/improve-everything
Jordan Brough
  • 6,808
  • 3
  • 31
  • 31
  • 3
    Using the gist by Jordan as a base, I made a script to checkout a recent branch by selecting it from the list: https://gist.github.com/fritz-c/c1e528b09bc1c0827a3c – Chris May 13 '15 at 08:23
  • Thanks @Chris! I've updated my script to incorporate that idea and I've listed you as a contributor in the script. – Jordan Brough Dec 20 '19 at 21:12
  • Updated script is this, btw: https://gist.github.com/jordan-brough/48e2803c0ffa6dc2e0bd – Jordan Brough Jan 21 '20 at 18:31
  • Can you incorporate this answer in a git alias? I do not know how to use grep and other cli tools in gitconfig alias. Preferably with the option - like git log? – kuga Jan 04 '21 at 10:31
  • @kuga the gist has instructions on how to make it available like `git recent` (download the script, make it executable, put it in your path). Is there a reason you want to use a git alias instead? – Jordan Brough Jul 08 '21 at 18:52
  • No specific reason. Its just easier. Did not think of making it a script though :) – kuga Jul 09 '21 at 14:40
  • `egrep` can be skipped by using: `git reflog --grep-reflog='^checkout: moving from [^ ]\{1,\}'` (explation for `\{1,\}` instead of `+` at https://www.regular-expressions.info/posix.html) – tig Feb 16 '23 at 20:45
5

I have a similar one liner in my zshell , it takes an arg to specify how long the history should be, which defaults to 10.

alias bstack='f() { git reflog | grep checkout | cut -d " " -f 8 | uniq | head ${1} | cat -n };f'

for example, to list the last 3 branches

bstack -3


 1  my-current-branch
 2  my-previous-branch
 3  my-third-most-recent-branch

I derived a couple useful shortcuts from this

alias bjmp='fn() { bstack ${1} | tail -1 | cut -f 2 | xargs git checkout  }; fn'

allows me to specify from the numbers above which branch to check out

bjmp -3

will checkout "my-third-most-recent-branch"

alias b="bstack -1"
alias bpop="bjmp -2"

are also useful to see the current branch in a single keystroke (although this is not the easiest way to do this), and to just checkout the previous branch.

sorenoid
  • 669
  • 7
  • 6
  • +1 For providing a solution that does not require a script, and suggesting a usefull alias for the command. – Robin Bastiaan Oct 12 '22 at 11:43
  • Thanks for this! I would recommend changing `grep checkout` to `grep checkout:` because the word `checkout` occurs during rebases as well, which results in an empty line when running this script. The `:` only seems to appear with normal checkouts. – mwcz Apr 20 '23 at 13:50
0

Here's a powershell script I cobbled together based on the other answers here:

function gsh() {
  # git switch with history of recent branches
  $branch = & git reflog | Select-String -Pattern "moving from (\S+) to (\S+)" | %{ $_.Matches.Groups[1].Value } | Invoke-Fzf -NoSort
  if ($branch)
  {
    & git switch $branch
  }
}

It makes use of the awesome fzf fuzzy finder to allow interactive selection of the branch to switch to - including fuzzy-filtering of the branches! See PSFzf for details on how to get the Invoke-Fzf command.

Daren Thomas
  • 67,947
  • 40
  • 154
  • 200