Search code examples
gitgit-resetgit-squash

Squashing commits after they are pushed


Imagine a git repository with the following commits:

Fixed issue 3               123eabc
Fixed issue 2 (part 2)      fa23b79
Fixed issue 2 (part 1)      7bea5cc
Fixed issue 1               0d229f4

These are all pushed to remote master already. Is there a way now to rewrite history and combine the middle two into one commit? Something like

Fixed issue 3               123eabc
Fixed issue 2               9d23e0c
Fixed issue 1               0d229f4

Solution

  • One option is to do an interactive rebase in which you squash the two issue 2 commits together.

    git rebase -i HEAD~4
    

    This tells Git that you want to do an interactive rebase involving the four commits including and counting backwards from the HEAD of your branch. This should show you a list looking something like the following:

    pick 0d229f4 Fixed issue 1
    pick 7bea5cc Fixed issue 2 (part 1)
    pick fa23b79 Fixed issue 2 (part 2)
    pick 123eabc Fixed issue 3
    

    Note the oldest commit appears first, and the most recent of the four commits appears last.

    Change the pick for the middle commit part 2 you want to combine with part 1 to squash:

    pick 0d229f4 Fixed issue 1
    pick 7bea5cc Fixed issue 2 (part 1)
    squash fa23b79 Fixed issue 2 (part 2)
    pick 123eabc Fixed issue 3
    

    Squashing means combining a commit labelled with squash into the commit above it, in this case merging part 2 into part 1.

    Then save this file and exit the editor, and complete the rebase.

    Note: Rewriting the history of a public branch can cause problems for anyone besides you who is using this branch. So you might want to avoid even using this answer if this situation applies to you.