A component's build progress reads under its buttons, and an unrelated history can be overridden

Two things, both about a card being able to act on what it says.

The progress bar, its counts and the last line a component printed now
sit below that component's buttons rather than above them. A bar reports
on the press that started it, so it reads in the order it happened -- and
above, it pushed the buttons down the moment a build began, moving the row
somebody had just pressed out from under their finger.

A pull that cannot fast-forward because the checkout shares no history
with its upstream now offers a way past it. There is no fast-forward
between two unrelated histories and there never will be, so the card was
one that could never be pulled again, with the only remedy on the build
machine -- exactly where the person holding the phone isn't. The card
reports the failure as before and a dialog offers a forced pull, naming
the branch and the upstream it is about to overwrite; confirming sends
?force=true, which resets onto the upstream instead of merging.

Whether it *is* that failure is decided structurally, by `git merge-base`
finding no common ancestor, rather than by matching what git printed:
those messages are translated, and a button that appeared only on an
English build machine would be worse than no button. It travels to the
phone as its own field for the same reason. The dirty-tree refusal stays
in front of it, so a forced pull can only ever discard something that was
committed, and a merely diverged history is not offered it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-08-31 22:03:44 -04:00
1 parent b0e83059a3
commit db47972a25
6 files changed
+306 -29

No files matched your search

+17
View File
@@ -256,6 +256,23 @@ mutable at runtime from the phone.
remote deliberately, and a card that mentions it every time is nagging
about a choice somebody made.
- **Unrelated histories are the one pull failure the phone may override.**
A checkout sharing no commit with its upstream has no fast-forward and
never will, so with nothing offered the card is one that can never be
pulled again -- and the way out is on the build machine, which is
exactly where the person holding the phone isn't. So `?force=true` on
the pull route resets onto the upstream instead of merging, behind a
dialog that names the branch it is about to overwrite (the only place
that is seen before it goes). Whether this *is* that failure is decided
structurally -- `git merge-base` finding no common ancestor -- and never
by matching what git printed: those messages are translated, and a
button that appeared only on an English build machine is worse than no
button. It travels as `PullError::unrelated_histories` rather than
inside the message for the same reason. The dirty-tree refusal stays in
front of it, so a forced pull can only ever discard something that was
committed, and a merely *diverged* history is not offered it -- there is
something better than throwing that away.
- **The branch line is how a failed remote check is visible at all.** With
it gone, `newCommits` stays false and the card reads as an app with no
updates -- the same silent failure the self-entry note below describes.