git: merge two branches: what direction?

Regarding the alternatives

git checkout iphone -b iphone31
git merge master

and

git checkout master -b iphone31
git merge iphone

they will have identical ease or difficulty, it is like arguing whether a glass is half full or half empty.

Version tree perception

How we look at version trees are in some way just our arbitrary perception.
Let’s say that we have a version tree like the following:

    A----------+
    |          |
    |          |
   \_/        \_/
    B          X
    |          |
    |          |
   \_/        \_/
    C          Y
    |
    |
   \_/
    D
    |
    |
   \_/
    E

And let’s say that we want to make a new version Z checked out from Y
based on the changes from C to E but not including the changes made from
A to C.

“Oh, that will be difficult because there is no common starting point.”
Well not really. If we just place the objects a little differently
in the graphical layout like this

      /
    C+---------+
    | \        |
    |          |
   \_/         |
    D          B
    |         / \
    |          |
   \_/         |
    E          A
               |
               |
              \_/
               X
               |
               |
              \_/
               Y

now things are starting to look promising. Notice that I have not
changed any relation ships here, the arrows all point the same way as
in the previous picture and version A is still the common base.
Only the layout is changed.

But it now trivial to imagine a different tree

    C'---------+
    |          |
    |          |
   \_/        \_/
    D          B'
    |          |
    |          |
   \_/        \_/
    E          A
               |
               |
              \_/
               X
               |
               |
              \_/
               Y

where the task would just be to merge version E normally.

So you can merge anything you want, the only thing that influence
the ease or difficulty is the aggregate of changes done between where
you select as a starting point or common base and where you merge to.
You are not limited to using the natural starting point the your
versioning tool suggest.

This might not be simple with some version control systems/tools,
but if all else fails there
is nothing that stops you from doing this manually by
checking out version C and save the file as file1,
checking out version E and save the file as file2,
checking out version Y and save the file as file3,
and run kdiff3 -o merge_result file1 file2 file3.

Answer

Now for your specific situation it is difficult to say exactly what
strategy that will produce the least amount of problems, but
if there are many changes that create some kind of conflict it
probably is easier to split up and merge smaller parts.

My suggestion would be that
since there are 32 commits between last-working and iphone,
you could for instance start by branching of master and then
merge in the first 16 commits. If that turns out to
be too much trouble, revert and try to merge the 8 first commits.
And so on. In worst case you end up merging each of the 32 commits one by one,
but it would probably be easier than having to handle all the
accumulated conflicts in one single merge operation (and
in that case you are working with a really diverging code base).

Tips:

Draw on paper a version tree and note with arrows what you want to
merge. Cross off things as they are done if you split up the process
in several steps. This will give you a clearer picture of what you want
to achieve, what you have done so far and what is left.

I can really recommend KDiff3, it is an excellent diff/merge tool.

Leave a Comment