Skip to content

Instantly share code, notes, and snippets.

@johnypony3
Last active April 4, 2022 11:05
Show Gist options
  • Save johnypony3/5ab6addacd39e3a7d848ffa7bd7bf53c to your computer and use it in GitHub Desktop.
Save johnypony3/5ab6addacd39e3a7d848ffa7bd7bf53c to your computer and use it in GitHub Desktop.

Squashing commits the easy way

Rewriting history is only safe if no one depends on your branch.

So for example never do this on parent branches ie: develop, master, a feature branch with child branches, etc.

Example workflow:

  1. Make feature branch
  2. Haxxor
  3. Push to origin (optional but your dentist recommends you floss)
  4. Repeat steps 2 - 3 as necessary
  5. Squash commits using the function in this article
  6. PR

During this workflow, many of the commits are incremental and the commit messages are not useful or helpful. This works well for this workflow.

A different method called interactive rebasing is more granular and gives you many options to rewrite history.

You can see the documentation here: git rebase -i

$ git log
commit ef02d1e8427982a747317b2fb287d03757405bcd
Author: johnypony3 <johnypony3@theemm.com>
Date:   Fri Jul 29 08:31:41 2016 -0700

    lorem ipsum

commit c9407b8c28c19cd743cfefea91ad6ab9cdc0c32d
Author: johnypony3 <johnypony3@theemm.com>
Date:   Fri Jul 29 08:31:23 2016 -0700

    WIP

commit 732c1331d5e28455ce2cfb3140290baf33079cb4
Author: johnypony3 <johnypony3@theemm.com>
Date:   Fri Jul 29 08:26:05 2016 -0700

    initial commit

None of these commit messages mean anything and there are 3 commits. At this point the work is dev complete and would like to squash these commits in to a single, understandable commit message.

I use the following command, where 2 is the count of commits that are to be squashed:

git reset --soft HEAD~2 && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

Protip: If your local and origin branches are in sync, if anything goes wrong, you can always delete local and pull from origin.

This opens the default text editor:

WIP

lorem ipsum

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#       modified:   readme

All comments are included and I can modify the comments to be something more useful.

Protip: the first comment is used as the title of your pr.

ie:

Dev Complete
* This work is as per the kitteh
* The readme has been updated as requested

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#       modified:   readme

And the result is:

$ git log
commit 3a1a0e058e1f06311312a034cf8587bfa6083b53
Author: johnypony3 <johnypony3@theemm.com>
Date:   Fri Jul 29 08:33:00 2016 -0700

    Dev Complete
    * This work is as per the kitteh
    * The readme has been updated as requested

commit 732c1331d5e28455ce2cfb3140290baf33079cb4
Author: johnypony3 <johnypony3@theemm.com>
Date:   Fri Jul 29 08:26:05 2016 -0700

    initial commit

If you have been pushing to the origin of your branch during development, you would need to force the push.

git push -f

TL;DR;

git reset --soft HEAD~2 && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
git push -f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment