Jez
Jez

Reputation: 30073

Pruning git branches

You can prune tracking branches in your repo that no longer exist on the remote repo using:

git remote prune [remoteName]

However this will only get rid of the tracking branches and not any local branches you have set up in addition, eg.:

$ git branch
* master
  some-remote-branch

$ git remote prune origin
Pruning origin
URL: https://myserver.com/DefaultCollection/_git/Repo
 * [pruned] origin/some-remote-branch

$ git branch
* master
  some-remote-branch <-- non-tracking branch still here!

Is there a way you can also prune the local non-tracking branches associated with pruned tracking branches, or do you always have to delete these manually?

Upvotes: 3

Views: 3212

Answers (2)

Marina Liu
Marina Liu

Reputation: 38116

git can not prune the local branches which tracking branches are deleted.

And the common ways to delete the local non-tracking branches are based on below situations:

Situation 1: There has a few branches in the git repo

If there has a few branches in your local repo, you can delete the local non-tracking branches manually.

You can use the command git branch -a to compare the remote tracking branches with local branches, and then delete related branch(es) manually.

Situation 2: There are lots of branches in git repo

If there are lots of branches in your git repo, or if you do not want to compare and delete the local non-trackign branches manually, then you can delete the local non-tracking branches automatically by scripts.

Below is the example with shell script to delete the local non-tracking branches automatically (assume master branch won’t be deleted):

#!/bin/sh

git fetch -p
#checkout HEAD to the branch which you will never delete, here as master won't be deleted
git checkout master

for local in $(git for-each-ref --format='%(refname:short)' refs/heads/)
do
{
  if [[ $(git branch -r) =~ $local ]]; then
    echo "local branch $local has related tracking branch"
  else
    git branch -D $local
  fi
}
done

Then the local non-tracking branch(es) will be deleted aothmatically.

BTW: except the git remote prune [remoteName] to prune a tracking branch, you can also use git fetch -p to prune all the tracking branches.

Upvotes: 1

Rudolf Tucek
Rudolf Tucek

Reputation: 349

This is not possible in git.

Git's first class principle is to avoid deleting data by accident. If you push your local branch and someone else (a co-maintainer) may delete it (by accident), you would have lost your entire work if you run the git remote prune cmd the next time (although you may recover your work via the git's reflog for a short time - but that's another story).

There is no automatic cleanup for local branches. You can observer similar behavior if you merge branch A into brach B. Branch A is still there - even after becoming obsolete - and YOU still have to delete it manually (again - on purpose).

Now that said, you can try something like this (pls, don't blindly copy'n'paste this snippet in your cmd line!)

git branch --merged | xargs git branch -d 2>/dev/null

This will delete literally all merged branches. Now it's very important to understand merged is a relative term. Merged means any tip of a local branch, that is a child of that branch you're running this command from.

If you run this from your master branch, you will get probably what you want - all obsolete/merged branches (from the perspective of the master branch) will be deleted - even a branch that might be called develop. However, if you run this from a different branch... well don't blame me for having any previously merged branches deleted.

PS: you can run git fetch -p or git fetch --prune. This will delete all stale remote branches. If you don't want to add the flags all the time, you can put

[fetch] prune = true

into your ~/.gitconfig

Upvotes: 2

Related Questions