This would do it (call the branch you are on originalBranch
):
git switch --det c2
git switch -c temp
git reset --soft c1
git commit -msquash
git rebase --onto temp c2 originalBranch
git branch -D temp
The idea is this:
- We get ourselves back at
c2
and plant a branch name temp
there, so that we can find it again.
- We then squash from
c2
all the way back to c1
inclusive — that's the soft reset followed by a commit; this is a type 1 regret. The name temp
now points to this new single squash commit.
- Finally, we return to whatever was the original HEAD (which I have named
originalBranch
) and move all the commits starting at (but not including) the old c2
onto the new single squash commit, which (as I have already said) is pointed to by the name temp
.
- Our work is now done, but we no longer need the branch name
temp
for anything, so we delete it.
So we have now gone from this:
A -- B -- C1 -- ? -- ? -- C2 -- D -- E -- F <- originalBranch
To this:
A -- B -- C1 -- squash -- D' -- E' -- F' <- originalBranch
\
-- ? -- ? -- C2 -- D -- E -- F
The old commits, as you can see from my diagram, still exist, but they will all be mopped up during the next garbage collection because no name points to them any longer.