Squash and Rebase your changes - gerhardol/gitextensions GitHub Wiki

There are number of git operations a software developer needs to master in order to effectively collaborate in today's world. These include git fetch (though commonly referred to as git pull), git commit and git push. However there few more operations one needs to learn.

Squash

It is quite common (especially in the OSS repositories) to receive a request from maintainers to "squash" your changes. This generally means that all the commits in your pull-request must be melded together as one. Sometime your PR may contain non-functional changes that may be preferred to keep separate (e.g. you may have moved type members around, or renamed files) because these could be making the diff unreadable. In that case "squash" mean mean to meld all auxiliary commits (such as "fix typo", "address feedback", etc.) need to be melded where appropriate, and your PR needs to take a shape in which you and/or maintainers of the project would want to merge keeping the history as clean and meaningful as possible.

So how do I squash?

There are many ways of achieving the desired outcome in git. Let's look at few ways.

Perform git reset

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

Interactive rebase

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

Rebase

It is quite common to have your changes end up in a conflict state with the main branch, and you needing to rebase to resolve the conflicts.

As with "squash" rebase can be done in several ways.

Perform git rebase

Here's how you can easily rebase the current and all its immediate parent commits (back to the BASE commit from the HEAD to) to a desired commit in Git Extensions:

  1. Right click on a commit you wish to rebase to and select "Rebase current branch on > Selected commit"
  2. Resolve all merge conflicts using your diff/merge tool of choice
  3. Push with lease to your remote branch once the rebase is complete

Interactive rebase

Similar to the squash operation describe above, we can perform an "interactive rebase" to (surprise!) rebase

  • 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 as required
  3. Save and close
  4. Resolve all merge conflicts using your diff/merge tool of choice
  5. Force push (with lease) back into your remote branch once you have resolved all the conflicts