3

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?

Jez
  • 27,951
  • 32
  • 136
  • 233
  • Then why don't you simply delete them `git branch -d some-remote-branch`? – Maroun Jan 22 '18 at 10:03
  • Did you read the question? That is deleting the branch manually. – Jez Jan 22 '18 at 10:07
  • Ah, missed last part. AFAIK you have to delete them manually. – Maroun Jan 22 '18 at 10:10
  • 1
    The fact that the upstream branch is gone doesn't mean your own should just go away. What if you made a commit or two on it that you want to save? (Git doesn't know if you did or not, it just keeps it since that's the safe default.) – torek Jan 22 '18 at 14:17
  • Possible duplicate of [Remove local branches no longer on remote](https://stackoverflow.com/questions/7726949/remove-local-branches-no-longer-on-remote) – 1615903 Jan 22 '18 at 17:20
  • Related question [How can I delete all git branches which have been “Squash and Merge” via GitHub?](https://stackoverflow.com/q/43489303/873282). – koppor Mar 28 '21 at 16:09

2 Answers2

2

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

Rudolf Tucek
  • 349
  • 4
  • 10
1

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.

Community
  • 1
  • 1
Marina Liu
  • 36,876
  • 5
  • 61
  • 74