Skip to content

Instantly share code, notes, and snippets.

@trungly
Created December 3, 2024 23:05
Show Gist options
  • Save trungly/8cd5f7850e86a8f572ecd59a8eab4d7b to your computer and use it in GitHub Desktop.
Save trungly/8cd5f7850e86a8f572ecd59a8eab4d7b to your computer and use it in GitHub Desktop.
#!/usr/bin/env fish
### Finds and optionally deletes all local branches that have been squashed-merged on remote
# Fetch latest from remote to ensure up-to-date references
git fetch --prune
# Get the list of local branches excluding the current one
set local_branches (git branch --format="%(refname:short)")
# Initialize an empty list to store branches to delete
set branches_to_delete
# Define protected branches
set protected_branches "ci" "uat" "staging" "prod" "master"
# Loop through each local branch
for branch in $local_branches
# Skip the current branch and protected branches
if [ $branch = (git rev-parse --abbrev-ref HEAD) ]
continue
end
# Check if branch is protected
if contains $branch $protected_branches
continue
end
# Check if the branch has been squash-merged on the remote main branch
# For squash-merged branches, we need to:
# 1. Find the merge base between the branch and main
# 2. Create a temporary commit with the branch's tree and merge base as parent
# 3. Use git cherry to see if this content is already in main
set merge_base (git merge-base origin/main $branch)
set temp_commit (git commit-tree (git rev-parse $branch^{tree}) -p $merge_base -m _)
set cherry_result (git cherry origin/main $temp_commit)
# If cherry result starts with "-", the changes are already in main
if string match -q -- "-*" $cherry_result
set branches_to_delete $branches_to_delete $branch
end
end
# If no branches were found, notify and exit
if test (count $branches_to_delete) -eq 0
echo "No local branches found that were squash-merged on remote."
exit 0
end
# Show all branches that will be deleted
echo "The following branches appear to be squash-merged on remote:"
for branch in $branches_to_delete
echo " - $branch"
end
# Prompt once for all branches
echo "Do you want to delete all these branches? (y/N)"
read -l confirm
if [ $confirm = "y" ]
for branch in $branches_to_delete
git branch -D $branch
end
else
echo "Operation cancelled. No branches were deleted."
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment