-
Notifications
You must be signed in to change notification settings - Fork 148
Developers guide
This guide mainly applies to developers who have write access to the https://github.com/NOAA-GFDL repositories. These developers should follow specific conventions or policies regarding branching and merging. Even if you don't have write access to the NOAA-GFDL/* repositories the material on this page may be useful for understanding and organising your development process.
Once you have downloaded all repositories with:
$ git clone --recursive [email protected]:NOAA-GFDL/MOM6-examples.git MOM6-examples
you will probably want to edit code in the sub-modules. Since sub-modules have specific versions checked out, you will need to checkout a branch instead. Type:
(cd src/MOM6; git checkout dev/master)
(cd src/SIS2; git checkout dev/master)
Under most circumstances, a git status
in MOM6-examples will reveal that nothing appears to have changed. That is because the HEAD of dev/master on all repositories are in sync and consistent with those recorded in MOM6-examples. If you ever issue a git submodule update
then the submodule(s) will be reset to the appropriate detached state.
There are many combinations of operations a developer might have to enact which in combination can be made more succinct than follows. Here, we have atomized some operations into self-contained steps from which a developer can build more sophisticated operations.
git status
is your friend. It tells you everything you should know. Because of the use of sub-modules git status
might show statuses that are not covered in most git
tutorials and documentation.
After a recent clone of MOM6-examples a git status
within the MOM6-examples directory will reveal
~/MOM6-examples$ git status
# On branch dev/master
nothing to commit (working directory clean)
which means everything is OK.
git fetch
will check with the origin
, in this case GitHub, and find out what has changed on the server since you last synced. git fetch
does not change your currently checked-out files. It will do no harm.
If you see no messages after git fetch
then you were already up to date. Often you will something like this:
~/MOM6-examples$ git fetch
Enter passphrase for key '/home/aja/.ssh/NOAA_rsa':
remote: Counting objects: 206, done.
remote: Compressing objects: 100% (121/121), done.
remote: Total 206 (delta 101), reused 116 (delta 83)
Receiving objects: 100% (206/206), 188.26 KiB | 0 bytes/s, done.
Resolving deltas: 100% (101/101), done.
From github.com:NOAA-GFDL/MOM6
9e328e9..50fe6e4 dev/master -> origin/dev/master
which means there are new commits on the server. A subsequent git status
will show:
On branch dev/master
Your branch is behind 'origin/dev/master' by 20 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working directory clean
Wow - someone has been busy!
After a git fetch
, when git status
shows:
# On branch dev/master
# Your branch is behind 'origin/dev/master' by 1 commit, and can be fast-forward
then you can "pull" in changes from GitHub without fear of [code] conflicts with your current working directory. Issue git pull
, for example:
~/MOM6-examples$ git pull
Updating e7b8b46..fa7e377
Fast-forward
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
When you are making a set of related code or configuration changes it is best practice to do so on a specific branch. Our branch naming policy recommends branch names of the form user/abc/description
for personal updates or `dev/description' for updates you are working on collectively.
To create your new branch:
git checkout dev/master
git branch user/abc/my_little_idea
git checkout user/abc/my_little_idea
where abc
are your user initials (we typically use initials for legacy reason but you could use your GitHub account name if you prefer) and my_little_idea
is a descriptive branch name. Notice that the first step was to checkout dev/master
. This ensures the branch originates from dev/master
which is a generally good idea although there are occasions where you might branch from another branch.
Without the second checkout, the current working directory would still show dev/master
. The git branch
creates the branch but does not move you on to it.
At a later stage, if you want to share your branch, you will need to push your branch upstream to GutHub with
git push origin user/abc/my_little_idea
Thereafter, when you are on your branch, a simple git push
will push to the correct remote branch.
We use branches for code that either needs to be evaluated via a pull request or should be kept aside. With the three-repository setup there is a question of where a branch (and associated pull request) should be made.
- If your explicit changes are only in
src/MOM6/
then make the branch withinsrc/MOM6/
and the pull request for MOM6.- if there are implied changes (e.g. changes answers or parameter documentation in MOM6-examples) then a branch in MOM6-examples is also needed unless are not submitted those answer changes - we will see those changes when we evaluate the MOM6 pull request.
- If your explicit changes are only in
src/SIS2/
then make the branch withinsrc/SIS2/
and the pull request for SIS2. - If your explicit changes are only in
MOM6-examples/
(e.g. intools/
orocean_only/
) then make the branch withinMOM6-examples/
and the pull request for MOM6-examples. - If you have explicit change in both
MOM6-examples/
andsrc/MOM6
(or other sub-module) then we need the same branch made in both. Only one pull request for MOM6 is necessary (a corresponding pull request for MOM6-examples would be OK but redundant).
The section "A core-developer working on GitHub" in the MOM6 repository policies document outlines the procedure for testing and commit in the context of one repository. This page illustrates how to make coordinate commits between two repositories, namely MOM6-examples and the sub-module MOM6. The same applies to the sub-module SIS2.
The usual workflow for code development is
- Develop and test code
This typically involves editing source code, compiling with all compilers, running tests with all executables and checking answers.
Rules for commiting to dev/master are in section Policies for dev/master but the highlights are:
-
each commit compiles without errors using all sanctioned compilers.
-
regression tests pass with all the sanctioned compilers.
-
commits are logged following the commit logging guidelines.
-
Commit code changes to MOM6
Commit to the MOM6 first (or the relevant sub-module) so that the new commit hash of MOM6 can be recorded with any associated changes in MOM6-examples.
cd src/MOM6
git add file1 [file2] ...
git commit
git push
Should there be any updates on GitHub before the git push
then the testing procedure in 1. should be revisited. The git push
is not immediately necessary but it will be required before a git push
of MOM6-examples so you might as well do "push MOM6" now. Besides, the longer you leave it, the more likely you'll have to update and merge.
- Add new version of MOM6 and new answers in MOM6-examples
If you cd
up to MOM6-examples, a git status
will now show that MOM6 has "(new commits)", e.g.:
> git status # On branch dev/master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: ice_ocean_SIS/OM4_025/timestats.gnu # modified: ice_ocean_SIS/OM4_025/timestats.intel # modified: ice_ocean_SIS/OM4_025/timestats.pgi # modified: src/MOM6 (new commits)
In this example, the new code we just pushed to MOM6 corrected a bug and changed the answers in OM4_025. The new answers and new version of MOM6 should be committed together:
git add -u ice_ocean_SIS/OM4_025/timestats.*
git add src/MOM6
git commit
git push
In the instance where the answers did not change then a git status
will show you that only src/MOM6
(has new commits), i.e.:
> git status # On branch dev/master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: src/MOM6 (new commits)
Simply adding and committing src/MOM6
will mean MOM6-examples is using the latest version of MOM6:
git add src/MOM6
git commit
git push
After following the commit procedure for MOM6 and MOM6-examples a git fetch
followed by a git status
might show
~/MOM6-examples/src/MOM6$ git status # On branch dev/master # Your branch is ahead of 'origin/dev/master' by 1 commit.
If this is the case, then do a git push
:
% git push Counting objects: 5, done. Delta compression using up to 64 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 432 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) To [email protected]:alistair.adcroft/mom6-workspace.git ae8b847..6a38fe6 master -> master
Now everyone else can see the commits you have just pushed, either on GitHub or by using git status and fetch.
After a git fetch
, when git status
shows
~/MOM6-examples$ git status
# On branch dev/master
# Your branch and 'origin/dev/master' have diverged,
# and have 3 and 2 different commit each, respectively.
then you have 3 commits to push but there are already 2 to "pull" which will stop you from being able to "push".
There are two ways forward. The first method results in merge-loops in the history. The second method often produces a linear-history (albeit with some commits in non-chronological order!).
If you issue git pull
this will merge your 3 commits with the servers 2 commits and create a new commit. If there are no conflicts you will be prompted with a commit message
Merge branch 'dev/master' of github.com:NOAA-GFDL/MOM6-examples into dev/master
which you should leave unchanged and save. You can optionally add annotations for the merge (be sure to leave the second line blank).
If there are conflicts during the merge, you should resolve the conflicts and create commits following the commit procedure for MOM6 and MOM6-examples.
This method rewinds your own commits, advances through the commits from GitHub and then replays your commits after those from GitHub. Issue git pull --rebase
, for example:
~/MOM6-examples$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Added new eddy parameterization
Applying: Fix problem with gnu compiler
If a conflict occurs you will see
~/MOM6-examples$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Creating conflict
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Failed to merge in the changes.
Patch failed at 0001 Creating conflict
When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To check out the original branch and stop rebasing run "git rebase --abort".
You will need to either resolve the conflicts or "abort" and try a merge as shown above.
If a git status
shows that MOM6 (or another sub-module) has "modified content" or "untracked content" then it means you have local edits in that directory, e.g.
% git status # On branch dev/master # Changes not staged for commit: # (use "git add/rm <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 (modified content, untracked content) # no changes added to commit (use "git add" and/or "git commit -a")
In this instance, you should cd src/MOM6
and follow the the commit procedure for MOM6 and MOM6-examples.
There are two cases where a git status
in MOM6-examples will show you that src/MOM6
has "new commits" like this:
> git status # On branch dev/master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: src/MOM6 (new commits)
Either you have added commits to MOM6 or there are new commits that MOM6-examples expects MOM6 to point too. Technically, the message means that the MOM6 commit registered in MOM6-examples is not the same as is currently checkout in the src/MOM6/
directory.
1) If you added commits to MOM6, then simply "add, commit and push" src/MOM6
as if it were a regular file. This will mean that new clones of MOM6-examples will use the newer version of MOM6:
git add src/MOM6
git commit
git push
It is important to push MOM6 first, otherwise a new clone of MOM6-examples will point to a non-existent commit of MOM6.
2) If the message appeared as a result of a git pull
in MOM6-examples/
then MOM6 needs to be updated. If you are in a developer mode you could just do
cd src/MOM6/
git pull
or as an end-user, in the MOM6-examples/
directory do:
git submodule update src/MOM6
which will fetch and checkout the correct version of MOM6.
Here are a few git commands.
- gitk fname
To pop various windows with history, comparisons, etc.
- git log
For logs of the changes made to the branch
- git diff MOM6
to see what files differ.
- git submodule update src/SIS2
An example of updating to a new submodule that has evolved outside of our main development path. Updating all submodules is necessary to ensure that local changes are compatible across all the submodules.
- From MOM6-examples/
git add src/MOM6
git commit src/MOM6
in order to update the submodule MOM6 that is held inside MOM6-examples.
Answers should not change, to the bit, when changing processor counts or layouts. Within the MOM6 code, there is a tool available to help resolve problems when answers do change (processor non-reproducibility). Namely, set the run-time flag DEBUG=True, in which case MOM6 will write out a series of checksums to std_err, along with informative messages about which fields are being checked. This output is independent of processor count, provided the solutions themselves are the same. So to debug a processor non-reproducibility issue, do two short runs with different PE counts (say, 32 and 31), and look for the first point in the code where the output differs. Grep through the code to see where the first differing call can be found. This method thus helps to isolate where in the code the processor non-reproducibility issue occurs.
This method tends to generate a lot of output to std_err, so very short runs are advised. Also, unless you think the problem is in the barotropic solver, it is a good idea to set DEBUG_BT=False to reduce the number of messages.
There is more than one kind of chunk that will show up in the diffs. We are looking for things like:
< u-point: c= 2363061 sw= 2357351 se= 2341484 nw= 2357077 ne= 2341213
Before steps fluxes%taux
< v-point: c= 2359974 sw= 2251831 se= 2237217 nw= 2353558 ne= 2338274
Before steps fluxes%tauy
< h-point: c= 2811287 Before steps fluxes%ustar
---
> u-point: c= 2363061 sw= 2327151 se= 2341484 nw= 2326875 ne= 2341213
Before steps fluxes%taux
> v-point: c= 2359974 sw= 2325100 se= 2310009 nw= 2353558 ne= 2338274
Before steps fluxes%tauy
> h-point: c= 2811355 Before steps fluxes%ustar
Here, taux and tauy have halo updates while ustar does not.