Subject: Re: [boost] [GitHelp] (Mis-)Understanding merge
From: Daniel James (dnljms_at_[hidden])
Date: 2014-02-26 03:42:48
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
>> 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.
Git doesn't normally make mistakes like this when the merge history is
usually more accurate. Although there are some rare edge cases .
>> 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:
>> 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.
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 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"
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.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk