Skip to content

Instantly share code, notes, and snippets.

@mgaitan
Last active August 23, 2024 20:01
Show Gist options
  • Save mgaitan/ba1e4e252b90a7fd4a4eb9e1742e94fb to your computer and use it in GitHub Desktop.
Save mgaitan/ba1e4e252b90a7fd4a4eb9e1742e94fb to your computer and use it in GitHub Desktop.
List or checkout recently used branches in git
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
List the most recent branches you have been working on, and checkout any of them.
# Install
Put this file somewhere in your PATH, and set execution permissions.
Git will recognize it as the "recent-branches" subcommand.
# Usage
Without positional argument, it shows the last 10 most recently used branches.
You can pass -n <number> to see more.
$ git recent-branches
1 - feature/EN-634
2 - feature/en-583_3
3 * master
4 - HOTFIX/spotify
5 - tests_factories
6 - feature/en-583_2
7 - _prod/workers/orders_py3
8 - prueba
9 - _prod/workers/products_py3
10 - staging
Passing a number will checkout the branch listed in that position.
$ git recent-branches 5
Switched to branch 'tests_factories'
Your branch is up to date with 'origin/tests_factories'.
In the list, the row with "*" (instead "-") is the current branch.
"""
import argparse
import re
import subprocess
from collections import OrderedDict
pattern = re.compile(r"checkout: moving from ([A-Za-z0-9_\/\-\.]+) to")
parser = argparse.ArgumentParser(description="Recent branches")
parser.add_argument("index", type=int, nargs="?", help="Move to the i-th branch in the list")
parser.add_argument("--limit", "-n", type=int, default=10, help="Show until the n-th branch")
parser.add_argument("--force", "-f", action="store_true", help="Force checkout")
args = parser.parse_args()
output = subprocess.check_output(["git", "reflog"], text=True)
# OrderedList.fromkeys(list).keys() works as a filter of repeated items in list
# keeping the first occurrence of them. A poor-man sorted set.
branches = list(OrderedDict.fromkeys(re.findall(pattern, output)).keys())
if args.index:
# use sw instead switch if available
# install sw from https://gist.github.com/mgaitan/d9a3523d79cd5f9fbfd626f646f0560b
use_sw = subprocess.call(["git", "sw"], stderr=subprocess.DEVNULL) == 2 and not args.force
cmd = ["git", "sw" if use_sw else "switch"]
if args.force:
cmd.append("-f")
cmd.append(branches[args.index - 1])
subprocess.call(cmd)
else:
current = subprocess.check_output(["git", "branch", "--show-current"], text=True).strip()
for i, branch in enumerate(branches[: args.limit], 1):
print(f"{i} {'*' if current == branch else '-'} {branch}")
@pzelnip
Copy link

pzelnip commented May 14, 2019

Love this idea, would be nice to have a way to say only show the top n branches. Ie something like:

git-recent-branches -n 5

to show the 5 most recent, rather than always show all. I have a few repos I interact with where there's a large number of branches, but only interact with a small handful.

@mgaitan
Copy link
Author

mgaitan commented Jul 24, 2019

@pzelnip, thanks for the idea. I've just implemented it, with a default to top 10 most recently used branches

@pzelnip
Copy link

pzelnip commented Jul 24, 2019

Nice!

@mgaitan
Copy link
Author

mgaitan commented May 12, 2022

@alvarmaciel
Copy link

I forked and added it to ask to switch branch
https://gist.github.com/alvarmaciel/884660733fdb7c6ad9603ceb23d239ca

@iamaamir
Copy link

iamaamir commented Feb 7, 2024

why not simply use fzf

git switch `git branch | fzf| tr -d '[:space:]'`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment