Mastering Git Branches and Commits with fzf: Speed Up Your Workflow
Written on
Chapter 1: Efficient Git Workflow
A significant part of being a software engineer involves effectively using Git to manage your work within a codebase. Another crucial component is the ability to swiftly find and utilize relevant information, particularly in Git. Below, you'll find a couple of fzf scripts that I've modified to better suit my workflow. Feel free to adapt these scripts, and if you have any updates or additional scripts that you find useful, please share!
I maintain a file in my home directory (e.g., ~/fsb.sh) and have created an alias in my ~/.zshrc to reference it (e.g., alias fsb=~/fsb.sh).
Section 1.1: Searching and Checking Out Git Branches
Currently, I haven't transitioned to using worktrees in Git, so I frequently need to check out different branches throughout my workday. Often, I join ongoing projects from other developers and must pull their branches to start my work.
To simplify this process, I use the script below by typing fsb (Fuzzy Search Branch) in the terminal. This command opens a floating window in the center of my screen, allowing me to select and check out a branch. If I press Esc, no changes are made, and I return to my terminal.
Walkthrough
The script begins by retrieving all Git branches with git branch --all and subsequently opens a selection window using fzf-tmux to choose from the available branches. If no branch is selected, the function exits early. The final step involves executing git checkout on the chosen branch after sanitizing the input to remove any extraneous text.
#!/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're looking for a way to fuzzy search branches and quickly check them out using fzf, this script is your solution.
Section 1.2: Browsing Git History with Preview
I've experimented with various plugins in Neovim (like Fugitive, AdvancedGitSearch, and Telescope) to search and explore commits, but they only meet some of my needs. This script aligns perfectly with my workflow, allowing me to search for commits, view diffs, and check out specific commits for testing or further exploration.
Upon entering fshow in the terminal, I see all the Git commits available for fuzzy searching, along with a preview window on the right side. I set up several custom key bindings, using ctrl-f / ctrl-b to navigate the preview. Pressing Enter opens a full-screen pager to examine the commit diff, and pressing q returns me to fzf. Ctrl-m also provides a preview of the commit diff.
If you wish to exit fzf, simply press q, and if you hit Ctrl-o, it will check out the selected commit while exiting fzf.
Walkthrough
The script starts by executing git log with a visually appealing format. This output is piped into fzf, which includes a preview window and a function to display the corresponding git diff. The header option in fzf provides a user-friendly title for usage instructions, along with several key mappings for quitting, paging up/down, and checking out the 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 some time to master the correct usage of the bind command and to understand the become option for fzf, which allows the current fzf process to be taken over by the git checkout process. This script is surprisingly powerful given its brevity and feels like a more extensive program due to its capabilities.
If you have any suggestions to enhance it, I'd love to hear them!
Chapter 2: Conclusion
Fzf is an incredibly versatile tool that can be leveraged in numerous ways to search and navigate files, Git commits, branches, and much more. My exploration and modification of these scripts have taught me a lot about fzf, and I hope you can reap some benefits from them as well. Please share any other fzf scripts you may have!
If you enjoyed this article, consider subscribing to Medium! For more Neovim articles, check these out:
If topics like this interest you, feel free to visit my YouTube channel. Have a fantastic day!
Discover how to search Git branches and commits rapidly with fzf.
Learn how to utilize fzf with Git for an efficient workflow.