Live data from Hacker News

Fortunately, I don't squash my commits

blog.ploeh.dk

171–180 of 333 posts

Re: Fortunately, I don't squash my commits

#171
post #12

Earlier quoted context omitted.

I find the individual commits on feature branches to be more noise than signal after they are merged . They can be useful during review, sometimes, but mostly I want a cleaner history. > they really would like a complete story, not 20 gargantuan commits that contain 3 years of development That sounds like maybe we split up work differently. 3 years of development for me or my team would likely have hundreds+ of merge…

But surely you would like to squash those merge commits as well, at some points? Hundreds of merge/squash commits pollute the history almost as much as thousands of normal commits, so after a large feature set is done, one should just squash all of it into a single commit. That way, you can have "nice" development history where tags for the old versions are redundant since they match commits one for one: $ git branch…

The git log isn't a release history, it's a development history. Squashing commits throws away context that could be useful in any number of ways.

There's nothing wrong with squashing a bunch of commits that really should have been a single commit from the start:

- Update X to do Y

- Fix typo in X

- Add "foo" option to X for when Y is a bar

But most of the time "features" consist of many changes: we add one function we're going to need, then another, then yet another... Then we change an API to expose the new functions, then extend the UI to make room for it and finally make put it into the application and pull all the strings together.

Squashing all these into one commit is just a bad idea. You can always do git rebase -i before merging to do minor fixups or even reorder your commits (like when you notice a typo after several other commits), but completely removing all granularity... just no.

Re: Fortunately, I don't squash my commits

#172
post #111

Earlier quoted context omitted.

My gripe with merge commits is they don't integrate nicely with `git blame`. If I'm looking through historic commits (to understand why a change was made, or perhaps to debug an issue) I'll often `git blame` the line and diff that commit. If the commit is super granular, I can't get the context of the whole change: I need to dig for the merge commit then look at that, which is faff. If there's a way that I don't know…

Why would you want one author for a merge commit? That merge can have many commits by many different authors.

They can, but

1. The large majority of PRs I've reviewed have a single contributor. Additional contributors are rare. When they do happen, they're often a minority contributor or simply consulting on a PR. It's net neutral when all PRs are squashed in the same pattern.

2. Even with multiple contributors, most features have one leader. It's much easier to talk to that person (and have them delegate) than it is to piece together multiple contributions.

Re: Fortunately, I don't squash my commits

#173
post #2

Do people out there actually squash commits? Granted, I didn't change many work places in my career, but at no place where I worked people squashed commits. What's even the point of it? It's not like people routinely read the commit history, and when they do, they really would like a complete story, not 20 gargantuan commits that contain 3 years of development.

I squash commits on large PRs on a case-by-case basis, especially when they have a lot of very small and silly commits (fix this, fix that, wip, ...) but implement a very specific feature which required a lot of experiments that didn't end up in the final PR. And yes, I use the commit history very frequently, so it's important for me that this doesn't contain too much noise. If I need to bisect a bug that was introdu…

Ideally, that would give you the best of both worlds. But some places delete the old branches after they're merged. It would be nice if there were an easy way to hide or rename old branches so that the in-use ones stand out.

Re: Fortunately, I don't squash my commits

#174

`squash` is a tool and it's neither good nor bad; it needs to be applied where it makes sense. The title is indeed click-baity. It would have been more interesting to read that the bug/mistake was caused as a result of squashing. It's not the case and I take issue with the way the author describes his commits. The problematic commit is described "Extract CreateTokenValidationParameters method", without an explanation…

Seems like the real bug was in his handling of JwtSecurityTokenHandler.

He claims to be an expert on dependency injection with two decades of automated testing experience. I wonder what was so hard about writing a test to cover this scenario?

Re: Fortunately, I don't squash my commits

#175

The reason to squash commits is more than just keeping your commit history read-able, it's about making easy to revert a feature and being able to keep history in a way that makes it simple to revert a change if you run into issues. If I rollout a rewrite of an endpoint and run into a weird issue in the QA environment, I'm a simple git revert away from fixing the issue. If I had spread that endpoint across 25 commits…

Wouldn't it be preferable, then, to avoid squashing your commits, and then tag your releases? This gets you the best of both worlds, you can still back out to a known good version in case of issues, and you can still bisect to narrow down the exact commit that caused your problem.

Bisect is the killer feature of git, for me. Squashing releases takes that superpower away.

Re: Fortunately, I don't squash my commits

#176

The reason to squash commits is more than just keeping your commit history read-able, it's about making easy to revert a feature and being able to keep history in a way that makes it simple to revert a change if you run into issues. If I rollout a rewrite of an endpoint and run into a weird issue in the QA environment, I'm a simple git revert away from fixing the issue. If I had spread that endpoint across 25 commits…

Completely agreed — squashing commits isn’t desirable in every circumstance, but if all the commits pertain to a single feature then it makes complete sense to me.

Re: Fortunately, I don't squash my commits

#177
post #28

Earlier quoted context omitted.

You have to go dig the branch out of the central repo, though, which is annoying and takes time. That was the price I was thinking of. You're certainly right that PRs and large commits are orthogonal.

Navigate to PR -> Restore Branch -> `git checkout ` How is this annoying or time consuming? It takes less effort than adding, committing and pushing changes.

Because with a test suite, git bisect, and a history that's been reasonably well cared for, I can just tell git "find me the bug" and go do something else until it's done.

I don't like having to go fiddle manually for that to work.

Ideally you have CI set up so the average test failure email points you to the small patch that broke it.

For bugs from the wild that doesn't work, obviously, but I still prefer less friction.

Re: Fortunately, I don't squash my commits

#178

The reason to squash commits is more than just keeping your commit history read-able, it's about making easy to revert a feature and being able to keep history in a way that makes it simple to revert a change if you run into issues. If I rollout a rewrite of an endpoint and run into a weird issue in the QA environment, I'm a simple git revert away from fixing the issue. If I had spread that endpoint across 25 commits…

I wish git had a builtin notion of two different types of commits: working commits and release commits.

I really like making tiny, continuous commits as I work. It's a great flow. git-revert becomes a Ctrl-Z on steroids. I don't what to clutter up the "official" history, with all these tiny changes, many of which don't even compile. That breaks git-bissect and all kinds of other flows.

So the only option is to squash commits. But there's something deeply uncomfortable and unsettling about permanently re-writing history. Plus, it's nice to have a history of those working commits as an artifact. If I'm trying to unpack the reason that I did something 9 months ago, then seeing a replay of the code changes is super-useful.

Re: Fortunately, I don't squash my commits

#179

It is not related to squashing or not. One of the main rule when using git (or any other VCS I guess) is that each commit should be atomic. IMO squashing commits is something that you should do locally, not remotely. For example I'm currently debugging a fairly large C application on an embedded system. Each bug has it's own branch. When debugging / testing / trying to fix it I tend to do a lot of commits. When the b…

Why do it locally when most modern repository software (GitHub, GitLab, BitBucket, etc) can do it for you when a PR is merged?

My point of view is that if work is being done on an individual feature or bug fix, having a view of the individual commits might help give any reviewers important context on how a final solution was arrived at. It can also be helpful to be able to see the specific changes that have been made since a prior review.

While in most cases I favor squashing commits when it comes time to merge into the parent branch, it seems like doing it manually just creates extra work and potentially throws away information that may have been useful to reviewers.

Re: Fortunately, I don't squash my commits

#180
post #58

Earlier quoted context omitted.

I often do intermediary commits that don't compile or break something significant, only to make sure that I don't lose the code. When that happens I always squash my commit afterwards once the code is in a usable state. The alternative is making bisecting harder which is not something that I want. I want every commit to compile and be testable individually. That definitely doesn't mean that I think it's a good idea t…

I'm a bit confused on your comments here. You state "I often do intermediary commits that don't compile ... to make sure that I don't lose the code" And follow that with "I want every commit to compile and be testable individually."

I mean that I do many small "crap" commits while developing, once I'm ready to merge into the main branch I clean the history to get proper, atomic commits.
Post reply on HN