4 ms·
It's far easier and less time-consuming to squash commits than it is to tease out logically distinct changes from a big mess into separate commits. The latter
by pengaru 5y ago
It's far easier and less time-consuming to squash commits than it is to tease out logically distinct changes from a big mess into separate commits. The latter is particularly troublesome when you require preserving bisectability, i.e. every final commit builds and functions. Being able to bisect saves tons of time chasing bugs.
This is one of those "ounce of prevention vs. a pound of cure" situations.
- pavas 5y agoFor the developer working on the change, or for the reviewer + everyone that comes after them looking at your commit (which can include your future self)? We tend to discount everyone else's time but our own. Might also be worth thinking about long term asymptotic effort vs marginal effort at a particular point in time--typically, the more often you do something (decomposing a commit into multiple independent parts, in this instance), the easier and less time-consuming it becomes.
- pengaru 5y ago> For the developer working on the change, or for the reviewer + everyone that comes after them looking at your commit (which can include your future self)? Both. I don't really follow what you're getting at, I think we're in agreement? confused
- pavas 5y agoYes we are; I thought you were advocating for larger commits since they're too difficult to break apart into logically independent pieces, but it seems I just misunderstood what you wrote the first time I read it.
- gregmac 5y agoTo me, the ability to bisect is a good reason not to squash (I assume you mean squash merge?). My commits all stand alone; each is a distinct change that pretty much always is in a working state. Often it will be a series of refactors before the real change. Ironically, though it makes bisect easier, I find it rarely need to use bisect: just looking at commit messages (via either log or blame) is often enough to isolate a problem. I accomplish this using interactive staging, and within my branch, and before I push, using any combination of rebase, squash, amend and fixup. I also prefix commits with the ticket to make referencing way easier. My failed experiments (a change that later is undone) don't usually make it to anyone else, unless it's something modified during a PR review. On a small handful of occasions I've changed something radically and will delete the remote branch, modify and interactive rebase ny local one and push it again (or push as a new branch). For a feature I work on for a couple days, I'll commit a couple dozen times or more, rebase/squash to maybe 5-10 commits anyone else sees, and push to origin maybe 2-5 times. When merging the branch (PR), I use merge --no-ff. This preserves commits and makes it easier to see later during a blame. And since the commit history is clean, it's not "noisy". One of the massive benefits of this is the ability to take a big PR and split it up for easier review: I can branch off halfway, make a PR there with just the refactors, merge it, then the actual change merges cleanly later, and preserves the parent commit relations, so you can visually see what happened. This also works great when you fix a bug on the way to adding a new feature, or want to ship the early part of a feature early before everything is done (but only decide that after work has already started on stuff you're not ready to ship).