Search code examples
gitgithubversion-controlbranchgit-branch

Delete local Git branches if their remote-tracking references don't exist anymore


I have a local and a remote Git repository.

  • In my local repository I create and switch to a new branch: git checkout -b feature/niceNewFeature

  • I do my coding, git add ., git commit and git push my feature/niceNewFeature branch to the remote repository (e.g. GitHub).

  • After this I create a GitHub Pull Request to merge feature/niceNewFeature branch into master - after the code is reviewed, I will do so.

  • Since feature/niceNewFeature is now merged to master, I will delete it on GitHub.

  • However, in my local repository, feature/niceNewFeature branch is still listed if I execute git branch command.

How do I remove feature/niceNewFeature branch from my local repository, since it is already merged to master and deleted from the remote repository?


Solution

  • Short answer:

    git fetch --prune

    git branch -lvv | cut -c3- | awk '/: gone]/ {print $1}' | xargs git branch -d

    Detailed answer:

    Firstly, remove any remote-tracking references that no longer exist on the remote:

    git fetch --prune (or git fetch -p)

    If you do this, and then you run git branch -vv (verbose), you will see that although feature/niceNewFeature branch is still listed, the upstream branch is now "gone":

    feature/niceNewFeature  832f7a7 [origin/feature/niceNewFeature: gone] Some commit message.
    

    Secondly, let's remove the local branches, with the following command:

    git branch -lvv | cut -c3- | awk '/: gone]/ {print $1}' | xargs git branch -d

    What it does, is basically the following:

    1. Lists all local (-l) branches in verbose mode (vv) (that's almost like our previous output)
    2. It cuts the first and second characters from the beginning of every line (which are spaces)
    3. With awk it filters the "gone" ones (/: gone]/), and gets their first column ({print $1}). Remember, the "gone" means that the remote-tracking reference doesn't exist anymore.
    4. The output (which is the name of the branch to be deleted, feature/niceNewFeature in our case) is piped to git branch -d (delete) with xargs command, so it will delete the branch. Note that the branch must be fully merged in its upstream branch, because only -d option is used, not -D (which is --delete --force).