Completing Git objects with fzf #
If you’re like me and you prefer to write Git commands by hand, you often need to type in commit hashes, branch names, tags, etc. And fzf can really help you with that.
With its numerous subcommands and options, git can be quite daunting even for the experienced. There is sophisticated, context-aware completion support for git command, but I find it lacking in several aspects.
- The “context-awareness” of it definitely helps, but in some cases it can be
limiting. For example, for
git checkout
, it lists branches and tags, but I sometimes need to check out a specific commit by its commit hash (a.k.a. detached head state). - We can’t tell whether a completion candidate is a tag, or a branch. We don’t see the details of each entry, just the names.
- Even if the completion for
git checkout
is extended to also present commit hashes as the candidates, it will be hardly useful, as we have no way of knowing what each hash represents. - It only works with git command, you can’t use it in other contexts.
So in addition to the completion, I use a set of dedicated key bindings for each type of git object; commit hashes, branches, tags, remotes, and the files that are modified or untracked, etc.
- CTRL-G CTRL-F for Files
- CTRL-G CTRL-B for Branches
- CTRL-G CTRL-T for Tags
- CTRL-G CTRL-R for Remotes
- CTRL-G CTRL-H for commit Hashes
- CTRL-G CTRL-S for Stashes
- CTRL-G CTRL-L for reflogs
- CTRL-G CTRL-W for Worktrees
- CTRL-G CTRL-E for Each ref (
git for-each-ref
)
They are implemented using fzf, so we can interactively search for things with
its efficient fuzzy matching algorithm, and with the --preview
option, we
not only see the list of the objects, but also the details of each entry,
without having to run additional commands.
The bindings are available in fzf-git.sh respository. Thank me later.