class PackedBatchRefUpdate extends BatchRefUpdate
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:
refs/x
(loose) and
a create of refs/x/y
.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.packed-refs
and commit by atomically
renaming the lock file.setAtomic(false)
. As an
optimization, an update containing a single ref update does not use the
packed-refs protocol.Modifier and Type | Field and Description |
---|---|
private RefDirectory |
refdb |
MAX_WAIT
Constructor and Description |
---|
PackedBatchRefUpdate(RefDirectory refdb) |
Modifier and Type | Method and Description |
---|---|
private static RefList<Ref> |
applyUpdates(RevWalk walk,
RefList<Ref> refs,
java.util.List<ReceiveCommand> commands) |
private static java.util.Map<java.lang.String,ReceiveCommand> |
byName(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.util.List<ReceiveCommand> commands) |
private static void |
reject(ReceiveCommand cmd,
ReceiveCommand.Result result,
java.lang.String why,
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) |
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
private RefDirectory refdb
PackedBatchRefUpdate(RefDirectory refdb)
public void execute(RevWalk walk, ProgressMonitor monitor, java.util.List<java.lang.String> options) throws java.io.IOException
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)
and
RefDatabase.performsAtomicTransactions()
.
execute
in class BatchRefUpdate
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 withoutjava.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.private static boolean containsSymrefs(java.util.List<ReceiveCommand> commands)
private boolean checkConflictingNames(java.util.List<ReceiveCommand> commands) throws java.io.IOException
java.io.IOException
private boolean checkObjectExistence(RevWalk walk, java.util.List<ReceiveCommand> commands) throws java.io.IOException
java.io.IOException
private boolean checkNonFastForwards(RevWalk walk, java.util.List<ReceiveCommand> commands) throws java.io.IOException
java.io.IOException
@Nullable private java.util.Map<java.lang.String,LockFile> lockLooseRefs(java.util.List<ReceiveCommand> commands) throws java.io.IOException
commands
- commands that we intend to execute.LOCK_FAILURE
.java.io.IOException
- an error occurred other than a failure to acquire; no locks are
held if this exception is thrown.private static RefList<Ref> applyUpdates(RevWalk walk, RefList<Ref> refs, java.util.List<ReceiveCommand> commands) throws java.io.IOException
java.io.IOException
private void writeReflog(java.util.List<ReceiveCommand> commands)
private java.lang.String toResultString(ReceiveCommand cmd)
private static java.util.Map<java.lang.String,ReceiveCommand> byName(java.util.List<ReceiveCommand> commands)
private static Ref peeledRef(RevWalk walk, ReceiveCommand cmd) throws java.io.IOException
java.io.IOException
private static void lockFailure(ReceiveCommand cmd, java.util.List<ReceiveCommand> commands)
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.util.List<ReceiveCommand> commands)
private static void reject(ReceiveCommand cmd, ReceiveCommand.Result result, java.lang.String why, java.util.List<ReceiveCommand> commands)