Okay... so it sounds like development
is a long-lived branch representing the previous release(s) - much like master
in gitflow.
And it sounds like v1.0
is a long-lived branch where you're assembling the next release, much like develop
in gitflow.
And a given local branch might be like a feature branch (in which case you'll merge it to v1.0
) or like a hotfix (in which case you'll merge it to both v1.0
and development
). The odd thing is that you always seem to create the local branches so that they could be merged to both. (So do you not know, at branch creation time, whether you'll be merging to development
? Because if that's not the case, making every branch "start over" at the merge base seems like it has some unnecessary merge resolution costs... But I digress.)
Let's step through your scenario with pictures. You start with
A -- x <--(development)
\
Z <--(v1.0)
and you create a local branch
A -- x <--(development)
|\
| Z <--(v1.0)
\
B -- C <--(feature)
and your coworker creates a local branch
A -- x <--(development)
|\
| x -- O <--(hotfix)
|\
| Z <--(v1.0)
\
B -- C <--(feature)
(Bear with me here; I realize that there may never be any one repo with all of these branches in it, but let's just look at the "big picture" anyway...)
So your coworker merges to both long-lived branches
A -- x -- M <--(development)
|\ /
| x --- O <--(hotfix)
|\ \
| Z ----- M <--(v1.0)
\
B -- C <--(feature)
Note that from this point forward, O
is the merge base for development
and v1.0
. But your branch was created when the merge base was A
, so now we reach your question: how to get hotfix
into your branch.
By now hotfix
is an integral part of the shared history, so you probably don't want to do anything that rewrites and/or duplicates the changes from its commits.
You likely don't want to merge v1.0
into your branch, because mixing Z
into your branch would seem to run against the grain of having created the branch at the merge base.
So you really just want to combine O
into your branch. Now let's switch gears a bit and look at how your local repo might see things, if I take your term "local branches" literally (meaning you don't have the hotfix
branch):
A -- x -- M <--(development)
|\ /
| x --- O
|\ \
| Z ----- M <--(v1.0)
\
B -- C <--(feature)
Now, given that feature
is also local (only present in your repo), one option is to rebase it to the new merge base - and this seems like it remains in the spirit of your workflow.
git rebase $(git merge-base development v1.0) feature
would give you
A -- x -- M <--(development)
|\ /
| x --- O -- B' -- C' <--(feature)
\ \
Z ----- M <--(v1.0)
At this point B'
and C'
are both untested states of the code. Ideally you should test both of them and address any issues (though, if there are issues in B'
that's easier said than done), so that you will still have a clean history.
The other option, which would avoid the "untested commits" issue but create a "messier" (though arguably more accurate) history, is to simply merge the merge-base into your branch.
git checkout feature
git merge $(git merge-base v1.0 development)
Which gives you something like
A -- x -- M <--(development)
|\ /
| x --- O -----------
|\ \ \
| Z ----- M <--(v1.0) \
\ \
B -- C -------------- M <--(feature)
Which, after taking the long way around to say "why", means we did essentially what you already did, except skipping the step of creating a branch for the merge because we can just refer to the merge base directly.
And that makes sense. You'd already figured out what changes to combine with your branch - you don't really want to change what commit you're merging. So the best we can do is find a simpler way to refer to those changes.