2

I'm not sure if this is a normal branching scenario but ...

suppose 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?

racl101
  • 2,892
  • 4
  • 32
  • 31
  • Wow thanks guys for all your helpful responses. I really appreciate that you took the time to answer my question. I will take a look at all these . I'm learning so much right now and I have to say I really like git. – racl101 Jul 26 '11 at 23:19

4 Answers4

2

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.)

Paŭlo Ebermann
  • 68,531
  • 18
  • 138
  • 203
2

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.

Community
  • 1
  • 1
1

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

Alex Bain
  • 761
  • 6
  • 11
0

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.

Community
  • 1
  • 1
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283