Chapter 5. Work With Branches

Squash Merge

Squash Merge
Tag:

Squash merge is another approach when you merge branches. This approach is useful when you don't want to keep every single detail of change histories in the master branch.

When you run the git merge command with the --squash option, all the changes made in the target branch are reflected in the destination branch. However, the command doesn't create a new commit. The changes are only reflected in the Working Tree and INDEX (see the main figure).

When you want to proceed with the change, you need to make a new commit by running the git commit command. This command records only one new commit under the master branch. All commits under Branch_A are combined (squashed) in the new commit.

We'll explain squash merge with the --squash option in more detail with command line examples below.

Command Line Example

The command line image below is a demonstration of the commit and merge actions, which are the same as the upper illustration in the main figure. M1, M2, M3, A1, and A2 are the commit messages that were already made before. We'll explain the commands and responses in the command line in six steps.

Squash-Merge

  1. Confirm the pre-merge commit history status by running the git log command on the master branch. You can see that the commit histories and branch statuses are the same as the ones illustrated in the main figure. (In this status, the merge operation done on the previous page has been reversed, and commit M4 has already been added to demonstrate the squash merge. Check the practice section below to see how to come to this status.)
  2. Run the git merge command with the --squash option. When running the command with the option, no commit is created. The command reflects the changes made on Branch_A in the Working Tree and INDEX.
  3. To confirm that the changes have not yet been committed on the master branch, run the git status command. You'll see a modified file under the INDEX. To understand what changes were made to the file, you can see an example in the image below (Working Tree File Status). You can see that the working file on the master branch has become an integrated version of the master branch (before squash) and Branch_A.
  4. To make a record of the change, run the git merge command.
  5. To check the latest branch status, run the git log command on the master branch. You can see that a new commit is created, however, there are no A1 and A2 in the commit history. This means that the squash option combined (squashed) all the changes made to the merging branch to simplify the line of commit history.
  6. To check the latest status of Branch_A, switch to Branch_A and run the git log command. You can see that nothing has changed on Branch_A

Squash-Merge

For a better understanding, please go through the following practice section.

bloovee-round-icon.pngDeveloper A (Project Owner Role)

Practice

Objective:
Check how the squash merge works

1. Prepare a practice file

In the practice on the previous page, Branch_A was already merged into the master branch. For this practice purpose, we need to reverse the commit history before Branch_A is merged.

To reverse the HEAD of the master branch to commit M3, reset the merge operation by running the git reset --hard command on the master branch. Use the commit hash of commit M3 which is generated on your computer. Also, make sure to use the --hard option. If you don't use the option, the statuses of the Working Tree, INDEX, and HEAD will be mixed.

Command Line - INPUT
git checkout master
git reset --hard e12beda
git log --oneline

You'll see that the HEAD of the master branch is back to Commit M3.

Command Line - RESPONSE
e12beda (HEAD -> master) M3
f5ff7aa M2
8bf5c03 M1

Next, create commit M4 to match the upper illustration on the main figure. Edit the HTML file (add <h1>M4</h1> and run the git commit command. To check the latest status, run the git log command again.

git_branch_practice.html
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<h1>M3</h1>
<h1>M4</h1>
<!-- /Master Branch-->
Command Line - INPUT
git commit -am "M4"
git log --oneline

Finally, you'll see the following master branch status, which matches the upper illustration on the main figure. As we haven't touched Branch_A, its status remains the same.

Command Line - RESPONSE
b7b73d4 (HEAD -> master) M4
e12beda M3
f5ff7aa M2
8bf5c03 M1

2. Perform squash merge

Now you are ready to execute the merge command. As you are already on the master branch, run the following command with the --squash option.

Command Line - INPUT
git merge --squash Branch_A

In this case, no commit is made as you can see the response in the command line like shown below.

Command Line - RESPONSE
Auto-merging git_branch_practice.html
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Instead, changes made on Branch_A are reflected in the Working Tree of the master branch shown in the text editor below.

git_branch_practice.html
<!doctype html>
<html lang="en">
<body>
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<h1>M3</h1>
<h1>M4</h1>
<!-- /Master Branch-->

<!-- Branch_A-->
<h1>A1</h1>
<h1>A2</h1>
<!-- /Branch_A-->

<!-- Branch_B-->
N/A
<!-- /Branch_B-->
</body>

The changes are also staged. To check the status, run the git status command.

Command Line - INPUT
git status

You can see that git_branch_practice.html was modified and staged (ready to commit).

Command Line - RESPONSE
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   git_branch_practice.html

2. Make a commit

As the git merge --squash command doesn't create a new commit in a normal setting, you need to run the git commit command to make a record like below.

Command Line - INPUT
git commit -am "Merge Branch_A (Squash)"

You can see that a new commit is created like shown below.

Command Line - RESPONSE
[master 161bc6c] Merge Branch_A (Squash)
 1 file changed, 2 insertions(+), 1 deletion(-)

3. Check commit histories and branch status

Check the status of the master branch first.

Command Line - INPUT
git log --oneline --graph

You can see that a new commit is created, however, there are no A1 and A2 in the commit history. This means that the squash option combined (squashed) all the changes made to the merging branch to simplify the line of commit history.

Command Line - RESPONSE
* 161bc6c (HEAD -> master) Merge Branch_A (Squash)
* b7b73d4 M4
* e12beda M3
* f5ff7aa M2
* 8bf5c03 M1

Next, check the status on Branch_A.

Command Line - INPUT
git checkout Branch_A
git log --oneline --graph

You can see that nothing has changed for Branch_A

Command Line - RESPONSE
* a4c4eb0 (HEAD -> Branch_A) A2
* 62dda63 A1
* e12beda M3
* f5ff7aa M2
* 8bf5c03 M1

Squash merge is another approach when you merge branches. This approach is useful when you don't want to keep every single detail of change histories in the master branch.

When you run the git merge command with the --squash option, all the changes made in the target branch are reflected in the destination branch. However, the command doesn't create a new commit. The changes are only reflected in the Working Tree and INDEX (see the main figure).

When you want to proceed with the change, you need to make a new commit by running the git commit command. This command records only one new commit under the master branch. All commits under Branch_A are combined (squashed) in the new commit.

We'll explain squash merge with the --squash option in more detail with command line examples below.

Command Line Example

The command line image below is a demonstration of the commit and merge actions, which are the same as the upper illustration in the main figure. M1, M2, M3, A1, and A2 are the commit messages that were already made before. We'll explain the commands and responses in the command line in six steps.

Squash-Merge

  1. Confirm the pre-merge commit history status by running the git log command on the master branch. You can see that the commit histories and branch statuses are the same as the ones illustrated in the main figure. (In this status, the merge operation done on the previous page has been reversed, and commit M4 has already been added to demonstrate the squash merge. Check the practice section below to see how to come to this status.)
  2. Run the git merge command with the --squash option. When running the command with the option, no commit is created. The command reflects the changes made on Branch_A in the Working Tree and INDEX.
  3. To confirm that the changes have not yet been committed on the master branch, run the git status command. You'll see a modified file under the INDEX. To understand what changes were made to the file, you can see an example in the image below (Working Tree File Status). You can see that the working file on the master branch has become an integrated version of the master branch (before squash) and Branch_A.
  4. To make a record of the change, run the git merge command.
  5. To check the latest branch status, run the git log command on the master branch. You can see that a new commit is created, however, there are no A1 and A2 in the commit history. This means that the squash option combined (squashed) all the changes made to the merging branch to simplify the line of commit history.
  6. To check the latest status of Branch_A, switch to Branch_A and run the git log command. You can see that nothing has changed on Branch_A

Squash-Merge

For a better understanding, please go through the following practice section.

bloovee-round-icon.pngDeveloper A (Project Owner Role)

Practice

Objective:
Check how the squash merge works

1. Prepare a practice file

In the practice on the previous page, Branch_A was already merged into the master branch. For this practice purpose, we need to reverse the commit history before Branch_A is merged.

To reverse the HEAD of the master branch to commit M3, reset the merge operation by running the git reset --hard command on the master branch. Use the commit hash of commit M3 which is generated on your computer. Also, make sure to use the --hard option. If you don't use the option, the statuses of the Working Tree, INDEX, and HEAD will be mixed.

Command Line - INPUT
git checkout master
git reset --hard e12beda
git log --oneline

You'll see that the HEAD of the master branch is back to Commit M3.

Command Line - RESPONSE
e12beda (HEAD -> master) M3
f5ff7aa M2
8bf5c03 M1

Next, create commit M4 to match the upper illustration on the main figure. Edit the HTML file (add <h1>M4</h1> and run the git commit command. To check the latest status, run the git log command again.

git_branch_practice.html
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<h1>M3</h1>
<h1>M4</h1>
<!-- /Master Branch-->
Command Line - INPUT
git commit -am "M4"
git log --oneline

Finally, you'll see the following master branch status, which matches the upper illustration on the main figure. As we haven't touched Branch_A, its status remains the same.

Command Line - RESPONSE
b7b73d4 (HEAD -> master) M4
e12beda M3
f5ff7aa M2
8bf5c03 M1

2. Perform squash merge

Now you are ready to execute the merge command. As you are already on the master branch, run the following command with the --squash option.

Command Line - INPUT
git merge --squash Branch_A

In this case, no commit is made as you can see the response in the command line like shown below.

Command Line - RESPONSE
Auto-merging git_branch_practice.html
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Instead, changes made on Branch_A are reflected in the Working Tree of the master branch shown in the text editor below.

git_branch_practice.html
<!doctype html>
<html lang="en">
<body>
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<h1>M3</h1>
<h1>M4</h1>
<!-- /Master Branch-->

<!-- Branch_A-->
<h1>A1</h1>
<h1>A2</h1>
<!-- /Branch_A-->

<!-- Branch_B-->
N/A
<!-- /Branch_B-->
</body>

The changes are also staged. To check the status, run the git status command.

Command Line - INPUT
git status

You can see that git_branch_practice.html was modified and staged (ready to commit).

Command Line - RESPONSE
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   git_branch_practice.html

2. Make a commit

As the git merge --squash command doesn't create a new commit in a normal setting, you need to run the git commit command to make a record like below.

Command Line - INPUT
git commit -am "Merge Branch_A (Squash)"

You can see that a new commit is created like shown below.

Command Line - RESPONSE
[master 161bc6c] Merge Branch_A (Squash)
 1 file changed, 2 insertions(+), 1 deletion(-)

3. Check commit histories and branch status

Check the status of the master branch first.

Command Line - INPUT
git log --oneline --graph

You can see that a new commit is created, however, there are no A1 and A2 in the commit history. This means that the squash option combined (squashed) all the changes made to the merging branch to simplify the line of commit history.

Command Line - RESPONSE
* 161bc6c (HEAD -> master) Merge Branch_A (Squash)
* b7b73d4 M4
* e12beda M3
* f5ff7aa M2
* 8bf5c03 M1

Next, check the status on Branch_A.

Command Line - INPUT
git checkout Branch_A
git log --oneline --graph

You can see that nothing has changed for Branch_A

Command Line - RESPONSE
* a4c4eb0 (HEAD -> Branch_A) A2
* 62dda63 A1
* e12beda M3
* f5ff7aa M2
* 8bf5c03 M1

Tag: