I like automating commands that I run often, and one of my favorite command line tools to use when automating scripts involving selection is FZF.
A very common task I do is create PR based on another git branch, or it’s more advanced version: create a PR based on a Jira ticket, as I published in a previous post.
Here’s a simple example using FZF and Github CLI:
gh pr create --base "$(git branch | fzf)" --draft --title "[DRAFT] Feature XYZ"
Cool, right?! In this example the branch I select is likely going to be some integration branch different than my current branch and everything should work fine.
But what happens when I need to use the current branch name in a script? For example, let’s say you are trying to push the current branch to a different remote branch1.
Easy! Let’s use
git branch and pipe it into
fzf as before, right?
git push $(git branch | fzf):some-remote-branch
Not so fast, cowboy! It’s easy to forget that, but
git branch is a CLI command
with output intended for humans, not scripts. Let’s review again what happens if
develop * XYZ-123-smtp-client ABC-456-shopify-api
In this example
git is trying to be helpful by showing you which branch is the
current one with the
* character. Unfortunately,
* is also a meaningful
character which is parsed by
git as a wildcard 🙀. So if you ran this command
above, and selected the current branch this is going to be the actual command:
git push * XYZ-123-smtp-client:some-remote-branch
git then translates to “all local branches”:
git push develop ABC-456-shopify-api XYZ-123-smtp-client XYZ-123-smtp-client:some-remote-branch
Yikes! This means that your local copy of
develop (stale / with any changes they have over the
remote) will be unintentionally pushed to their default upstream branch as well!
And that’s only if you have 2 stale branches locally, what if you have more?!2
The reason I didn’t catch this for many years has been because I usually needed to grab the name of another branch.
git branch has a
--format option that allows returning just the
branch names with no “current” indicator:
git branch --format='%(refname:short)'
Next time you use
git branch in a script remember to use the
--format flag to
avoid a mess!
- Maybe you think this is a contrived example because you can just type your branch name and call it a day. But what if you use this command often and your branch names are by convention long and annoying to type because they contain a ticket number and the ticket title.↩
- You may want to check out this other alias I use to clean remotely deleted branches locally.↩