PolyWolf's Blog

added this to my .zshrc

Published: 4/4/2024, 6:35:35 PM

Originally published on Cohost in 2 parts.


alias prune="git remote prune origin | sed -n -E '/polywolf/ s/.*(polywolf.*)/\1/p' | xargs git branch -D"

because i found myself typing it out from memory that often

oh no… I’m becoming one of Those girlies aren’t i…

”PolyWolf, What Does This Do?”

i’m glad you asked!! let’s break it down:

NOTE: this assumes some familiarity with how git branches work. See this and potentially this for quick explainer

Goals

in git, I like to use short-lived feature branches that I then rebase onto main, squash to a single commit, and delete1. Turns out this style of git is so common that GitHub has a dedicated option for doing this with a single click on a pull request.

The problem with the GitHub click is that, while the branch is deleted in the remote repository, the branch you were working on locally is still around and clutters up git branch output and any tab-complete things you have set up. So! What we want to do, then, is have a command that you can run periodically to delete local branches that were deleted on the remote.

Getting A List Of Branches To Delete

This is actually a tricky UX question! How do you know the difference between a “deleted branch” and “a branch you haven’t pushed yet”? The answer is, you don’t! There is no way for git to know this information 🙂

But! We can still do something that’s almost as good: getting a list of branches that have been deleted on the remote since the last time you did a prune. There is a command for this: git remote prune origin. This will look at all the locally-cached remote-tracking branches (the ones starting with origin/), and delete any that are no longer present on the remote.

This is almost exactly what we want. But as I said earlier, even if the branch origin/polywolf/feature-branch is deleted, polywolf/feature-branch will stick around. Fortunately, git remote prune origin prints out what it does. Unfortunately, there are no formatting options for its output, so we resort to Manually Parsing It.

Editing Streams With The Stream EDitor

this is in fact what sed is meant to do! Let’s break down the specific invocation I use:

The Arguments

From sed --help

The Script

From man sed (let’s be real here) searching on Stack Overflow:

Great! We’ve collected all the branches we need into a “list” (newline-separated strings), and now we just need to delete them. But how?

Deleting A Branch

The command to delete a branch is git branch -d. However, in this normal delete, git will complain the branch hasn’t been merged. We don’t care about this, because our feature branches have been effectively added as a commit on main, so we need to tell git “yes we really want to delete this branch”, which we can do with git branch -D.

Deleting ALL The Branches

The typical way of iterating over a list in bash-likes is

for branch in $(the-expression)
do
  git branch -D "$branch"
done

This is the same as running git branch -D b1; git branch -D b2; git branch -D b3; ..., which, while somewhat inefficient from starting so many processes, Just Works™️. But! As it turns out, git branch -D b1 b2 b3 ... has the same effect, so we can use xargs (I absolutely adore xargs, it is so useful in one-liners).

xargs takes in a “list” on standard input, and then turns that into an argument list it appends to whatever command you give it. So, given the list of branches we have currently, xargs git branch -D does exactly what we want!

And there you have it! A comprehensive explanation of a 1-liner I wrote for my own purposes that will probably be useful to no one else. This is the power of custom aliases/scripts, u can really tailor your own shell experience. it’s almost too powerful… i still have a lot to learn tho!

Footnotes

  1. I did a couple internships at a Mercurial shop and have sworn by this model ever since. You Will Never3 Convince Me Merge Commits Are Good

  2. this is fancy Regex speak. don’t worry about it kitten 2

  3. ok Never is a strong word but u get my point

#programming#shell scripting