Implement fetch support for TagOpt AUTO_FOLLOW, FETCH_TAGS
commitc8aa19f39142c31d98492696329bcc13d50c04c7
authorShawn O. Pearce <spearce@spearce.org>
Sat, 17 May 2008 04:00:48 +0000 (17 00:00 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Sat, 17 May 2008 04:01:52 +0000 (17 00:01 -0400)
tree9fb5bbc6dd3f4e987ded7b7874d9d83af629149e
parent50ea9db3f26f2a8cdfc9d569f8dc30f0eebd6539
Implement fetch support for TagOpt AUTO_FOLLOW, FETCH_TAGS

If tagopt == TagOpt.FETCH_TAGS we want all of the tags the remote
has, even if that means getting objects we do not yet have and would
not have requested otherwise in our want list.  This case is quite
trivial as we just need to add any tag object which is not already in
our local repository and which is not in our ask list to the list of
things we want.  The transport will get everything in a single shot.

If tagopt == TagOpt.AUTO_FOLLOW things are a little bit more complex.
Here we want to get an annotated tag only if we do not already have
it and it peels to something we will have when the fetch is complete.

For cases where a branch we want is pointing at the peeled object
for a tag the branch is in our ask list, so we can easily see that
the referred object will be available when the fetch completes.
Adding in a request for the tag is quite cheap, as only the tag
needs to be transferred and we want that anyway.  This may allow
us to avoid a second network connection to acquire the tags after
the branch objects are obtained.

If we aren't asking for the tag's peeled object, but we already
have it locally in our repository, chances are its reachable from
our existing local refs.  Asking for the tag is not likely to
cause additional network transfer time.  This case can happen if a
maintainer has recently tagged a historical revision, one that we
have previously fetched.

If the FetchConnection is able to automatically follow tags (such as
due to the native protocol "include-tags" extension) we may be able
to complete the fetch in only one connection by checking to see if
the objects are complete after the fetch.  If they are then we don't
need any further network transport.  However there is no point in
testing for completeness of tags we do not have (but want) if the
transport did not magically include them in our last fetch call.

If we have to open a second connection for tag fetch we may not
be talking to the same repository.  This can easily happen on busy
public mirror sites that utilize round-robin DNS.  To avoid asking
for objects that the remote does not advertise (as perhaps the one
mirror is ahead of or behind the other) we correct our state to
reflect the new connection's advertised refs.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.spearce.jgit/src/org/spearce/jgit/transport/FetchProcess.java
org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java