Delivering a branch to a remote agent
The act that moves a branch to a machine somewhere else, what it refuses, and the trap that returns a number instead of an error.
Delivering a branch to a remote agent
A remote machine does not share your filesystem, and the product does not hand code to it by copying files. A delivery moves one named branch, and it spans four repositories:
| the repository | its part in one delivery |
|---|---|
| your local owning checkout | the source, and the only place the branch is measured from |
| the machine's admission mirror | a bare repository on the machine; the one push target |
| the machine's shared clone | the working repository; it fetches from the mirror |
| the machine itself | where the two far repositories live |
The order is not an implementation detail. The mirror is advanced first, then the clone fetches it, and then the clone's own local branch of that name is fast-forwarded to the same commit — because that local branch is the one a new far worktree is cut from. A clone cannot fetch a commit the mirror does not yet have.
That third step only ever fast-forwards, and every case is named: a clone with no local branch of that name is left alone; a local branch already at or ahead of the delivered commit is reported and never rewound; a local branch that is behind with uncommitted work in its checkout, or that has diverged, is refused with nothing moved. If the far host cannot answer whether a live checkout holds that branch, or whether that checkout is clean, the advance is refused too, and the refusal prints the command it could not run.
--repo names both the local source and the (machine, repository) pair whose mirror receives the
branch. --branch names the branch. Neither is ever guessed.
Rehearse it first:
The rehearsal performs the local, far-mirror and far-clone measurements, changes neither far repository, and exits non-zero when a far reference is stale — so a non-zero rehearsal is the answer "there is work to do here", not a failure.
What it refuses, and why
| the refusal | what it means |
|---|---|
--repo or --branch absent | the verb never guesses either; rerun naming both |
| the branch is not a named branch | a delivery with no named reference resolves an unresolvable bare HEAD on a fresh mirror and comes back as an empty tree at exit zero. There is no defensible default, so absence refuses |
| the machine is not admitted | it is not in your registry |
| the machine binds repository pairs, but not this one | refused by name; it never advances a different repository's mirror instead |
| the machine has no absolute worktrees root recorded | the far shared clone cannot be addressed; the refusal carries the verb that records one |
| the far mirror has diverged from your local branch | refused, never forced. A mirror that is a strict ancestor of your branch may be fast-forwarded; a mirror that is anything else holds commits a force would destroy |
| the clone's local branch is behind with uncommitted work, or has diverged | refused by name, nothing moved and nothing discarded |
What is structurally impossible here: a force-push, a prune, a deletion, or any push to your
own origin. Nothing in the delivery path names, fetches from, pushes to, or mutates origin —
that remote stays exclusively in your hands.
What it proves when it finishes. After it runs, it re-measures the far references. Unless the mirror and the clone both equal your local branch, the verb fails its own success predicate and says the values it read. A push and a fetch that both exit zero while the far side still reads short is exactly the outcome this postcondition exists to catch.
The sibling verb delivers the stream's base the same way, with the same three steps and the same refusals:
Without --base it refreshes the branch held by that repository's landing worktree
(wt-land, see workspace layout), and refuses by name
when exactly one such worktree cannot be found.
⛔ The trap that costs the most: which <branch> is fresh depends on where you stand
The same branch name means two different things in two places, and the mistake does not look like a mistake — you get a number, not an error.
| you stand in | FRESH is | can be STALE | why |
|---|---|---|---|
| your workspace (home) | <branch> (local) | origin/<branch> | merges land locally and nothing self-pushes, so the trunk lives in the local reference |
| a machine's shared clone (far) | origin/<branch> | <branch> (local) | every delivery moves origin/<branch>. The local branch of the same name is fast-forwarded with it only when it can be — it stays where it was when it is ahead, when a refusal stopped the advance, or when the clone was updated by anything other than these two verbs |
One check works in both places. Run it before you count anything:
It names each reference beside its object, so you do not have to remember argument order to apply the table. A missing reference simply omits its line instead of collapsing the measurement into a fatal error.
If the two objects differ, one of them is lying about everything you are about to count.
Which one is decided by the table above, not by reflex. Getting it backwards costs in both
directions: a commit count taken against a stale local branch inside a far clone reports hundreds
of commits on a branch that contributed none, and the same reflex at home reads origin/<trunk>
and reports green for a trunk that is red.
⚠ Write this into the order for a remote agent. An agent in confinement will make exactly the reflex you would, and it has no way to tell which clone it is sitting in unless you tell it.