Change Management

This documentation assumes the reader is already familiar with using git for managing file revisions.

Getting started

GROMACS development happens on gitlab at https://gitlab.com/gromacs/gromacs. Create a user account at https://gitlab.com/users/sign_in#register-pane or use an existing account at gitlab.com. For more information on how to use gitlab have a look at their extensive user documentation at https://docs.gitlab.com/ee/user/index.html.

If you do not already have a GROMACS repository set up, use git clone git@gitlab.com:gromacs/gromacs.git to obtain the current GROMACS repository from gitlab. Otherwise use git remote add gitlab git@gitlab.com:gromacs/gromacs.git.

Using gitlab, new code enters GROMACS by merging git development branches into the main branch.

To automatically detect issues in new code, it is tested within continuous integration (CI) with a large combination of settings. See Automatic source code formatting for help meeting and testing the style guidelines.

More information about change management is available on the gitlab wiki.

Setting up login credentials with gitlab

You will need a public ssh key:

ssh-keygen -t rsa -C "your.email@address.com"
cat ~/.ssh/id_rsa.pub

Copy the output of the last command, go to gitlab.com, click your user symbol in the right top corner of the panel to the left, and select Preferences.

Choose SSH keys in the menu on the left and paste your key in the text field.

Creating issues

The meta-level code design and discussions is organised in issues and visible at https://gitlab.com/gromacs/gromacs/-/issues. Please check if your issue, or a similar issue, already exists before creating a new one. See Guidelines for creating meaningful issue reports for more information.

Note that all Redmine issues have been transferred to gitlab retaining the original issue number from Redmine. However, comments and discussion are now represented by gitlab user @acmnpv - the original authors are found inline at the bottom of the comments.

Uploading code for review - creating a merge request

Issues are addressed with new code via “merge requests” (MR). Find the current MRs at https://gitlab.com/gromacs/gromacs/-/merge_requests. There are two ways of creating a merge request - either via the gitlab graphical user interface or via the command line.

To use the GUI, find the relevant issue or open a new one, then find the “create merge request” button to create a merge request related to that issue in gitlab. We recommend using the “Mark as draft” option until you are completely satisfied with the code yourself and all tests are passed.

Select milestone and assignees to make tracking of the progress easier. Keep the requirements for merging as they are set by default.

You can also use git push on the command line directly and create a merge request following the link that is output on the command line.

Your repository should be in sync with the GROMACS repository. To ensure this, use git fetch to obtain the newest branches, then merge the main branch into your branch with git merge main while on your branch.

You can create MRs without having a Developer role account, but in order to trigger MR test pipelines you must be a project member with (at least) the Developer role. Project membership can be requested via the Gitlab web interface. The Developer role is granted based on acquaintance and/or knowledge about intentions to contribute to the project.

As mentioned in Code Review, the Developer role is different to membership in the GMX Developers approval group. Approving and merging changes require higher privileges than what is required for counting as a Developer.

Naming branches

Good names: documentation_UpdateDevelopersDocsTOGitLab, nbnxm_MakeNbnxmGPUIntoClass, pme_FEPPMEGPU, 1234-ml-fix-issue.

Bad names: branch1234, mybranch, test, etc

N.b., prefixing the branch with an issue number (such as 1234-ml-fix-issue above), followed by a hyphen, automatically links the branch to the issue. Milestones and labels are copied and the issue will be closed when the MR is merged, see the Gitlab documentation.

Documentation

Contributors and reviewers frequently overlook the effects of changes on the built documentation. Contributors and reviewers should note that the build artifacts from the automated test jobs are available for download through the GitLab CI web interface (webpage:build job artifacts). For earlier review or alternative preferences, consider building and sharing a Docker image containing the built documentation. See docs/docs.dockerfile in the source tree.

Labels

Labels help developers by allowing additional filtering of issues and merge requests.

The GROMACS project defines many labels.

To minimize duplicated documentation, refer to the GitLab project Labels web interface for label descriptions.

When creating a new label, please provide a short description so that people can understand what the label is intended to convey, and when they should apply it to their own issues or merge requests.

In general:

  • Ongoing categorizations to help specify the GROMACS component or development area use the #7F8C8D color.

  • Specific features or subproject areas targeting an upcoming release use the #8E44AD background color.

  • Status labels use #428BCA. Note that Status labels are also used for Issues, and are used according to status label guidelines

Code Review

Reviewing someone else’s uploaded code

The reviewing workflow is the following:

  1. https://gitlab.com/gromacs/gromacs/-/merge_requests shows all open changes

  2. A change needs two approvals to go in, of which one approval has to come from a member of either GMX Core or GMX Developers approval groups.

  3. Usually a patch goes through several cycles of voting, commenting and updating before it becomes merged, with votes from the developers indicating if they think that the change has progressed enough to be included.

  4. A change is submitted for merging and post-submit testing by clicking “Merge”.

Do not review your own code. The point of the policy is that at least two non-authors have approved, and that the issues are resolved in the opinion of the person who applies an approval before a merge. If you have uploaded a minor fix to someone else’s patch, use your judgement in whether to approve yourself.

Membership in the GMX Developers and GMX Core approval groups are based on long-term engagement in the project and does not correlate directly with a Developer role account.

