Part 4: Squash & Cherry-pick
A Practical Tutorial for Beginners to Advanced Users

In the previous parts of Git for Everyone, we learned the fundamentals of Git, branches, remote repositories, conflicts, reset, reflog, and how to recover from mistakes.
Now let's look at two Git features that become especially useful when working with a team:
Git Squash
Git Cherry-pick
Both involve moving or organizing changes, but they solve very different problems.
Why Do We Need Squash and Cherry-pick?
Imagine you are working on a login feature.
During development, you might create several commits:
add login page
fix login button
fix validation
fix CSS
fix typo
final login changes
There is nothing technically wrong with this. Git is doing exactly what it should do.
But when another engineer looks at the project history six months later, these small development commits may not tell a very useful story.
Instead, the team may prefer the history to look like:
Add user login feature
This is where squashing becomes useful.
What Is Git Squash?
Squash means combining multiple commits into a smaller number of commits, often into one logical commit.
For example, instead of:
A → B → C → D → E → F
we may want:
A → S
where S represents the complete feature.
The important idea is:
Squash is mainly about cleaning up commit history.
A Real Example
Suppose you create a branch:
git switch -c feature/login
During development, you make several commits:
git add .
git commit -m "add login form"
git add .
git commit -m "fix login validation"
git add .
git commit -m "fix login styling"
git add .
git commit -m "fix login error message"
Your branch now contains several commits related to the same feature.
Before merging this work into the main branch, the team may decide that these should appear as one logical change.
For example:
Add user login feature
Squash Merge on GitHub
One of the easiest ways to squash commits is through a GitHub Pull Request.
A Pull Request may contain several commits:
add login form
fix validation
fix CSS
fix error message
When the Pull Request is ready, the team can choose:
Squash and merge
The main branch can then receive one logical commit:
Add user login feature
This is particularly useful when a feature branch contains many small development commits.
Squash from the Command Line
Git also allows us to prepare a squash merge from the command line.
git switch main
git merge --squash feature/login
At this point, Git has prepared the changes, but the final commit has not yet been created.
You can then create the commit yourself:
git commit -m "Add user login feature"
The result is a cleaner history on the main branch.
When Should You Use Squash?
Squash is useful when:
A feature contains many small commits.
Some commits are temporary development steps.
You want the main branch history to represent logical changes.
Your team prefers one meaningful commit per Pull Request.
But remember:
Clean history is useful only when it improves understanding.
Don't squash everything just because you can.
Now, What Is Cherry-pick?
Cherry-pick solves a completely different problem.
Imagine that another branch contains an important bug fix.
For example:
feature/payment
A → B → C → D
Commit C contains an important security fix.
But you don't want to merge the entire feature/payment branch.
You only want that particular commit.
This is where:
git cherry-pick
becomes useful.
How Cherry-pick Works
First, find the commit:
git log --oneline
Suppose you see:
8a91abc fix payment timeout
72bd112 add payment UI
51fa812 add payment API
You want:
8a91abc fix payment timeout
Switch to the branch where you need the fix:
git switch release/2.0
Then:
git cherry-pick 8a91abc
Git applies the changes from that commit to the current branch.
A Practical Production Example
Imagine your company has:
main
develop
release/2.0
feature/payment
A critical security fix has been developed on develop:
fix: prevent unauthorized payment access
However, the production release branch also needs that fix.
You may not want to merge the entire develop branch into production.
Instead:
git switch release/2.0
git cherry-pick <commit-hash>
Now the specific fix has been applied to the release branch.
Squash vs Cherry-pick
Situation | Recommended approach |
|---|---|
Many small commits belong to one feature | Squash |
Clean up feature history before merging | Squash |
Move one specific commit to another branch | Cherry-pick |
Apply an urgent fix to a release branch | Cherry-pick |
Bring an entire branch together | Merge |
One Important Warning About Cherry-pick
Cherry-pick is powerful, but it should not become the default way your team moves code between branches.
Using it excessively can result in:
Duplicated changes
Confusing history
More difficult conflict resolution
Harder maintenance
Use cherry-pick when you have a specific reason to move a particular commit.
The Easy Way to Remember
Merge
"Bring branches together."
Squash
"Turn several commits into one logical change."
Cherry-pick
"Give me this particular commit."
Once you understand this mental model, choosing between them becomes much easier.
Final Thought
Git is not only about storing code. It is also about maintaining a history that engineers can understand and maintain.
A good engineer therefore doesn't simply ask:
"Which Git command should I run?"
Instead, they ask:
"What change am I trying to move, and what should the project history look like afterwards?"
That small shift in thinking is what takes you from simply using Git to engineering with Git.