5

I have a lot of local branches. Running git branch lists them and they overflow the page. I often want to toggle between the currently checked out branch and the branch I was working on last, or possibly one before the last. The process is to scan the list of 20-30 local branches by eye or possibly command+f if I'm lucky enough to remember a keyword (or ticket number).

Instead I'd like to say git branch and have it display branches by checkout order. The same way you seem many items listed in many programs ordered by most recent activity. This seems like an obvious default choice for order criterion and I'm surprised it isn't git's default.

edit:

i revised my question to ask only about a sort by checkout. i'm unable to find a sorting predicate that will filter the output of git branch by the date of each branches most recent checkout.

Community
  • 1
  • 1
Alex Bollbach
  • 4,370
  • 9
  • 32
  • 80
  • 1
    I'm not quite sure whether this is what you want: `git reflog --pretty="%D" | grep -v ^$` (I'm sure there's a better way to do this). – musicmatze Dec 21 '17 at 15:33
  • 1
    Possible duplicate of [How can I get a list of git branches, ordered by most recent commit?](https://stackoverflow.com/questions/5188320/how-can-i-get-a-list-of-git-branches-ordered-by-most-recent-commit) – phd Dec 21 '17 at 15:34
  • Most recent commit and most recent checkout are two very different metrics. – jthill Dec 22 '17 at 20:00
  • @jthill thats why i edited my questions to be about which one i care about. am i missing something – Alex Bollbach Dec 22 '17 at 20:51
  • ? No, was addressing phd's comment, your question is clearly not a dup of that. `@{-1}` is git syntax for the previous explicit checkout, @{-2} for the one before that. You don't need to generate a list and pick from it, just say what you want directly. – jthill Dec 22 '17 at 23:23
  • @musicmatze one improvement - `git reflog --pretty="%D" | grep -v ^$ | uniq` – Nitsan Avni Feb 03 '20 at 15:02
  • Does this answer your question? [How can I get a list of Git branches that I've recently checked out?](https://stackoverflow.com/questions/25095061/how-can-i-get-a-list-of-git-branches-that-ive-recently-checked-out) – Bergi Sep 24 '20 at 13:49

3 Answers3

4

List Branches in the order they were checked out (not in last commit order):

git log -g --grep-reflog "checkout:" --format="%gs" | cat -n | sed -E "s/^\s+([0-9]+).*from (.*) to .*/\1 \2/g" | tac

You can then check one of them out with

git checkout @{-nnn}

where nnn is the number displayed before the branch name. To toggle between the current and previous branch, simply use

git checkout -

You can combine above command to new git command like this:

git config --global alias.lb '!git log -g --grep-reflog "checkout:" --format="%gs" | cat -n | sed -E "s/^\s+([0-9]+).*from (.*) to .*/\1 \2/g" | tac; read -p "Aussuchen: " i; git checkout @{-$i}'

to use

git lb

to display the last used branches and select one of them.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Marcus
  • 617
  • 3
  • 8
  • 1
    Note: some environments, like macOS, don't have `tac`. So use `| tail -r` instead. Or more usefully, add `alias tac='tail -r'` to the rc/profile file for your shell. I also had trouble with the sed operation, so here was my final command to get the last 25 on macOS: `git log -25 -g --grep-reflog "checkout:" --format="%gs" | sed -E "s/^checkout: moving from (.*) to.*/\1/g" | cat -n | tail -r` – AndrewF Nov 28 '18 at 03:36
  • 1
    to this i would add `| sort | head -n 5` to show only last 5 branches and in order of recency – dstandish Jul 30 '20 at 20:00
1

Have you tried the for-each-ref option? There are a lot of sortable fields.

Here is one that sorts by authordate

 git for-each-ref  --sort='-*authordate'

When I test this on my own smaller set of branches, the most recently created/checked out one is at the top.

It looks like these are the only DATE/TIME fields in the git-ref structure:

"authordate"
"committerdate"
"taggerdate"
"creatordate"

You can find out more here by trying this command to get the docs:

git for-each-ref --help

Maybe as script that checks .git/refs/heads for updates?

DDeMartini
  • 339
  • 1
  • 6
  • thanks. but i don't see any that go by checkout date. its probably a coincidence that most recently checked out and most recently committed-to happen to coincide with each other. in my case, as someone who frequently checks out various branches without committing any work, that coincidence rarely arises. – Alex Bollbach Dec 21 '17 at 17:25
  • @AlexBollbach I guess that's one of the dates that git-ref does not have/support. I updated the answer with the only 4 that looks like date/time fields. So it looks like you can order on the one's you've committed too but, aside from some tricky directory timestamp checks with a batch script of some type, ordering by checkout date itself doesn't seem to be native to git. :/ The test cases I have available to myself were not complex/large enough to expose the defect in the suggested answer. – DDeMartini Dec 21 '17 at 20:36
  • sure i'm sure a sufficiently bashful programmer could conjure up something to do this non natively. – Alex Bollbach Dec 21 '17 at 20:40
1

I often want to toggle between the currently checked out branch and the branch I was working on last, or possibly one before the last.

Thank you for describing the situation giving you difficulties, as well as asking how to implement the solution you're attempting.

Git's got a very direct way of dealing with this. To repeat the checkout you were working on last,

git checkout @{-1}

and to repeat the one before last

git checkout @{-2}
jthill
  • 55,082
  • 5
  • 77
  • 137
  • this should be the accepted answer. `git rev-parse --abbrev-ref @{-1}` to get the names, `git show @{-1}` to get the commit details – math2001 Oct 22 '20 at 00:45