Archived
Fetch in the background and follow changes in the repositories
- On startup, after the local state is shown, fetch the superproject and every initialized submodule (all remotes, prune, at most 8 at once). Fetches never prompt; failures show git's message. --no-fetch skips it, f fetches again. - The header shows "fetching n/m", then the fetch age and failures; the detail pane shows each submodule's last fetch and fetch errors. - The git provider polls each repository's metadata (refs, HEAD, index, .gitmodules) every 2 s and reports changes. The app reloads only what changed, keeping old values, expansion and cursor; loads are single-flight with coalesced reruns. Refresh is driven by the repositories, so a fetch in another shell updates the view like ours. - r reloads everything (worktree edits are not watched). - Docs: F50-F53, N1/N8 rewritten, D18-D20 (D12 superseded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
19c6f17eb2
commit
27f0c0b5d2
@@ -14,6 +14,7 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"submarine/internal/submodule"
|
||||
)
|
||||
@@ -27,8 +28,13 @@ const maxBetween = 50
|
||||
|
||||
// Provider reads a superproject and its submodules with git.
|
||||
type Provider struct {
|
||||
root string // absolute superproject root
|
||||
sem chan struct{} // bounds concurrent Status calls
|
||||
root string // absolute superproject root
|
||||
sem chan struct{} // bounds concurrent Status calls
|
||||
fetchSem chan struct{} // bounds concurrent fetches
|
||||
sshEnv []string // extra environment for fetches
|
||||
|
||||
// WatchInterval is how often Watch checks for changes.
|
||||
WatchInterval time.Duration
|
||||
|
||||
mu sync.RWMutex
|
||||
mods map[string]info // by Submodule.Path; filled by Tree
|
||||
@@ -49,8 +55,11 @@ func New(dir string) (*Provider, error) {
|
||||
return nil, fmt.Errorf("%s is not a git repository", dir)
|
||||
}
|
||||
return &Provider{
|
||||
root: root,
|
||||
sem: make(chan struct{}, runtime.NumCPU()),
|
||||
root: root,
|
||||
sem: make(chan struct{}, runtime.NumCPU()),
|
||||
fetchSem: make(chan struct{}, maxFetches),
|
||||
sshEnv: sshBatchEnv(root),
|
||||
WatchInterval: 2 * time.Second,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -168,6 +177,12 @@ func status(ctx context.Context, in info) (*submodule.Status, error) {
|
||||
return st, nil
|
||||
}
|
||||
|
||||
if gitDir, _, err := gitDirs(in.dir); err == nil {
|
||||
if fi, err := os.Stat(filepath.Join(gitDir, "FETCH_HEAD")); err == nil {
|
||||
st.FetchedAt = fi.ModTime()
|
||||
}
|
||||
}
|
||||
|
||||
// checkout and worktree
|
||||
head, err := run(ctx, in.dir, "rev-parse", "HEAD")
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user