Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete.
98 lines
5.8 KiB
Markdown
Executable File
98 lines
5.8 KiB
Markdown
Executable File
# Selected-path Git maintenance
|
|
|
|
The optional `git` namespace of `tools/devkit/devkit.py` is a deliberately
|
|
narrow maintenance workflow. It is not a replacement for normal Git, the
|
|
release executor, required human review, or Gitea's canonical issue state.
|
|
|
|
From the Meta repository, preview and then save a plan for explicit files:
|
|
|
|
```sh
|
|
python3 tools/devkit/devkit.py git plan --repo core --path webui/src/example.ts --message "Fix the reviewed example"
|
|
python3 tools/devkit/devkit.py git plan --repo core --path webui/src/example.ts --message "Fix the reviewed example" --apply
|
|
```
|
|
|
|
Use the saved `git-…` plan ID for the remaining commands. Each mutation needs
|
|
its own `--apply`; an unqualified command only previews the operation:
|
|
|
|
```sh
|
|
python3 tools/devkit/devkit.py git commit git-PLAN_ID
|
|
python3 tools/devkit/devkit.py git commit git-PLAN_ID --apply
|
|
python3 tools/devkit/devkit.py git push git-PLAN_ID
|
|
python3 tools/devkit/devkit.py git push git-PLAN_ID --apply
|
|
python3 tools/devkit/devkit.py git status git-PLAN_ID
|
|
```
|
|
|
|
The immutable local plan binds the registered repository, HEAD, branch, origin
|
|
fetch/push URL hashes, Git configuration, complete index identity, explicit
|
|
selected file paths, working-tree hashes, expected Git blobs, and commit message.
|
|
Raw remote URLs and file contents are not stored. A changed input blocks the
|
|
operation; inspect it and create another plan instead of weakening the check.
|
|
Receipts are private local records with integrity checks, not signed approval
|
|
or a security attestation.
|
|
|
|
Commit captures each selected file once, verifies the captured bytes and Git
|
|
blob against the plan, and builds an isolated index/tree from the frozen HEAD
|
|
plus only those blobs. Git's normal identity rules create the commit object;
|
|
an atomic branch compare-and-swap publishes it only if the planned parent is
|
|
still current. Active hooks/signing remain refused rather than bypassed.
|
|
An editor racing with this operation cannot substitute newer working-tree
|
|
bytes: those edits remain uncommitted, and the helper never overwrites files.
|
|
|
|
The real index is protected by Git's standard index lock. Only selected entries
|
|
are updated from a prepared private copy; unrelated staging and index flags are
|
|
preserved. If the index changes independently, its new data is not overwritten
|
|
and the receipt requires reconciliation. The resulting parent, message,
|
|
changed paths, blobs/modes and unrelated index entries are verified.
|
|
Git refs and index files are separately atomic, not one filesystem transaction.
|
|
Independent writers that ignore the standard index lock can still change refs
|
|
during publication. The helper rechecks the exact recorded candidate before
|
|
index recovery and before recording success; it refuses an uncertain result
|
|
instead of adopting a newer HEAD or claiming that competing work was its own.
|
|
Directories, noncanonical paths, implicit globs, staging-all, amend,
|
|
force-push and extra-tag publication are not supported. A selected file with
|
|
different staged and working-tree changes is refused; decide explicitly which
|
|
version to commit using normal Git first.
|
|
|
|
Push requires the recorded commit to remain current, an unchanged origin and
|
|
one standard-transport push destination. It requests a normal, non-forced push
|
|
of that commit to the recorded branch and checks the remote branch afterward.
|
|
The push preview does not contact a remote. A normal push may run the remote's
|
|
usual CI or server-side hooks; this is an external effect of the separately
|
|
authorized push, not of planning or committing.
|
|
|
|
Local active hooks (including index-change hooks), filter/encoding attributes,
|
|
signing, external fsmonitor/SSH configuration, Git environment overrides,
|
|
in-progress merge/rebase/cherry-pick operations, submodules, symlinks and
|
|
assume-unchanged/skip-worktree entries, split indexes and replacement/graft
|
|
history are deliberately
|
|
unsupported. The helper
|
|
refuses these cases instead of disabling hooks, signatures or filters. An
|
|
unused globally installed filter definition alone does not block maintenance;
|
|
active attributes are checked across tracked files as well as selected files.
|
|
Custom remote receive-pack/upload-pack/helper commands, recursive submodule
|
|
pushes and partial-clone lazy fetch are also refused. Of inherited `GIT_*`
|
|
variables, only `GIT_OPTIONAL_LOCKS`, `GIT_TERMINAL_PROMPT` and `GIT_PAGER` are
|
|
allowed (every command explicitly passes `--no-pager`, so the pager is inert);
|
|
namespace, identity, alternate-index/object-directory and unknown overrides
|
|
are not silently removed. Git subprocesses have bounded input/output and
|
|
deadlines; cancellation terminates their owned process group, including
|
|
transport helpers. Network failures can still leave a remote effect uncertain,
|
|
which is why receipts require explicit reconciliation rather than blind retry.
|
|
|
|
An interruption or uncertain failure is recorded before any retry. Use
|
|
`git reconcile git-PLAN_ID` to preview, then add `--apply` to verify an
|
|
already-existing result. Reconciliation never makes a commit or push. It may
|
|
finish the selected real-index update after an interrupted commit publication,
|
|
but only when the original index fingerprint still matches; independent staged
|
|
work is preserved and requires normal Git resolution. For an
|
|
uncertain push it may read the frozen remote, but only with `--apply`. If no
|
|
planned commit is current, the helper reports that state and requires a fresh
|
|
plan after inspection. A forcibly killed process may leave its private scratch
|
|
index or an owned Git index lock; the helper never guesses that an existing
|
|
lock is safe to delete. Blob/commit preparation can leave unreferenced Git
|
|
objects for ordinary Git garbage collection. It never automatically resets,
|
|
restores, deletes, or rolls back user work.
|
|
|
|
The maintenance tests use disposable local repositories and local bare remotes.
|
|
They never commit or push the user's workspace repositories.
|