Skip to content

git: worktree, stat checked-out files via the open fd. - #2258

Open
cedric-appdirect wants to merge 1 commit into
go-git:mainfrom
cedric-appdirect:worktree/checkout-fstat-index
Open

git: worktree, stat checked-out files via the open fd.#2258
cedric-appdirect wants to merge 1 commit into
go-git:mainfrom
cedric-appdirect:worktree/checkout-fstat-index

Conversation

@cedric-appdirect

@cedric-appdirect cedric-appdirect commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

checkoutFile returns the file FileInfo obtained from fstat on the open descriptor before it is closed, and addIndexFromFile consumes it directly instead of issuing a separate lstat per checked-out file. This removes a path lookup from the checkout hot path and, for BoundOS, an extra os.Root open/close per file. Symlinks still lstat since there is no fd to fstat.

Benchmark results (darwin/arm64, Apple M4 Pro, benchstat):
  BenchmarkCloneLargeRepo                       537.6ms -> 380.1ms  -29.30% (p=0.001, n=7)
  BenchmarkCloneDeepRepo                       1283.4ms -> 969.8ms  -24.43% (p=0.001, n=7)
  BenchmarkResetHardIgnoredDir/BaselineNoIgnoredFiles
                                               11.74ms -> 11.80ms        ~ (p=0.683, n=15)

The reset benchmark resets to HEAD, so no checkout occurs and it is unaffected by this change, as expected.

cedric-appdirect added a commit to cedric-appdirect/go-git that referenced this pull request Jul 15, 2026
BoundOS opens and closes a fresh *os.Root for every filesystem operation,
so each checked-out file pays several directory open/close syscalls on top
of the write itself. Open one *os.Root for the duration of a reset and route
the checkout write/delete path through it via osfs.FromRoot, wrapped in the
same validating worktreeFilesystem so path validation is unchanged. Fall back
to the default filesystem for non-OS backends.
This change is intentionally limited to root reuse; it does not touch the
post-write Lstat in addIndexFromFile, which is addressed separately by go-git#2258
via fstat on the open descriptor. The two stack cleanly.

Assisted-by: GLM 5.2 <noreply@z.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
@pjbgf

pjbgf commented Jul 16, 2026

Copy link
Copy Markdown
Member

@cedric-appdirect LGTM. Please rebase and fix the conflict above.

@cedric-appdirect
cedric-appdirect force-pushed the worktree/checkout-fstat-index branch from 26bc780 to 543a251 Compare July 16, 2026 16:04
@cedric-appdirect
cedric-appdirect force-pushed the worktree/checkout-fstat-index branch from 543a251 to 0565fad Compare July 29, 2026 18:22
checkoutFile returns the file FileInfo obtained from fstat on the open
descriptor before it is closed, and addIndexFromFile consumes it directly
instead of issuing a separate lstat per checked-out file. This removes a
path lookup from the checkout hot path and, for BoundOS, an extra os.Root
open/close per file. Symlinks still lstat since there is no fd to fstat.

Benchmark results (darwin/arm64, Apple M4 Pro, benchstat):
  BenchmarkCloneLargeRepo                       537.6ms -> 380.1ms  -29.30% (p=0.001, n=7)
  BenchmarkCloneDeepRepo                       1283.4ms -> 969.8ms  -24.43% (p=0.001, n=7)
  BenchmarkResetHardIgnoredDir/BaselineNoIgnoredFiles
                                               11.74ms -> 11.80ms        ~ (p=0.683, n=15)

The reset benchmark resets to HEAD, so no checkout occurs and it is
unaffected by this change, as expected.

Assisted-by: Cursor with Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Cedric BAIL <cedric.bail@appdirect.com>
@cedric-appdirect
cedric-appdirect force-pushed the worktree/checkout-fstat-index branch from 0565fad to cd09af8 Compare July 29, 2026 19:12
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.

2 participants