Downsides of using squash merging

I keep wondering: are there any benefits to not use squash merging for projects hosted on GitHub or GitLab?

To me, squashing makes the history much clearer, but I still see many projects using rebase

2 Likes

I guess it depends on the project’s conventions, but if each PR is made of meaningful commits with good (descriptive) messages, then squashing them is losing useful information: git blame cannot tell you anymore which precise commit message corresponds to a particular line.

Also, it’s easier to read/understand a small (self-contained) commit than a big squash of many commits.

2 Likes

it can also make it more difficult when the PR would have shown the src changes together with the test changes, for example

But yeah, I see your point. I guess that with lots of discipline and huge (feature) PRs, it would work better to rebase

I would squash merge unless a PR is intentionally factored into a series of logically separate commits. In that case I would merge, preserving non-linear history. Some people prefer rebase in that case to preserve linear history but I don’t see why DAGs are scary. The way GitHub does rebasing of PRs also loses all connection to the PR so that’s not great.

4 Likes

My experience is that most PRs are so complex that the only reasonable approach is to:

  • squash merge
  • rely on PR discussion history in e.g. GitHub to understand the rationale

and for simple PRs it usually does not make a difference.

I would say that if PR consists of logically separate parts they should probably be separate PRs in the first place in most of the cases.

6 Likes

Something to keep in mind is that many PRs are broken at intermediate commits, and so if you merge without squashing then you will break things like git bisect. It’s useful to try and make every commit on the main/master branch a working commit (e.g. compiling, passing its own tests), and squash–merge helps with that.

13 Likes

Suppose you have a repository where PRs do not squash commits and there is no rebasing or fast-forwarding when you merge a PR. After merging, are the intermediate commits in the PR considered by git to be part of the main branch? I was under the impression that only the merge commit would be considered part of the main branch.

Here’s an example of what the commit graph looks in that case, according to git log (with some specialized settings):

* 3fa3972 - Another main branch commit. (10 months ago) <Cameron Bieganek>
*   b79f320 - Merge pull request #25 from my-repo/my-branch (11 months ago) <Cameron Bieganek>
|\  
| * b107569 - Third commit on mybranch. (11 months ago) <Cameron Bieganek>
| * b8be6ff - Second commit on mybranch. (11 months ago) <Cameron Bieganek>
| * f525f0b - First commit on mybranch. (11 months ago) <Cameron Bieganek>
|/  
* 7972188 - Another main branch commit. (11 months ago) <Cameron Bieganek>
* 679e8f5 - Main branch commit. (11 months ago) <Cameron Bieganek>

Good point, I was thinking of rebasing without squashing; merging without squashing is fine in that regard. Update: Nope, see below.

Thanks. It’s a little confusing, since if you run something like git log --oneline main for the case above, you see this,

3fa3972 Another main branch commit.
b79f320 Merge pull request #25 from my-repo/my-branch  
b107569 Third commit on mybranch.
b8be6ff Second commit on mybranch.
f525f0b First commit on mybranch.
7972188 Another main branch commit.
679e8f5 Main branch commit.

which makes it look like those intermediate branch commits are in fact considered to be on the main branch.

I don’t know what git log --oneline main would look like for a case similar to the above but where there are additional commits on main before mybranch is merged into main.

I did some googling, and apparently this is not true. :frowning_face: In fact, git bisect does apparently search feature branches, not just merge commits.

To have it ignore commits “internal” to feature branches, you apparently need to jump through some additional hoops: https://blog.quantic.edu/2015/02/03/git-bisect-debugging-with-feature-branches/ and How do you get git bisect to ignore merged branches? - Stack Overflow … though recently this apparently became easier with git bisect --first-parent

4 Likes

Wow, that’s good to know. I’m glad they added git bisect --first-parent.

Thanks!

I only ever merge my own PRs without squashing if the intermediate commits all pass tests (which you can conveniently check using git rebase -i and the x directive in the rebase script file), so this is definitely a somewhat advanced situation.

3 Likes