Course Tonight

Course Tonight

Did You Know?

Docy turns out that context is a key part of learning.

Chapter 16: Squashing

Estimated reading: 4 minutes 6 views

Section 16.1: Squash Recent Commits Without Rebasing

If you want to squash the previous x commits into a single one, you can use the following commands:

git reset --soft HEAD~x
git commit

Replace x with the number of previous commits you want to include in the squashed commit.

Note: This will create a new commit, essentially forgetting information about the previous x commits, including their author, message, and date. You may want to copy-paste an existing commit message.

Section 16.2: Squashing Commit During Merge

You can use git merge --squash to squash changes introduced by a branch into a single commit. No actual commit will be created.

git merge --squash <branch>
git commit

This is more or less equivalent to using git reset, but it is more convenient when the changes being incorporated have a symbolic name. Compare:

git checkout <branch>
git reset --soft $(git merge-base master <branch>)
git commit

Section 16.3: Squashing Commits During a Rebase

Commits can be squashed during a Git rebase. It is recommended that you understand rebasing before attempting to squash commits in this fashion.

  1. Determine the commit you would like to rebase from and note its commit hash.
  2. Run the following command: git rebase -i [commit hash].

    Alternatively, you can use HEAD~4 instead of a commit hash to view the latest commit and the four commits before it.

  3. In the editor that opens, determine which commits you want to squash. Replace pick at the beginning of those lines with squash to squash them into the previous commit.
  4. After selecting the commits to squash, you will be prompted to write a commit message.

Logging Commits to Determine Where to Rebase:

git log –oneline

612f2f7 This commit should not be squashed
d84b05d This commit should be squashed
ac60234 Yet another commit
36d15de Rebase from here
17692d1 Did some more stuff
e647334 Another Commit
2e30df6 Initial commit

git rebase -i 36d15de

At this point, your chosen editor will open, allowing you to describe what you want to do with the commits. Git provides help in the comments. If you leave it as is, nothing will happen because every commit will be kept in the same order as before the rebase. In this example, we apply the following commands:

pick ac60234 Yet another commit
squash d84b05d This commit should be squashed
pick 612f2f7 This commit should not be squashed

Git Log After Writing Commit Message:

git log –oneline

77393eb This commit should not be squashed
e090a8c Yet another commit
36d15de Rebase from here
17692d1 Did some more stuff
e647334 Another Commit
2e30df6 Initial commit

Section 16.4: Autosquashing and Fixups

When committing changes, it is possible to specify that the commit will be squashed or fixed up to another commit using the following syntax:

git commit --squash=[commit hash of the commit to which this commit will be squashed to]

Alternatively, you can use --fixup=[commit hash] to fix up the commit.

It is also possible to use words from the commit message instead of the commit hash. For example:

git commit --squash :/things

In this case, the most recent commit with the word “things” in its message will be used.

The commit message for these commits will begin with ‘fixup!’ or ‘squash!’, followed by the rest of the commit message to which these commits will be squashed.

When rebasing, the --autosquash flag should be used to enable the autosquash/fixup feature.

Section 16.5: Autosquash: Committing Code You Want to Squash During a Rebase

Given the following history, imagine you make a change that you want to squash into the commit bbb2222 (A second commit):

$ git log --oneline --decorate
ccc3333 (HEAD -> master) A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit

Once you’ve made your changes, you can add them to the index as usual, then commit them using the --fixup argument with a reference to the commit you want to squash into:

$ git add .
$ git commit --fixup bbb2222
[my-feature-branch ddd4444] fixup! A second commit

This will create a new commit with a commit message that Git can recognize during an interactive rebase:

$ git log --oneline --decorate
ddd4444 (HEAD -> master) fixup! A second commit
ccc3333 A third commit
bbb2222 A second commit
aaa1111 A first commit
9999999 Initial commit

Next, perform an interactive rebase with the --autosquash argument:

$ git rebase --autosquash --interactive HEAD~4

Git will propose to squash the commit you made with the --fixup commit into the correct position:

pick aaa1111 A first commit
pick bbb2222 A second commit
fixup ddd4444 fixup! A second commit
pick ccc3333 A third commit

To avoid typing --autosquash for every rebase, you can enable this option by default:

$ git config --global rebase.autosquash true

Leave a Comment

Share this Doc

Chapter 16: Squashing

Or copy link

CONTENTS