Skip to content

Instantly share code, notes, and snippets.

@noahsark769
Created January 14, 2016 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save noahsark769/e5859ef5c91f17d7e76f to your computer and use it in GitHub Desktop.
Save noahsark769/e5859ef5c91f17d7e76f to your computer and use it in GitHub Desktop.
Fuzzy branch checkout with branch name matching
#!/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"""
if b in a or a in b:
return 0.9
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]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment