Introduction
There are times where we need to squash a tail of short commits and tidy up our commit history.This is seen more on code base where we have to remotely check whether they are fine.Good example is a Jenkins pipeline file.Any small updates we make in codebase to check if the pipeline change are working we need to commit and push.
Now when you are ready to squash your commits together you have couple of options.Lets discuss this in the below section.
Method1: Using Rebase command
This is the orthodox way to squash any commits together.If you are new to VI this might be little tricky. Please follow the steps I mention below in order.
Do git log to see the list of commit we target to squash
$ git log
commit d65ac9eaaa5a9f92cc2182ccd3cb6e930981842b (HEAD -> master, origin/master)
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:57:12 2020 +0530
seventh commit
commit b6fa7c63c0a8563aff9b7b70f526003b7842e62f
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:56:54 2020 +0530
sixth commit
commit ab176dfc5d096a51bc9e63effc280f348b714581
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:55:47 2020 +0530
fifth commit
commit 64710907985cd4a2c331686d7fb0d24b9aabf2b0
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 14:34:35 2020 +0530
collapsed branch
4th commit
here we want to squash fifth,sixth,seventh commit and create a new commit as collapsed commit 2 on top of commit 64710 (lets name it as target).
Now do
once this command is entered, a VI editor will open which will show list of commit ids
pick ab176df fifth commit
pick b6fa7c6 sixth commit
pick d65ac9e seventh commit
# Rebase 6471090..d65ac9e onto 6471090 (3 commands)
carefully note that it shows all the 3 commit ids which we want to club to one. Now we need to select the commit with latest changes and mark it as pick and all the other as squash.
Those who are new to VI
press I to goto insert mode.Slowly move your cursor near "pick" text and replace it with "s" (meaning squash)
once done press escape
your final file will look like this
pick ab176df fifth commit
s b6fa7c6 sixth commit
s d65ac9e seventh commit
press :wq! and enter - this will write the changes into the file.VI editor will close after this
now a new window will popup, this is to edit the commit messages if you like.If you dont bother to change it just :wq! again
done. we have successfully rebased.
[detached HEAD 3153732] fifth commit
Date: Sun May 3 17:55:47 2020 +0530
1 file changed, 4 insertions(+), 1 deletion(-)
Successfully rebased and updated refs/heads/master.
if you do a git status now you will see message like this
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 3 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
let us understand this, so currently we are 1 commit ahead(the squashed commit) of origin/master. And because we have removed the previous three commits (which is still in origin/master) we have diverged our branch working master and origin/master.
Now we need to upload this commit rewrites to our remote repo.to do that git push needs to be forced.otherwise will get this error
To https://github.com/sayanawsit4/git-squash-merge-test.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/sayanawsit4/git-squash-merge-test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
this is understandable as our head and remote head has diverged.So we need inform (force) remote git repo to take the cleaned up commit history and changes.
$ git push -f origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 279 bytes | 279.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/sayanawsit4/git-squash-merge-test.git
+ d65ac9e...3153732 master -> master (forced update)
we are done now. Do a git log and check the commit history now.
$ git log
commit 315373283dcbe1c7561e93a32969fbab0943ad37 (HEAD -> master, origin/master)
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:55:47 2020 +0530
fifth commit
sixth commit
seventh commit
commit 64710907985cd4a2c331686d7fb0d24b9aabf2b0
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 14:34:35 2020 +0530
collapsed branch
4th commit
Method2 :
This is a more unorthodox method.Many a times git rebase might be time consuming especally when you have big commit history and your inside corporate device that runs tons to antivirus.Follow the steps carefully
Do a git log to identify the commits we want to squash
$ git log
commit 5e39e623a905a3befd750ed99484c3457c4087c3 (HEAD -> master, origin/master)
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 18:47:14 2020 +0530
ten commit
commit 0ebcd4adec8f898a5db77f11b204b007c43495e0
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 18:46:33 2020 +0530
ninth commit
commit 2e39fd2963337e7f312298fcb6e779c9dd5fd050
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 18:46:08 2020 +0530
eight commit
commit 315373283dcbe1c7561e93a32969fbab0943ad37 -- target
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:55:47 2020 +0530
fifth commit
sixth commit
seventh commit
in this case we are going to squash eight,ninth,tenth commit together into 1 on top of commit hash 31537 (this is our target)
So in this we have to checkout the target commit(315373) without allowing to overwrite changes from the latest commit(5e39e62).To do this open your project in notepad++ as a workspace and then do a checkout. When notepad++ prompts to overwrite(as the checkout is forcing it do) just select NO.This will keep the changed files in ‘M’ modified state.Just hit save in all this modified files( all modified files will come with red sign in notepad++)
$ git checkout 315373283dcbe1c7561e93a32969fbab0943ad37
Note: switching to '315373283dcbe1c7561e93a32969fbab0943ad37'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 3153732 fifth commit
you will get a message saying HEAD is detached, dont worry about this.Git is just complaining because we have checkout out a random commit which it has no control to increment HEAD.
As mentioned above,when notepad prompts dont change this files.Click No.Save the file.
Now the the most important part.Follow along..
create a a temp branch out of this commit
$ git checkout -b temp
Switched to a new branch 'temp'
point master and temp branch to the same commit id
$ git branch -f master temp
git checkout master branch
$ git checkout master
Switched to branch 'master'
M hello.txt
Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
commit the changes
$ git commit -m 'collapsed changes 2'
[master c859ae2] collapsed changes 2
1 file changed, 4 insertions(+), 1 deletion(-)
delete temp branch
$ git branch -d temp
Deleted branch temp (was 3153732).
git push force changes to remote.
$ git push -f origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 6 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 275 bytes | 275.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/sayanawsit4/git-squash-merge-test.git
+ 5e39e62...c859ae2 master -> master (forced update)
we are done. Lets check the git logs now
$ git log
commit c859ae2ccf6388c48b5d3207de77005651b59e2c (HEAD -> master, origin/master)
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 19:25:01 2020 +0530
collapsed changes 2
commit 315373283dcbe1c7561e93a32969fbab0943ad37
Author: sayannayas <sayannayas@gmail.com>
Date: Sun May 3 17:55:47 2020 +0530
fifth commit
sixth commit
seventh commit
We have successfully Squashed the changes to a single commit.
Conclusion
Here we learnt how to clean up commit history using orthodox method of rebasing.We also learnt unorthodox method of cleaning the commits using simple pointer mechanism and some quirky.Thanks for reading.
Reference
- Understanding Request, RITM, Task in ServiceNow
- Steps to create a case in ServiceNow (CSM)
- Performance Analytics in 10 mins
- Event Management in 10 minutes - part1
- Event Management in 10 minutes - part2
- Custom Lookup List
- Script includes in 5 minutes
- Interactive Filter in 5 minutes
- UI Policy in 6 Minutes
- Client Side Script Versus Server Side Script in 3 minutes
- Java
- ACL
- Performance analytics(PA) Interactive Filter
- Various Configurations in Performance analytics(PA)
- Service Portal
- Performance Analytics(PA) Widgets
- Performance Analytics(PA) Indicator
- Performance Analytics(PA) Buckets
- Performance Analytics(PA) Automated Breakdown
- Client Script
- Rest Integration
- Understanding the Request, RITM, Task
- Service Catalogs
- Events in ServiceNow
- Advance glide script in ServiceNow
- CAB Workbench
Comments