Skip to main content

Module push_guard

Module push_guard 

Source
Expand description

Pre-receive path guard for git push.

The pod repository uses receive.denyCurrentBranch=updateInstead, so every path a push adds, changes or deletes on the checked-out branch is written straight into the pod working tree, bypassing the REST/MCP path rules. This module inspects a git-receive-pack request before the CGI sees it and refuses the whole push (nothing is unpacked, no ref moves, nothing is checked out) if any path it changes is refused by the embedder’s classifier.

§What is checked

  • the pushed pack is indexed into a throw-away quarantine object directory (backed by the real object store as an alternate), so nothing reaches the repository unless the CGI later accepts the same bytes;
  • every commit the push introduces (rev-list <new> --not --all) is diffed against each of its parents (renames are split into delete + add, so both sides are seen), covering delete-then-recreate sequences and commits that are not on the tip;
  • for the ref that HEAD points at (the only ref updateInstead checks out) the new tip is additionally diffed against the current HEAD, which covers objects pushed earlier to another ref and then promoted;
  • every changed path (added, modified, deleted, type-changed) goes through the embedder-supplied PushPathGuard; paths that are not UTF-8, are absolute, or contain ., .., empty, backslash or NUL components are refused outright;
  • a new tree entry of mode 120000 (symlink) or 160000 (submodule) is refused outright.

§Limits

The work is bounded: a request body above MAX_PUSH_BODY_BYTES, more than MAX_PUSH_COMMITS new commits, more than MAX_PUSH_PATHS changed paths, or a check that exceeds PUSH_CHECK_TIMEOUT is refused rather than left to hang. Requests are serialised per repository so HEAD cannot move between the check and the CGI run.

Structs§

PushRefusal
A refused push: the client-facing reason.

Constants§

MAX_PUSH_BODY_BYTES
Largest git-receive-pack request body that is inspected (64 MiB). Larger pushes are refused.
MAX_PUSH_COMMANDS
Most ref updates one push may carry.
MAX_PUSH_COMMITS
Most new commits one push may introduce.
MAX_PUSH_PATHS
Most changed paths one push may carry, summed over all inspected diffs.
PUSH_CHECK_TIMEOUT
Wall-clock budget for the whole inspection.

Type Aliases§

PushPathGuard
Classifier for pushed paths. Receives a repository-relative path with a leading / (for example /.well-known/token/x.json) and returns true when a push must not change it.