Enable parallel checkout for faster worktree creation
Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Successful in 18s
CI / Test (push) Failing after 1m19s
CI / Lint (push) Successful in 18s
CI / Integration Tests (push) Successful in 1m2s
CI / Coverage Report (push) Has been skipped
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Successful in 18s
CI / Test (push) Failing after 1m19s
CI / Lint (push) Successful in 18s
CI / Integration Tests (push) Successful in 1m2s
CI / Coverage Report (push) Has been skipped
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
Add EnableParallelCheckout() helper to git package and call it when creating bare repos. This configures checkout.workers=0 (auto-detect cores) and checkout.thresholdForParallelism=100. Expected 2-8x speedup on SSD for large repos (e.g., java rig with 85k files). Based on research in hq-dqc7t (APFS CoW optimization). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -442,10 +442,10 @@ func (g *Git) CommitAll(message string) error {
|
|||||||
|
|
||||||
// GitStatus represents the status of the working directory.
|
// GitStatus represents the status of the working directory.
|
||||||
type GitStatus struct {
|
type GitStatus struct {
|
||||||
Clean bool
|
Clean bool
|
||||||
Modified []string
|
Modified []string
|
||||||
Added []string
|
Added []string
|
||||||
Deleted []string
|
Deleted []string
|
||||||
Untracked []string
|
Untracked []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,6 +767,22 @@ func (g *Git) IsAncestor(ancestor, descendant string) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EnableParallelCheckout configures git to use parallel workers during checkout.
|
||||||
|
// This can significantly speed up worktree creation on SSDs (2-8x for large repos).
|
||||||
|
// Setting workers=0 auto-detects the number of CPU cores.
|
||||||
|
// Safe to call multiple times - git config is idempotent.
|
||||||
|
func (g *Git) EnableParallelCheckout() error {
|
||||||
|
// Auto-detect number of workers (0 = number of logical cores)
|
||||||
|
if _, err := g.run("config", "checkout.workers", "0"); err != nil {
|
||||||
|
return fmt.Errorf("setting checkout.workers: %w", err)
|
||||||
|
}
|
||||||
|
// Only parallelize when there are enough files to benefit
|
||||||
|
if _, err := g.run("config", "checkout.thresholdForParallelism", "100"); err != nil {
|
||||||
|
return fmt.Errorf("setting checkout.thresholdForParallelism: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// WorktreeAdd creates a new worktree at the given path with a new branch.
|
// WorktreeAdd creates a new worktree at the given path with a new branch.
|
||||||
// The new branch is created from the current HEAD.
|
// The new branch is created from the current HEAD.
|
||||||
// Sparse checkout is enabled to exclude .claude/ from source repos.
|
// Sparse checkout is enabled to exclude .claude/ from source repos.
|
||||||
@@ -1135,8 +1151,8 @@ type UncommittedWorkStatus struct {
|
|||||||
StashCount int
|
StashCount int
|
||||||
UnpushedCommits int
|
UnpushedCommits int
|
||||||
// Details for error messages
|
// Details for error messages
|
||||||
ModifiedFiles []string
|
ModifiedFiles []string
|
||||||
UntrackedFiles []string
|
UntrackedFiles []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean returns true if there is no uncommitted work.
|
// Clean returns true if there is no uncommitted work.
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import (
|
|||||||
|
|
||||||
"github.com/steveyegge/gastown/internal/beads"
|
"github.com/steveyegge/gastown/internal/beads"
|
||||||
"github.com/steveyegge/gastown/internal/claude"
|
"github.com/steveyegge/gastown/internal/claude"
|
||||||
"github.com/steveyegge/gastown/internal/constants"
|
|
||||||
"github.com/steveyegge/gastown/internal/config"
|
"github.com/steveyegge/gastown/internal/config"
|
||||||
|
"github.com/steveyegge/gastown/internal/constants"
|
||||||
"github.com/steveyegge/gastown/internal/git"
|
"github.com/steveyegge/gastown/internal/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -342,6 +342,13 @@ func (m *Manager) AddRig(opts AddRigOptions) (*Rig, error) {
|
|||||||
fmt.Printf(" ✓ Created shared bare repo\n")
|
fmt.Printf(" ✓ Created shared bare repo\n")
|
||||||
bareGit := git.NewGitWithDir(bareRepoPath, "")
|
bareGit := git.NewGitWithDir(bareRepoPath, "")
|
||||||
|
|
||||||
|
// Enable parallel checkout for faster worktree creation on large repos.
|
||||||
|
// This is especially beneficial for repos with 10k+ files (e.g., java rig).
|
||||||
|
if err := bareGit.EnableParallelCheckout(); err != nil {
|
||||||
|
// Non-fatal: parallel checkout is an optimization, not required
|
||||||
|
fmt.Printf(" Warning: could not enable parallel checkout: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Determine default branch: use provided value or auto-detect from remote
|
// Determine default branch: use provided value or auto-detect from remote
|
||||||
var defaultBranch string
|
var defaultBranch string
|
||||||
if opts.DefaultBranch != "" {
|
if opts.DefaultBranch != "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user