Boost logo

Boost :

Subject: Re: [boost] [GitHelp] (Mis-)Understanding merge
From: Edward Diener (eldiener_at_[hidden])
Date: 2014-02-26 09:23:38


On 2/26/2014 3:42 AM, Daniel James wrote:
> On 26 February 2014 08:12, Edward Diener <eldiener_at_[hidden]> wrote:
>>
>> Yes, how did you figure that out ?
>
> I went to https://github.com/boostorg/ and looked at what had been
> recently changed.
>
>>> there are a lot of
>>> differences between master and your merge base, when you merge git
>>> won't take these into account - it only deals with changes made after
>>> the last merge.
>>
>>
>> I thought Git was always smart enough to find the merge base and then do a
>> three way merge between the merge base, the commit being merged to and the
>> commit being merged from.
>
> The three way merge works by looking at the differences between the
> merge base and the two heads. Just considering this file, in 'develop'
> the file is unchanged. In 'master' the file is in the merge base, but
> not in master, so git assumes the file has been removed - remember it
> only looks at those three revisions, and none others. Since there's no
> change on the develop branch, but there is on the master branch, git
> picks the master branch.

Just for the sake of argument:

'develop' has file
'master' does not have file
'merge base' has file

I tell git to merge from 'develop' to 'master'.

Why would not git see that a file which is in 'develop' and is in the
'merge base' but is not in 'master', needs to be added to 'master' as
part of the three way merge ?

>
> Git doesn't normally make mistakes like this when the merge history is
> usually more accurate. Although there are some rare edge cases .

It just seems like incorrect 3-way merging logic to me.

>
>>> This is the tricky thing about transitioning from
>>> subversion to git, they have different models of merging, subversion
>>> is based on tracking individual changesets, git is based on the
>>> history graph. You could try finding the old changesets that haven't
>>> been merged and cherry pick them.
>>
>>
>> This would theoretically mean that I would have to go one by one through
>> every 'develop' change. Ugh ! I thought Git was supposed to save me from
>> having to do all that tedious work.
>
> It typically does, but in this case it doesn't have a decent merge
> history as that's really difficult to extract from our complicated and
> messy subversion merge history. You don't have to go through every
> change, you can look at the differences between master and develop,
> and then use 'git log' and 'git annotate' to find which revision they
> come from. Although that gets a lot harder when there's a mix of
> merged and unmerged changes.
>
>>> But even after doing that there are still a lot of old changes that
>>> need to be merged, mainly in the documentation:
>>>
> [snip]
>>>
>>> You could try to track down all the appropriate changes, but IMO the
>>> best thing to do is to get develop to a release-worthy point and just
>>> overwrite master from develop.
>>
>>
>> I could do that. If I did do I just push 'develop' to 'origin/master' ?
>>
>> I could also, after having done my local merge, just do a 'git diff master
>> develop' and then update master with appropriate changes.
>
> Don't just push develop to origin/master as that will break history.

You are right. I forgot about the history.

> There actually used to be a command for doing this kind of merge, but
> the git developers decided it was a bad idea and removed it. Here's
> the way I emulate it:
>
> # Make sure we're up to date and on the right branch
> git fetch
> git checkout master
>
> # Cheap way to tell git that this is a merge:
> git merge --no-commit -s ours origin/develop
>
> # Copy changes over from develop:
> git diff --binary origin/develop | git apply -R --index
>
> # Commit the "merge"
> git commit
>
> I got that technique from http://stackoverflow.com/a/5211321/2434
>
> Once that's done you should be able to merge normally in the future.

Thanks ! I need to do more reading about 'merge'.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk