Class PackedBatchRefUpdate
- java.lang.Object
-
- org.eclipse.jgit.lib.BatchRefUpdate
-
- org.eclipse.jgit.internal.storage.file.PackedBatchRefUpdate
-
class PackedBatchRefUpdate extends BatchRefUpdate
Implementation ofBatchRefUpdate
that uses thepacked-refs
file to support atomically updating multiple refs.The algorithm is designed to be compatible with traditional single ref updates operating on single refs only. Regardless of success or failure, the results are atomic: from the perspective of any reader, either all updates in the batch will be visible, or none will. In the case of process failure during any of the following steps, removal of stale lock files is always safe, and will never result in an inconsistent state, although the update may or may not have been applied.
The algorithm is:
- Pack loose refs involved in the transaction using the normal pack-refs
operation. This ensures that creating lock files in the following step
succeeds even if a batch contains both a delete of
refs/x
(loose) and a create ofrefs/x/y
. - Create locks for all loose refs involved in the transaction, even if they are not currently loose.
- Pack loose refs again, this time while holding all lock files (see
RefDirectory.pack(Map)
), without deleting them afterwards. This covers a potential race where new loose refs were created after the initial packing step. If no new loose refs were created during this race, this step does not modify any files on disk. Keep the merged state in memory. - Update the in-memory packed refs with the commands in the batch, possibly failing the whole batch if any old ref values do not match.
- If the update succeeds, lock
packed-refs
and commit by atomically renaming the lock file. - Delete loose ref lock files.
setAtomic(false)
. As an optimization, an update containing a single ref update does not use the packed-refs protocol. - Pack loose refs involved in the transaction using the normal pack-refs
operation. This ensures that creating lock files in the following step
succeeds even if a batch contains both a delete of
-
-
Field Summary
Fields Modifier and Type Field Description private RefDirectory
refdb
-
Fields inherited from class org.eclipse.jgit.lib.BatchRefUpdate
MAX_WAIT
-
-
Constructor Summary
Constructors Constructor Description PackedBatchRefUpdate(RefDirectory refdb)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private static RefList<Ref>
applyUpdates(RevWalk walk, RefList<Ref> refs, java.util.List<ReceiveCommand> commands)
private boolean
checkConflictingNames(java.util.List<ReceiveCommand> commands)
private boolean
checkNonFastForwards(RevWalk walk, java.util.List<ReceiveCommand> commands)
private boolean
checkObjectExistence(RevWalk walk, java.util.List<ReceiveCommand> commands)
private static boolean
containsSymrefs(java.util.List<ReceiveCommand> commands)
void
execute(RevWalk walk, ProgressMonitor monitor, java.util.List<java.lang.String> options)
Execute this batch update.private static void
lockFailure(ReceiveCommand cmd, java.util.List<ReceiveCommand> commands)
private java.util.Map<java.lang.String,LockFile>
lockLooseRefs(java.util.List<ReceiveCommand> commands)
Lock loose refs corresponding to a list of commands.private static Ref
peeledRef(RevWalk walk, ReceiveCommand cmd)
private static void
reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.lang.String why, java.util.List<ReceiveCommand> commands)
private static void
reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.util.List<ReceiveCommand> commands)
private java.lang.String
toResultString(ReceiveCommand cmd)
private static void
unlockAll(java.util.Map<?,LockFile> locks)
private void
writeReflog(java.util.List<ReceiveCommand> commands)
-
Methods inherited from class org.eclipse.jgit.lib.BatchRefUpdate
addCommand, addCommand, addCommand, addPrefixesTo, addProposedTimestamp, blockUntilTimestamps, disableRefLog, execute, getCommands, getPrefixes, getProposedTimestamps, getPushCertificate, getPushOptions, getRefLogIdent, getRefLogMessage, getRefLogMessage, isAllowNonFastForwards, isAtomic, isForceRefLog, isForceRefLog, isRefLogDisabled, isRefLogDisabled, isRefLogIncludingResult, isRefLogIncludingResult, newUpdate, setAllowNonFastForwards, setAtomic, setForceRefLog, setPushCertificate, setPushOptions, setRefLogIdent, setRefLogMessage, toString
-
-
-
-
Field Detail
-
refdb
private RefDirectory refdb
-
-
Constructor Detail
-
PackedBatchRefUpdate
PackedBatchRefUpdate(RefDirectory refdb)
-
-
Method Detail
-
execute
public void execute(RevWalk walk, ProgressMonitor monitor, java.util.List<java.lang.String> options) throws java.io.IOException
Execute this batch update.The default implementation of this method performs a sequential reference update over each reference.
Implementations must respect the atomicity requirements of the underlying database as described in
BatchRefUpdate.setAtomic(boolean)
andRefDatabase.performsAtomicTransactions()
.- Overrides:
execute
in classBatchRefUpdate
- Parameters:
walk
- a RevWalk to parse tags in case the storage system wants to store them pre-peeled, a common performance optimization.monitor
- progress monitor to receive update status on.options
- a list of option strings; set null to execute without- Throws:
java.io.IOException
- the database is unable to accept the update. Individual command status must be tested to determine if there is a partial failure, or a total failure.
-
containsSymrefs
private static boolean containsSymrefs(java.util.List<ReceiveCommand> commands)
-
checkConflictingNames
private boolean checkConflictingNames(java.util.List<ReceiveCommand> commands) throws java.io.IOException
- Throws:
java.io.IOException
-
checkObjectExistence
private boolean checkObjectExistence(RevWalk walk, java.util.List<ReceiveCommand> commands) throws java.io.IOException
- Throws:
java.io.IOException
-
checkNonFastForwards
private boolean checkNonFastForwards(RevWalk walk, java.util.List<ReceiveCommand> commands) throws java.io.IOException
- Throws:
java.io.IOException
-
lockLooseRefs
@Nullable private java.util.Map<java.lang.String,LockFile> lockLooseRefs(java.util.List<ReceiveCommand> commands) throws java.io.IOException
Lock loose refs corresponding to a list of commands.- Parameters:
commands
- commands that we intend to execute.- Returns:
- map of ref name in the input commands to lock file. Always contains
one entry for each ref in the input list. All locks are acquired
before returning. If any lock was not able to be acquired: the
return value is null; no locks are held; and all commands that were
pending are set to fail with
LOCK_FAILURE
. - Throws:
java.io.IOException
- an error occurred other than a failure to acquire; no locks are held if this exception is thrown.
-
applyUpdates
private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs, java.util.List<ReceiveCommand> commands) throws java.io.IOException
- Throws:
java.io.IOException
-
writeReflog
private void writeReflog(java.util.List<ReceiveCommand> commands)
-
toResultString
private java.lang.String toResultString(ReceiveCommand cmd)
-
peeledRef
private static Ref peeledRef(RevWalk walk, ReceiveCommand cmd) throws java.io.IOException
- Throws:
java.io.IOException
-
lockFailure
private static void lockFailure(ReceiveCommand cmd, java.util.List<ReceiveCommand> commands)
-
reject
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.util.List<ReceiveCommand> commands)
-
reject
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.lang.String why, java.util.List<ReceiveCommand> commands)
-
-