noresm:svnbestpractice

This is an old revision of the document!


SVN - Best Practice/FAQ

We encourage developers to use branches when developing the model. Do you find version control, branching and merging a bit difficult, try the NorESM svn branch/merge tutorial to understand branching and merging. In 30 minutes you can become an svn wizard

Follow this link to find the tutorial: SVN Branch/Merge tutorial

A branch is your own version of the repository. Sometimes it is nice to work on a feature “in private” without having to relate to other developers' codes. And sometimes you want to work on something which takes some time before it is finished.

In these cases you can create a branch. You can work on it on your own or in a team of colleques. When you are happy with the the content of the branch, you can merge it back to the trunk.

The trunk is considered a safe repository. The code in the trunk should always have passed a set of tests to make sure it is stable.(https://wiki.met.no/noresm/testlist)

Branches let you take advantage of the svn features, but without having to worry every day that your code passes the tests.

Create a branch with (http://svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html)

$ svn copy http://svn.example.com/repos/calc/trunk \
           http://svn.example.com/repos/calc/branches/my-calc-branch \
           -m "Creating a private branch of /calc/trunk."

Then check out the branch using

svn checkout $BRANCHURL nameOfBranchOnMyPC

In most cases the answer is “always”. However look at it this way:

If you work directly on the trunk you have to check that your code passes the tests every time you change the code. This is cumbersome and takes a lot of time. However if you are on a branch, you can work peacefully together with your small team taking full advantage of the version control system. In the end, when you and your teammates are happy with the changes, you perform the tests and merge back to trunk.

You should obviously test your code also before you commit to a branch, but for a branch the test does not include running and analyzing long simulations.

The NorESM branches have the following naming convension : {PurposeOfLife}_{ParentTagName}. This means that a branch name should state why it is created and where it is created from.

PurposeOfLife is a text string (allowed characters are a-z, A-Z, 0-9 and “.”) that must start with feature, release or private, where

  • a feature branch is a temporary branch created to work on a complex change without interfering with the stability of /trunk (or another parent branch). Feature branches are always reintegrated. See also http://svnbook.red-bean.com/en/1.7/svn.branchmerge.commonpatterns.html
  • a release branch is created if a version with frozen functionality is desired. The development on the release branch itself is limited to bug fixes, addition of forcing scenarios and other minor changes. Releases branches are not reintegrated.
  • a private branch can be created if a project requires a strongly tailored version of the model, that typically is maintained by only one person. Commits to a private branch should be agreed on with the branch creator. Private branches are not reintegrated.

ParentTagName is the name of an existing noresm tag.

Examples of valid branch names are:

  • featureIceActivation_trunk2.0-1 (development of ice activation feature, created from tag trunk2.0-1)
  • release2.0.0_trunk2.0-19 (release branch created from tag trunk2.0-19)
  • release2.0.1_release2.0.0-15 (release branch created from tag release2.0.0-15)
  • privateHiatusStudy_release2.0.1-3 (private branch for Ingo's hiatus study, created from tag release2.0.1-3)

Note that in this scheme a new branch is never branched off directly from trunk or another branch. A tag MUST be created before creating a branch (see section on tags below).

Naming of feature branches and associated tags

Consider the following example: A small group decides to have a branch of their own. The group defines their branch's purpose of life as “featureLandSurfaceModeling”.

They can now branch off from trunk and create the branch featureLandSurfaceModeling_trunk2.0-1. They will work happily on their branch until one day they have completed their feature. In the mean time they have tagged their branch a couple of times as featureLandSurfaceModeling-1, featureLandSurfaceModeling-2.

After the feature is completed, the branch is merged back to trunk, and following svn recommendations, the branch should now be considered dead.

The team still want their branch on which they cooperate well. They should now re-generate their branch from trunk, for example featureLandSurfaceModeling_trunk2.0-40. This is OK. The repository should now have two branches, but by inspection of branch names it is easy to see that featureLandSurfaceModeling_trunk2.0-40 is the recent one and the other is a dead end.

While developing on featureLandSurfaceModeling_trunk2.0-40, the team decides to tag their model twice, creating the tags featureLandSurfaceModeling-3 and featureLandSurfaceModeling-4.

The repository now has four tags: featureLandSurfaceModeling-1, featureLandSurfaceModeling-2, featureLandSurfaceModeling-3 and featureLandSurfaceModeling-4. They originate from two different branches. However this is OK in the NorESM naming convention scheme!

Naming of release branches and associated tags

The PurposeOfLife string of a release branch should begin with “release” followed by <ModelMajorVersion>.<ModelMinorVersion>.<ReleaseMinorVersion> (e.g., release2.0.1).

The numbers <ModelMajorVersion> and <ModelMinorVersion> are inherited from the tag from which the branch is created. The number <ReleaseMinorVersion> is set to 0 in the special case that the parent is a trunk tag (e.g., release2.0.0_trunk2.0-19) and augmented if the release branch is created from an existing release branch tag (e.g., release2.0.1_release2.0.0-5).

See section “How should I name the tag?” for more information on <ModelMajorVersion> and <ModelMinorVersion>.

You can decide this for yourself. The main hypothesis is that the trunk is always stable and working, so you will not harm your branch by merging from trunk. If you are working on something which you will finally merge back to the trunk, you can merge often. Then the final merge will be easier.

Just use svn merge ^/noresm/trunk (The “^” means “the URL of the repository's root directory“ in newer versions of svn. In older versions you need to give full URL)

You can merge to trunk after your changed code has passed a list of tests. The tests are available here: https://wiki.met.no/noresm/testlist

If your code does not pass the tests, you can not merge your code back to the trunk

Note that in svn, you can only merge ONE time from your branch to the trunk, or you risk making a mess of the system! (See http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html =⇒ “Reintegrating a branch”, note the statement Once a –reintegrate merge is done from branch to trunk, the branch is no longer usable for further work”)

The merge command (from trunk) will be something like (http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html)

svn merge --reintegrate $BRANCHURL

A tag is a version of the model which should be considered “frozen”. It makes sense to make a new “tag” for a production system, for example a specific version which should be used for many runs.

In svn notation, there is no difference between a branch and a tag. It is just a question of naming convension. Recommended convension is that tags are branches saved under the “tags” subdirectory and a branch is saved under the “branches” directory.

In NorESM tags are considered frozen, and people are not allowed to do developement on tagged versions.

Create the tag with a command like (http://svnbook.red-bean.com/en/1.6/svn.branchmerge.tags.html)

svn copy http://svn.example.com/repos/calc/trunk \
           http://svn.example.com/repos/calc/tags/release-1.0 \
           -m "Tagging the 1.0 release of the 'calc' project."

You should create a tag in the following cases:

  • When you want to create a branch! Always tag the model first and then create the branch from the tag.
  • A “released” version, a version which has been properly tested and which we recommend other users to run
  • A version which has been used for some specific paper (maybe you want to do more runs after referee comments)

Tags created from trunk have the naming convention:

trunk{MainModelVersion}.{MinorModelVersion}-{IncreasingVersionNumber}

Tags created from branches have the naming convention:

{BranchPurposeOfLife}-{IncreasingVersionNumber}

Every time a release branch is created from trunk, then MinorModelVersion is increased and IncreasingVersionNumber reset to 1. If no new release branch is created, then MinorModelVersion stays the same and IncreasingVersionNumber is increased.

MainModelVersion and MinorModelVersion are global counters while IncreasingVersionNumber is local to the trunk or a specific branch.

Examples are:

  • trunk2.0-1
  • trunk2.0-2
  • featureIceActivation-1
  • release2.0.0-1
  • release2.0.0-2
  • release2.0.1-1 (associated branch created from tag release2.0.0-2)
  • privateHiatusStudy-1 (owned by Ingo)
  • privateKatlaStudy-1 (owned by Øyvind)

Note how this is consistent with the branch naming scheme. You actually need to create a tag in order to give your branch a proper name!

A user has performed a control simulation using a tagged NorESM version. He wants to use this control simulation as baseline for several new implementations. How should he create/update working branches without having to worry about changes in trunk that can affect the result?

This is straight forward. The user creates several branches based on the original tag. Following the naming convension scheme, they all have a different “PurposeOfLife” but they have the same ParentTagName. The combination is a unique branch name for all the new implementations.

A tagged NorESM version has been used for the production of a certain simulation. Part of the simulations has to be rerun with extended diagnostic capability (e.g., with U10 output). How can I commit the extended diagnostic capability to svn?

One can imagine that something like this happened:

  • The originally tagged version was made from a branched called “releaseExperimentX_trunk2.0-45”
  • The experiment was run with “releaseExperimentX_3”

When the update is needed there are two possibilities:

Option 1

This is the normal (and simplest) case:

Update the “releaseExperimentXVersion_trunk2.0-45” branch with the changes needed. After the development is done on “releaseExperimentXVersion_trunk2.0-45” brand, tag this as “ReleaseExperimentX-4” and do the experiments.

Option 2

In the mean time, someone has done a lot of bugfixing in “releaseExperimentX_trunk2.0-45”, so the latest version of “releaseExperimentXVersion_trunk2.0-45” is significantly different from “releaseExperimentX-3” and you are afraid including the bugfixes will change the original results. You can not include all the bugfixes before doing the extra simulations so using the latest version of “releaseExperimentX_trunk2.0-45” is not an option.

In this case, create a new branch: “releaseExperimentX_releaseExperimentX-3” (alternatively “releaseExperimentXForPaperReview_releaseExperimentX-3”), update it and tag it “releaseExperimentX-4”.

You have to consider the following: Do you want to create a new “PurposeOfLife” in this case? It depends on the amounts of the bugfixes. Probably you want the bugfixes anyway at some later stage (there was a reason someone put them there!!) Then you don't need a new “PurposeOfLife”.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • noresm/svnbestpractice.1388160990.txt.gz
  • Last modified: 2022-05-31 09:23:24
  • (external edit)