mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-15 10:59:32 +01:00
fix(git): the fetch timeout reaches the whole tree, a tick covers every session on its folder, and the rest of the review (review)
`execFile` signals the `git` parent only, so a fetch that times out can leave its http helper still running, and on the interval that repeats every run with nobody watching. `runFetch` now spawns `detached`, so the fetch and the helper it spawns share one process group, and the kill is SIGTERM to the negative pid then SIGKILL `FETCH_KILL_ESCALATION_MS` later; the escalation is not cancelled when the promise settles, because the caller is answered at the timeout while the group is still dying. The output cap is kept, and the clone's slot queue is not needed here. The tick is two passes: every enabled local session is collected by folder, a folder is due when ANY session open on it is due, the folder is probed once for the group, and the run is published to every session on it. A single pass decided by the order the sessions were read, so [long, short] published only the short one and the 3600 s session's row never updated again while its folder was fetched every 30 s. `gitNonInteractiveEnv` writes BatchMode ssh as a default, not an override: `core.sshCommand` is read inside the same slot and the same bound as the fetch it serves, and `fetchEnvFor` keeps the repository's answer when it has one, because that is usually the setup that works on a machine with several ssh setups. The `accept-new` host key it can write is stated next to the BatchMode note: a prompt is stopped, a write is not. The write claim is scoped to the Git panel and to the timer, with cloning and worktree management named as the writes that happen when the user asked for them, and the zh keys sit with the group of the UI surface their English string belongs to. Tests: the process-group test proves the tree by group membership, because the helper is a grandchild (`git fetch` runs `git remote-http`, which spawns `git-remote-http`) and because the group is what the negative pid reaches, and it remembers each process once found instead of re-scanning a group it had already emptied. The non-zero-exit test changed premises: `git fetch --quiet` in a repository with no remote exits 0 on git 2.47.3, so resolving empty stdout there was correct, and the case that has to reject is a remote pointing at a path that is not a repository. The join test asserts after the run and does not await the request before the held run is released, which would wait on the run the test is holding.
This commit is contained in:
1 parent
ea4318947b
commit
3411d7f35a
15 files changed
+686
-165
No files matched your search
@@ -89,17 +89,21 @@ bounds the Git window's Fetch button; raise it for repositories on a slow networ
|
||||
|
||||
**Git fetch on an interval** (synced, off by default) runs `git fetch` on a timer for the repositories the
|
||||
Git window lists, so the `behind` number is current without a click, and **Git fetch: how often** (synced,
|
||||
30 to 3600 seconds, default 300) is the gap between runs for a case with no choice of its own — timed from
|
||||
30 to 3600 seconds, default 300) is the gap between runs for a session that has no override of its own — timed from
|
||||
the start of a run, so a slow repository does not push the next one out. These are the only Git settings
|
||||
that are synced rather than per device, because the server's scheduler is what acts on them: kept per
|
||||
device, the scheduler would read nobody's number. **Session Options → Git** overrides both the switch and
|
||||
the interval for one session, and that override wins even while the app switch is off; a session that follows
|
||||
the app shows the app's values and its rows go inert until you turn **Follow the app setting** off. Nothing is
|
||||
ever fetched for a Docker or remote (SSH) session, and a repository a container can write to is refused
|
||||
before any git runs. Sessions open on the same folder share one run. Both default to off because `git fetch`
|
||||
is the one git command Codeman runs that writes, and the one that can run a repository's own hooks
|
||||
before any git runs. Sessions open on the same folder share one run, and a folder is fetched when ANY session open on it is due, so the order the sessions were read cannot decide which interval wins. Both default to off because `git fetch`
|
||||
is the one git command the Git window runs that writes — cloning and worktree management write too, but only
|
||||
when you asked for them at the moment you asked — and the one that can run a repository's own hooks
|
||||
(`reference-transaction`, `pre-auto-gc` through the maintenance a fetch triggers, and config commands such as
|
||||
`credential.helper`).
|
||||
`credential.helper`), and the one that can run later by itself, on a timer. The ssh it runs is BatchMode so
|
||||
nothing waits for a login, and that is a default, never an override: your own `GIT_SSH_COMMAND`, or the
|
||||
repository's `core.sshCommand`, is used when either is set. ⚠️ The default's `StrictHostKeyChecking=accept-new`
|
||||
records an unknown host key in `~/.ssh/known_hosts` without asking — BatchMode stops a prompt, not a write.
|
||||
|
||||
Most default to off. The stock desktop header is system stats, File Viewer, Tiles, and the gear.
|
||||
**Header Stats Style** picks how the system stats and plan usage are drawn: *Compact*
|
||||
|
||||
@@ -254,16 +254,20 @@ Click it for a draggable window, in the style of the File Viewer:
|
||||
remote (SSH) sessions.
|
||||
|
||||
It is read-only apart from that fetch: Codeman never commits, checks out or changes the
|
||||
repository, and `git fetch` writes remote-tracking refs only — it is the one git command here that
|
||||
writes, and the one that can run a repository's own hooks (`reference-transaction`, `pre-auto-gc` through the
|
||||
maintenance a fetch triggers, and config commands such as `credential.helper`), which is why nothing runs on
|
||||
a timer until you opt in. A fetch holds git's ref lock, so an agent's own `git pull` in the same repository
|
||||
repository, and `git fetch` writes remote-tracking refs only — it is the only git command the Git window
|
||||
runs that writes, the only one that can run a repository's own hooks (`reference-transaction`,
|
||||
`pre-auto-gc` through the maintenance a fetch triggers, and config commands such as `credential.helper`),
|
||||
and the only one that can run later by itself, on a timer: cloning and worktree management write too, but
|
||||
only when you asked for them at the moment you asked, which is why nothing runs on a timer until you opt in. A fetch holds git's ref lock, so an agent's own `git pull` in the same repository
|
||||
can hit the same `cannot lock ref`, and a folder is fetched by one run at a time. It is not shown for Docker
|
||||
or remote (SSH) sessions, and a repository at or inside a Docker case
|
||||
workspace is skipped even from a local session, before any git runs (a container can write there,
|
||||
and git would run that repository's own configuration on the host). Fetch asks nothing of you: it
|
||||
uses the sign-in your own git already has, and it gives up quickly rather than waiting on an
|
||||
invisible login prompt. The
|
||||
invisible login prompt. That BatchMode ssh is a default, never an override: your own
|
||||
`GIT_SSH_COMMAND`, or the repository's `core.sshCommand`, is used when either is set, and ⚠️ the default's
|
||||
`StrictHostKeyChecking=accept-new` records an unknown host key in `~/.ssh/known_hosts` without asking —
|
||||
BatchMode stops a prompt, not a write. The
|
||||
data comes from `GET /api/sessions/:id/git-status`, `GET /api/sessions/:id/git-diff` and, on that
|
||||
click or the interval you turned on, `POST /api/sessions/:id/git-fetch`
|
||||
(see the [API reference](https://github.com/Ark0N/Codeman/blob/master/docs/api-reference.md)).
|
||||
|
||||
Reference in new issue
Block a user