Here's how I address this problem.
When I'm developing, but before I create a PR, I'll create a bunch of stream-of-consciousness commits. This is stuff like "Fix typo" or "Minor formatting changes" mixed in with actual functional changes.
Right before I create the PR, or push up a shared branch, I do an interactive rebase (git rebase -i).
This allows me to organize my commits. I can squash commits, amend commits, move commits around, rewrite the commit messages, etc.
Eventually I end up with the 2-4 clean commits that your coworkers have. Often I design my commits around "cherry-pick" suitability. The commit might not be able to stand on its own in a PR, but does it represent some reasonably contained portion of the work that could be cherry-picked onto another branch if needed?
Granted, all of the advice above requires you to adhere to a "prefer rebase over merge" workflow, and that has some potential pitfalls, e.g. you need to be aware of the Golden Rule of Rebasing:
https://www.atlassian.com/git/tutorials/merging-vs-rebasing#...
But I vastly prefer this workflow to both "merge only," where you can never get rid of those stream-of-consciousness commits, and "squash everything," where every PR ends up with a single commit, even if it would be more useful to have multiple commits that could be potentially cherry-picked.
The only problem I have with this workflow in the command line is that I would like to be able to split changes to the same file across multiple commits. I think some GUI tools enable this, anyone know about it?
Have a look at `tig`. It's even included in Git for Windows now and does this reasonably well.
Only the keybindings are a bit weird if you're not accustomed to Vim bindings:
- Open tig
- Change into the staging view with `s`
- Select your file using the arrow or `j` and `k` keys
- Press Return to show the diff
- Navigate to the line(s) in question with `j` and `k` (arrow keys will switch files)
- Stage parts with `1` (single line), `2` (chunk parts), `u` (chunks) or split chunks with `\`
- "Leave" the diff with `q`
- You can find the keybindings with `h` in the help screen, which also uses Vim keys -- like manpages usually do