class WalkPushConnection extends BaseConnection implements PushConnection
Since there are no Git-specific smarts on the remote side of the connection the client side must handle everything on its own. The generic push support requires being able to delete, create and overwrite files on the remote side, as well as create any missing directories (if necessary). Typically this can be handled through an FTP style protocol.
Objects not on the remote side are uploaded as pack files, using one pack file per invocation. This simplifies the implementation as only two data files need to be written to the remote repository.
Push support supplied by this class is not multiuser safe. Concurrent pushes to the same repository may yield an inconsistent reference database which may confuse fetch clients.
A single push is concurrently safe with multiple fetch requests, due to the careful order of operations used to update the repository. Clients fetching may receive transient failures due to short reads on certain files if the protocol does not support atomic file replacement.
WalkRemoteObjectDatabase
Modifier and Type | Field and Description |
---|---|
(package private) WalkRemoteObjectDatabase |
dest
Database connection to the remote repository.
|
private Repository |
local
The repository this transport pushes out of.
|
private java.util.Map<java.lang.String,Ref> |
newRefs
Complete listing of refs the remote will have after our push.
|
private java.util.Collection<RemoteRefUpdate> |
packedRefUpdates
Updates which require altering the packed-refs file to complete.
|
private java.util.LinkedHashMap<java.lang.String,java.lang.String> |
packNames
Packs already known to reside in the remote repository.
|
private Transport |
transport
The configured transport we were constructed by.
|
private URIish |
uri
Location of the remote repository we are writing to.
|
Constructor and Description |
---|
WalkPushConnection(WalkTransport walkTransport,
WalkRemoteObjectDatabase w) |
Modifier and Type | Method and Description |
---|---|
void |
close() |
private void |
createNewRepository(java.util.List<RemoteRefUpdate> updates) |
private void |
deleteCommand(RemoteRefUpdate u) |
private boolean |
isNewRepository() |
private static java.lang.String |
pickHEAD(java.util.List<RemoteRefUpdate> updates) |
void |
push(ProgressMonitor monitor,
java.util.Map<java.lang.String,RemoteRefUpdate> refUpdates)
Pushes to the remote repository basing on provided specification.
|
void |
push(ProgressMonitor monitor,
java.util.Map<java.lang.String,RemoteRefUpdate> refUpdates,
java.io.OutputStream out)
Pushes to the remote repository basing on provided specification.
|
private void |
safeDelete(java.lang.String path) |
private void |
sendpack(java.util.List<RemoteRefUpdate> updates,
ProgressMonitor monitor) |
private void |
updateCommand(RemoteRefUpdate u) |
available, getMessages, getMessageWriter, getPeerUserAgent, getRef, getRefs, getRefsMap, markStartedOperation, setMessageWriter, setPeerUserAgent
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getMessages, getPeerUserAgent, getRef, getRefs, getRefsMap
private final Repository local
private final URIish uri
final WalkRemoteObjectDatabase dest
private final Transport transport
private java.util.LinkedHashMap<java.lang.String,java.lang.String> packNames
This is a LinkedHashMap to maintain the original order.
private java.util.Map<java.lang.String,Ref> newRefs
private java.util.Collection<RemoteRefUpdate> packedRefUpdates
If this collection is non-empty then any refs listed in newRefs
with a storage class of Ref.Storage.PACKED
will be written.
WalkPushConnection(WalkTransport walkTransport, WalkRemoteObjectDatabase w)
public void push(ProgressMonitor monitor, java.util.Map<java.lang.String,RemoteRefUpdate> refUpdates) throws TransportException
Only one call per connection is allowed. Subsequent calls will result in
TransportException
.
Implementation may use local repository to send a minimum set of objects
needed by remote repository in efficient way.
Transport.isPushThin()
should be
honored if applicable. refUpdates should be filled with information about
status of each update.
push
in interface PushConnection
monitor
- progress monitor to update the end-user about the amount of
work completed, or to indicate cancellation. Implementors
should poll the monitor at regular intervals to look for
cancellation requests from the user.refUpdates
- map of remote refnames to remote refs update
specifications/statuses. Can't be empty. This indicate what
refs caller want to update on remote side. Only refs updates
with
RemoteRefUpdate.Status.NOT_ATTEMPTED
should passed. Implementation must ensure that and appropriate
status with optional message should be set during call. No
refUpdate with
RemoteRefUpdate.Status.AWAITING_REPORT
or
RemoteRefUpdate.Status.NOT_ATTEMPTED
can be leaved by implementation after return from this call.TransportException
- objects could not be copied due to a network failure,
critical protocol error, or error on remote side, or
connection was already used for push - new connection must be
created. Non-critical errors concerning only isolated refs
should be placed in refUpdates.public void push(ProgressMonitor monitor, java.util.Map<java.lang.String,RemoteRefUpdate> refUpdates, java.io.OutputStream out) throws TransportException
Only one call per connection is allowed. Subsequent calls will result in
TransportException
.
Implementation may use local repository to send a minimum set of objects
needed by remote repository in efficient way.
Transport.isPushThin()
should be
honored if applicable. refUpdates should be filled with information about
status of each update.
push
in interface PushConnection
monitor
- progress monitor to update the end-user about the amount of
work completed, or to indicate cancellation. Implementors
should poll the monitor at regular intervals to look for
cancellation requests from the user.refUpdates
- map of remote refnames to remote refs update
specifications/statuses. Can't be empty. This indicate what
refs caller want to update on remote side. Only refs updates
with
RemoteRefUpdate.Status.NOT_ATTEMPTED
should passed. Implementation must ensure that and appropriate
status with optional message should be set during call. No
refUpdate with
RemoteRefUpdate.Status.AWAITING_REPORT
or
RemoteRefUpdate.Status.NOT_ATTEMPTED
can be leaved by implementation after return from this call.out
- output stream to write sideband messages toTransportException
- objects could not be copied due to a network failure,
critical protocol error, or error on remote side, or
connection was already used for push - new connection must be
created. Non-critical errors concerning only isolated refs
should be placed in refUpdates.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 throws Exception
.
Implementers shouldn't throw checked exceptions. This override narrows
the signature to prevent them from doing so.
close
in interface java.lang.AutoCloseable
close
in interface Connection
close
in class BaseConnection
private void sendpack(java.util.List<RemoteRefUpdate> updates, ProgressMonitor monitor) throws TransportException
TransportException
private void safeDelete(java.lang.String path)
private void deleteCommand(RemoteRefUpdate u)
private void updateCommand(RemoteRefUpdate u)
private boolean isNewRepository()
private void createNewRepository(java.util.List<RemoteRefUpdate> updates) throws TransportException
TransportException
private static java.lang.String pickHEAD(java.util.List<RemoteRefUpdate> updates)