Skip to content
Alistair Adcroft edited this page Mar 22, 2022 · 3 revisions

How to Contribute

MOM6 is an open source project. This means that it relies on a global community of users and developers to maintain and improve the model. It is licenced under the LGPLv3. If you use MOM6 and find anything that needs fixing, or make changes that you think could be useful to others, please contribute the changes back to the main repository.

MOM6 uses Github to manage collaboration. If you are not familiar with GitHub, don't worry, there's lots of excellent documentation out there, for example these guides. In particular contributing to an open source project is explained here. Please read through this before continuing, it will make it a lot easier to understand the terminology.

How to update this wiki

The wiki attached to a public repository can be edited by anyone. Just navigate to the page you wish to edit and click on the 'edit' button on the top right hand side.

Understanding the repository layout

This project is arranged into several repositories that are linked together using git submodules. The MOM6-examples repository is the parent, with other repositories embedded within it. The parent repository also contains experiment configurations and regression tests.

MOM6 repository relationships

When you clone MOM6-examples, the matching versions of MOM6 and SIS2 are known by git and can be downloaded also.

Why separate repositories

When the repository only had MOM6-related code and configurations everything worked hunky-dory. But since the configurations and regression tests for SIS2 have appeared we had a version consistency problem between SIS2 source and the tests. Further, we know there will be more break up of components coming down the line so we've opted for a solution that will allow us to add more components in the future.

Advantages:

  • Versioning of configurations, answers and model source.
  • Commits and branches affecting just source code are limited to the source code repositories.
  • Commits affecting just configurations are limited to the MOM6-examples repository.
  • Deployment of a specific set of configurations is ensured to have a specific version of source codes.
  • Leads to smaller individual repositories so you do not have to download everything at once.
  • Allows different groups to maintain separate configurations pointing to the same source codes.

Disadvantages:

  • It seems more complicated than a single mega-repository ... until you get used to it.

The state of submodules

Assuming that you cloned MOM6-examples with

$ git clone --recursive https://github.com/NOAA-GFDL/MOM6-examples.git MOM6-examples

then the sub-modules under MOM-examples will be in detached states pointing to a specific version for each sub-module. This is important and powerful; these particular versions of MOM6 and SIS2 are what were used to obtain the regression tests in MOM6-examples. It means whenever an end-user clones the repository (or updates) they automatically get the correct version of each sub-module.

If you ever issue git status in MOM6-examples/ and see

$ git status
On branch dev/master
Your branch is up-to-date with 'origin/dev/master'.
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
  (commit or discard the untracked or modified content in submodules)

	modified:   src/MOM6 (new commits)

it might mean the submodule src/MOM6 needs to be updated with git submodule update src/MOM6.

Setting up your working directory

In order to push updates to GitHub, you will first need a "GitHub fork" of the particular repository. To reduce the burden on you of keeping everything in sync, only make forks of repositories that you plan to edit. You will then point the URL in your working directory to your fork.

See the following sections about creating a fork of one or more of the NOAA-GFDL/* repositories, depending on where it is that you want to make changes. Here's some useful GitHub documentation to get started: fork-a-repo.

After you have made a fork, or if you already have push-access to a repository, then you will need to set the URL appropriately for each repository where you will be making changes and pushing to a remote (e.g. GitHub).

For example, if you have a fork of MOM6-examples then

cd MOM6-examples/
git remote set-url origin [email protected]:your_GitHub_account/MOM6-examples.git

where you must replace "your_GitHub_account" with your GitHub account name. Here, "origin" is the default name for a remote. You can have multiple remotes and/or use different names but this is typically not needed.

Similarly, if you have a fork of MOM6 source code then

cd src/MOM6/
git remote set-url origin [email protected]:your_GitHub_account/MOM6.git

accordingly.

Do the above for each repository/fork that you forked or have push-access to.

About GitHub forks

Since forks are a key mechanism for contributing to MOM6, we should explain a few things.

  • A GitHub "fork" makes a complete copy of a repository at an instant in time; the entire history up to the moment of forking is copied.
  • The fork is under the control of the fork creator (you).
  • The fork creator can use that repository to store their own branches.
    • Those branches can be shared back to the original repository or to anyone else.
  • Forks can be short-lived or permanent.
  • Forks can be kept in sync with the parent repository (e.g. https://help.github.com/articles/fork-a-repo/).
    • Syncing is manual, not automatic.
  • You can treat a fork like a branch. It is really much much more than a branch but you can treat your fork as a branch.
  • You can think of a fork as a "multi-branch", where you create your own branch off of every existing branch. (However, at this point, it is best not to think too deeply.).

Here are some typical setups based on forking:

  • No GitHub forks
    • Most frequent for end-users who just want a particular (fixed) version of everything.
    • You can keep local modifications (using git) but sharing your modifications is inconvenient.
  • Fork of just MOM6-examples
    • Useful for storing and sharing your own experiment configurations and analysis tools.
    • The sub-modules for source code automatically point back to the original repositories.
  • Fork of just MOM6
    • For storing and sharing your own code modifications to the ocean model.
  • Fork of both MOM6-examples and MOM6
    • For storing and sharing your own code modifications to the ocean model and your variants on experiments.
    • Most likely setup if you will be doing any ocean-model development (code or experiment).
  • Fork of both MOM6-examples and SIS2
    • For storing and sharing your own code modifications to the sea-ice model and your variants on experiments.
    • Most likely setup if you will be doing sea-ice model development (code or experiment).
  • Forks of all the above
    • You want to do it all - go for it!

Gotcha with forks

  • The most common problem with forks is users immediately update an existing branch (e.g. master, dev/master, or dev/gfdl) which makes it hard to later sync with the parent repository when the corresponding branch has diverged. Solution:
    • Create your own new branches when committing your own work into your fork.

Creating and cloning a fork

Let's assume that you want to make changes to REPO-X (which could be one of MOM6, SIS2, FMS, MOM6-examples, etc.).

  1. Go to the page for that repo, e.g. MOM6-examples on GitHub, MOM6, SIS2, etc.
  2. Click on "Fork" (near the top-right) of that page.
  3. GitHub will create a fork of this repository and a page for it. It will have a URL of the form https://github.com/<your_github_account_here>/REPO-X. You should be automatically taken to this page. On the right hand side of the page, you will see either "HTTPS clone URL" or "SSH clone URL". Select "SSH" and then copy the URL.
  4. If REPO-X is MOM6-examples then use the URL from above to clone your forked repository with:
$ git clone --recursive [email protected]:your_GitHub_account/MOM6-examples.git MOM6-examples

The above command will give you your own copy of MOM6-examples but with all submodules (such as MOM6, SIS2, FMS etc) pointing to the NOAA-GFDL repositories. To see this:

$ cd MOM6-examples
$ git remote -v
origin    [email protected]:<your_github_account_here>/MOM6-examples.git (fetch)
origin    [email protected]:<your_github_account_here>/MOM6-examples.git (push)
$ cd src/MOM6
$ ls
config_src/  LICENSE.md  pkg/  README.md  src/
$ git remote -v
origin    https://github.com/NOAA-GFDL/MOM6.git (fetch)
origin    https://github.com/NOAA-GFDL/MOM6.git (push)
  1. If REPO-X is something other than MOM6-examples then you'll need to clone MOM6-examples first (either your fork or the original) and then set up the submodule remote url to point to REPO-X:
cd src/MOM6
git remote set-url origin [email protected]:your_GitHub_account/MOM6.git

Do not edit .gitmodules because that will appear as a change in the repository and subsequent commits could not be accepted to the original MOM6-examples.

This step can be repeated for one or more of the submodule repositories.

Making code changes

Now that you have a fork of the repositories you can go ahead and make changes. How you organize development is up to you.

Always work on a branch - never commit changes to the master, dev/master, or dev/gfdl branches or an existing unrelated branch.

It is good practice to use a new branch for each individual project.

Read the Developers Guide and Branching and merging to get some ideas.

Syncing a fork with the NOAA-GFDL repositories

Sync using with multiple remotes method

The following instructions assume that you are working from a fork of the NOAA-GFDL repositories AND all your own commits are on other branches (not on master, dev/master or dev/gfdl). For this we'll assume you have forked/cloned the MOM6 (source code) repository. Imagine that some changes are made to the main (upstream) NOAA-GFDL repository that you would like to incorporate into your fork. You can do this, for example, with MOM-examples:

  1. Sync your dev/master with the parent dev/master
git remote add upstream [email protected]:NOAA-GFDL/MOM6.git
git checkout dev/master
git pull upstream dev/master

You could replace dev/master with dev/gfdl if you are keeping up to date with the developer branch.

  1. If you want dev/master on your fork (on GitHub) to be up to date then do
git push

Note that upstream is a label of your choice. You could equally call it GFDL or fred, e.g. git remote add GFDL [email protected]:NOAA-GFDL/MOM6.git. You only need to add a remote once per working directory.

Syncing using the single remote method

Some users find multiple remotes confusing. As an alternative, you can forego adding a remote. Let's say you have commits on your own branch 'mybranch' and you've heard that the master repository has new commits that you really really need to use. We will blend, sync and merge in two steps.

Sync your dev/master with the parent dev/master:

git checkout dev/master
git pull https://github.com/NOAA-GFDL/MOM6.git dev/master
git push

This syncs dev/master on your fork of MOM6 with the NOAA-GFDL repository. This is equivalent to git pull upstream dev/master in the multiple remote method above. Again, you can replace dev/master with dev/gfdl if you wish to stay up to date with the GFDL developers.

Pulling the latest code into your branch

If you have synced dev/master (or dev/gfdl) using one of the above methods you can now merge the new commits on dev/master into your branch with:

git checkout mybranch
git merge dev/master

If you have any conflicts then you will need to resolve them by editing the affected files, git add those files and then git commit to finalize the merge. Hopefully, if you sync frequently enough, conflicts will be few and far between.

If you are happy with the merge then you can

git push

to push your branch up to GitHub for safe keeping.

You can mimic the single remote method and pull directly onto your branch without syncing dev/master or dev/gfdl by doing this:

git checkout mybranch
git pull https://github.com/NOAA-GFDL/MOM6.git dev/master

which will fetch and merge commits in one step.

Contributing changes to the NOAA-GFDL repository

Once you have code ready to submit to the core developers to merge onto dev/gfdl there are three things that need to be done:

  1. Make sure your fork/branch has all the latest changes, see Syncing a fork with the NOAA-GFDL repositories.
  2. Run tests and make sure they pass, described below. We will not consider code that does not compile or unnecessarily changes to existing configurations/solutions.
  3. Create a pull request, described below.

Note that most contributions are to be made to dev/gfdl so that dev/master and master evolve more slowly.

Testing

To run all the tests:

This section is not correct/uptodate - nosetests does not exist

cd MOM-examples
nosetests

Creating a pull request

A pull request is a request to the upstream (NOAA-GFDL) github user/organisation to merge your changes into one of their repositories. The project maintainers will review your pull request code, run some tests and then merge the changes.

  1. Navigate to your branch (either via the branch tab or the pull down menu in the commits tab).

  2. Click the green icon, image alt text, near the top left, with a mouse-over that reads "Compare, review, create pull request".

  3. The next page shows you the change relative to where you start your branch on dev/gfdl.

  4. Click image alt text.

  5. Fill out a descriptive but succinct title

  6. In the comment box, please summarize all the commits involved and explain or justify the code changes.

  7. Then click image alt text and you are done.

Summary

The process described above of forking a repository, doing development, running tests, creating a pull request, and contributing code is very powerful. It allows large numbers of people (possibly from all of the world) to work together to build software.