How to squash commits which have merge-commit in between?
I am working on a feature branch.
- Made several commits. Squashed commits.
- Pushed changes to remote branch. Got conflicts.
- Merged changes from master, resolved conflicts on feature branch.
git fetch origin master
git merge FETCH_HEAD
- Resolved conflicts manually.
git commit
git push
- I made one more commit.
So, current commit history looks like this. From current to old:
- commit 3
- commit M yyy (Merged)
- commit 2
How do I squash above 3 commits into 1 before I merge my feature branch to master?
Solution 1:
You can rebase -i
starting with commit 2
's parent (that is, the commit on master
that you branched from. You'll likely have to re-resolve conflicts when you get to the merge commit.
So if your history looks like
* D commit 3 (HEAD)
* M merge
/|
| * C commit 2
* | B commit on master
|/
* A (master)
Start with git rebase -i A
. You'll see a list of commits including both master
and your_branch
, but not the merge commit. pick
the first one (B
or C
, depending on timing) and squash
the rest.
Solution 2:
You can use the tool I've created specifically for this task:
https://github.com/sheerun/git-squash
It's only necessary to merge master branch, and then run squashing command:
git merge master
git squash master
Solution 3:
Assuming the feature branch is called feature
and the main branch main
:
Create a temporary branch from main
:
git checkout -b temp main
Squash the feature
branch in:
git merge --squash feature
Commit the changes (the commit message contains all squashed commit messages):
git commit
Go back to the feature
branch and point it to the temp
branch:
git checkout feature
git reset --hard temp
Delete the temporary branch:
git branch -d temp