Subject: Re: Another look?

From: "Kristoffer Haugsbakk" <[email-masked]>
Date: Fri, 02 Jan 2026 10:48:46 +0100

On Fri, Jan 2, 2026, at 00:38, Harald Nordgren wrote:
>> Again this seems to do a "step 1 goes in a direction, step 2 fixes
>> its mistake, step 3 changes course" drunken-man's walk.
>>
>> The same advice to restructure them into a logical incremental
>> progression that moves the codebase in one consistent direction to
>> eventually reach the goal at the end applies.
>
> Isn't programming always bit of drunken-man's walk?

We don’t have to present the chain of code changes as they “really
happened”. An alternative is to present what will eventually be the
final version as if you had both a borderline perfect plan, foresight,
and execution. And that’s the convention in this project. Because that’s
the natural progression of a patch series; each iteration you get help
to arrive at what looks like the perfect iteration. (Until someone finds
a off-by-one error two years later?)

What *really happened* is always fiction in any case.

> I'm very hesitant to restructure my history before I am confident I will
> not need any of the old work later -- I would hate to lose history if I
> make a mistake.
>
> One option is to keep my code backed up on a separate branch locally, but
> this gets problematic as I add more work (endless cherry-picking and
> squashing) between local branches before submitting new patches. So now you
> know some of my reasoning. I'm not saying I'm right, but it's a bit
> fear-based.

To make a snapshot of each version seems inevitable in my book since you
are encouraged to include a range-diff (and optionally also an
interdiff) between each iteration.

Now you of course have the backup of each version because you can
download the patches that you yourself posted. But that’s more work then
just snapshotting each version, for me at least.

> With that said, my idea has always been to squash everything into a single
> commit before merging this. The whole diff is not that big. I can split it
> into code in one commit and tests in another.
>
> As a side-note: In my day job we only allow "squash and merge" on our
> GitHub. This gives devs the flexibility to treat their branches as a WIP
> area before merging, but still gives a pristine git history after merge.
> This feels to me like a good trade-offs. But again, happy to take
> instructions on how to do better.

If that’s a good trade off, what are the variables involved in the trade
off? So far it seems like:

1. Flexibility to iterate like you want
2. A final history without any back-and-forth noise (pristine/sober
   walk)

But a third variable here is

3. A series of logically separated commits

And you don’t get that with that approach. And a good final history is
very important in many people’s eyes.

People call this mandatory squash strategy some word similar to *clean*
presumably because there is no back-and-forth noise. That’s the memetic
contagion. But there are other adjectives as well:

• Bloated: When the mandated squash strategy forces different concerns
  (code formatting, whitespace formatting, refactor, bug fix, ...) to be
  truncated into one commit
• Lossy: When so many commits get squashed that you cannot, with any
  amount of analysis, piece together what lines in the commit message
  correspond to some part of the diff (especially likely to happen if
  (1) the squash commit message is a bullet list and (2) the commit
  messages are just things like “WIP” and “fix”)

Someone might argue that the squash merges will not be large because the
pull requests are not large and the tasks are not large. Or they should
not be. But that demands more of both the project/task management and
the pull request management:

1. Better project management foresight and planning. Notice that we have
   traded the rewriting commits strategy of “perfect plan, foresight,
   and execution” for demanding more foresight from project
   management. Just because we have mandated no more than one commit per
   pull request or patch series.

   And “perfect plan, foresight, and execution” is not even a
   requirement. Just a contrast to the one-commit requirement. A project
   could allow contributors to both present “perfect plan, foresight,
   and execution” series as well as messy series, with the latter being
   squashed at the integrator’s/reviewer’s/mantainer’s discretion.
2. Divide changes into more pull requests or patch series. At least with
   vanilla GitHub that causes overhead as you have to manually link all
   the pull requests. You might also have to manually link the pull
   requests using URLs if the target branch of the PR does not do it for
   you.

   On the other hand you might have little or no overhead with some
   “stacked PR” tool.

The one-commit rule works just as well if not better[1] than the
alternatives in theory. The problem is that the theory demands much more
from project management and pull request handling.

† 1: Part of the motivation is often avoiding merge commits. And if
     merge commits always cause point deductions then a perfectly
     executed squash merge strategy will always win over some strategy
     involving true merges.

     Although I would personally choose a rebase-with-trailer strategy
     over squash merges here; rebase the series/PR and add a trailer to
     each commit which links to the series/PR.

>>[snip]