Fetch only on request, remove --no-fetch

Nothing is fetched on startup any more; the header and detail pane show
the last fetch and f fetches everything. Records the change as D22.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 12:13:01 +02:00
co-authored by Claude Sonnet 5.5
parent 928e76154f
commit a285a35c95
8 changed files with 36 additions and 32 deletions
+1 -2
View File
@@ -31,8 +31,7 @@ Installs `submarine` and the alias `sub` (linux/macOS, amd64/arm64) to
**Prototype.** The UI is complete for browsing. It reads real repositories
through a git provider (`internal/submodule/git`): `submarine [dir]`. It
fetches in the background on startup (`--no-fetch` to skip; `f` to fetch
again) and follows changes made in other shells. `submarine --mock` shows
fetches only when asked (`f`) and follows changes made in other shells. `submarine --mock` shows
the built-in mock data (`internal/submodule/mock`). `!` shows only
submodules with problems. The actions `u` and `b` only show a "not
implemented" message ([drafts of the write actions](actions.md)).
+4 -4
View File
@@ -119,9 +119,9 @@ The mock provider (`internal/submodule/mock`) covers every state and sleeps
calling `Status()` → `statusLoadedMsg`.
3. Each result is stored on the submodule (`Status` or `Err`); the view
updates incrementally, including parents' hidden-issue counts.
4. After the first tree: the watcher starts (`changeMsg`), and the
background fetch starts one `tea.Cmd` per fetchable repository
(`fetchDoneMsg`).
4. After the first tree: the watcher starts (`changeMsg`). Nothing is
fetched until the user presses `f`, which starts one `tea.Cmd` per
fetchable repository (`fetchDoneMsg`).
5. The spinner ticks only while something loads or fetches.
### Fetch and refresh are decoupled (D20)
@@ -197,7 +197,7 @@ No CI runner: releases are built and published from a developer machine.
so `sub` works too). `SUBMARINE_UPDATE_URL` overrides the registry.
- After the TUI exits, a one-line notice is printed if a newer release
exists. The check runs in the background at startup, at most once a day
(cached in the user cache dir) and is off for dev builds, `--no-fetch`,
(cached in the user cache dir) and is off for dev builds,
`--mock` and `SUBMARINE_NO_UPDATE_CHECK=1`.
## Testing
+18 -1
View File
@@ -150,7 +150,7 @@ removed + untracked.
**Consequences.** One extra `git diff` per dirty submodule, none for clean
ones. Not included: staged/unstaged markers, diff bodies, stash count.
## D18 — Background fetch on startup
## D18 — Background fetch on startup (superseded by D22)
**Context.** Without fetching, every answer is only as fresh as the user's
last `git fetch`, which they rarely run in every submodule.
@@ -296,3 +296,20 @@ count as problems because their state is unknown (D7 counts `error` as danger
too); the cost is that rows vanish as statuses arrive, so the selection is
refitted after each status. Staged pins are not shown by it, since they are
not issues.
## D22 — Fetch only on request
**Context.** D18 fetched every repository on startup. With hundreds of
submodules that is hundreds of network round trips (and credential or
host-key failures) every time the tool opens, whether or not the user wants
fresh remote data.
**Decision.** Supersedes D18. Nothing is fetched on startup. The header and
the detail pane show the last fetch (`FETCH_HEAD`, also from fetches made in
other shells), so the user can judge how stale the remote refs are and press
`f` to fetch. The `--no-fetch` flag is removed with it (it still had the
side effect of switching off the update check; that has
`SUBMARINE_NO_UPDATE_CHECK`).
**Consequences.** Right after startup, `unpushed`, `↓n` and the like are as
fresh as the last fetch. `fetched never` appears for a repository that was
never fetched. The progress display and per-submodule fetch errors stay as
they are, they now belong to `f`.
+5 -5
View File
@@ -100,9 +100,10 @@ commit hashes. It doesn't answer the questions users actually have:
### Fetch and refresh
- **F50** On startup, after the local state is shown, the superproject and
every initialized submodule are fetched in the background (all remotes,
with prune). `--no-fetch` turns this off.
- **F50** Nothing is fetched on startup. The header and the detail pane show
when the repositories were last fetched (`FETCH_HEAD`), whoever did it.
`f` fetches the superproject and every initialized submodule in the
background (all remotes, with prune).
- **F51** While fetching, the header shows progress (`fetching 12/174`)
instead of the fetch age; afterwards the age and the number of failed
fetches. The detail pane shows each submodule's last fetch and, if it
@@ -141,13 +142,12 @@ See [actions.md](actions.md) for the draft of the write actions.
```sh
submarine [dir] # the repository containing dir (default: current directory)
submarine --mock # built-in mock data
submarine --no-fetch [dir] # no background fetch on startup
```
## Non-functional requirements
- **N1** Startup must not block on the network. The tool shows the local
state at once and fetches in the background (F50).
state at once and uses the network only when the user asks (F50).
- **N2** Loading many submodules must not freeze the UI (async, per
submodule).
- **N3** Colors follow the user's terminal theme (ANSI 16 colors); the UI