115

From the man page:

Deletes all stale tracking branches under <name>.
These stale branches have already been removed from the remote repository
referenced by <name>, but are still locally available in "remotes/<name>".

So I removed a bunch of branches using

git push origin :staleStuff

and then ran

git remote prune origin

However, only one single local branch was pruned. Some of these branches were created by me, some by co-workers. Does this indicate that I wasn't tracking those branches correctly in the first place?

msouth
  • 832
  • 11
  • 21
Felixyz
  • 19,053
  • 14
  • 65
  • 60

1 Answers1

191

When you use git push origin :staleStuff, it automatically removes origin/staleStuff, so when you ran git remote prune origin, you have pruned some branch that was removed by someone else. It's more likely that your co-workers now need to run git prune to get rid of branches you have removed.


So what exactly git remote prune does? Main idea: local branches (not tracking branches) are not touched by git remote prune command and should be removed manually.

Now, a real-world example for better understanding:

You have a remote repository with 2 branches: master and feature. Let's assume that you are working on both branches, so as a result you have these references in your local repository (full reference names are given to avoid any confusion):

  • refs/heads/master (short name master)
  • refs/heads/feature (short name feature)
  • refs/remotes/origin/master (short name origin/master)
  • refs/remotes/origin/feature (short name origin/feature)

Now, a typical scenario:

  1. Some other developer finishes all work on the feature, merges it into master and removes feature branch from remote repository.
  2. By default, when you do git fetch (or git pull), no references are removed from your local repository, so you still have all those 4 references.
  3. You decide to clean them up, and run git remote prune origin.
  4. git detects that feature branch no longer exists, so refs/remotes/origin/feature is a stale branch which should be removed.
  5. Now you have 3 references, including refs/heads/feature, because git remote prune does not remove any refs/heads/* references.

It is possible to identify local branches, associated with remote tracking branches, by branch.<branch_name>.merge configuration parameter. This parameter is not really required for anything to work (probably except git pull), so it might be missing.

(updated with example & useful info from comments)

Code Commander
  • 16,771
  • 8
  • 64
  • 65
max
  • 33,369
  • 7
  • 73
  • 84
  • I understood the situation to be: the branches are still present locally but removed from remote repo. Now I want to remove all local branches that do not exist on the remote, therefore I run git prune. That's what "These stale branches have already been removed from the remote repository" says to me. Am I wrong? – Felixyz Nov 02 '10 at 15:04
  • 3
    You are right, but you may have misunderstood the meaning of "local branches" in case of `git prune`. Only branches in `/refs/remotes//` are subject to pruning; any branches in `/refs/heads/` won't be touched - you have to manually manage these. – max Nov 02 '10 at 15:28
  • Aha, that's indeed what I thought. So there's no way to do what I want: automatically delete all branches in heads that are tracking remote branches, by checking if those remote branches are deleted? – Felixyz Nov 03 '10 at 19:11
  • 2
    There is no built-in command for that, but you may write such script yourself. Tracking branches can be identified by presence of `branch..merge` config parameter. – max Nov 03 '10 at 19:48
  • This answer would be better if you added the information in the comments into the answer itself so that everyone who comes here and has the same misconception as @Felixyz doesn't have to look at your answer funny and then read the comments to finally gain understanding. – Akrikos Jul 24 '15 at 17:48