- Using squash mechanism
- Using good old git reset
Here is the scenario . Say if you made some commits with small changes like remove small space 1 , change variable name , remove space 2 . Later you realize the commits are kind of silly , you want all these commits to be merge into one called something like code cleanup .
Using squash for this problem a bit complex (not if you get used to it) . But it sort of gives you an overall idea on what is happening . This is how you do it .
Method 1 : Using squash mechanism
First of all make sure your master branch is up-to date with the related upstream branch . And say you are in a feature branch called , well feature-branch .
in your git bash , run this command git rebase -i master
you will get the vim interactive console and you will see all of your 3 commits listed
Here the process is simple . You can pick one commit which can be your parent commit using pick, and the rest of the commits can be linked under this parent commit using squash command . Also you can change the order of the commits as well . So according to our scenario , we can do something like this ...
So yeah that is it . Just save and exit . And you will get another interactive console like below ..
You can just skip this window by just quitting without save or you can give new names to your commits . So here i am renaming the top most commit (which is my parent commit of all 3 commits) as Code cleanup . And again save and exit .. You will see something like below ..
That's it , you have successfully merge 3 of your silly commits into one commit which is going to make a better commit history for you . Now you can just use git push origin feature-branch --force to push your single commit to the remote repository .
Note : we are using --force because this process has changed the commit hashes . In any case , when you use force push , you need to absolutely make sure you know what you are doing .
If you go to your repository and view the commit history , you can see the squashed commits like this visualized in a different way ..
So that's how you squash your commits in Git . It is a bit time consuming process , but if you get used to it , it is very useful .
Method 2 : Using good old git reset
So unlike squashing your commits , you can easily merge your little commits into one using git reset command . It is really simple . Take the same scenario i have mentioned above . Now what you need is , Taking the HEAD position 3 commits back . By doing this you are resetting the last 3 commits .
git reset --soft HEAD~3
Now you have un-stage changes . All you need to do now is to put them into a single commit
git commit -m "Code cleanup"
Or better way , merge these 2 commands into one
git reset --soft HEAD~3 && git commit -m "Code cleanup"
There you go ! That's it . now push --force to push the new commit into the remote repository . The same warning regarding force push applies here as well .
The awesome thing about these 2 methods is that you can change the commits even after you have pushed the changes into the remote repository . So don't worry , it is never too late with git .
more info on squashing can be found here