Skip to content

Persist Settings by merging owned fields onto the live settings - #824

Merged
sbertix merged 1 commit into
mainfrom
sbertix/settings-avoid-global-rebuild
Aug 22, 2026
Merged

Persist Settings by merging owned fields onto the live settings#824
sbertix merged 1 commit into
mainfrom
sbertix/settings-avoid-global-rebuild

Conversation

@sbertix

@sbertix sbertix commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

The Settings window rebuilt the entire GlobalSettings from its own mirrored
state fields on every write, so a field it did not mirror was persisted as its
default. This threads only the fields the window owns onto the current on-disk
value instead, through a single applyOwnedFields list, leaving everything else
untouched: a field the window does not own now rides through verbatim rather than
being reset. The load-time worktree-path normalization likewise writes back only
the path it canonicalizes rather than the whole struct.

The three notification-inspector prefs (scope, grouping, unread-only) are no
longer mirrored into Settings state. The inspector writes them straight to the
shared settings file, so owning them let a Settings edit, or a load that
normalized the worktree base path, clobber an inspector change made after the
settings were read. They are carried through the merge now.

Type of change

  • Bug fix (the linked issue is a bug report)
  • Feature (the linked issue is a feature request marked ready)
  • Documentation
  • Other (please describe)

How was this tested?

New reducer tests cover the invariant: a completeness guard that starts disk at
defaults and state at fully non-default values, so every owned field must be
written for the persisted struct and the settingsChanged payload to match; plus
guards that a concurrent inspector pref write survives both an unrelated Settings
edit and a load-time path normalization.

  • make check passes (format + lint)
  • make test passes
  • I built and ran the app to confirm the change works

Checklist

  • This pull request is linked to an issue with Closes # above.
  • For a feature, the linked issue is labeled ready.
  • I am the author of this work and accountable for it; no commit is authored or co-authored by an AI agent.
  • I have read the Contributing guide and the Code of Conduct.

The Settings window rebuilt the entire GlobalSettings from its own mirrored
fields on every write, so a field it did not mirror was persisted as its
default. Merge only the fields the window owns onto the current on-disk value
instead, through a single applyOwnedFields list, leaving everything else
untouched: a GlobalSettings field the window does not own now rides through
verbatim rather than being reset. The load-time path normalization likewise
writes back only the path it canonicalizes rather than the whole struct.

Stop mirroring the notification inspector prefs (scope, grouping, unread-only).
The inspector writes them straight to the shared file, so owning them let a
Settings edit, or a load that normalized the path, clobber an inspector change
made after the settings were read; they are carried through the merge now.

Add a completeness test that starts disk at defaults and state at fully
non-default values, so every owned field must be written for the persisted
struct and the settingsChanged payload to match, plus tests that a concurrent
inspector pref write survives both an unrelated Settings edit and a load-time
path normalization.
@sbertix
sbertix enabled auto-merge (squash) August 22, 2026 16:54
@sbertix
sbertix merged commit ec1ec02 into main Aug 22, 2026
3 checks passed
@sbertix
sbertix deleted the sbertix/settings-avoid-global-rebuild branch August 22, 2026 17:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant