Deleting old branches & tags from local Git repository which are not present in remote
Published on

Deleting old branches & tags from local Git repository which are not present in remote


Git prune old branches which do not exist in the remote repository

git remote prune origin

Pruning origin
URL: https://XXXXX/_git/ui

- [pruned] origin/test

This command will remove all the remote-tracking branches which don't exist in the central repository. But this will not delete the branches which you've checked out. You'll have to use the below command to remove those branches that only exist in the local repository but don't have a tracking branch in the remote repository. We will only delete pruned branches, not local branches that were never pushed to the origin.

Here is the command which you'll need to run on Linux or macOS

git branch -vv | grep 'origin/.*: gone]' | awk '{print $1}' | xargs git branch -d

Deleted branch test (was 8301e25).

If you're on Windows then you'll need to run the below command in powershell

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Deleted branch test (was 8301e25).

If you don't have any branches that need to be deleted, you get the below error message because grep doesn't find any results and passes them on to git branch -d without any arguments. So make sure to run git remote prune origin first before running this command to delete local branches without tracking branch.

> git branch -vv | grep 'origin/.\*: gone]' | awk '{print $1}' | xargs git branch -d
fatal: branch name required

Your git repository will now be clean with only branches that have a remote tracking branch.

Deleting a Git tags locally & remotely

Let’s say you're are a programmer working on some project in GitHub. You work on a local cloned repository on your macOS and push commits to remote repository, i.e. GitHub to sync changes every time.

Now lets consider a repository which has some tagged commits A, B, C, D, E. And it also synched these tags with our remote repository but suddenly you felt that the tags B, D & E are not required. So you delete them directly in GitHub.

The next day when you're working on your local repository and you want to check the tags available in this repository you type in git tag -l which will list A, B, C, D, E. But you're expecting to see only A & C.

The next thought that comes to your mind would be to sync your repository with a remote one. So you run git fetch or git pull which would sync all your remote changes. But just to cross check you'll run git tag -l to find A & C, but the result is again not what you're expecting. it’s again A, B, C, D, E.

The reason being Git has a default disposition of keeping data unless it’s explicitly thrown away; this extends to holding onto local references to branches on remotes that have themselves deleted those branches.

If left to accumulate, these stale references might make performance worse on big and busy repos.

To delete a tag remotely you need to use --delete option with push. Please see the example below.

git push --delete origin v1.0.0

 - [deleted]         v1.0.0

But this would not delete the tag locally, you can check the same by running git tag -l.

git tag -l


You can prune the local repository tags which have been deleted remotely by using the following command

git fetch --prune --prune-tags

 - [deleted]         (none)     -> v1.0.0

Now if you list your tags you'll not find v1.0.0 locally.

git tag -l


To sync, i.e. prune your local repository with old tags you can run below.

git fetch --prune-tags

You can find more information on this in the official documentation

If want to configure git to always prune tags when fetching, then you can run the below command which would update your config:

git config fetch.pruneTags true