Repository navigation
Operators can create repositories from the CLI and the SDK. Branch names are
read exactly in every RPC, and agents can no longer write the server's own
references in any mode. Reftable housekeeping no longer fails on busy
repositories. Some error codes change; see "Upgrade".
New
graft repo createand SDKRepo.Create. An operator, with the
shared token, creates a repository:
graft repo create demo.git --initial-commit --branch feature/demo.
The repository can be cloned straight away. The command converges: run it
again after a failure and it does only what is missing. It never adds a
commit to a repository that already has references, and it refuses when
HEAD points to another branch. Agent tokens are refused. In authoritative
mode the repository is registered with the storage core; in shadow mode the
command prints thegraft storage importstep. QUICKSTART no longer needs
git initandgit push.
Security
-
Branches are read by their exact names in every operations RPC:
UserFFBranch, UserMergeBranch, UserDeleteBranch, UserUpdateSubmodule,
UserCherryPick, UserRevert, UserApplyPatch, UserRebaseConfirmable and the
default branch. Before, git's revision rules let another reference answer
for a branch, such asrefs/tags/refs/heads/xor a tag named like an
existing branch. Any client that could push a tag could use that to choose
the commit an operation started from. -
Start points (
start_branch_nameof cherry-pick and revert, the remote
branch of a rebase) follow git, with one difference: an existing branch
beats a tag or arefs/xof the same name. Also:- a full object ID is that commit;
refs/...is read exactly;heads/,tags/andremotes/names follow git;- a reflog entry needs the reference's own reflog;
<rev>:pathis refused.
The local and the start-repository paths give the same answers.
-
Agents never write
refs/graft/, in every mode. The reservation was
enforced by the reference-transaction hook only in standalone mode. It is
now an invariant of the server.SSHService/SSHUploadArchivecan no longer
be opened to agents: git's upload-archive ignores hidden references, so it
could readrefs/graft/by name. The layers are described in
AGENT-SECURITY.md, with end-to-end tests that push as an agent and drive
the real hook in both modes.
Fixes
- Reftable housekeeping on busy repositories.
git pack-refsexits with
a lock or "concurrently modified" error when a writer races it. That
failure is harmless (git itself ignores it), but it failed the whole
OptimizeRepository, so the commit-graph and later steps were skipped.
It is now recorded aspacked_refs=skipped, with a warning, and
housekeeping continues; every other error stays fatal. - Stale reftable table locks (
<table>.ref.lock, left by a killed git) are
removed after the same grace period astables.list.lock. Before, they
blocked compaction forever. - A detached HEAD in
FindDefaultBranchName(head only) is a
FailedPrecondition, not an Internal error.
Measured, not built
STORAGE.md has two new sections, both measured and both ending in "don't
build":
- Where the upload time goes. A file-bucket upload costs two fsyncs.
Sharing the directory fsync would save at most 4.3 ms, and it is worse for
large packs. The long tails in use come from the disk being shared with
the database: put the bucket on another device. - Inline compaction stays. Without git's inline reftable compaction, 50
writers are 2.6x slower and reads 4x slower.
CI
- Tests that pass only on gotestsum's re-run are now shown as warnings on
the run page, and their output is kept as an artifact. Before, they left
the job green and invisible. - New legs run the reference-heavy packages on reftable.
- Five timing-dependent tests now assert their property without the wall
clock.
Upgrade
Error codes that change:
- A contended repository lock in CreateRepository, CreateFork,
CreateRepositoryFrom*, CreateObjectPool, ReplicateRepository and backup
restore: Internal → FailedPrecondition "repository is already locked". - UserCreateBranch refused by access checks: Internal → PermissionDenied.
- A revision passed as a branch name (
main~1) now fails as not found when
the branch is read. gitaly_housekeeping_tasks_totalhas a new statusskippedfor
packed_refs. On reftable, these events used to count as failures.
Configuration:
- An
agent_rpcsentry that namesgitaly.SSHService/SSHUploadArchivenow
stops the server at startup. Remove it.
No data migration.