Re: Bug in git remote prune?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]