Skip to content

Instantly share code, notes, and snippets.

@Emuentes
Last active September 17, 2018 14:26
Show Gist options
  • Save Emuentes/48848aaddf3e7cc3b13e to your computer and use it in GitHub Desktop.
Save Emuentes/48848aaddf3e7cc3b13e to your computer and use it in GitHub Desktop.
Delete remote git branches that have been merged into develop
# Breakdown of the process
# NOTE: I am searching for branches merged into Develop because I'm using GiT flow
# 1) git branch -r --merged develop
# Get remote branches that have been merged into develop
# 2) grep -v -E '(\*|master|develop)'
# From those branches returned by the above command,
# exclude: master, develop, & the currently selected branch (the branch name beggining with an asterisk)
# 3) cut -f2- -d '/'
# Step 2 returns branch names prefixed with "origin/"
# The cut command uses delimiter '/' to split the string at the FIRST slash.
# -f2- asks the cut command to print "field 2" everything after the slash until the end of the line.
# This is important because we need the branch name WITHOUT the "origin/" prefix for the final command.
# ==> What happens without cut? <==
# Let's say you have some branches with names like, "parent/child/sub-child" on origin.
# Before cut, each remote branch name printed at step 2 looks like this: "origin/parent/child/sub-child"
# The final command will attempt to delete "origin/origin/parent/child/sub-child"
# You will get this error, "error: unable to delete 'origin/parent/child/sub-child': remote ref does not exist"
# 4) xargs -n 1
# I set xargs parameter "-n" to 1 to ensure that at most one argument is taken
# from the input to be passed to the invocation of the new command.
# The result is that the final command gets run once per line.
# The resulting commands that xargs will invoke are effectively:
# $ git push origin --delete add_new_user_gravatar_links
# $ git push origin --delete assign_unique_key_to_uploads
# $ git push origin --delete remember_the_last_activity_per_user
# $ git push origin --delete update_kaminari_to_thread_safe_version
# 5) git push origin --delete
# Delete the remote git branches one by one as listed from step 2 forward.
# References
# printing all remote branches that have been merged
# http://stackoverflow.com/questions/226976/how-can-i-know-in-git-if-a-branch-has-been-already-merged-into-master#answer-227026
# xargs explanation
# http://stevenharman.net/git-clean-delete-already-merged-branches
# "cut" and GREP's "-o" options explained on UNIX stack exchange forum
# http://unix.stackexchange.com/questions/24140/return-only-the-portion-of-a-line-after-a-matching-pattern#answer-149211
# Deleting remote branches
# https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches#Deleting-Remote-Branches
echo "Deleting remote branches that have been merged into Develop, excluding develop, master, and the currently checked out branch"
git branch -r --merged develop | grep -v -E '(\*|master$|develop$)' | cut -f2- -d '/' | xargs -n 1 git push origin --delete
echo "Removing remote tracking for the branches that no longer exist"
git remote update -p
# An alternative the command on the line above -> git fetch --all --prune
echo "Remote branches cleaned up"
@mattcpchen
Copy link

good stuff.

@Emuentes
Copy link
Author

There is a somewhat minor flaw in this script.

Branches with the word "develop" anywhere in their name are excluded by:
grep -v -E '(\*|master|develop)'

@Emuentes
Copy link
Author

changing to the following will only include branches that end in the word develop or master... for my purposes this is what I want so I am adding this to my gist.
grep -v -E '(\*|master$|develop$)'

Keep the above in mind if this is not your intent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment