\Drupal\strata\Branch Branch

A named line of configuration history forked off a commit.

A branch carries the configuration realm and nothing else, and that is a property of how each realm is captured rather than a feature that was left out. A configuration object is captured WHOLE on every save, so its value at any commit is one complete document and a three-way merge over it is an ordinary operation on complete values. Content entities and table rows are captured as FIELD DELTAS against a parent, so merging them would mean replaying two divergent delta chains and inventing a resolution wherever they disagree. That is not a merge; it is data loss with extra steps. So a branch that received a change in any other realm refuses the merge and names the subject rather than dropping it quietly.

A branch is a ref. refs/heads/main is the trunk, refs/heads/<name> is a branch, and everything that already reads refs - reachability, prune, verify, strata:flush --ref - treats it as one without being told about branching at all.

Summary

Methods
Properties
Constants
__construct
ref
isTrunk
isUnchanged
at
refFor
nameFor
isValidName
assertName
jsonSerialize
fromArray
name
forkedFrom
tip
actor
createdAt
REALM
HEADS
TRUNK
MAX_NAME
No protected methods found
No protected properties found
No protected constants found
No private methods found
No private properties found
No private constants found

Constant

REALM

REALM = \Drupal\strata\Journal\Realm::CONFIG

The realm a branch may carry.

HEADS

HEADS = 'heads/'

Ref prefix every branch lives under, trunk included.

TRUNK

TRUNK = 'main'

The branch name the trunk answers to.

MAX_NAME

MAX_NAME = 128

Longest name a branch may carry, which is what the local index column holds.

Properties

$name

$name : string

Type

string

$forkedFrom

$forkedFrom : string

Type

string

$tip

$tip : string

Type

string

$actor

$actor : ?int

Type

int|null

$createdAt

$createdAt : int

Type

int

Methods

__construct()

__construct(string  $name, string  $forkedFrom, string  $tip, int|null  $actor = null, int  $createdAt = 0) : mixed

Constructs a branch.

Parameters

string $name

The branch name, without the heads/ prefix.

string $forkedFrom

Address of the commit the branch was cut from.

string $tip

Address of the commit it currently points at, which is the fork point until something is flushed onto it.

int|null $actor

Drupal user id that created it, or NULL for unattended work.

int $createdAt

Unix microseconds it was created at.

Throws

\InvalidArgumentException

When the name is not usable, or either address is not a valid digest.

Returns

mixed —

ref()

ref() : string

The ref name this branch is stored under.

Returns

string —

Something such as heads/release-12, which is what RefStore takes.

isTrunk()

isTrunk() : bool

Whether the branch is the trunk.

Returns

bool —

TRUE for main.

isUnchanged()

isUnchanged() : bool

Whether anything has been flushed onto the branch since it was cut.

Returns

bool —

TRUE when the tip is still the fork point.

at()

at(string  $tip) : self

The same branch pointing at another commit.

Parameters

string $tip

The new tip.

Throws

\InvalidArgumentException

When the address is not a valid digest.

Returns

self —

A new branch.

refFor()

refFor(string  $name) : string

The ref name a branch name maps to.

Parameters

string $name

The branch name.

Throws

\InvalidArgumentException

When the name is not usable.

Returns

string —

The ref name.

nameFor()

nameFor(string  $ref) : string|null

The branch name a ref name maps back to.

Parameters

string $ref

The ref name, such as heads/release-12.

Returns

string|null —

The branch name, or NULL when the ref is not a branch.

isValidName()

isValidName(string  $name) : bool

Whether a name is one a branch may carry.

Two rules, both of which have to hold. RefStore refuses an empty or traversal segment, because a ref name becomes an object key and heads/../../etc would write outside the site's own prefix. On top of that a branch name is lowercase alphanumeric with -, _ and /, so the name reads the same in a URL, a Drush argument and an object key, and so two names cannot differ only by case on a store that is case-insensitive.

Parameters

string $name

The candidate name.

Returns

bool —

TRUE when the name is usable.

assertName()

assertName(string  $name) : void

Refuses a name a branch may not carry.

Parameters

string $name

The candidate name.

Throws

\InvalidArgumentException

When the name is not usable, naming it and the rule it broke.

Returns

void —

jsonSerialize()

jsonSerialize() : array<string,mixed>

{@inheritdoc}

Returns

array

The branch as a plain array. The tip is deliberately absent: the ref is where the tip lives, and a copy of it in the metadata object would be a second answer that can go stale.

fromArray()

fromArray(array  $data, string  $tip) : self

Rebuilds a branch from its stored metadata and the ref that names its tip.

Parameters

array $data

The array produced by Branch::jsonSerialize().

string $tip

The commit the ref points at.

Throws

\InvalidArgumentException

When the metadata does not describe a branch.

Returns

self —

The branch.