visit our site

Git housekeeping tutorial: clean-up outdated branches in local and remote repositories

In Development

by Sergii Boiko by August 11, 2014

After working with branch per feature for a while any Git-repository becomes a mess of outdated and not finished branches. To deal with this issue, we need to clean-up three kinds of branches:

  • Local branches – our day-to-day working branches
  • References to remote branches – aka origin/branch-name items
  • Actual remote branches – branches on remote server(e.g.: github, bitbucket, gitorius)

In this tutorial we suppose, that “master” – is a default branch, where everything is merged(for someone it could be “develop”, or “release” branch), and “origin” – it’s a name of remote. If you use different names, just change them in appropriate commands.

Local branches

At first, list all local branches:

We need to know what branches are already merged in “master” and can be easily removed:

Now, remove all outdated branches with:

Next, decide what to do with not merged branches:

If some of them is just abandoned stuff that you don’t need anymore, remove it with “-D” option:

References to remote branches

After each git pull or git fetch command Git creates references to remote branches in local repository, but doesn’t clean up stale references.

List referenced remote branches:

Clean-up outdated references:


Update repository with:

and Git automatically prunes all stale references.

Remote branches

Usually, remote repository is a big garbage heap of stale branches, if there is no responsible housekeeping person.

After previous git remote prune origin we should have synched list of remote branches.

At first, we can find branches which are already merged in “master”:

But this command does not provide much information. What if this branch is merged, but still used for feature development. Would be cool to know last commit date and author.

This magic snippet provides all required information:

Now, you can delete own remote branches, and ask other authors to clean-up theirs:

Similar snippet for not merged branches:

This list should be reviewed more thoroughly to avoid losing important commits.

Tip for Github users

After the last Github update, Branches page is divided into “Your branches”, “Active branches” and “Stale branches”, and it shows same information as previous commands.

Bonus snippets

Usually, it’s simple to remove local and appropriate remote branches at once.

This snippet shows only local merged branches, which have appropriate remote merged branches:

More hardcore snippet with date and author information:

Same snippets for not merged branches:

Moving stuff into .gitconfig

It’s hard to remember such code, so the best way is to create shell scripts and put them in local “bin” folder. Note that these snippets work only in bash(and zsh). For example, let’s put first snippet into “bin/git-both-merged” file:

Don’t forget to make it executable( chmod 755 git-both-merged), and you can also make a git alias for this script. Put next line in .gitconfig:

Now you can call it via git command:

In the same vein you can create git aliases for all snippets from this article.

That’s it, folks. Now, it’s time to clean-up all stale stuff!

* Railsware is a premium software development consulting company, focused on delivering great web and mobile applications. Learn more about us.
  • Alex Mishyn

    Is there any command to sync(smth like remove local branch is remote doesn’t exists) local branches with remote ?

    • Dmitry Pliska

      git fetch –prune

      • ayanko

        git config –global fetch.prune true

  • Artur Termenji

    Try to use ‘git branch -avv’. It shows all branches in one command (local + remote), and shows HEAD commit with hash and message for each branch.
    Pretty useful command to alias it for something like ‘gb’

  • ari gold

    From the git man page

    –merged []
    Only list branches whose tips are reachable from the specified commit (HEAD if not specified).

    which implies that if you’re working on a branch that hasn’t diverged from develop – say a new one – that it will show up in git branch --merged. It’s not really “merged” but it’s tip is reachable from the HEAD of where ever you run the command from (in this article master, with me develop). It’s not really a big deal to delete a branch that is equivalent to master (or develop) but it’s good to know why it’s showing.

    Speaking of articles, thanks for the great one!

  • Anil

    Nice article . is there any way we can delete remote branches based the particular date range. Ex : delete all the remote branches which are merged to master & not modified in last 4 months.

    • thanks for useful article Sergii Boiko.
      I would also be interested in answer to this question, it would be very useful.

  • Pablo

    chmod +x git-both-merged is better, it doesn’t touch r and w privileges.

  • Grégory Joseph

    If git-both-merged is in your PATH, you shouldn’t need an alias.

  • Pingback: Git : Tips & Tricks - Liip Blog Liip()

  • Did not know about git fetch -p

  • florian

    Thanks! Very helpful!

    • John Steill

      Ditto. Exactly what I was looking for. Thanks mate.

  • James

    What if I want to delete all branches that [are merged] + [are older than 30 days] + [do not start with “origin/rel”]?

  • Very useful thanks!

  • Christine Shaffer

    Thank you so much for this! Very clear & concise

  • Spindle

    In addition to local merged branches, you can also run

    to delete all the local merged branches as you saw in

  • Pablo Ezequiel Leone Signetti

    This is a very valuable knowledge! Thank you for sharing.

  • Stefano

    Thank you Sergii, there’s some very nice wizardry in your code! :)

  • Jin Kwon

    What a great information you shared! Thank you.

  • Aparna Sarkar

    Exactly what i was looking for…!!!

Signup for our weekly newsletter

Want to get more of Railsware blog?

RSS Feed

We're always ready to help!

Contact us