返回 DeepSeek-Reasonix
workspace_repo.go
根目录 / desktop / workspace_repo.go
1 package main
2
3 import (
4 "context"
5 "path/filepath"
6 "time"
7
8 "reasonix/internal/control"
9 "reasonix/internal/gitcmd"
10 )
11
12 const workspaceRepoOpenLimit = 3 * time.Second
13
14 // sessionWorkspaceRepo is the git identity ctrl's session resolved for base
15 // when it opened, and whether that session holds one for base at all.
16 func sessionWorkspaceRepo(ctrl control.SessionAPI, base string) (gitcmd.Repo, bool) {
17 c, ok := ctrl.(interface{ WorkspaceRepo() gitcmd.Repo })
18 if !ok {
19 return gitcmd.Repo{}, false
20 }
21 repo := c.WorkspaceRepo()
22 return repo, repo.Dir != "" && filepath.Clean(repo.Dir) == filepath.Clean(base)
23 }
24
25 // workspaceRepo is the identity host git reads root through: the one its
26 // session opened with, or, for a root no session holds yet, the one it
27 // resolves to now, as opening it would.
28 func workspaceRepo(root string, ctrl control.SessionAPI) (gitcmd.Repo, error) {
29 base, err := workspaceBaseFromRoot(root)
30 if err != nil {
31 return gitcmd.Repo{}, err
32 }
33 if repo, ok := sessionWorkspaceRepo(ctrl, base); ok {
34 return repo, nil
35 }
36 return openWorkspaceRepo(base), nil
37 }
38
39 func openWorkspaceRepo(base string) gitcmd.Repo {
40 ctx, cancel := context.WithTimeout(context.Background(), workspaceRepoOpenLimit)
41 defer cancel()
42 repo, err := gitcmd.Open(ctx, base)
43 if err != nil {
44 return gitcmd.Repo{Dir: base}
45 }
46 return repo
47 }
48
49 // workspaceRepoForRoot is root's identity as a tab session holding it opened
50 // it, or as opening it now would.
51 func (a *App) workspaceRepoForRoot(root string) (gitcmd.Repo, error) {
52 var ctrl control.SessionAPI
53 a.mu.RLock()
54 for _, tab := range a.tabs {
55 if tab.Ctrl != nil && sameProjectRoot(tab.WorkspaceRoot, root) {
56 ctrl = tab.Ctrl
57 break
58 }
59 }
60 a.mu.RUnlock()
61 return workspaceRepo(root, ctrl)
62 }
63
63 lines GO