A large part of being a Software Engineer is using Git effectively to track your work in a code base. Another aspect is to quickly and efficiently find and utilize information, especially when it comes to Git.
Here are a couple fzf scripts that others have shared that I have tweaked to fit into my workflow.
Feel free to copy these and if you have updates or other scripts that you use in your workflow please share!
For both scripts I have a file in my home directory (e.g.
~
) and I have an alias in my~/.zshrc
pointing to it (e.g.alias fsb=~/fsb.sh
).
Search and Checkout Git Branch
I haven’t made the switch to using worktrees in Git yet so I will checkout other branches constantly and switch between them during my workday.
Typically I join work that is already in flight from another pair and need to pull that branch down to begin work for the day.
To make my life significantly more easy, I use the script below by typing fsb
(Fuzzy Search Branch) into a terminal.
This will then pop up a floating window in the middle of my screen that I can select a branch and checkout that branch.
If I hit Esc then nothing is checked out and I am returned to my terminal.
Walkthrough
The script starts with grabbing all the git branches using git branch --all
and then using fzf-tmux
to open a window to select a branch from that list of $branches
.
If no branch is selected then the function returns early.
The final step in the function is to call git checkout
on the provided $branch
after removing any leading text up to the first space and the substring “remotes” along with all directories and the trailing slash if present using sed
.
#!/bin/bash
# Fuzzy search Git branches in a repo
# Looks for local and remote branches
function fsb() {
local pattern=$*
local branches branch
branches=$(git branch --all | awk 'tolower($0) ~ /'"$pattern"'/') &&
branch=$(echo "$branches" |
fzf-tmux -p --reverse -1 -0 +m) &&
if [ "$branch" = "" ]; then
echo "[$0] No branch matches the provided pattern"; return;
fi;
git checkout $(echo "$branch" | sed "s/.* //" | sed "s#remotes/[^/]*/##")
}
fsb "$@"
If you want a way to fuzzy search for branches and quickly check them out using fzf then use this script.
Search Git History with Preview
I have tried a few different plugins in Neovim (e.g. Fugitive, AdvancedGitSearch, Telescope) to search for commits and explore them but they only get me so far.
This script is exactly what I want my workflow to be in searching for commits and exploring the diffs and then checking out that commit to run tests or do further exploration.
After running fshow
in my terminal, I am presented with all the git commits that I can fuzzy search over and a preview window to the right of them.
I setup several custom key bindings, use ctrl-f / ctrl-b to go up / down the preview window.
Hitting Enter will open a pager to explore the commit diff full screen and hitting q in the pager will take you back to fzf.
Ctrl-m will also open up the pager for previewing the commit diff.
If you hit q then you exit fzf and if you hit Ctrl-o it will checkout the git commit and exit fzf as well.
This let’s me quickly jump in and out of the git commit diffs and find exactly what commit I needed.
Walkthrough
The script stars by using git log
and setting a nice looking format. That is then piped into fzf with a preview window and a function is given to present a nice preview of the git diff.
The header
option is given to fzf to show a nice header for usage options as well as several bind
keymappings for quitting, paging up/down and checking out the currently selected commit.
#!/bin/bash
# Fuzzy search over Git commits
# Enter will view the commit
# Ctrl-o will checkout the selected commit
function fshow() {
git log --graph --color=always \
--format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
fzf --ansi --no-sort --reverse --tiebreak=index --bind=ctrl-s:toggle-sort --preview \
'f() { set -- $(echo -- "$@" | grep -o "[a-f0-9]\{7\}"); [ $# -eq 0 ] || git show --color=always $1 ; }; f {}' \
--header "enter to view, ctrl-o to checkout" \
--bind "q:abort,ctrl-f:preview-page-down,ctrl-b:preview-page-up" \
--bind "ctrl-o:become:(echo {} | grep -o '[a-f0-9]\{7\}' | head -1 | xargs git checkout)" \
--bind "ctrl-m:execute:
(grep -o '[a-f0-9]\{7\}' | head -1 |
xargs -I % sh -c 'git show --color=always % | less -R') << 'FZF-EOF'
{}
FZF-EOF" --preview-window=right:60%
}
fshow "$@"
It took me awhile to get the correct usage of bind and to figure out the become
option for fzf which allows the current fzf process to be taken over by the git checkout process.
Pretty nifty.
This script is incredibly mighty for how short it is and feels like much larger program to be able to support such functionality.
Check this one out for yourself and if you have any ways you would extend it then definitely let me know!
Conclusion
Fzf is truly an amazing piece of software and you can use it in so many different ways to search and explore files, git commits, git branches, and so many others. I learned a lot about fzf simply from researching and tweaking these scripts and I hope that you can get some of the benefits from them as well. Please share if you have other fzf scripts!
Here are a few other Neovim articles you should check out: