Pergunta

How to delete feature branches that is already feature completed?

In my local machine when I run 'git branch' I still see old branches that no longer exist in the remote repo.

I tried running: 'git fetch -p'

It says deleted on some branch, but when I run 'git branch', they are still there.

Is there a way to delete them all with one command?

Foi útil?

Solução

In git, you have "branches", which are yours and yours alone; and then you have "remote branches", which—despite the name—are actually local, but are created and deleted bases on the branches your git sees whenever it contacts a remote git and asks it: "hey, what branches do you have over there?"

When you run git fetch -p it contacts your remote (usually origin) and gets its list of branches, and then deletes the remote branches that are gone on the remote.

When a remote branch like feature exists and you do git checkout feature, that creates a local branch called feature, that "tracks" your remote-branch known as origin/feature. When they, on the remote, delete their feature, your git fetch -p only deletes the remote/feature branch. So there's nothing left for your local branch to track, but git fetch won't delete your local feature, only origin/feature. Just because they are done with theirs, does not mean you are done with yours.

If you are done with yours, you should just delete it yourself:

git branch -d feature

This will give you an error message if there are some commit(s) that will become "unreachable". If it does, but you're really sure you want to delete it anyway, use a capital-D delete:

git branch -D feature

to delete it anyway. Be careful, as a typo here that deletes the wrong thing can make for some terrible hours of recovering stuff.


Edit to add, per comments on original posting: if you want to automate the deletion of local branches that have an upstream set, but the upstream itself is gone, you would need a script to do it. Something like this (totally untested) is likely to work:

#! /bin/sh

git for-each-ref --format '%(refname:short)' refs/heads |
while read branch; do
    # $branch is the local branch, see if it has an upstream configured
    remote=$(git config --get branch.$branch.remote) || continue
    upstream=$(git config --get branch.$branch.merge) || continue
    # $branch is configured with an upstream
    [ "$remote" = "." ] && continue # upstream is local: skip

    # If remote branch still exists, skip this local branch.
    # Note: assumes remote.$remote.fetch = +refs/heads/*:refs/remotes/$remote/*
    # We could try to parse remote.$remote.fetch lines but that is too hard
    # for me to just type in as a throwaway script on SO.
    git rev-parse -q --verify $remote/$upstream >/dev/null && continue
    echo "$branch is configured to track $remote/$upstream but that's gone"
    echo "I'll try a safe delete here"
    git branch -d $branch
done

(I would not use git branch -D here, that's too dangerous.)

Outras dicas

I found something that can delete all obsolete branches:

git branch --merged | xargs git branch -d
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top