Say I have a branch named feature
that has been branched off master
. Both, developer1 and developer2 checkout feature
. developer1 commits a change to feature
and pushes it. Then developer3 pushes something to master
. At this point master
and feature
diverge, each having a separate commit.
What's the right way to go about getting the latest from master
into the feature
, if there are conflicts? Should I rebase master
into the feature
, or merge it in?
EDIT:
I should mention that in this case I would not want to rewrite the history on developer2. Because that would be bad. Right?
Considering feature
branch is already shared, it shouldn't be rebased on master
(as it changes its - shared - history).
A simple merge from master
to feature
will be enough (without speculating as why dev3
pushed to master
in the first place).
As Adam Dymitruk comments, this is called a "back-merge", and, depending on the role you attribute to master
, it is questionable: if master
represents the stable production state, you should merge to master
, not from master
.
But again, my answer made no assumption on said role.
This is why the famous git-flow illustrates in its blog post merges which are coming to master (from, for instance, an hotfix
branch, as I commented earlier)
git
is a great tool; but, it cannot take the place of good communication among developers.
You have to ask whether the changes in master
must also be included in feature
. Ideally, a feature branch should have the smallest amount of code possible.
If the change(s) absolutely must be included in feature
, then the you have basically two options: git rebase
; and, git cherry-pick
. I suppose you could perform a backward merge from master
into feature
; but, that can lead to bad situations...
cherry-pick
allows you to apply a specific commit or multiple commits to the current HEAD
, keeping comment and author information. After having successfully cherry-pick
ed, git is smart enough to know that the two commits are the same when merging feature
back into master
. If it's just a few commits we're talking about, then cherry-pick
should be sufficient.
rebase
allows you to apply the current branch (line of commits) starting from a different point in history. As you pointed out, this can be troublesome for developer1 and developer2 who already have copies of feature
. They would also need to rebase
their local development onto the new feature
branch.
At any rate, the commit directly to master
by developer3 should have been in its own feature branch, and that feature branch should have been merged. That feature branch could then have been merged into feature
as necessary. Assuming just one (the most recent) commit in master
, you could rectify the situation as follows:
# Ensure clean working directory
$ git stash
# Create new branch at master
$ git branch some-descriptive-name master
# Move master back one commit
$ git checkout master
$ git reset --hard HEAD^
# Merge the new branch into master
$ git merge --no-ff some-descriptive-name
# Forcibly update master
# YOU SHOULD COMMUNICATE WITH OTHER DEVS BEFORE DOING THIS
$ git push -f origin master
# Merge the new branch into feature
$ git checkout feature
$ git merge --no-ff some-descriptive-name
I cannot stress enough how valuable good communication is because these kinds of "oops" things can and do happen all the time.
Good luck!
EDIT:
The part about cherry-pick
ing was written with the assumption that there was only a few commits (or just one) to master
and that they all would be cherry-pick
ed.
x -- y (master)
\
a -- b -- c (feature)
the third developer should not be writing a feature on master. The rare exception is a hotfix. But even then, it should be it's own branch then merged with --no-ff
onto master. I've written a long post about branch per feature here: http://dymitruk.com/blog/2012/02/05/branch-per-feature/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With