Painpoints of maintaining an Open Source Community Fork — merge of a new Release

One of the worst case scenarios for a long running community driven fork is a new release of the forked Project. Especially, if this release is only published by a downloadable package and without access to a VCS on their side.

One of the possible ways to handle this, is doing a diff of the new release, and the release the Fork is currently based on. While this is fastly done, it becomes harder with every change the Fork did. Because it will become harder to handle eventual conflicts of changes. Even more, when single places got changed multiple times to solve different problems.

Another approach is to take the new release as direct base, and to apply all changes again. In a Github Project this can be quite easy, as most changes were PRs before, which are still referencable as git Branches. On the downside, this can become quite a time consuming process.

I will here describe my process for the second approach to verify the current result of the Magento-LTS update from 1.9.2.4 to 1.9.3.0.

command: git branch -a — merged remotes/origin/1.9.2.4
command: git branch -a — merged remotes/origin/1.9.2.4

Here I now have a list off all branches being part of the current 1.9.2.4 branch of the fork. If you wonder how I got all the PRs as branches, I modified my .git/config a bit to use one of Githubs not so known features

[remote “origin”]
 url = git@github.com:OpenMage/magento-lts.git
 fetch = +refs/heads/*:refs/remotes/origin/*
 fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

After taking the original imported version of 1.9.3.0 we now have only this result where we are now starting to check and apply all the PRs again.

For merges it is important to use the same order they occurred in again, else it would include some older changes in an not so easy review-able way. Most of the changes are easiest to include via cherry-pick, which has quite good support in gitk.

To keep this in easy to review chunks, I do every time I reach a “milestone” where we imported a new release , a git merge with the strategy “ours”, which marks all till then as merged, without changing any file in the current branch. This is usefull when you come to patches, which can only partially be merged. Here this is the case for one patch which brings PHP7 support, which is mostly implemented in the new Release, but differs in one part, and misses two other parts. This could also be cherry picked, but as a real merge it is easier to analyse and find the reference later. In the end we then have a commit graph like this:

As you see, I started mostly with cherry picks, and did later more merges. Thats because in the beginning I could let a good set of commits out, as they were already granted to be included in newer releases. Because of the “ours” merges I could then later simply merge bigger parts of history over. The amount of changes does not look like much in this screen, but to review and verify all this I put ~10 hours of work into it. Also this method is only to recommend, when you feel very confident with git and merging.

As result of this I found a set of files, which should not exist anymore inside the fork, as they were originally removed in releases. Also I found two patches, which need a more detailed review now, as its not clear, if the official release fixed them completely.