Squash Commits

VIDEO

To squash commits together, we're going to use the extremely powerfulgit rebasecommand. This is one of my_favorite_commands, but it did take me_quite_a while to become comfortable with it. At first, it was somewhat challenging for me to get a handle on how it works, and then (after reading countless warnings online) I was scared to actually use it for fear of irreparably damaging my project's Git history.

But I'm here to tell you thatgit rebaseisn't really all that difficult, and that you can bravely make changes to your repository without fear of doing any damage! (<-- quite the claim, isn't it!?!)

Let's first get a big picture idea of how squashing works, and then we'll actually do some squashing with thegit rebasecommand.

VIDEO

The command I used is:

$ git rebase -i HEAD~3

The Rebase Command

Thegit rebasecommand will move commits to have anew base. In the commandgit rebase -i HEAD~3, we're telling Git to useHEAD~3as the base where all of the other commits (HEAD~2,HEAD~1, andHEAD) will connect to.

The-iin the command stands for "interactive". You_can_perform a rebase in a non-interactive mode. While you're learning how to rebase, though, I definitely recommend that you do_interactive_rebasing.

Ancestry References

As a brief refresher,HEADindicates your current location (it could point to several things, but typically it'll either point to a branch name or directly to a commit's SHA). The~3part means "three before", soHEAD~3will be the commit that's three before the one you're currently on. We're using this relative reference to a commit in thegit rebasecommand.

Let me demonstrate how to use this command to combine the three destination commits into one.

VIDEO

QUIZ QUESTION

In the command:

$ git rebase -i HEAD~3

...theHEAD~3is an ancestry reference to a commit that will act as the new base for the commits that are being rebased.

Which of the following could be used as a reference to a base?

  • a SHA

  • a branch name

  • a tag name

SUBMIT: All.

That's correct! You can use any of these as a reference to the location where the newly-rebased commits will branch off from.

Force Pushing

In the video, I had to force push the branch. I had to do this because GitHub was trying to prevent me from accidentally deleting commits. Because I used thegit rebasecommand, I effectively_erased_the three separate commits that recorded my addition of Florida, Paris, and Scotland. I usedgit rebaseto combine or_squash_all of these commits into one, single commit.

Usinggit rebasecreates a new commit with a new SHA. When I tried usinggit pushto send this commit up to GitHub, GitHub knew that accepting the push would erase the three separate commits, so it rejected it. So I had to_force push_the commits through usinggit push -f.

⚠️ Force Pushing ⚠️

In this instance, force pushing my commits was necessary. But if you try to push commits and GitHub rejects them, it's trying to help you, so make sure to review what commits you're pushing_and_the commits that are on GitHub to verify you're not about to overwrite content on your remote repository accidentally!

Rebase Commands

Let's take another look at the different commands that you can do withgit rebase:

  • use p or pick – to keep the commit as is
  • use r or reword – to keep the commit's content but alter the commit message
  • use e or edit – to keep the commit's content but stop before committing so that you can:
    • add new content or files
    • remove content or files
    • alter the content that was going to be committed
  • use s or squash – to combine this commit's changes into the previous commit (the commit above it in the list)
  • use f or fixup – to combine this commit's change into the previous one but drop the commit message
  • use x or exec – to run a shell command
  • use d or drop – to delete the commit

When to rebase

As you've seen, thegit rebasecommand is incredibly powerful. It can help you edit commit messages, reorder commits, combine commits, etc. So it truly is a powerhouse of a tool. Now the question becomes "_When_should you rebase?".

Whenever you rebase commits, Git will create a new SHAfor each commit! This has drastic implications. To Git, the SHA is the identifier for a commit, so a different identifier means it's a different commit,regardless if the content has changed at all.

So you should not rebase if you have already pushed the commits you want to rebase. If you're collaborating with other developers, then they might already be working with the commits you've pushed. If you then usegit rebaseto change things around and then force push the commits, then the other developers will now be out of sync with the remote repository. They will have to do some complicated surgery to their Git repository to get their repo back in a working state...and it might not even be possible for them to do that; they might just have to scrap all of their work and start over with your newly-rebased, force-pushed commits.

Recap

Thegit rebasecommand is used to do a great many things.

# interactive rebase

$ git rebase -i 
<
base
>
# interactively rebase the commits to the one that's 3 before the one we're on

$ git rebase -i HEAD~
3

Inside the interactive list of commits, all commits start out aspick, but you can swap that out with one of the other commands (reword,edit,squash,fixup,exec, anddrop).

I recommend that you create abackupbranch_before_rebasing, so that it's easy to return to your previous state. If you're happy with the rebase, then you can just delete thebackupbranch!

Further Research

results matching ""

    No results matching ""