# Squashing Commits In Git # Squashing And Why You Should Do It Squashing commits in git is something I originally would only do if my companies repo server like bitbucket or git has squashing upon merge enabled. However, it's something you can do with the cli and vim pretty easily, and it makes your PR's look amazing when you have everything under one neat commit ready to be merged into master. It also hides all those mistakes you made in those 300 commits of your feature branch... I encourage you to squash **BEFORE** you open a PR into develop and master. Let's see how it's done! --- ## TLDR In VIM Editor ``` git rebase -i origin/master :%s/pick/squash/g ``` - Change first `squash` to `pick` then `:wq` - Change commit messages to single message (or as many as you need) then `:wq` - `git push -f` --- ### Things To Know And Need - Do not perform this on your master branch - All the commands in this post will be demoed in vim editor. Because why nano? - Git installed. It was innevitable. ## Git Rebase What is a `git rebase`? in simple terms, it's merging one branch, onto another. Git merge will preserve your history as it happened, while rebasing will rewrite it. This makes sense as to why we use rebase to squash, because rewriting your history is what we want to do. A git rebase alone won't do what we want, we need to be able to pick the commits we want to edit and squash. That's where the `-i` (`--interactive`) option comes in. A squash in git is simply an interactive rebase. we take our branch and commits, and rebase them on master or develop (whichever branch you're merging into) and then we pick which commits to squash. Let's try it out. I've made a repo for testing these commands, and we can see I've made five commits on the feature branch: ``` [jayson@RyterINC Test-git-repo] git log commit 9ae72b1e1188c1c83fb9110325d4d10134dbd0d2 (HEAD -> test-branch, origin/test-branch, origin/HEAD) Author: Ryterinc Date: Mon Nov 22 23:02:03 2021 -0500 removing jenkins dir commit 620650a7aa98001dc051a5bc2749e0a8e4035104 Author: Ryterinc Date: Mon Nov 22 23:01:36 2021 -0500 BLAH BLAH BLAH commit eed2a6b23905e34d53398e67daa1ed6c673ce319 Author: Ryterinc Date: Mon Nov 22 23:01:19 2021 -0500 mooooore commits commit 69671e5a524eb7da697cf51d220da5fb54df7d7c Author: Ryterinc Date: Mon Nov 22 23:01:00 2021 -0500 another commit commit 5fc7d53a7cacf5d2035f2a57b0eb61cf2dcbf1f2 Author: Ryterinc Date: Mon Nov 22 23:00:44 2021 -0500 heres a commit commit 6870360f406cc96d5567ceac4142123d4d7352b4 (origin/master, master) Author: Jayson Ryter Date: Sat Feb 8 20:01:06 2020 -0500 adding submodule ``` Now, it would be very sloppy and unproffesional of me to commit these five commits to master, especially with the messages provided. Let's squash these into one and make a meaningful message now that my development is done. In my case, I want to merge into my master branch, so let's rebase onto it interactively `git rebase -i origin/master` From here, we are taken to a commit page where we will decide which commits to keep and which to squash. ``` pick 5fc7d53 heres a commit pick 69671e5 another commit pick eed2a6b mooooore commits pick 620650a BLAH BLAH BLAH pick 9ae72b1 removing jenkins dir # Rebase 6870360..9ae72b1 onto 620650a (5 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop = remove commit # l, label