Commit often locally is right; the history people read is a different thing. Rhythm that works:
- One branch per feature:
git switch -c feat/export-csv. - Commit every time it works (wip is fine there).
- Merge to main with squash, with one proper message: "Add CSV export of filtered bookings". Main now reads like a changelog, and
git bisector blame gets you to one feature.
And let the AI write the messages: "commit the staged changes with a message describing what changed and why." Cursor's source control panel also has a generate-message button.