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?
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.
In my case, I started working with a branch that had several commits, then a merge with the main/source branch, then more commits and I wanted to squash all commits, but kept running into an error because of the merge commit:
error: commit is a merge but no -m option was given.
->C1->C2->M(merge with source branch)->C3->C4
There's probably a better way (and I look forward to learning), but what I ended up doing after much reading and trial and error was creating a copy branch for reference, then reverting the current branch to C1,
reset --hard (C1 hash)
then cherry-picking C2, C3, C4, then squashing, then rebasing ... resulting in:
M->C
(just one commit that has been rebased with source!)
I hope this helps someone else with the same problem.