This commit is contained in:
spoons-and-mirrors 2025-08-21 17:30:29 +02:00 committed by GitHub
commit 8f3ccbe859
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -220,16 +220,18 @@ func (m *statusComponent) initWatcher() error {
return err return err
} }
if err := watcher.Add(headFile); err != nil { // Watch the entire .git directory instead of just HEAD so that atomic
// rewrites of HEAD or refs are always detected across platforms.
if err := watcher.Add(gitDir); err != nil {
watcher.Close() watcher.Close()
return err return err
} }
// Also watch the ref file if HEAD points to a ref // Also watch the current ref file (in case of direct hash vs ref switches)
refFile := getGitRefFile(m.app.Info.Path.Cwd) refFile := getGitRefFile(m.app.Info.Path.Root)
if refFile != headFile && refFile != "" { if refFile != headFile && refFile != "" {
if _, err := os.Stat(refFile); err == nil { if _, err := os.Stat(refFile); err == nil {
watcher.Add(refFile) // Ignore error, HEAD watching is sufficient _ = watcher.Add(refFile) // ignore error: directory watch usually sufficient
} }
} }
@ -247,24 +249,30 @@ func (m *statusComponent) watchForGitChanges() tea.Cmd {
for { for {
select { select {
case event, ok := <-m.watcher.Events: case event, ok := <-m.watcher.Events:
branch := getCurrentGitBranch(m.app.Info.Path.Root)
if !ok { if !ok {
return GitBranchUpdatedMsg{Branch: branch} return GitBranchUpdatedMsg{Branch: getCurrentGitBranch(m.app.Info.Path.Root)}
} }
if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) { if event.Has(fsnotify.Write) || event.Has(fsnotify.Create) || event.Has(fsnotify.Rename) {
// Debounce updates to prevent excessive refreshes // Small delay to allow git to finish updating refs
now := time.Now() time.Sleep(60 * time.Millisecond)
if now.Sub(m.lastUpdate) < 100*time.Millisecond { // Drain any burst of subsequent events without extra sleeps
continue DrainLoop:
for {
select {
case e := <-m.watcher.Events:
_ = e // ignore, we just want to collapse bursts
continue
case <-time.After(5 * time.Millisecond):
break DrainLoop
}
} }
m.lastUpdate = now
if strings.HasSuffix(event.Name, "HEAD") { if strings.HasSuffix(event.Name, "HEAD") {
m.updateWatchedFiles() m.updateWatchedFiles()
} }
return GitBranchUpdatedMsg{Branch: branch} return GitBranchUpdatedMsg{Branch: getCurrentGitBranch(m.app.Info.Path.Root)}
} }
case <-m.watcher.Errors: case <-m.watcher.Errors:
// Continue watching even on errors // ignore errors, keep watching
case <-m.done: case <-m.done:
return GitBranchUpdatedMsg{Branch: ""} return GitBranchUpdatedMsg{Branch: ""}
} }
@ -326,7 +334,7 @@ func (m *statusComponent) Cleanup() {
func NewStatusCmp(app *app.App) StatusComponent { func NewStatusCmp(app *app.App) StatusComponent {
statusComponent := &statusComponent{ statusComponent := &statusComponent{
app: app, app: app,
lastUpdate: time.Now(), lastUpdate: time.Time{},
} }
homePath, err := os.UserHomeDir() homePath, err := os.UserHomeDir()