Hacker News new | ask | show | jobs
by jahsome 1228 days ago
I've hit a couple shops in a row now where squashes are The Way. It's such a short-sighted and misguided policy.

I don't understand what is so appealing about a linear commit history. It's a fabrication of reality, and I have never been grateful for it, only enraged.

Why wouldn't you want to know what _actually_ happened? What is being gained besides an aesthetically pleasing "commits" tab on GitHub?

4 comments

As someone who does maintenance instead of new feature development: you're right. Squash merges are totally useless. I always want the real history, which lets me see when during the feature development the bug was actually introduced, and the original commit timestamps, which I can correlate to comments on the case.

There is never reason to squash. The best of both worlds is to always force a merge commit (disable fast-forward merges) and look at the log formatted whichever way you want (--first-parent shows people that linear history without destroying history).

Linear history is the only sane way to have usable history. Merge spaghetti is a good way to ensure that nobody would ever being able to navigate it.

Squashing large number of commits is questionable practice, though.

> Linear history is the only sane way to have usable history. Merge spaghetti is a good way to ensure that nobody would ever being able to navigate it.

1. you can have a linear history by rebasing then fast-forwarding onto the target

2. but it’s complete nonsense, learn your tools e.g. `git log --first-parent` (and how to merge), merge commits work perfectly fine

3. and importantly you can rebase then merge, which cleanly packages a set of changes behind a single merge commit without interspersing with other branches, and yet without losing the branche’s details

I'm sorry, I don't mean to be dismissive, but I just can't read that as anything other than "doing it correctly makes it harder."

That sentiment is not IMHO a particularly potent argument for _anything_ related to engineering.

Accuracy, not convenience, should be the goal. If you need to make consuming the data more convenient, that should be the focus.

To be clear using the word "correctly' is putting a lot more confidence behind my opinion than I ever intended, i.e. I am open to counterpoints, and do not portend to think a one size fits all policy is realistic.

You can list only merge commits to get a linear log, without destroying history.
Yes. I think the right way to do it is probably with "git log --first-parent", which will give you a linear history, and the linear history will contain only merge commits provided your project was configured to allow only merge commits. However, if you also allow squash or rebase merging then the linear history from "git log --first-parent" may contain commits that are not merges and will show the details of any PR that was rebase-merged. So, if you're going to allow merge commits at all, perhaps that's an argument for allowing only merge commits.

There's also "git log --merges" but that would presumably show any merge commits that happen to be present in a branch that is being merged so it wouldn't necessarily be linear.

If you disallow merge commits on GitHub, does that prevent a merge commit from being introduced as part of a rebase merge? If it doesn't, then presumably the only way to guarantee a linear history on GitHub is to allow only squash merging.

So, if you don't trust your developers to always do the right thing perhaps you should either only allow merge commits or only allow squash merging?

Good points. Ideally, I prefer a workflow where features are branches and merged in, with fast forwarding disabled and rebasing used to keep feature branches updated. History is preserved, a linear history exists as merge commits, and merge commits also map cleanly to PRs.
You could do a rebase instead of a merge
Branch merge commit message is where you want the meaningful message. The individual commits are more or less noise for the vast majority of developers (half of which are below average). A useful system accounts for the most common case and it's not on the individual commit level.
You do realize you're proposing "do extra work to prevent the history from being usable for the small percent who use it", right? The squashed history is lost, not hidden.

And those below-average developers probably aren't looking at the history at all anyway.

To be clear, I'm implying that a meaningful branch merge commit message is important. That's the change that matters for project history...which may or may not include a squashed history of the branch. The individual commit messages before that are for the developer(s) to manage as they see fit.

At any time, a developer might make another branch, then merge branches or squash the whole history of their branch or create a new branch and add the changes as if it was a fresh branch. Meaningful history is lost in those cases as well. Adding micro-managing process might get (more or less) predictable results, but it almost always pushes developers toward anti-patterns ensuring those predictable results are not what was intended.

GitHub flow is a natural companion to squash merges as a rule.