Skip to main content

Git squash

12th October, 2022

Updated: 13th October, 2022

    Tuesday 5 July 2011

    With git it’s possible to squash previous commits into one. This is a great way to group certain changes together before sharing them with others. ~ Here’s how to squash some commits into one. Let’s say this is your current git log.

    * df71a27 - (HEAD feature_x) Updated CSS for new elements (4 minutes ago)
    * ba9dd9a - Added new elements to page design (15 minutes ago)
    * f392171 - Added new feature X (1 day ago)
    * d7322aa - (origin/feature_x) Proof of concept for feature X (3 days ago)

    You have a branch feature_x here. You’ve already pushed d7322aa with the proof of concept of the new feature X. After that you’ve been working to add new element to the feature, including some changes in CSS. Now, you want to squash your last three commits in one to make your history look pretty.

    The command to accomplish that is:

    git rebase -i HEAD~3

    This will open up your editor with the following:

    pick f392171 Added new feature X
    pick ba9dd9a Added new elements to page design
    pick df71a27 Updated CSS for new elements

    Now you can tell git what to do with each commit. Let’s keep the commit f392171, the one were we added our feature. We’ll squash the following two commits into the first one - leaving us with one clean commit with features X in it, including the added element and CSS.

    Change your file to this:

    pick f392171 Added new feature X
    squash ba9dd9a Added new elements to page design
    squash df71a27 Updated CSS for new elements

    When done, save and quit your editor. Git will now squash the commits into one. All done!

    Note: do not squash commits that you’ve already shared with others. You’re changing history and it will cause trouble for others.

    How to squash commits before submitting PR

    • never squash or rebase on shared branches (master/staging etc)
    • never squash or rebase on on somebody elses branch - always branch off to your own environment or check with the person first.
    • always include the remote name when pushing to a repository 99% of the time it will be origin but when it comes to deployments sometimes the remote name is different and you dont want to accidentally push to a remote deployment branch on heroku for example
    1. if you don't have it already setup this alias on your machine
    git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

    typing git lg will now give you a nicely formatted git log list of commits

    1. Find out how many commits there have been since you branched off the main or equivelent branch by running git lg note the number of commits you've made on your branch.
    2. git rebase -i HEAD~X where X is the number of commits you've made since branching off.

    This will open up your editor with the following:

    pick f392171 Added new feature X
    pick ba9dd9a Added new elements to page design
    pick df71a27 Updated CSS for new elements

    All the options for what to do in each commit is shown in the comments - all you need to do is go though and change the word pick to what you want to do. (squash, fixup, reword, pick etc) (hit i to enter insert mode and esc to ender the command giving mode in vim)

    Personally I reword the first commit to be ticket id: description then squash all others below that into the top commit so you end up with something like this:

    reword f392171 Added new feature X (changed to be ticket id + desc)
    squash ba9dd9a Added new elements to page design
    squash df71a27 Updated CSS for new elements

    Once you save this shift + esc + : then type wq and run git lg again you'll see that you now have one commit since you branched off master.

    The next task is pushing these changes to remote. Since rebase is rewriting the history of your branch its considered destructive. This isn't really much of an issue on a personal feature branch but it's not something you would do to shared branches.

    Since you're replacing the old commits with one new one you need to force push to the remote - triple check the branch name is correct! 😅

    git push --force -u origin feature/feature-branch-name


    e0c77cea-4ad1-4dcc-9050-5d8f974ee045

    Created on: 12th October, 2022

    Last updated: 13th October, 2022

    Source: Site Unreachable

    Tagged With: