Skip to content

Updating Mono to a Newer Upstream Version

Hasso edited this page May 20, 2022 · 3 revisions

To update our custom mono to a newer upstream version, you basically need to do the following steps:

  • Fetch upstream mono
  • Create a feature branch
  • Merge upstream branch into our develop branch
  • Create a new version number to make our custom mono unique
  • Build and test locally
  • Upload for review

More in detail this involves the following commands in a git-bash (on Windows) or terminal window:

Simple merge

Fetch upstream mono

cd fwrepo/mono
git remote add upstream https://github.com/mono/mono.git
git fetch upstream
git checkout develop
git pull origin

Create a feature branch

git start task develop mono-3.2

Merge upstream tag into our develop branch

You can see the available tags with

git tag -l

Then merge the desired tag into our develop branch.

git merge mono-3.2.1

You can probably make your life easier by using the 'recursive' merge strategy and favour the changes from the upstream branch:

git merge -s recursive -X theirs mono-3.2.1

and resolve any conflicts. Review all changes that the merge introduced, especially the places where both ours and theirs introduced new code. Then commit the merge locally. Since it's a merge from upstream we ignore any whitespace issues.

git commit --no-verify --message "Merge upstream tag 'mono-3.2.1' into develop"

Verify that the commit has a change-id appended. If not simply amend the commit and it will be added.

Create a new version number to make our custom mono unique

We want our custom mono that have a unique version number so that MonoDevelop can distinguish our custom mono from the stock mono. Edit the file configure.in. Towards the top there's a line similar to

AC_INIT(mono, [3.2.1],

that contains the version number (the exact syntax depends on the mono version, or rather the autotools version that is used). Change that to

AC_INIT(mono, [3.2.1.1],

and commit the change:

git add configure.in
git commit -m "Increment our mono version number"

Build and test locally

git clean -dxf
./autogen.sh --prefix=/usr/local
make
sudo make install
sudo cp -f /usr/local/bin/mono{,-real}
sudo cp -f /usr/local/bin/mono-fw /usr/local/bin/mono

If you get any compilation errors because the merge introduced errors, it's easiest to move the increment version number commit out of the way (doing an interactive rebase to amend the merge commit would also be possible but is more complicated because it involves a merge conflict):

git checkout -b tmp
git checkout feature/mono-3.2.1
git reset --hard HEAD^

You're now on the merge commit. Make the necessary changes and amend the merge commit. Then cherry-pick the increment version number commit and try the build again.

git commit
git cherry-pick tmp
git branch -D tmp
make

If everything compiled and installed successfully you should start FW and test that everything works.

Upload for review

git review

Alternative: Cherry-pick our changes

Especially when moving to a new major mono version that is released on a new branch it might be easier to start with the new branch and cherry-pick our changes.

You start by fetching the upstream repo (see above).

Create a feature branch

Create a feature branch based on the upstream tag 'mono-3.2.1' and merge our develop branch into this branch.

git checkout -b feature/mono-3.2.1 mono-3.2.1
git branch --set-upstream-to=develop
git merge -s ours -m "Use upstream tag 'mono-3.2.1' as new base for develop" develop

Cherry-pick unique changes

Get the list of changes that we will need to apply. These are all changes that are on develop but not on the upstream branch. As upstream branch (upstream/mono-2-10) the branch should be specified that last served as base for develop.

git log --reverse --oneline develop ^upstream/mono-2-10 | cut -d' ' -f1 > /tmp/commits

Then cherry-pick the changes:

cat /tmp/commits | while read LINE; do echo "Cherry-picking $LINE" && git cherry-pick -x $LINE || break ; done

It is very likely that cherry-picks fail. If it fails because of conflicting changes you should resolve the conflicts by running

git mergetool

and then committing the change with

git commit

But it's also possible that the cherry-pick fails because the change has been applied in the upstream branch. Either way you should remove the sha's of the commits up to the failing one from /tmp/commits and run the cherry-picking command from above again until all changes are either cherry-picked or determined obsolete.

Be careful when resolving conflicts that only introduce whitespace differences. The upstream change should have priority even if the formatting is off.

The rest of the process is the same as above. Start with creating a new version number to make our custom mono unique (see above).

Clone this wiki locally