Assuming:
Currently I have a branch like this:
--(C1) :B-Master
\--(C2)--(C3) :B-Feature1
\--(C4)--(C5) :B-Feature2
\--(C6)--(C7) :B-Feature3
How do I rebase into something like this:
---(C1)-------------(R1)----------------(R2) :B-Master
\--(C2)--(C3)--/ \ / :B-Feature1
\--(C4)--(C5)--/ :B-Feature2
\--(C6)--(C7) :B-Feature3
Explanation:
Currently in my Master branch there's a last commit of C1. And at C1 I have multiple different idea coming regarding different feature. I start to code each of them on different branch. When each of the feature completed.
Example: When Feature1 branch complete, I want to rebase the Feature2 branch into R1. Meaning the Feature2 branch has all code of Feature1 code before C4 even exist.
Existing commit C4
cannot be changed in any way at all and that includes the fact that its parent is commit C1
. So you can't get what you want, but you can probably get what you need (as the Rolling Stones song goes): a new C4'
(C8
?) that is a lot like C4
but attaches to R1
.
I prefer single-letter names for commits, and would draw the original this way:
...--B <-- master
|\
| C--D <-- feature1
|\
| E--F <-- feature2
\
G--H <-- feature3
We'll end up with, e.g.:
...--B------I------J <-- master
|\ / \ /
| C--D E'-F' <-- feature2
\ `...... <-- feature1
G--H <-- feature3
where commit I
is a (forced) merge commit made to merge feature1
into master
without doing a fast-forward, E'-F'
are the copies of E-F
altered to come after I
, J
is another forced merge, and G-H
are untouched as they still spring from commit B
:
git switch master
git merge --no-ff feature1
git switch feature2
git rebase master
git switch master
git merge --no-ff feature2
If you don't need to force merge commits I
and J
to exist, see Bogdan Onischenko's answer.