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.