Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git fetch prune is not working

I have a bunch of remote branches that were deleted and now I want to remove the branches locally. I've tried:

git fetch -p

but it does not work.

If I do:

git branch -r

and

git branch

the lists are not the same because git branch still lists deleted remote branches, even after I run git fetch -p. I've seen this as the accepted answer to do this in quite a few questions on here, but it isn't working for me.

I'm not sure I've worded the problem correctly so here's another explanation. Say I have:

GitHub: (remote)
    Branch A
    Branch B
    Branch C

Local:
    Branch A ==> (remote) Branch A
    Branch B ==> (remote) Branch B
    Branch C ==> (remote) Branch C

Now somebody deletes a branch on GitHub, giving:

GitHub: (remote)
    Branch A
    Branch C

What I want my local repo to look like is:

Local:
    Branch A ==> (remote) Branch A
    Branch C ==> (remote) Branch C

like image 765
Christopher Perry Avatar asked Jan 23 '14 19:01

Christopher Perry


People also ask

What is fetch prune in git?

git fetch --prune is the best utility for cleaning outdated branches. It will connect to a shared remote repository remote and fetch all remote branch refs. It will then delete remote refs that are no longer in use on the remote repository.

Does git fetch delete local branches?

git fetch would prune remote references that do not exist (if you added that to your config file), and the rest of the command deletes local branches that have been merged.

How do I prune local branches?

Prune/Cleanup the local references to remote branch The command git remote prune origin --dry-run lists branches that can be deleted/pruned on your local. An option --dry-run is needed. Now go ahead and actually prune/cleanup the local references by running the command git remote prune origin .


2 Answers

To expand on hobbs' comment, git fetch -p (or git remote prune or any similar command) only deletes, from your repository, each "remote branch" that is no longer present on the remote.

If you've made a local branch, that label won't go away unless you delete it manually.

For instance, suppose on remote origin, there was a branch named sparkly:

$ git fetch
...
 * [new branch]      sparkly    -> origin/sparkly

You don't have a branch named sparkly at this point (unless you already had one!); you only have origin/sparkly (which lives in a separate name-space, refs/remotes/ rather than refs/heads/).

If you created your own branch named sparkly earlier, it probably does not track this new origin/sparkly. If you create your own branch named sparkly now, though, it will track origin/sparkly.

In both cases, though, nothing will delete it automatically. You have to do that manually.

One reason why: there's no guarantee that just because origin/sparkly has gone away, you are done with it ("it" being the local branch you created, which may or may not track this remote branch). If git deleted your label along with the origin/ version, any commits you had been working on might become very hard to find.

So, the short answer is: you'll have to do this manually (or semi-manually, you could automate it as much as you like). Use:

git branch -d sparkly

to delete it only if that's "safe" (in git's opinion :-) ), or:

git branch -D sparkly

to delete it even if git thinks this is "unsafe".

like image 174
torek Avatar answered Nov 05 '22 14:11

torek


To "forget" locally, removed remote branches you could do

git remote prune myRemote

(Edit to take the comment into account)

Now, to delete your local branches as well you could do

remote=origin

for branch in $(git branch | sed 's/\*//'); do                          
  if [ -z "$(git branch --all | grep $remote | grep $branch)" ]; then   
    git branch -D $branch  
  fi                                                                    
done                    

If you plan to do this kind of manipulation often, you could put this in a script in your PATH, call it git-delete-local-to-sync, and then, in your repo, just type git delete-local-to-sync

like image 25
gturri Avatar answered Nov 05 '22 16:11

gturri