40

To squash multiple commits, I have always used:

git reset --soft HEAD~<number of commits to squash> && git commit

But I wonder if there is a good way to do this in a good git client like git extensions? It would be cool if you could just select consecutive commits and squash them.

Slaknation
  • 2,124
  • 3
  • 23
  • 42

4 Answers4

71

There are multiple ways of doing a squash.

Here's how you can easily squash the current and all its immediate parent commits into a single commit in Git Extensions:

  1. Right click on a commit you wish to squash to and select "Reset the current branch to here"
  2. Select either "Soft reset" (retain staged files) or "Mixed reset" (unstage all files)
  3. Stage, if necessary
  4. Commit

Here's an animation of the above:

enter image description here


Another way is to do an "interactive rebase" either

  • via a command line (git rebase -i, read docs), or
  • via UI (e.g. Git Extensions).

To do an interactive rebase in Git Extensions:

  1. Right click on a commit you wish to squash to and select "Rebase current branch on > Selected commit interactively..."
  2. In the presented dialog alter the history, such as choose which commits to squash or reword
  3. Save and close

Here's an animation of the above:

enter image description here

RussKie
  • 1,630
  • 11
  • 20
  • 3
    *soft* reset is more what is asked ;) – Philippe May 15 '18 at 22:26
  • 12
    Great answer, very helpful. It would be a great idea to slow a bit the animated gif if possible... ;-) – Pierre FABIER Jun 25 '18 at 11:24
  • 2
    1. right click on a commit you wish to squash to and select "Reset the current branch to here" 2. Select either "Soft reset" (retain staged files) or "Mixed reset" (unstage all files) 3. Stage, if necessary 4. Commit – RussKie Jun 26 '18 at 12:11
  • 1
    Notice that you might lose some files that are in git ignore if you added them using git add -f. You'll have to add them again manually – asaf92 Dec 06 '18 at 14:59
  • I have replaced the old fast version with the slow from [here](https://stackoverflow.com/a/53398900/284240) – Tim Schmelter Jan 16 '20 at 12:31
  • 1
    @PierreFABIER Chrome extensions to pause the gifs: https://superuser.com/a/1435047/930939 – RazvanR Jan 27 '20 at 09:07
  • @RussKie: Could you add your [comment](https://stackoverflow.com/questions/46733179/git-extensions-squash-commits#comment89076145_47464064) to the answer itself? Would be great, thanks! – testing Jul 03 '20 at 15:58
  • Thank you for the suggestion - done. Also expanded the answer to include the interactive rebase option. – RussKie Jul 06 '20 at 12:09
20

Here is the slowed down version of the accepted answer:

Here is the slowed down version of the accepted answer

user1682406
  • 1,971
  • 1
  • 12
  • 9
8

(Assuming you're using Windows)

Yes, I believe TortoiseGit can do it. As a previous user of TortoiseSVN, I would recommend it. When viewing the commit log, you can do the following:

Combine multiple commits context menu

In addition, when you commit using TortoiseGit, you'll have the option to simply amend your previous commit, so you can do this as you go. It will also pull in the last commit message when you do this (I cleared mine for privacy reasons in the screenshot).

Amend last commit

Of course, I'm sure you already know this, but don't try to combine or amend commits that are already pushed to remote, or your next push will fail miserably.

As an extra bonus, you'll get the benefits of overlay icons when browsing your working copy in Explorer.

Explorer icons

BoffinBrain
  • 6,337
  • 6
  • 33
  • 59
  • 2
    This is easier than git extension – liang Oct 09 '18 at 07:56
  • I would agree! I did try using Git Extensions but strongly prefer having native integration with Explorer. – BoffinBrain Oct 11 '18 at 06:44
  • But be aware that the way GitExtensions present the feature is more similar to the way Git is doing it. So if you understand one, you should be able to understand the other... – Philippe Apr 16 '19 at 09:24
8

You could achieve this easily with GitExtensions by 2 ways.

The first is to do exactly the same thing but from the GUI which is suitable when you don't want to use the existing commit messages of the commits you watch to squash. .

 git reset --soft HEAD~<number of commits to squash>

From the history browser of GitExtensions, right click on the last commit you want to keep and select 'reset branch to here'. Then select the option 'soft'.

 git commit

Then commit the changes that are still staged.

The second is to a 'rebase --interactive' :

Right click on the same commit described above and select 'rebase on'. In the pop-up check the checkbox 'interactive'.

Then, in the editor, set the commit action to 'squash'. Read a good documentation on the interactive rebase before doing it. This solution is perfect when you want to write a good commit message built from the commits messages from the commits you are squashing.

Philippe
  • 28,207
  • 6
  • 54
  • 78