Class PackedBatchRefUpdate

java.lang.Object
org.eclipse.jgit.lib.BatchRefUpdate
org.eclipse.jgit.internal.storage.file.PackedBatchRefUpdate

class PackedBatchRefUpdate extends BatchRefUpdate
Implementation of 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:

  1. 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 of refs/x/y.
  2. Create locks for all loose refs involved in the transaction, even if they are not currently loose.
  3. 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.
  4. 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.
  5. If the update succeeds, lock packed-refs and commit by atomically renaming the lock file.
  6. Delete loose ref lock files.
Because the packed-refs file format is a sorted list, this algorithm is linear in the total number of refs, regardless of the batch size. This can be a significant slowdown on repositories with large numbers of refs; callers that prefer speed over atomicity should use setAtomic(false). As an optimization, an update containing a single ref update does not use the packed-refs protocol.