So I was working on an old, crusty veteran of a git repo and I noticed it had ~300 branches on remote. This rubbed me the wrong way so I spent some time cleaning up all of those branches. Here’s what I learned:
Finding Branches
git fetch will pull down all the remote refs
git remote prune your_remote will remove any remote refs you have locally that have been removed from your remote
git branch will show all of your local branches
git branch -a will show all of your local/remote branches
git branch -a --merged will show you all of the branches that have been merged into your current branch.
git branch -a --no-merged will show you all of the branches that haven’t been merged into your current branch.
Deleting Branches
git branch -d branch_name will delete the given branch locally
git push your_remote :branch_name will delete the given branch on your remote.
Putting it together
So, deleting those excess branches might look something like:
git checkout develop
git fetch
git remote prune your_remote # Don't show branches that have already been deleted
git branch -a --merged # This will show all branches that have been merged into develop
Then, once you have your branch names to delete
git branch -d branch_name
git push your_remote :branch_name
Automating the Process
You can easily write a bash script (or ruby, or whatever) that goes through (maybe as a cron job) and deletes merged branches.
I elected not to do this for now because I have a strong aversion to the combination of ‘automatic’ and ‘hard-delete’ .
One thing to keep in mind here is that if you have a master branch and a develop branch (like in git flow) running the command git branch --merged will likely list develop from the master branch.
Keeping it clean
For the first ~290 branches I had sitting around, I copy and pasted all of the branch names into a new textmate window and used the bulk line update to prepend git push your_remote : to each line, then I ran that file as a shell script.
Moving forward, I just ensure that any time a feature branch is merged into develop I delete that branch locally and remotely. That way the repo is always nice and slim.
Matt Brdiges
Jul 10, 2012
Wow! This is fantastic! Didn’t know about `git remote prune`. I have to do this every so often with my team (we end up with 30 or 40 hanging branches on a regular basis, but not mine! ;) ), so this will be very helpful!
Jordan Maguire
Jul 10, 2012
Awesome Matt, glad I could help you out
mlambie
Jul 10, 2012
I love the gardening metaphors: pruning excess branches like you would a tree.
Samuel Cochran
Jul 15, 2012
Like you mention, I use y shell to optimise this to only one interaction with remote (but not in cron):
git push origin $(git branch -r --merged origin/master | sed "s/origin\\//:/" | egrep -v "HEAD|master|develop")If you want to see what it does first, chuck an
echoin front.Uros Jurglic
Jul 16, 2012
Good post!
One addition I use quite a lot – fetches remotes and prunes local that were deleted:
git fetch -p
Jason Rudolph
Jul 16, 2012
Good stuff!
As a bonus, recent versions of Git have added some usability improvements to make these tasks easier and more intuitive.
=== Fetch and Prune in One Step ===
Prior to Git 1.6.6, you needed two steps into order to fetch and prune:
git fetchgit remote prune your_remote
As of Git 1.6.6, you can actually combine fetching and pruning in a single command.
git fetch --prune=== Improved Syntax for Deleting Remote Branches ===
I would argue that the original syntax is odd and a bit unintuitive for deleting remote branches:
git push your_remote :branch_nameWho thought “:” was a good indicator for “delete”? ;-)
As of Git 1.7.0, you can use this alternative syntax to delete remote branches:
git push your_remote --delete branch_nameJordan Maguire
Jul 17, 2012
Nice – Thanks Jason and Uros.
Valeriy
Jul 17, 2012
>>>You can easily write a bash script (or ruby, or whatever) that goes through (maybe as a cron job) and deletes merged branches.
You can use gitlab. There is function automerge branch with option “delete source-branch”
Jason Rudolph
Jul 17, 2012
It looks like WordPress decided to apply some unintended formatting to my comment above. There should be two dashes before “prune” and “delete”.
Let’s see if this makes WordPress happy:
Fetch and prune:
git fetch --pruneDelete remote branch:
git push your_remote –delete branch_nameJohn Athayde
Jul 17, 2012
You need to put them in a code block to get it to not auto parse the double dash into an em-dash
Pingback: Git Basics: Cleaning up excess branches « Coffee & diamonds – Information about the Java and Ruby worlds!!!