Jay Soffian <jaysoffian@xxxxxxxxx> writes: > Let's say you've got the following tracking branches: > > refs/remotes/origin/master > refs/remotes/origin/next > refs/remotes/origin/ghost > > And origin has only "master" and "next" (ghost has been removed upstream). > > Further, let's say you've got a refspec of: > > [remote "origin"] > fetch = +refs/heads/master:refs/remotes/origin/master > > What should "git remote prune origin" do? > > In my opinion, it should prune "next" and "ghost". "ghost" is gone > from upstream, so that's obvious. I think "next" should also be pruned > because the refspec indicates the user is no longer interested in it. > > Currently it doesn't do anything (it only considers "master" per the > refspec, which is still on origin, so it doesn't think there is > anything to prune). In your scenario, tracking branches for next and ghost couldn't have come from the refspec you have in the configuration, but they do exist. The user has added them on purpose, perhaps by temporarily using wildcard refspec, or perhaps by giving a refspec from the command line. It does not matter how they got there, but the important thing to keep in mind is that, even if the remote had refs/heads/{next,ghost}, we wouldn't update it if we ran "git fetch" now. In this situation, "git remote prune" should never prune 'next' nor 'ghost'. If we were to implement auto-pruning in 'git fetch', it should behave the same way. I would define the logic to decide if refs/remotes/REMOTE/BRANCH is stale to be: * See if there exists a refspec (either wildcard or concrete) that may cause "git fetch" to update the tracking branch in question, if the remote side had an appropriate ref. If there is no such refspec, stop here. It is not stale. In your example, when considering refs/remotes/origin/master, there is such a refspec, and the "appropriate ref" is "refs/heads/master" on their side. When considering refs/remotes/origin/{next,ghost}, there is none. You stop here. * Then see if that ref exists at the remote side. If it exists, stop here. It means "git fetch" would update the tracking branch in question, so it is not stale. In your example, when considering refs/remotes/origin/master, the matching remote ref 'refs/heads/master' exists, so our tracking ref is not stale. * Otherwise, it is stale, and we can prune it. Imagine a hypothetical "git fetch" that understands a ref with a magic value 0{40} to signal "this ref is gone", and imagine what happens if the origin had 'ghost' that has such a magic SHA-1 in it. It would become easier to understand how the above logic works. - When you issue "git fetch" under the condition of your example, think what would happen to 'next' (which has an ordinary value, not the magic "delete this" request). Nothing happens. We do not update it. - Nothing happens to 'ghost' either when you issue "git fetch". It does not matter if that ref has this magic 'delete this' value. Nothing happens because we were told by the refspec not to even look at these refs/heads/{next,ghost} refs on the other side. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html