Hi Michael,
On Thursday, March 23, 2017 at 10:10:02 PM UTC+1, Michael Gersten wrote:
>
> I need help with the syntax of rebase.
>
> I have a branch, "Dish", that was branched off of master. This was about a
> month ago.
>
> Making a new branch off master, and merging Dish into it, worked just
> fine. No problem.
>
> Now, I have "master", and from it, "merged-dish".
>
> Time to update master. All good so far.
>
> What I want is an easy way to update "merged-dish". So I tried to rebase
> it.
>
> git rebase --onto master Dish
>
> git rebase --onto master merged-dish
>
> Both of these were no-ops.
>
> So what's the best way to keep a local branch up to date as the upstream
> master updates?
>
Until more knowledgeable/experienced people chime in, I`ll try to give some
hopefully useful feedback. Anyone, please feel free to correct me or
provide additional info I might have missed, I`m still learning myself.
To understand what happened, it might be best to use some visualization of
what is going on.
Prior to your "rebase" attempts, after you updated "master", your history
looked something like this:
(*1*) ---A---B---C---D---E---F (master)
\ \
\ M (merged-dish)
\ /
X---Y---Z (Dish)
As you said you`re trying to rebase "merged-dish" now, I`ll assume you`re
on the "merged-dish" branch.
(*2*) git rebase --onto master Dish
This means "rebase current branch (merged-dish) on new base `master`
(commit F) from old base `Dish` (commit Z)". But what are the actual steps?
Let`s see:
1. Find all commits between old base "Dish" (Z) and current branch
"merged-dish" (M) (contained in "merged-dish" but not in "Dish"). This
results in commits B, C, D (you may expect to see M here, too, but it is
missing as "rebase" by default does not preserve merge commits).
2. Replay these commits on top of new base "master" - but as these are
contained inside "master" already, there is nothing to be done here, as you
noticed, only "merged-dish" gets updated to point to where "master" is
(commit F):
(*3*) ---A---B---C---D---E---F (master, merged-dish)
\
X---Y---Z (Dish)
(depending on the changes you have, you might end up with some merge
conflicts during a rebase, but the end result should be as shown above)
Now, on to the next one:
(*4*) git rebase --onto master merged-dish
This one confuses me a bit as you didn`t mention if you did anything
between this and the previous command, because if you tried it right after
the previous one, it doesn`t really make much sense.
Why? If we ended up in a situation shown on graph (3) and tried command
(4), the steps to do would look something like this:
1. Find all commits between old base "merged-dish" (F) and current
branch "merged-dish" (F) (contained in "merged-dish" but not in
"merged-dish")... and as already obvious, this returns nothing, no commits,
so there`s nothing to be done in the next step - as you noticed again.
All this said, the important question is - what should you have done
instead?
As usual, it depends on what you wanted to accomplish in the first place.
For example, I`m not sure what was the idea behind "merged-dish" branch...?
Anyway, let`s say this is some starting point:
(*5*) ---A---B---C---D (master)
\
X---Y---Z (Dish)
MERGE FLOW (M)
If you wanted to update your "Dish" branch with recent commits from
"master" using a merge, you should have just done that (while on "Dish"
branch):
(*M6*) git merge master
... which would give you this situation:
(*M7*) ---A---B---C---D (master)
\ \
X---Y---Z---M (Dish)
You can then keep working on both "master" and "Dish", and merge from
"master" to "Dish" when you feel like it***:
(*M8*) ---A---B---C---D---E---F (master)
\ \
X---Y---Z---M---W (Dish)
(*M9*) ---A---B---C---D---E---F (master)
\ \ \
X---Y---Z---M---W---M2 (Dish)
Finally, when you`re satisfied with your "Dish" completeness, you may merge
it back to "master":
(*M10*) ---A---B---C---D---E---F---G---H (master)
\ \ \
X---Y---Z---M---W---M2--V---U (Dish)
(*M11*) ---A---B---C---D---E---F---G---H---M3 (master)
\ \ \ /
X---Y---Z---M---W---M2--V---U (Dish)
You can now delete branch "Dish", keep it for reference, or even merge
"master" into it (being a fast-forward merge):
(*M12*) ---A---B---C---D---E---F---G---H---M3 (master, Dish)
\ \ \ /
X---Y---Z---M---W---M2--V---U
REBASE FLOW (R)
Alternatively, if you wanted to use the rebasing flow, you can just keep
rebasing "Dish" on top of "master". So in situation (5), you would do this
instead (while on "Dish" branch):
(*R6*) git rebase master
... which would give you this (in comparison to previous (M7)):
(*R7*) ---A---B---C---D (master)
\
X'--Y'--Z' (Dish)
Again, you can then keep working on both "master" and "Dish", and rebase
"Dish" to "master" when you feel like it*** (command (R6)):
(*R8*) ---A---B---C---D---E---F (master)
\
X'--Y'--Z'--W (Dish)
(*R9*) ---A---B---C---D---E---F (master)
\
X''-Y''-Z''-W' (Dish)
Finally, when you`re satisfied with your "Dish" completeness, you may do
one more (final) rebase:
(*R10*) ---A---B---C---D---E---F---G---H (master)
\
X''-Y''-Z''-W'--V---U (Dish)
(*R11*) ---A---B---C---D---E---F---G---H (master)
\
X'''Y'''Z'''W''-V'--U' (Dish)
... and then merge it back to "master" (which will now be a fast-forward
merge):
(*R12*) ---A---B---C---D---E---F---G---H---X'''Y'''Z'''W''-V'--U' (master,
Dish)
[***] There is a whole theory behind making a decision when to merge (or
rebase) to update your topic branch, depending on what your flow/goal is,
and even if that should be done at all (until all the work is done), but
that is yet another topic.
Regards,
Buga
--
You received this message because you are subscribed to the Google Groups "Git
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.