5

There are (too) many questions regarding how to squash commits for git and other DVCS, such as:

My question is, do I want to squash commits? Should I keep the detailed sequence of commits showing how a feature was developed, or should I rather squash them into one once the feature is finished, to keep the history cleaner?

Community
  • 1
  • 1
Petr
  • 62,528
  • 13
  • 153
  • 317

3 Answers3

8

Reasons for squashing commits:

  • A cleaner, simpler history.
  • A smaller history. Less baggage when cloning repos.
  • Removes "junk" commits, such as typo fixes.
  • Gives the opportunity to improve commit messages.

Reasons against squashing commits:

  • We can no longer follow the history of that feature/bugfix in order to learn how it was developed or see alternative solutions that were attempted but later replaced. (Cited from Mike Gerwitz's A Git Horror Story.)
  • It renders git bisect useless. If we find a bug in the software that was introduced by a single patch consisting of 300 squashed commits, we are left to dig through the code and debug ourselves, rather than having Git possibly figure out the problem for us. (Cited from Mike Gerwitz's A Git Horror Story.)

Please feel free to add other reasons to this wiki answer, if you don't want to give your own answer.

Dennis
  • 56,821
  • 26
  • 143
  • 139
Petr
  • 62,528
  • 13
  • 153
  • 317
  • 1
    Keep in mind that these options (and reasons for choosing to squash or not) are not mutually exclusive. I tend to take a middle ground: squash away the noise (tiny and "junk" commits) but leave the overall history mostly intact, even when trying out alternative solutions, etc. – smudge Jul 15 '14 at 22:32
2

It depends on how granular you want the history to be. If there are lines that were added and deleted in the smaller commits, would it be useful to others to see them in the commit history later, or would they be just noise that would mislead future maintainers?

Consider the diff that would be expressed as one commit if you squashed all the smaller ones. Does it correctly communicate the whole point of the change (or series of changes)? Alternatively, is there something in an intermediate commit that communicates some essential message about what you were doing?

If you were implementing the changes again, would it be necessary to have the same intermediate commits? Usually for me, those intermediate commits are either scaffolding on which I iteratively constructed the whole change, in which case I can discard them via squashing. Sometimes some intermediate commits fixed silly errors or typos that just don't need to be part of the commit history, so they can be squashed too.

There's no hard and fast rule. When considering whether to squash particular commits, ask whether they contribute smoke that makes the whole change unclear or whether they contribute light that helps to explain the whole change.

David M
  • 4,325
  • 2
  • 28
  • 40
1

One of the strengths of DVCS is the ability to make frequent, small commits for checkpointing and preserving work without necessarily having to publish it.

That said, I've recently started to encounter what I consider to be limitations of the default "rewriting history is bad" position encouraged by Mercurial. With features split into many commits, and merging rather than rebasing, history can get very cluttered very quickly. As DavidM points out, which approach, or combination of approaches, you take will depend on how you use your history afterwards. I've found myself using tools like Mercurial queues and rebase more frequently, to help keep history cleaner.

I'm also intrigued by the potential of Mercurial's (currently) bleeding-edge obsolescence marker concept. By storing the original changesets but allowing them to be superseded by a squashed one, it would seem you can have your cake and eat it, too: clean history with only the latest, sensibly-sized changesets shown by default - but always with the option to unpack a feature and scrutinise the smaller efforts which went into it.

Community
  • 1
  • 1
anton.burger
  • 5,637
  • 32
  • 48
  • The obsolence marker concept seems very promising, allowing to keep immutable history _and_ avoiding clutter, solving my dilemma. I really hope it catches on. – Petr Feb 23 '13 at 09:01