7

We can squash the last N commits in Git. As I understand, we can squash last N commits using git rebase -i HEAD~N or git reset --soft HEAD~N.

In the answers for this question (Squash my last X commits together using Git) most upvoted answer advices to use git reset --soft HEAD~N, which is not the accepted one. Accepted answer recommends git rebase -i HEAD~N. Hence I get confused, which one would be prefered to be used.

How those these approaches differ from each other? Which one is recommended or safe to be used?

3
  • 3
    The rebase is command is much fancier and much more capable, and hence takes more work (by the computer). The reset-and-commit command is much simpler and much less capable, and hence easier (for the computer). The final result, if all you're doing is squashing everything, is the same, so use whichever one you find easier—or, if your computer is excruciatingly slow, use the reset-and-commit method so that it takes a few seconds rather than 30 minutes. I find that for a lot of commits, the rebase is harder for me too, because I have to change a lot of lines from pick to s.
    – torek
    Commented Aug 29, 2021 at 10:47
  • 2
    Of course, if you want or need any of the extra capabilities of rebase, use rebase.
    – torek
    Commented Aug 29, 2021 at 10:47
  • stackoverflow.com/a/11225432/7976758 Found in stackoverflow.com/…
    – phd
    Commented Aug 29, 2021 at 12:45

2 Answers 2

3

Both commands you gave can be used to rewrite the history of a branch. The soft reset option:

git reset --soft HEAD~N

will move the HEAD pointer of the branch back N commits, while simutaenously placing the work from those commits into the stage. If you were to then commit from this point, you would have squashed the commits into a single new commit.

The rebase option:

git rebase -i HEAD~N

will bring up a window showing the previous N commits. On each line, for each commit, you may choose to pick (keep), squash, reword, etc. You could achieve the same result as the soft reset option as above by choosing squash for the commits in question. However, interactive rebase is much more powerful than this.

Which method you use depends on the complexity of your operation. We might view the soft reset as a poor man's version of interactive rebase, the latter which is heavy duty.

2

git rebase -i allows you to interactively rebase the commit range - you can choose which commits to take, which to drop, reorder them, manually intervene at some point, and, as you noted, squash them etc.

git reset --soft just removes all the commits, leaving the index intact.

1
  • More precisely, leaving the index and working tree intact (and the "removed" commits still exist, they're just hard to find now).
    – torek
    Commented Aug 29, 2021 at 10:45

Not the answer you're looking for? Browse other questions tagged or ask your own question.