Skip to content

basou: Name the base a board's repos are compared with, count what is ahead of it, and say when it was last fetched - #365

Merged
takashi-matsuyama merged 2 commits into
board/shape-v3from
board/repos-base
Oct 18, 2026
Merged

takashi-matsuyama merged 2 commits into
board/shape-v3from
board/repos-base

Conversation

@takashi-matsuyama

Copy link
Copy Markdown
Member

What

The repos section of a version 3 record names the branch each repo is compared with, counts the commits ahead of it, and says when it was last fetched (experimental, record_version: 3).

  • behind_main is renamed behind, counted as before. The repos method stays 2.
  • base: the branch of origin compared with, as origin/<branch>: the one refs/remotes/origin/HEAD names, or origin/main when it names none (the same resolution as 0.70.1). Null, with its meaning and no entry, when there is neither. When origin/HEAD names a branch that is not there, base is that name and behind / ahead are not measured, as behind_main was not.
  • ahead: the commits HEAD has that the base does not (rev-list --count base..HEAD); 0 for a HEAD with no commit yet. Not measured where behind is not (a shallow clone, a HEAD that names no commit, a base that cannot be read).
  • fetched_at: the mtime of git rev-parse --git-path FETCH_HEAD (this worktree's), in UTC, only when FETCH_HEAD holds the line git writes for the base's branch of origin's URL at the commit the base is at now (<oid>\t[not-for-merge]\tbranch '<branch>' of <url>). Otherwise null with no entry: no FETCH_HEAD, an empty one (a failed fetch), no such line (a fetch since from another URL, or of other branches only), or one at another commit (a fetch in another worktree, a push since). A base, a FETCH_HEAD or origin's URL that cannot be read is an entry, as other gaps are. A later git fetch --append moves the time and leaves origin's line, and a remote at origin's URL writes the same line as origin; the docs say both.
  • The URL is compared as git writes it there: the user and password of a URL with a scheme or of user@host:path taken out, then the slashes at its end, then one .git (git's transport_anonymize_url and the trimming after it). A URL this does not reproduce gives null, never a time. This closes the case of a remote at another URL whose branch of the same name is at the same commit.
  • fetched_at is left out of the digest and of the difference from the previous record: a fetch that brings nothing still rewrites FETCH_HEAD. Its not_found entries stay in both: they follow a ref or a file that cannot be read, not a fetch.

Also: basou board measure prints them on each repo's line (base origin/main, behind 1, ahead 0, fetched <time>, or no base (...)); the board page measured on the spot draws them as columns (a recorded board page draws no repos table, so records of version 1 and 2 need nothing there); basou board guide says what the four mean in step 2, and in the principles for 04 that ahead above 0 is not only commits not pushed and is read with branch; the record version comment and the CHANGELOG (Unreleased).

basou still sends nothing: git remote get-url origin and FETCH_HEAD are read locally.

Tests

  • New in measure.test.ts: ahead with merges; fetched_at for a not-for-merge line; null with no entry for a clone never fetched, a failed fetch, a fetch of another branch only, a fetch of another remote, at another URL, whose main is at the same commit, and a push; the FETCH_HEAD of the worktree measured (a linked worktree's absolute path); origin URLs fetched over an ssh stand-in that runs the command locally (user@host:path/, a password, git+ssh, '@' in the path, a local path), held against what git itself wrote; hand-written lines for another URL, a tag, a scheme git does not take, several trailing slashes, a local path with '@' and ':', and a name of five characters; an unreadable FETCH_HEAD (EACCES, EISDIR); a git that cannot say where FETCH_HEAD is; the digest unmoved by a later or a failed fetch.
  • Existing repos tests moved to the new fields, with entries for base, ahead and fetched_at where they now apply.
  • diff.test.ts: fetched_at is not compared; against a record of version 1 or 2, behind_main is removed and base, behind, ahead added.
  • live.test.ts, view.test.ts, board.test.ts, guide.test.ts: the page's columns and their classes, the CLI line, the guide's text.
  • Second commit (review follow-ups): a branch and an origin path that are not ASCII; removing only one .git; the not_found entries of fetched_at staying in the digest; a git remote get-url stopped by a signal is an entry; a later --append fetch and a remote at origin's URL, as the docs now say.

… ahead of it, and say when it was last fetched

In a version 3 record, each repo's behind_main is now behind, counted as
before, next to base (origin/<branch>: the branch origin/HEAD names, or
origin/main when it names none; null when there is neither), ahead (the
commits HEAD has that the base does not) and fetched_at (when FETCH_HEAD
was last written, only when it holds the line of the base's branch of
origin's URL, as git writes it there, at the commit the base is at now).
fetched_at is left out of the digest and of the difference from the
previous record. The repos method stays 2.

basou board measure prints the four on each repo's line, the board page
measured on the spot draws them as columns, and the guide says how to read
them when judging 04.
…tched_at moves without a fetch of origin

Review follow-ups. A git remote get-url that ends with no exit code (it
could not be started, or a signal stopped it) is now a gap, not a null
that says origin has no URL. The docs, the guide and the changelog say
that a later fetch with --append moves fetched_at and leaves origin's
line, that a remote at origin's URL writes the same line, and that what
is told apart is another URL rather than another remote; the guide no
longer calls fetched_at the time of the last fetch outright. New tests
pin a branch and a URL that are not ASCII, removing only one .git, the
not_found entries of fetched_at staying in the digest, the remote get-url
gap, and the two cases above. The changelog entry is rewrapped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant