I'm not sure if this is a normal branching scenario but ...
开发者_如何学Pythonsuppose that I create a branch, say branch C, from master and then merge back other previously existing branches, say branches A and B, back into master, and I need some of the code from A and B in branch C then can I merge from master to branch C?
And if so, are there any reasons why this would not be a good idea? Is this a common operation in git?
Yes and yes.
You can merge whichever way you like in git. Merge simply means "combine these histories". When git can't, its default mode is to just dump the changes on you, a "merge conflict" but you can also alter that behaviour to lean towards "ours" or "theirs". Take a look at the git-merge docs for a full explanation of the hundreds of options...
So, from your explanation, a diagram of histories might look like this:
*-------*-------*------* master
|
*----*-----* A
|
*-------* B
|
*----* C
Where *
is just some commit on that branch, except the point they're all created. So how do you fix this issue? Well, I would:
git checkout A
being on A, basically we're going to merge A in to master like so:
git merge master
there is a good reason for doing that - when presented to another developer, assuming the merge is accurate, this represents a straightforward fast-forward merge for them. In other words, to merge A into the actual master in someone else's repository this becomes easier. Now, the next step, which you or another developer could do:
git checkout master && git merge A
That pulls in A. It should basically have no merge conflicts at all, since the process of merging master into A resolved them and the developer responsible for integrating A handled it.
So then
git checkout B && git merge master
again, resolve merge problems, then git checkout master && git merge B
Finally, you're saying can I merge master
into C? Absolutely. We've just done that process twice.
We use this particular way of doing things at work. Basically, I get the other developers to let me know when their branches are ready, then I merge them in, then everyone merges master into their branches, and the process repeats. You can even do this with remote repositories. If you have tracking branches in a remote, git pull
pulls in your changes. This is actually a git fetch
followed by a git merge
, So if you're not tracking somebody else's branch, you can still apply the merge like so:
They can do git merge leaddeveloper/master
where leaddeveloper
is a remote name. Then they can correct any conflicts, send an email to the lead developer saying "please pull" and the lead developer can type git fetch && git merge juniordeveloper1/somebranch
or more likely git fetch && git diff master..juniordeveloper1/somebranch
to work out what they've done first.
In short, this I think is a really good way of managing a project. It keeps everyone up to date and ensures the guy handling the main master doesn't also have the job of integrating the code.
On the subject of git rebase, this question deals with it very neatly.
This is a quite normal operation.
git checkout C
git merge master
would the usual way to do this (you can ommit the first if you are already on this branch).
The rebase
command mentioned by Alex is an alternative, but this has other results. (In effect, you get a more linear history for your branch, but all the old commits on C before the rebase (and after the original branch) have now other names (commit IDs), since they have the commits in A and B in their ancestors.)
Definitely a normal scenario. This is what you'd want to do:
$ git checkout your-branch
$ git rebase master
To better understand rebasing, here's an example. Let's say that this is your commit history:
H--I--J [branch C]
/
A--B--C--D--E--F--G [master]
As you can see, master has had multiple new commits since you created your branch.
If you rebased your branch against master, that history would now look like:
H'--I'--J' [branch C]
/
A--B--C--D--E--F--G [master]
Now Branch C is up to date, and incorporates all the changes since you originally created the branch.
Resources:
http://book.git-scm.com/4_rebasing.html
http://kernel.org/pub/software/scm/git/docs/git-rebase.html
Unless branch C is heavily shared, that is pulled from the upstream repo by other user, I would still favor the rebase
approach mentioned in Alex's answer.
Rebase first (C
on top of master
), merge later (C
on master
).
If you have only some commits of A
and B
that you would need in C
, cherry-picking is would be solution, but as I mention in "Use GIT fork / branches" (at the end of it), cherry-pick has drawbacks.
精彩评论