返回 DeepSeek-Reasonix
workspace_repo.go
根目录 / internal / boot / workspace_repo.go
1 package boot
2
3 import (
4 "context"
5 "os"
6 "path/filepath"
7 "time"
8
9 "reasonix/internal/gitcmd"
10 )
11
12 // workspaceRepoTimeout bounds the one git call a session open makes.
13 const workspaceRepoTimeout = 10 * time.Second
14
15 // workspaceRepo is root's git identity for the session being built, settled
16 // before the session runs any command. A rebuild of the same workspace keeps
17 // the identity its session opened with instead of rediscovering it from files
18 // that session could since have written.
19 func workspaceRepo(ctx context.Context, carried gitcmd.Repo, root string) gitcmd.Repo {
20 abs, err := filepath.Abs(root)
21 if err != nil {
22 return gitcmd.Repo{Dir: root}
23 }
24 if carried.Dir != "" && filepath.Clean(carried.Dir) == abs {
25 return carried
26 }
27 if !underGitMarker(abs) {
28 return gitcmd.Repo{Dir: abs}
29 }
30 ctx, cancel := context.WithTimeout(ctx, workspaceRepoTimeout)
31 defer cancel()
32 repo, err := gitcmd.Open(ctx, abs)
33 if err != nil {
34 return gitcmd.Repo{Dir: abs}
35 }
36 return repo
37 }
38
39 // underGitMarker reports whether dir or an ancestor holds a .git entry, so a
40 // workspace outside any repository never starts git (on macOS a missing git is
41 // an installer prompt, not an error).
42 func underGitMarker(dir string) bool {
43 for {
44 if _, err := os.Lstat(filepath.Join(dir, ".git")); err == nil {
45 return true
46 }
47 parent := filepath.Dir(dir)
48 if parent == dir {
49 return false
50 }
51 dir = parent
52 }
53 }
54
54 lines GO