Expand description
Where short-lived private files live:
the per-user scratch directory and the repository scratch directory,
never the system temporary directory.
What:
Where the wrapper keeps short-lived private files:
the per-user scratch directory (<state>/cli-git/scratch) for work that has no repository
in hand,
and the repository scratch directory (<common-dir>/cli-git-scratch) for work inside one.
Both are checked as private (a real directory of this user, mode 0700) and swept of entries
older than a day each time they are prepared.
Why:
The system temporary directory is never used (issue 1809, repo rule XTD):
which device backs it is unknowable (a small tmpfs, a per-user quota, a slow disk),
and a full one broke every session.
A file left by a killed process must not accumulate without bound,
so every preparation of a directory also collects what is stale in it.
doc/planning/cli-git-scratch-locations.md records the choice per site.
In TS you’d write (pseudocode):
const scratch = join(env.XDG_STATE_HOME ?? join(env.HOME, '.local/state'), 'cli-git', 'scratch');
await mkdir(scratch, { recursive: true, mode: 0o700 });
await sweepOlderThan(scratch, 24 * 60 * 60 * 1000);Constants§
- REPOSITORY_
SCRATCH_ NAME - The entry in a Git common directory that holds repository scratch.
- SCRATCH_
STALE_ AFTER - How old an entry must be before a preparation removes it: far longer than any command of the wrapper runs (its longest bound is minutes), so a live process never loses a file.
Functions§
- prepare_
repository_ scratch - What: Create the repository scratch directory beside the common Git directory’s other private storage, check that it is private, sweep its stale entries, and return it. Why: Git input for a commit transaction is written there: it is on the repository’s own device, needs no environment variable, and is collected with the repository.
- prepare_
user_ scratch - What: Create the per-user scratch directory with its missing parents, check that it is private, sweep its stale entries, and return it. Why: The linter and the push probe write there; the check refuses a directory another account could write.
- scratch_
file - What:
An anonymous file (no name in the directory) in the per-user scratch directory of
environment, open for reading and writing. Why: Child output goes to a file so that no reader thread can outlive a stopped child; the file has no name from the start (an unnamed temporary file where the system has them, otherwise a name removed at once), so a killed process leaves nothing to collect, and the system temporary directory is never used. - state_
directory - What:
The per-user state directory of the wrapper:
cli-gitunder an absoluteXDG_STATE_HOME, or under.local/statein the home directory. Why: The injected environment decides the location, never a fixed path; a relativeXDG_STATE_HOMEis ignored as the XDG rules say. It mirrors the cache directory of the version cache. - sweep_
stale - What:
Remove every entry of
directorylast modified more thanmax_agebeforenow, and return how many it removed. A link is removed itself and never followed; a directory is removed with its contents. Why: A process killed between making a scratch file and removing it leaves the file behind, and nothing else would ever collect it. The directory belongs to the wrapper alone, so every entry in it is the wrapper’s; an entry modified in the future is kept, because a wrong clock must not delete live files. - user_
scratch_ path - What: The per-user scratch directory’s path, or the sentence that says what the environment lacks. Nothing is created. Why: Callers that run without a repository learn the location first and create it only when they need it, so a command with nothing to write never touches the disk.