Team members’ contributions to a pull request (PR) can quickly increase the PR’s commit history when collaborating on a project. You accept a small typo fix here, a great suggestion there, and before you know it, you’ve added 100 commits to a PR you planned to keep small. While LinkORB prefers to keep the size of PRs small, having a small PR with a large number of commits can make it difficult to review, undo, or track changes.
To maintain a cleaner, more manageable commit history, we recommend squashing similar and related commits on a child branch before merging a PR. Squashing is the process of merging similar and related commits into one before or after pushing changes upstream.
This document provides guidance on how to squash commits using:
- GitHub Desktop
- Git on the Command Line (CLI)
- Git Graph in a Codespace or Visual Studio Code (VSCode)
Specifically, it discusses:
How squashing works
Git provides a rebase command that allows users to rewrite the history of a repository by:
- Selecting some (or all) commits on a branch.
- Squeezing all changes from the selected commits into a staging area (uncommitted branch).
- Creating a new commit that treats the merged commits as one (new) commit.
- Erasing previously logged individual entries of the merged commits from the commit history and replacing them with a single commit containing all the squashed changes.
Assuming you’ve been assigned the task of customising a web app template and updating the app’s documentation. The commit history of your branch may look similar to the below example.
82af5ac (HEAD -> customize-template-4096) docs: paraphrase sentence #4096
5c2195e docs: fix typo #4096
73a05c3 docs: update README.md #4096
a8f3604 fix: missing semi-colon (pesky eslint!) #4096
852495f refactor: reduce login controller length #4096
c2c9c96 feat: initial commit (definitely buggy) #4096
Although each of the three latest commits (prefixed by docs) introduces a different change, taken together, they simply update the app’s documentation (in the README.md file). For this reason, you may clean up the commit history by squashing all three commits into one. The commit history example above will look similar to the following after all docs changes are squashed:
30a2041 (HEAD -> customize-template-4096) docs: update README.md #4096
a8f3604 fix: missing semi-colon (pesky eslint!) #4096
852495f refactor: reduce login controller length #4096
c2c9c96 feat: initial commit (definitely buggy) #4096
When should I squash a commit?
Consider squashing related commits when a PR:
-
Ships a non-complex feature or fix that has a large commit history.
-
Contains multiple commits that are similar or related. For example, three subsequent related commits may be squashed into one if the last two fix an error in the first.
-
Includes multiple commits that can be grouped into logical units. For example, you may squash 30 commits that contain code and documentation changes into two (one docs and one feat) commits.
Organize and squash related commits into logical units instead of squashing all commits into one.
-
Only contains documentation.
Documentation commits are great candidates for squashing. However, commits should be squashed with discretion when they contain functional code. Look out for and resolve all rebase conflicts in messages and alerts shown after each step before finalising the squashing operation.
Squashing is recommended but not required. If squashing related commits takes more than 90 minutes or results in difficult-to-resolve conflicts, please abort (e.g.,
git rebase --abort) the squashing operation and request that the PR be merged as-is.
How to squash commits using GitHub Desktop
Squash related commits using GitHub Desktop as follows:
- Download and install GitHub Desktop if it is not already installed on your computer.
- Depending on where the repository is stored, select Add local repository or Clone repository from the File menu, then find and open the repository whose commits you want to squash.
- Click Current branch at the top of the screen and select the branch you want to work on.
- Click History in the left sidebar.
- Hold down the Ctrl or the Shift key on your keyboard and click the commits you wish to squash.
- Right-click the selected commits and select Squash commits.
- Modify the merge messages of the squashed commit if necessary and click Squash commits when prompted.
- Click Push origin in the top bar to push the changes to GitHub.
How to squash commits using Git CLI
Use Git to squash multiple commits from the command line as follows:
-
Open a terminal and navigate to the root of the repository’s folder.
-
Ensure you’re on the branch you wish to squash (some) of its commits by running the below command:
git branchThe selected branch is marked by an asterisk. Proceed to step 3 below if you’re on the correct branch. Or, run
git switch YOUR-BRANCH-NAMEto switch to the branch you want to change. -
Print a compressed version of the branch’s history to the screen by running the following command:
git log --oneline -
Locate the oldest commit in the range of commits that you want to squash and copy the hash of the commit directly before (below) it. Note that the latest commit is shown first in the commit history.
For example, if you want to squash the latest three documentation commits in the below example, copy the hash of the fix commit (i.e.,
a8f3604 fix: missing semi-colon (pesky eslint!) #4096) that is directly before (below) it.82af5ac (HEAD -> customize-template-4096) docs: paraphrase sentence #4096 5c2195e docs: fix typo #4096 73a05c3 docs: update README.md #4096 a8f3604 fix: missing semi-colon (pesky eslint!) #4096 852495f refactor: reduce login controller length #4096 c2c9c96 feat: initial commit (definitely buggy) #4096 -
Start the interactive rebase editor by running the below command. Replace
COMMIT-HASH-YOU-COPIEDwith the commit hash you copied in the previous step.git rebase -i COMMIT-HASH-YOU-COPIEDFor example, if you want Git to merge all three docs commits in the above example into a single one, pass the hash (a8f3604) of the fix commit directly before (below) it to the
git rebasecommand:git rebase -i a8f3604git rebase -i a8f360instructs git to use commita8f360as the base or as the latest commit upon which the squashed commits will be placed.a8f360, in the above example, is essentially the latest snapshot of the branch before the squashed commits are added to the commit history. -
Skip the first line (oldest commit) of the rebase editor and replace the word pick with squash or s in subsequent lines that start with the word pick.
The contents of the rebase editor of our example will look similar to the following after we complete this step:
pick 73a05c3 docs: update README.md #4096 s 5c2195e docs: fix typo #4096 s 82af5ac docs: paraphrase sentence #4096 -
Merge the squashed commits into the branch’s history with the below command:
git rebase --continue -
Modify and/or save the merge/commit messages for the squashed commits and close the merge/commit editor.
The squashed commit history of our example will look like the following after committing the changes:
08c4754 (HEAD -> customize-template-4096) docs: update README.md #4096 a8f3604 fix: missing semi-colon (pesky eslint!) #4096 852495f refactor: reduce login controller length #4096 c2c9c96 feat: initial commit (definitely buggy) #4096 -
Push the changes to GitHub
git push origin BRANCH-NAMEIf you pushed the commits to GitHub before squashing them, you may need to pass the
-foption or--forceflag to thegit pushcommand.git push -f origin BRANCH-NAME
How to squash commits using Git Graph
Git Graph is a VSCode extension for managing Git repositories. It provides a graphical user interface that may be used to squash related commits in a local VSCode environment or a GitHub Codespace as follows:
-
Install Git Graph in your Codespace or VSCode instance if it isn’t already installed.
-
Click the Git Graph button on VSCode’s bottom pane.
-
If the branch on which you want to squash commits isn’t checked out, check it out by right-clicking the branch’s name in the Graph field and selecting Checkout branch.
-
Right-click the commit message previous to the oldest commit in the range of commits you want to squash. For example, if you want to squash the three commits highlighted by a purple rectangle in the image shown below, right-click the commit highlighted by the orange rectangle.

-
Select Rebase current branch to this commit.
-
Tick the Launch interactive rebase in new terminal checkbox.
-
Click Yes, rebase.
-
Skip the first line (oldest commit) of the rebase editor and replace the word pick with squash or s in subsequent lines that start with the word pick.
The contents of the rebase editor of our example will look similar to the following after we complete this step:
pick 73a05c3 docs: update README.md #4096 s 5c2195e docs: fix typo #4096 s 82af5ac docs: paraphrase sentence #4096If your branch includes unrelated commits added after or in between the commits that you want to squash, do not replace
pickwithsorsquashin the lines that hold the records of those commits. Please see do not alter unrelated commits for more information. -
Click the source control button on VSCode’s side pane.
-
If necessary, modify the commit message.
-
Click Continue.
-
Click Publish branch to push the commits to GitHub.
Further reading
Please refer to the following guides for additional Git collaboration guidance: