Class BasePackFetchConnection
- All Implemented Interfaces:
AutoCloseable,Connection,FetchConnection
- Direct Known Subclasses:
InternalFetchConnection,TransportGitAnon.TcpFetchConnection,TransportGitSsh.SshFetchConnection,TransportHttp.SmartHttpFetchConnection,TransportLocal.ForkLocalFetchConnection
This is the canonical implementation for transferring objects from the remote repository to the local repository by talking to the 'git-upload-pack' service. Objects are packed on the remote side into a pack file and then sent down the pipe to us.
This connection requires only a bi-directional pipe or socket, and thus is easily wrapped up into a local process pipe, anonymous TCP socket, or a command executed through an SSH tunnel.
If BasePackConnection.statelessRPC is
true, this connection can be tunneled over a request-response style
RPC system like HTTP. The RPC call boundary is determined by this class
switching from writing to the OutputStream to reading from the InputStream.
Concrete implementations should just call
BasePackConnection.init(java.io.InputStream, java.io.OutputStream) and
BasePackConnection.readAdvertisedRefs() methods in constructor or before any use. They
should also handle resources releasing in close() method if needed.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static class(package private) static classprivate static class -
Field Summary
FieldsModifier and TypeFieldDescription(package private) final RevFlagMarks a commit listed in the advertised refs.private boolean(package private) final RevFlagMarks a commit known to both sides of the connection.private final FilterSpecEither FilterSpec.NO_FILTER for a filter that doesn't filter anything, or a filter that indicates what and what not to send to the server.private booleanprivate Stringprivate static final intMaximum number of 'have' lines to send before giving up.private intprotected static final intAmount of data the client sends before starting to read.private GitProtocolConstants.MultiAckprivate booleanprivate booleanstatic final StringThe client supports fetching objects that are reachable from a tip of a ref that is allowed to fetch.static final StringThe client supports fetching objects at the tip of any ref, even if not advertised.static final StringThe client specified a filter expression.static final StringInclude tags if we are also including the referenced objects.static final StringMulti-ACK support for improved negotiation.static final StringMulti-ACK detailed support for improved negotiation.static final StringThe client supports receiving a pack before it has sent "done".static final StringThe client does not want progress messages and will ignore them.static final StringThe client supports packs with OFS deltas.static final StringThe client supports shallow fetches.static final StringThe client supports using the side-band for progress messages.static final StringThe client supports using the 64K side-band for progress messages.static final StringThe client supports packs with deltas but not their bases.private PackLockprivate PacketLineOut(package private) final RevFlagMarks an object as having all its dependencies.private RevCommitList<RevCommit>All commits that are immediately reachable by a local ref.private booleanprivate TemporaryBuffer.HeapRPC state, ifBasePackConnection.statelessRPCis true or protocol V2 is used.private final RevFlagprivate booleanprivate final RevWalkFields inherited from class org.eclipse.jgit.transport.BasePackConnection
additionalHaves, CAPABILITY_SYMREF_PREFIX, in, local, out, outNeedsEnd, pckIn, pckOut, statelessRPC, timeoutIn, timeoutOut, transport, uri -
Constructor Summary
ConstructorsConstructorDescriptionBasePackFetchConnection(PackTransport packTransport) Create a new connection to fetch using the native git transport. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidvoidclose()booleanDid the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)get tags?booleanDid the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)validate graph?protected voiddoFetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have, OutputStream outputStream) Execute common ancestor negotiation and fetch the objects.private voiddoFetchV2(ProgressMonitor monitor, Collection<Ref> want, OutputStream outputStream) private Stringfinal voidfetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have) Fetch objects we don't have but that are reachable from advertised refs.final voidfetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have, OutputStream outputStream) Fetch objects we don't have but that are reachable from advertised refs.getCapabilitiesV2(Set<String> advertisedCapabilities) (package private) BasePackFetchConnection.FetchConfigAll locks created by the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)call.private voidprivate voidmarkCommon(RevObject obj, PacketLineIn.AckNackResult anr, boolean useState) private voidmarkReachable(Set<ObjectId> have, int maxTime) private voidprivate intmaxTimeWanted(Collection<Ref> wants) private voidnegotiate(ProgressMonitor monitor) private voidprotected voidNotification event delivered just before the pack is received from the network.private voidprivate booleanreadAcknowledgments(BasePackFetchConnection.FetchStateV2 fetchState, PacketLineIn input, ProgressMonitor monitor) Reads and processes acknowledgments, adding ACKed objects as "have"s to the global stateTemporaryBuffer.private voidreceivePack(ProgressMonitor monitor, OutputStream outputStream) private booleansendNextHaveBatch(BasePackFetchConnection.FetchStateV2 fetchState, PacketLineOut output, ProgressMonitor monitor) Sends the next batch of "have"s and terminates theoutput.private booleansendWants(Collection<Ref> want, PacketLineOut p) voidsetPackLockMessage(String message) Set the lock message used when holding a pack out of garbage collection.Methods inherited from class org.eclipse.jgit.transport.BasePackConnection
addUserAgentCapability, endOut, getCapability, getPeerUserAgent, getProtocolVersion, init, isCapableOf, lsRefs, noRepository, readAdvertisedRefs, setProtocolVersion, updateWithSymRefs, wantCapabilityMethods inherited from class org.eclipse.jgit.transport.BaseConnection
available, getMessages, getMessageWriter, getRef, getRefs, getRefsMap, markStartedOperation, setMessageWriter, setPeerUserAgentMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.eclipse.jgit.transport.Connection
getMessages, getPeerUserAgent, getRef, getRefs, getRefsMap
-
Field Details
-
MAX_HAVES
private static final int MAX_HAVESMaximum number of 'have' lines to send before giving up.During
negotiate(ProgressMonitor)we send at most this many commits to the remote peer as 'have' lines without an ACK response before we give up.- See Also:
-
MIN_CLIENT_BUFFER
protected static final int MIN_CLIENT_BUFFERAmount of data the client sends before starting to read.Any output stream given to the client must be able to buffer this many bytes before the client will stop writing and start reading from the input stream. If the output stream blocks before this many bytes are in the send queue, the system will deadlock.
- See Also:
-
OPTION_INCLUDE_TAG
Include tags if we are also including the referenced objects.- Since:
- 2.0
- See Also:
-
OPTION_MULTI_ACK
Multi-ACK support for improved negotiation.- Since:
- 2.0
- See Also:
-
OPTION_MULTI_ACK_DETAILED
Multi-ACK detailed support for improved negotiation.- Since:
- 2.0
- See Also:
-
OPTION_THIN_PACK
The client supports packs with deltas but not their bases.- Since:
- 2.0
- See Also:
-
OPTION_SIDE_BAND
The client supports using the side-band for progress messages.- Since:
- 2.0
- See Also:
-
OPTION_SIDE_BAND_64K
The client supports using the 64K side-band for progress messages.- Since:
- 2.0
- See Also:
-
OPTION_OFS_DELTA
The client supports packs with OFS deltas.- Since:
- 2.0
- See Also:
-
OPTION_SHALLOW
The client supports shallow fetches.- Since:
- 2.0
- See Also:
-
OPTION_NO_PROGRESS
The client does not want progress messages and will ignore them.- Since:
- 2.0
- See Also:
-
OPTION_NO_DONE
The client supports receiving a pack before it has sent "done".- Since:
- 2.0
- See Also:
-
OPTION_ALLOW_TIP_SHA1_IN_WANT
The client supports fetching objects at the tip of any ref, even if not advertised.- Since:
- 3.1
- See Also:
-
OPTION_ALLOW_REACHABLE_SHA1_IN_WANT
The client supports fetching objects that are reachable from a tip of a ref that is allowed to fetch.- Since:
- 4.1
- See Also:
-
OPTION_FILTER
The client specified a filter expression.- Since:
- 5.0
- See Also:
-
walk
-
reachableCommits
All commits that are immediately reachable by a local ref. -
REACHABLE
Marks an object as having all its dependencies. -
COMMON
Marks a commit known to both sides of the connection. -
STATE
-
ADVERTISED
Marks a commit listed in the advertised refs. -
multiAck
-
thinPack
private boolean thinPack -
sideband
private boolean sideband -
includeTags
private boolean includeTags -
allowOfsDelta
private boolean allowOfsDelta -
noDone
private boolean noDone -
noProgress
private boolean noProgress -
lockMessage
-
packLock
-
maxHaves
private int maxHaves -
state
RPC state, ifBasePackConnection.statelessRPCis true or protocol V2 is used. -
pckState
-
filterSpec
Either FilterSpec.NO_FILTER for a filter that doesn't filter anything, or a filter that indicates what and what not to send to the server.
-
-
Constructor Details
-
BasePackFetchConnection
Create a new connection to fetch using the native git transport.- Parameters:
packTransport- the transport.
-
-
Method Details
-
fetch
public final void fetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have) throws TransportException Fetch objects we don't have but that are reachable from advertised refs.Only one call per connection is allowed. Subsequent calls will result in
TransportException.Implementations are free to use network connections as necessary to efficiently (for both client and server) transfer objects from the remote repository into this repository. When possible implementations should avoid replacing/overwriting/duplicating an object already available in the local destination repository. Locally available objects and packs should always be preferred over remotely available objects and packs.
Transport.isFetchThin()should be honored if applicable.- Specified by:
fetchin interfaceFetchConnection- Parameters:
monitor- progress monitor to inform the end-user about the amount of work completed, or to indicate cancellation. Implementations should poll the monitor at regular intervals to look for cancellation requests from the user.want- one or more refs advertised by this connection that the caller wants to store locally.have- additional objects known to exist in the destination repository, especially if they aren't yet reachable by the ref database. Connections should take this set as an addition to what is reachable through all Refs, not in replace of it.- Throws:
TransportException- objects could not be copied due to a network failure, protocol error, or error on remote side, or connection was already used for fetch.
-
fetch
public final void fetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have, OutputStream outputStream) throws TransportException Fetch objects we don't have but that are reachable from advertised refs.Only one call per connection is allowed. Subsequent calls will result in
TransportException.Implementations are free to use network connections as necessary to efficiently (for both client and server) transfer objects from the remote repository into this repository. When possible implementations should avoid replacing/overwriting/duplicating an object already available in the local destination repository. Locally available objects and packs should always be preferred over remotely available objects and packs.
Transport.isFetchThin()should be honored if applicable.- Specified by:
fetchin interfaceFetchConnection- Parameters:
monitor- progress monitor to inform the end-user about the amount of work completed, or to indicate cancellation. Implementations should poll the monitor at regular intervals to look for cancellation requests from the user.want- one or more refs advertised by this connection that the caller wants to store locally.have- additional objects known to exist in the destination repository, especially if they aren't yet reachable by the ref database. Connections should take this set as an addition to what is reachable through all Refs, not in replace of it.outputStream- OutputStream to write sideband messages to- Throws:
TransportException- objects could not be copied due to a network failure, protocol error, or error on remote side, or connection was already used for fetch.
-
didFetchIncludeTags
public boolean didFetchIncludeTags()Did the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)get tags?Some Git aware transports are able to implicitly grab an annotated tag if
TagOpt.AUTO_FOLLOWorTagOpt.FETCH_TAGSwas selected and the object the tag peels to (references) was transferred as part of the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)call. If it is possible for such tags to have been included in the transfer this method returns true, allowing the caller to attempt tag discovery.By returning only true/false (and not the actual list of tags obtained) the transport itself does not need to be aware of whether or not tags were included in the transfer.
- Specified by:
didFetchIncludeTagsin interfaceFetchConnection- Returns:
- true if the last fetch call implicitly included tag objects; false if tags were not implicitly obtained.
-
didFetchTestConnectivity
public boolean didFetchTestConnectivity()Did the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)validate graph?Some transports walk the object graph on the client side, with the client looking for what objects it is missing and requesting them individually from the remote peer. By virtue of completing the fetch call the client implicitly tested the object connectivity, as every object in the graph was either already local or was requested successfully from the peer. In such transports this method returns true.
Some transports assume the remote peer knows the Git object graph and is able to supply a fully connected graph to the client (although it may only be transferring the parts the client does not yet have). Its faster to assume such remote peers are well behaved and send the correct response to the client. In such transports this method returns false.
- Specified by:
didFetchTestConnectivityin interfaceFetchConnection- Returns:
- true if the last fetch had to perform a connectivity check on the client side in order to succeed; false if the last fetch assumed the remote peer supplied a complete graph.
-
setPackLockMessage
Set the lock message used when holding a pack out of garbage collection.Callers that set a lock message must ensure they call
FetchConnection.getPackLocks()afterFetchConnection.fetch(ProgressMonitor, Collection, Set), even if an exception was thrown, and release the locks that are held.- Specified by:
setPackLockMessagein interfaceFetchConnection- Parameters:
message- message to use when holding a pack in place.
-
getPackLocks
All locks created by the lastFetchConnection.fetch(ProgressMonitor, Collection, Set)call.- Specified by:
getPackLocksin interfaceFetchConnection- Returns:
- collection (possibly empty) of locks created by the last call to fetch. The caller must release these after refs are updated in order to safely permit garbage collection.
-
clearState
private void clearState() -
doFetch
protected void doFetch(ProgressMonitor monitor, Collection<Ref> want, Set<ObjectId> have, OutputStream outputStream) throws TransportException Execute common ancestor negotiation and fetch the objects.- Parameters:
monitor- progress monitor to receive status updates. If the monitor is theNullProgressMonitor.INSTANCE, then the no-progress option enabled.want- the advertised remote references the caller wants to fetch.have- additional objects to assume that already exist locally. This will be added to the set of objects reachable from the destination repository's references.outputStream- ouputStream to write sideband messages to- Throws:
TransportException- if any exception occurs.- Since:
- 3.0
-
doFetchV2
private void doFetchV2(ProgressMonitor monitor, Collection<Ref> want, OutputStream outputStream) throws IOException, BasePackFetchConnection.CancelledException -
sendNextHaveBatch
private boolean sendNextHaveBatch(BasePackFetchConnection.FetchStateV2 fetchState, PacketLineOut output, ProgressMonitor monitor) throws IOException, BasePackFetchConnection.CancelledException Sends the next batch of "have"s and terminates theoutput.- Parameters:
fetchState- is updated with information about the number of items written, and whether to expect a packfile nextoutput- to write tomonitor- for progress reporting and cancellation- Returns:
trueif a "done" was written and we should thus expect a packfile next- Throws:
IOException- on errorsBasePackFetchConnection.CancelledException- on cancellation
-
readAcknowledgments
private boolean readAcknowledgments(BasePackFetchConnection.FetchStateV2 fetchState, PacketLineIn input, ProgressMonitor monitor) throws IOException, BasePackFetchConnection.CancelledException Reads and processes acknowledgments, adding ACKed objects as "have"s to the global stateTemporaryBuffer.- Parameters:
fetchState- to updateinput- to read frommonitor- for progress reporting and cancellation- Returns:
trueif a "ready" was received and a packfile is expected next- Throws:
IOException- on errorsBasePackFetchConnection.CancelledException- on cancellation
-
close
public void close()Close any resources used by this connection.
If the remote repository is contacted by a network socket this method must close that network socket, disconnecting the two peers. If the remote repository is actually local (same system) this method must close any open file handles used to read the "remote" repository.
If additional messages were produced by the remote peer, these should still be retained in the connection instance for
Connection.getMessages().AutoClosable.close()declares that it throwsException. Implementers shouldn't throw checked exceptions. This override narrows the signature to prevent them from doing so.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceConnection- Overrides:
closein classBasePackConnection
-
getFetchConfig
BasePackFetchConnection.FetchConfig getFetchConfig() -
maxTimeWanted
-
markReachable
- Throws:
IOException
-
parseReachable
-
sendWants
- Throws:
IOException
-
getCapabilitiesV2
- Throws:
TransportException
-
enableCapabilities
- Throws:
TransportException
-
negotiate
private void negotiate(ProgressMonitor monitor) throws IOException, BasePackFetchConnection.CancelledException -
negotiateBegin
- Throws:
IOException
-
markRefsAdvertised
private void markRefsAdvertised() -
markAdvertised
-
markCommon
private void markCommon(RevObject obj, PacketLineIn.AckNackResult anr, boolean useState) throws IOException - Throws:
IOException
-
receivePack
- Throws:
IOException
-
onReceivePack
protected void onReceivePack()Notification event delivered just before the pack is received from the network. This event can be used by RPC such asTransportHttpto disable its request magic and ensure the pack stream is read correctly.- Since:
- 2.0
-