Guide for reviewing

  • First and foremost, check correctness to the extent possible;

  • As portability and performance are the next most important things, do check for potential issues;

  • Check adherence to the coding standards;

  • We should try to ensure that commits that implement bugfixes (as well as important features and tasks) get an issue tracker entry created and linked. The linking is done automatically through special syntax

  • If the commit is a bugfix:

    • if present in the issue tracker, it has to contain a valid reference to the issue;

    • if it is a major bug, there has to be a bug report filed in the issue tracker  (with urgent or immediate priority) and referenced appropriately.

  • If the commit is a feature/task implementation:

    • if it is present in the issue tracker it has to contain a valid reference to the issue;

    • If no current issue is currently present and the change would benefit of one for future explanation on why it was added, a new issue should be created.

Update the Status label

Closing Merge Requests

A merge request that has had no updates for six months or more can acquire the status label “Status::Stale” If the proposed change still seems important and the next steps are unclear, contributors with stale issues are encouraged…

  • to contact existing reviewers (or potential reviewers),

  • to participate in the developer discussion forum, and

  • to attend the biweekly teleconference to coordinate.

If the future of the merge request has not become clear within a month (especially if it has become stale multiple times), developers may close the merge request with a label indicating why it has entered a “closed” state. “Status::MR::…” labels do not indicate that the merge request has been reviewed unless it is explicitly rejected.

See Issue 4126 for background discussion.

See also

General issue workflow for use of Status labels in Issue management.

More git tips

Q: Are there some other useful git configuration settings?

A: If you need to work with branches that have large differences (in particular, if a lot of files have moved), it can be helpful to set

git config diff.renamelimit 5000

to increase the limit of inexact renames that Git considers. The default value is not sufficient, for example, if you need to do a merge or a cherry-pick from a release branch to main.

Q: How do I use git rebase (also git pull --rebase)?

A: Assume you have a local feature branch checked out, that it is based on main, and main has gotten new commits. You can then do

git rebase main

to move your commits on top of the newest commit in main. This will save each commit you did, and replay them on top of main. If any commit results in conflicts, you need to resolve them as usual (including marking them as resolved using git add), and then use

git rebase --continue

Note that unless you are sure about what you are doing, you should not use any commands that create or delete commits (git commit, or git checkout or git reset without paths). git rebase --continue will create the commit after conflicts have been resolved, with the original commit message (you will get a chance to edit it).

If you realize that the conflicts are too messy to resolve (or that you made a mistake that resulted in messy conflicts), you can use

git rebase --abort

to get back into the state you started from (before the original git rebase main invocation). If the rebase is already finished, and you realize you made a mistake, you can get back where you started with (use git log <my-branch>@{1} and/or git reflog <my-branch> to check that this is where you want to go)

git reset --hard <my-branch>@{1}

Q: How do I prepare several commits at once?

A: Assume I have multiple independent changes in my working tree. Use

git add [-p] [file]

to add one independent change at a time to the index. Use

git diff --cached

to check that the index contains the changes you want. You can then commit this one change:

git commit

 If you want to test that the change works, use to temporarily store away other changes, and do your testing.

git stash

If the testing fails, you can amend your existing commit with git commit --amend. After you are satisfied, you can push the commit for review. If you stashed away your changes and you want the next change to be reviewed independently, do

git reset --hard HEAD^
git stash pop

(only do this if you pushed the previous change upstream, otherwise it is difficult to get the old changes back!) and repeat until each independent change is in its own commit. If you skip the git reset --hard step, you can also prepare a local feature branch from your changes.

Q: How do I edit an earlier commit?

A: If you want to edit the latest commit, you can simply do the changes and use

git commit --amend

If you want to edit some other commit, and commits after that have not changed the same lines, you can do the changes as usual and use

git commit --fixup <commit>

or

git commit --squash <commit>

where <commit> is the commit you want to change (the difference is that --fixup keeps the original commit message, while --squash allows you to input additional notes and then edit the original commit message during git rebase -i). You can do multiple commits in this way. You can also mix --fixup/--squash commits with normal commits. When you are done, use

git rebase -i --autosquash <base-branch>

to merge the --fixup/--squash commits to the commits they amend. See separate question on git rebase -i on how to choose <base-branch>.

In this kind of workflow, you should try to avoid to change the same lines in multiple commits (except in --fixup/--squash commits), but if you have already changed some lines and want to edit an earlier commit, you can use

git rebase -i <base-branch>

but you likely need to resolve some conflicts later. See git rebase -i question later.

Q: How do I split a commit?

A: The instructions below apply to splitting the HEAD commit; see above how to use git rebase -i to get an earlier commit as HEAD to split it.

The simplest case is if you want to split a commit A into a chain A’-B-C, where A’ is the first new commit, and contains most of the original commit, including the commit message. Then you can do

git reset -p HEAD^ [-- <paths>]
git commit --amend

to selectively remove parts from commit A, but leave them in your working tree. Then you can create one or more commits of the remaining changes as described in other tips.

If you want to split a commit A into a chain where the original commit message is reused for something else than the first commit (e.g., B-A’-C), then you can do

git reset HEAD^

to remove the HEAD commit, but leave everything in your working tree. Then you can create your commits as described in other tips. When you come to a point where you want to reuse the original commit message, you can use

git reflog

to find how to refer to your original commit as HEAD@{n}, and then do

git commit -c HEAD@{n}

Q: How do I use git rebase -i to only edit local commits?

A: Assume that you have a local feature branch checked out, this branch has three commits, and that it is based on main. Further, assume that main has gotten a few more commits after you branched off. If you want to use git rebase -i to edit your feature branch (see above), you probably want to do

git rebase -i HEAD~3

followed by a separate

git rebase main

The first command allows you to edit your local branch without getting conflicts from changes in main. The latter allows you to resolve those conflicts in a separate rebase run. If you feel brave enough, you can also do both at the same time using

git rebase -i main