Establishing a merge point after SVN Conversion
Introduction
When you are ready to merge the develop
branch to master
(or better yet a release branch that's branched off master
), there's a bit of housekeeping to be done the first time after the conversion from svn so that future merges proceed smoothly. We're going to create a merge point between
the develop
and master
branches so that Git knows the last point the two branches were in synch. Once we've done that Git will perform a merge by replaying the commits on develop on top of master, starting from the last known merge: in other words Git will perform the tricky stuff of figuring out what to merge for us.
You need to do this procedure before you start routine maintenance on your library as described in Getting Started with Modular Boost Library Maintenance.
Preparation
Peter Dimov suggested the following in response to problems encountered by others:
To avoid unpleasant surprises, what I did was ensure that develop
and master
are identical before doing the first merge.
cd modular-boost/libs/<my-library> git checkout develop git diff --name-status master..develop
gave me an overview on where the two branches differ; the same command without --name-status
goes into more detail. git checkout develop
is only needed if develop
hasn't already been done.
(In principle, we all have kept our trunk and release branches in sync, so the above ought to have yielded nothing. In practice, however, all libraries likely had differences because (1) we sometimes forget to merge, (2) sometimes other people changed trunk and didn't merge and we didn't know, and (3) Stephen Kelly's Boost-wide changes were only on trunk.)
I then proceeded to identify the commits causing each change. I don't remember how exactly I did that, probably by using git log
on the modified files and by looking at the commit history on !Github.
After that, I applied each missing commit using git cherry-pick <sha>
. That is, if a commit on develop
was not present on master
, I applied it to master
with git cherry-pick
; and if a commit on master
was missing on develop
(things like that do happen occasionally), I applied it on develop
. I tried to do this in chronological order, which minimizes conflicts.
What made it more interesting for me is that I sometimes didn't want a commit to be part of the initial state, so I reverted it using git revert
instead of applying it to the other branch using git cherry-pick
; but this should probably not be needed most of the time.
The final result of all that cherry picking should be a state in which git diff master..develop
doesn't report any differences. Once there, things are a simple merge away, as described below.
Step-by-step
Remember to do a git push
if the preparation left any non-pushed commits.
- Navigate to the history for your library on GitHub, starting with branch master. For example the Config library can be seen here.
- Look down through the commit history and make a note of the last merge in svn land. In our example, it was on October 25th 2013.
- Use the dropdown box to change the history to point to the develop branch. Config library can be seen here.
- Find the last commit before the date noted above. Click on the commit message for that commit to go to the actual diff for that change, in our example here. The SHA1 for that commit is shown below and to the right of the commit message, in this case it's
67f6b934f161dc5da2039004986a14d9217afae4
. Copy that SHA1 to your clipboard.
Create a merge to that specific commit. Begin by changing your library to the master branch:
git checkout master
Now create a merge to the specific commit above; since we don't really want to actually change the master branch we'll use the -s ours
option to avoid any conflicts:
git merge --no-ff --no-commit -s ours 67f6b934f161dc5da2039004986a14d9217afae4
Caution: Check any changed files carefully, particularly if you thought master
was up-to-date. You can use git status
and git diff master..develop
to check for modifications. In the example case there are none. If all is as expected, make the commit and push to GitHub:
git commit -am "Create first merge point for Git" git push
Then navigate to your libraries history again, and check that the merge shows up, our config example is here. You're now ready for "routine" merges to proceed as per Git Flow (or whatever other strategy you wish to use).