{"thread":{"id":"21491","subject":"Bug in git remote prune?","startedAt":"2009-11-06T00:34:03Z","lastAt":"2009-11-06T01:58:01Z","messageCount":3,"participants":["Jay Soffian","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"126938","messageId":"76718490911051634w2d364b73m567e73039508c857@mail.gmail.com","threadId":"21491","inReplyTo":null,"subject":"Bug in git remote prune?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-11-06T00:34:03Z","receivedAt":"2009-11-06T00:34:03Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"Let's say you've got the following tracking branches:\n\nrefs/remotes/origin/master\nrefs/remotes/origin/next\nrefs/remotes/origin/ghost\n\nAnd origin has only \"master\" and \"next\" (ghost has been removed upstream).\n\nFurther, let's say you've got a refspec of:\n\n[remote \"origin\"]\n  fetch = +refs/heads/master:refs/remotes/origin/master\n\nWhat should \"git remote prune origin\" do?\n\nIn my opinion, it should prune \"next\" and \"ghost\".  \"ghost\" is gone\nfrom upstream, so that's obvious. I think \"next\" should also be pruned\nbecause the refspec indicates the user is no longer interested in it.\n\nCurrently it doesn't do anything (it only considers \"master\" per the\nrefspec, which is still on origin, so it doesn't think there is\nanything to prune).\n\nThoughts?\n\nj.\n"},{"id":"126943","messageId":"7vvdho5t9s.fsf@alter.siamese.dyndns.org","threadId":"21491","inReplyTo":"76718490911051634w2d364b73m567e73039508c857@mail.gmail.com","subject":"Re: Bug in git remote prune?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-11-06T01:36:15Z","receivedAt":"2009-11-06T01:36:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> Let's say you've got the following tracking branches:\n>\n> refs/remotes/origin/master\n> refs/remotes/origin/next\n> refs/remotes/origin/ghost\n>\n> And origin has only \"master\" and \"next\" (ghost has been removed upstream).\n>\n> Further, let's say you've got a refspec of:\n>\n> [remote \"origin\"]\n>   fetch = +refs/heads/master:refs/remotes/origin/master\n>\n> What should \"git remote prune origin\" do?\n>\n> In my opinion, it should prune \"next\" and \"ghost\".  \"ghost\" is gone\n> from upstream, so that's obvious. I think \"next\" should also be pruned\n> because the refspec indicates the user is no longer interested in it.\n>\n> Currently it doesn't do anything (it only considers \"master\" per the\n> refspec, which is still on origin, so it doesn't think there is\n> anything to prune).\n\nIn your scenario, tracking branches for next and ghost couldn't have come\nfrom the refspec you have in the configuration, but they do exist.  The\nuser has added them on purpose, perhaps by temporarily using wildcard\nrefspec, or perhaps by giving a refspec from the command line.\n\nIt does not matter how they got there, but the important thing to keep in\nmind is that, even if the remote had refs/heads/{next,ghost}, we wouldn't\nupdate it if we ran \"git fetch\" now.\n\nIn this situation, \"git remote prune\" should never prune 'next' nor\n'ghost'.  If we were to implement auto-pruning in 'git fetch', it should\nbehave the same way.\n\nI would define the logic to decide if refs/remotes/REMOTE/BRANCH is stale\nto be:\n\n * See if there exists a refspec (either wildcard or concrete) that may\n   cause \"git fetch\" to update the tracking branch in question, if the\n   remote side had an appropriate ref.\n\n   If there is no such refspec, stop here.  It is not stale.\n\n   In your example, when considering refs/remotes/origin/master, there is\n   such a refspec, and the \"appropriate ref\" is \"refs/heads/master\" on\n   their side.  When considering refs/remotes/origin/{next,ghost}, there\n   is none.  You stop here.\n\n * Then see if that ref exists at the remote side.  If it exists, stop\n   here.  It means \"git fetch\" would update the tracking branch in\n   question, so it is not stale.\n\n   In your example, when considering refs/remotes/origin/master, the\n   matching remote ref 'refs/heads/master' exists, so our tracking ref is\n   not stale.\n\n * Otherwise, it is stale, and we can prune it.\n\nImagine a hypothetical \"git fetch\" that understands a ref with a magic\nvalue 0{40} to signal \"this ref is gone\", and imagine what happens if the\norigin had 'ghost' that has such a magic SHA-1 in it.  It would become\neasier to understand how the above logic works.\n\n - When you issue \"git fetch\" under the condition of your example, think\n   what would happen to 'next' (which has an ordinary value, not the magic\n   \"delete this\" request).  Nothing happens.  We do not update it.\n\n - Nothing happens to 'ghost' either when you issue \"git fetch\".  It does\n   not matter if that ref has this magic 'delete this' value.\n\nNothing happens because we were told by the refspec not to even look at\nthese refs/heads/{next,ghost} refs on the other side.\n"},{"id":"126945","messageId":"76718490911051758h5afb6a40x9cef3e63ae2a809c@mail.gmail.com","threadId":"21491","inReplyTo":"7vvdho5t9s.fsf@alter.siamese.dyndns.org","subject":"Re: Bug in git remote prune?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-11-06T01:58:01Z","receivedAt":"2009-11-06T01:58:01Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Thu, Nov 5, 2009 at 8:36 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nothing happens because we were told by the refspec not to even look at\n> these refs/heads/{next,ghost} refs on the other side.\n\nGotcha, and that's all you had to say, but I appreciate the long\nexplanation. :-)\n\nj.\n"}]}