Skip to content

gitrepo: serve immutable Git checkouts over NFSv4.1 - #34

Draft
tomhjp wants to merge 1 commit into
mainfrom
tomhjp/nfsv4-gitrepo-fs
Draft

tomhjp wants to merge 1 commit into
mainfrom
tomhjp/nfsv4-gitrepo-fs

Conversation

@tomhjp

@tomhjp tomhjp commented Oct 9, 2026

Copy link
Copy Markdown
Member

This commit adds a new experimental package gitrepo, which serves read-only checkouts of git commits over NFSv4.1 using github.com/tailscale/nfsv4. It is for ephemeral workloads like CI VMs that know which commits they need before they start.

A long-lived Manager keeps one bare repository per configured remote, under a root directory. The first checkout of a repository runs "git init --bare", and each checkout of a commit that is not yet in the repository fetches it by SHA into refs/gomodfs/.

NewFS serves a fixed set of checkouts at /repos// as a nodefs filesystem, which the caller serves with its own nfsv4.Server. Each view needs its own server, so jobs on one host cannot see each other's checkouts and we don't need to include the SHA-1 as part of the checkout path. Each repository reads objects with one long-running "git cat-file --batch" process for fast content reads. All contents are immutable, so every object grants read delegations.

Each checkout has a read-only .git directory, so that read-only Git commands and Go's VCS stamping work. It contains HEAD, a shallow file, an index generated from the tree, and the loose objects of the commit and no other commit.

cmd/gomodfs gets -repo, -commit, and -repo-nfs flags to serve one checkout next to the module cache as a demo, and CI mounts that checkout on Linux and macOS.

Updates tailscale/corp#47555

@tomhjp
tomhjp requested a review from bradfitz October 9, 2026 13:38
This commit adds a new experimental package gitrepo, which serves
read-only checkouts of git commits over NFSv4.1 using
github.com/tailscale/nfsv4. It is for ephemeral workloads like CI VMs
that know which commits they need before they start.

A long-lived Manager keeps one bare repository per configured remote,
under a root directory. The first checkout of a repository runs "git
init --bare", and each checkout of a commit that is not yet in the
repository fetches it by SHA into refs/gomodfs/<sha>.

NewFS serves a fixed set of checkouts at /repos/<owner>/<repo> as a
nodefs filesystem, which the caller serves with its own nfsv4.Server.
Each view needs its own server, so jobs on one host cannot see each
other's checkouts and we don't need to include the SHA-1 as part of the
checkout path. Each repository reads objects with one long-running
"git cat-file --batch" process for fast content reads. All contents are
immutable, so every object grants read delegations.

Each checkout has a read-only .git directory, so that read-only Git
commands and Go's VCS stamping work. It contains HEAD, a shallow file,
an index generated from the tree, and the loose objects of the commit
and no other commit.

cmd/gomodfs gets -repo, -commit, and -repo-nfs flags to serve one
checkout next to the module cache as a demo, and CI mounts that
checkout on Linux and macOS.

Updates tailscale/corp#47555

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
@tomhjp
tomhjp force-pushed the tomhjp/nfsv4-gitrepo-fs branch from 8fef03d to ebec194 Compare October 9, 2026 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant