Skip to content

Commit b2a079e

Browse files
authored
Merge pull request #237 from shelltime/claude/fix-git-lock-error-8J8Iv
Prevent git lock conflicts in daemon background polling
2 parents fd739d8 + 3f94286 commit b2a079e

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

daemon/git.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package daemon
22

33
import (
44
"context"
5+
"os"
56
"os/exec"
67
"strings"
78
"time"
@@ -16,6 +17,16 @@ type GitInfo struct {
1617
IsRepo bool
1718
}
1819

20+
// gitCmd creates a git command that won't acquire optional locks.
21+
// This prevents conflicts with user-initiated git operations when the daemon
22+
// polls git status in the background. Uses GIT_OPTIONAL_LOCKS=0 which is
23+
// equivalent to passing --no-optional-locks to every git command.
24+
func gitCmd(ctx context.Context, args ...string) *exec.Cmd {
25+
cmd := exec.CommandContext(ctx, "git", args...)
26+
cmd.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0")
27+
return cmd
28+
}
29+
1930
// GetGitInfo returns git branch and dirty status for a directory.
2031
// It uses the native git CLI which is significantly faster and more memory-efficient
2132
// than the pure-Go go-git implementation, especially on large repositories.
@@ -28,19 +39,19 @@ func GetGitInfo(workingDir string) GitInfo {
2839
defer cancel()
2940

3041
// Check if this is a git repo
31-
if err := exec.CommandContext(ctx, "git", "-C", workingDir, "rev-parse", "--git-dir").Run(); err != nil {
42+
if err := gitCmd(ctx, "-C", workingDir, "rev-parse", "--git-dir").Run(); err != nil {
3243
return GitInfo{}
3344
}
3445

3546
info := GitInfo{IsRepo: true}
3647

3748
// Get branch name from HEAD
38-
if out, err := exec.CommandContext(ctx, "git", "-C", workingDir, "rev-parse", "--abbrev-ref", "HEAD").Output(); err == nil {
49+
if out, err := gitCmd(ctx, "-C", workingDir, "rev-parse", "--abbrev-ref", "HEAD").Output(); err == nil {
3950
info.Branch = strings.TrimSpace(string(out))
4051
}
4152

4253
// Check dirty status via porcelain output (empty = clean)
43-
if out, err := exec.CommandContext(ctx, "git", "-C", workingDir, "status", "--porcelain").Output(); err == nil {
54+
if out, err := gitCmd(ctx, "-C", workingDir, "status", "--porcelain").Output(); err == nil {
4455
info.Dirty = len(strings.TrimSpace(string(out))) > 0
4556
}
4657

0 commit comments

Comments
 (0)