#!/usr/bin/env python """ git fuzzy-checkout Same as `git checkout branch`, but with fuzzy matching if checkout fails. Turns `git checkout barnch` into `git checkout branch`, assuming `branch` is a branch. """ import difflib import sys from subprocess import check_output, check_call, CalledProcessError def git_branches(): """construct list of git branches""" text = check_output(["git", "branch"]).decode('utf8', 'replace') return [ line.lstrip('*').strip() for line in text.splitlines() ] def proximity(a, b): """measure proximity of two strings""" return difflib.SequenceMatcher(None, a, b).ratio() def fuzzy_checkout(branch): """wrapper for git-checkout that does fuzzy-matching Helps with typos, etc. by automatically checking out the closest match if the initial checkout call fails. """ try: check_call(["git", "checkout", branch]) except CalledProcessError: branches = git_branches() branches = sorted(branches, key=lambda b : proximity(branch, b)) best = branches[-1] if proximity(best, branch) > 0.6: print "best match for '%s': '%s' (%.1f%%)" % (branch, best, 100*proximity(best, branch)) try: check_call(["git", "checkout", best]) except CalledProcessError: return 1 return 0 if __name__ == '__main__': sys.exit(fuzzy_checkout(sys.argv[1]))