Install purge-unused-git-branches

Demo

https://user-images.githubusercontent.com/5678065/142405828-21e7a439-b127-4fcb-af13-7cbe6d947400.mov

Purpose

I find it quite annoying to keep old/unused Git branches in my local repositories. Most of the time, those branches have been merged some time ago, but I keep on forgetting to delete them manually. So I made this little utility to help me/you with that 😇

It will simply compare your local branches with the remote ones, and ask you if you wish to delete all the unused branches, or select the ones you want to remove manually.

Notes

You must use this script in your terminal, in a Git repository folder. This is why I excluded it from the Kit UI. Adding Kit scripts to your Path will make it easier to run this one from anywhere:

# Add this in your .zhsrc or .bashrc
export PATH=$HOME/.kenv/bin:$PATH

Then run the script from anywhere (in a Git repo):

purge-unused-git-branches

Source

/** @type {import("@johnlindquist/kit")} */
// Exclude: true
$.verbose = false
const TOKENS_TO_REMOVE = ["* ", "origin/", "HEAD -> "]
// Utility to process ZX output by converting lines into an array and removing
// some tokens from the branch names (so remote branches and local branches have
// the same name)
const processOutput = (output) => [
...new Set(
output
.split("\n")
.map((branch) => {
let res = branch.trim()
TOKENS_TO_REMOVE.forEach((token) => (res = res.replaceAll(token, "")))
return res
})
.filter((branch) => branch.length > 0)
),
]
// Retrieve remote and local branches
console.log("Parsing remote and local branches...")
const remoteBranches = await $`git branch -r`.then((output) =>
processOutput(output.stdout)
)
const localBranches = await $`git branch`.then((output) =>
processOutput(output.stdout)
)
// Compute the set of branches that are not used
const branchesToRemove = localBranches.filter(
(branch) => !remoteBranches.includes(branch)
)
// No branches to remove, nothing to do !
if (branchesToRemove.length === 0) {
console.log("No branches to remove. All good 👌")
exit()
}
// Output the list of branches to remove
console.log(
`Found ${branchesToRemove.length} branches that only exist locally:`
)
branchesToRemove.map((branch) => console.log(` - ${branch}`))
console.log()
// Ask the user to confirm the list of branches to remove
const choice = await arg({
placeholder:
"Do you wish to delete all thoses branches, or select some manually ?",
hint: "[a]ll/[s]elect",
})
if (choice === "a") {
// Removing all branches at once
console.log("Deleting all branches...")
for (const branch in branchesToRemove) {
await $`git branch -D ${branchesToRemove[branch]}`
}
console.log("✅ Done.")
} else if (choice === "s") {
// Ask the user to select branches to remove
for (const branch in branchesToRemove) {
const branchName = branchesToRemove[branch]
const answer = await arg({
placeholder: `Delete ${branchName}?`,
hint: `[y]es/[n]o/[e]xit`,
})
if (answer === "y") {
try {
await $`git branch -D ${branchName}`
console.log(`✅ Branch ${branchName} successfully deleted locally.`)
} catch (err) {
console.error(
`❌ Something went wrong while deleting your branch ${branchName}.`
)
}
} else if (answer === "e") {
console.log("Exiting...")
break
}
}
}
console.log("All done, bye 👋")

Install purge-unused-git-branches