Class PackedBatchRefUpdate
BatchRefUpdate
that uses the packed-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.-
Field Summary
FieldsFields inherited from class org.eclipse.jgit.lib.BatchRefUpdate
MAX_WAIT
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionapplyUpdates
(RevWalk walk, RefList<Ref> refs, List<ReceiveCommand> commands) private boolean
checkConflictingNames
(List<ReceiveCommand> commands) private boolean
checkNonFastForwards
(RevWalk walk, List<ReceiveCommand> commands) private boolean
checkObjectExistence
(RevWalk walk, List<ReceiveCommand> commands) private static boolean
containsSymrefs
(List<ReceiveCommand> commands) void
execute
(RevWalk walk, ProgressMonitor monitor, List<String> options) Execute this batch update.private static void
lockFailure
(ReceiveCommand cmd, List<ReceiveCommand> commands) lockLooseRefs
(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, String why, List<ReceiveCommand> commands) private static void
reject
(ReceiveCommand cmd, ReceiveCommand.Result result, List<ReceiveCommand> commands) private String
private static void
private void
writeReflog
(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 Details
-
refdb
-
-
Constructor Details
-
PackedBatchRefUpdate
PackedBatchRefUpdate(RefDirectory refdb)
-
-
Method Details
-
execute
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:
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
-
checkConflictingNames
- Throws:
IOException
-
checkObjectExistence
private boolean checkObjectExistence(RevWalk walk, List<ReceiveCommand> commands) throws IOException - Throws:
IOException
-
checkNonFastForwards
private boolean checkNonFastForwards(RevWalk walk, List<ReceiveCommand> commands) throws IOException - Throws:
IOException
-
lockLooseRefs
@Nullable private Map<String,LockFile> lockLooseRefs(List<ReceiveCommand> commands) throws 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:
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, List<ReceiveCommand> commands) throws IOException - Throws:
IOException
-
writeReflog
-
toResultString
-
peeledRef
- Throws:
IOException
-
unlockAll
-
lockFailure
-
reject
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, List<ReceiveCommand> commands) -
reject
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, String why, List<ReceiveCommand> commands)
-