wiki:pm-svn-branches

Version 4 (modified by andreasw, 14 years ago) (diff)

finished first draft

Dealing with Branches and Tags

The detailed description of this topic in the subversion book can be found here.

A tag is a name that is given by the project maintainer to a particular revision of the code in a repository, so that one can easily retrieve it without having to specify a revision number. Typically, one might want to give tags to stable versions of the code.

A branch is a specific "line" of code development. One always has a main branch, which represents what the common user should obtain from the repository as current release. In subversion, this main branch is by convention called trunk. But it is a very good idea, and we highly recommend this, to do the code development in a different branch, so that one can submit code changes to the repository, without disturbing the users of the official version. In such a development branch, one can safely continue to work, possily sharing the changes with other developers, and if a new stable version has been obtained, the changes can be merged to the official trunk version.

If you have used CVS before, you know the notion of "branches" and "tags". In CVS, there are specific commands to organize tags and branches, which can sometimes be confusing. It is important to understand that subversion works in a different, much easier way.

Subversion itself does not know about tags and branches. Instead, one can use the fact that subversion (in constrast to CVS) also keeps revisions of directories, just as for files, and that an svn copy retains the change history for copied files and directories.

By convention, the directory stucture in the svn repository at the very base of a project (say, Prjct), is

Prjct ---- trunk
  |
  |------- branches
  |
  -------- tags

Creating New Branches and Tags

In the trunk directory should be the current official release of the project, i.e., the stuff that you want users to download. If you want to create a new branch, say a development branch called devel from the current trunk version, you use svn copy to create a copy of trunk in a new subdirectory (in the svn repository) under branches.

You can do this without having to use a local copy of the entire repository by specifying URLs for both the source and the destination of the copy. For the Prjct example project, you would do this with

svn copy https://www.coin-or.org/svn/Prjct/trunk \
         https://www.coin-or.org/svn/Prjct/branches/devel \
         -m "Creating devel branch"

Since this is a write action to the repository, you will need to provide a message that logs the change you are doing (this is what the "-m" flag is for). If you omit this flag, your default editor will open and ask you to provide the log message.

If you now want to check out the development branch devel to be able to make changes and submit them back to the devel branch, you specify the corresponding directory in the repository in your svn checkout command, such as

svn co https://www.coin-or.org/svn/Prjct/branches/devel Coin-Prjct-devel

This will create a subdirectory Coin-Prjct-devel (or however you name it) in which you can work.

At a later point you probably want to transfer the changes you made in the development branch over to the main release trunk branch. For this you use svn merge as described further below.

Just as you create new branches with svn copy, you can create a tag by copying the version you want to tag into a subdirectory in the tags subversion repository directory, for example with

svn copy https://www.coin-or.org/svn/Prjct/trunk \
         https://www.coin-or.org/svn/Prjct/tags/ver-1-0-0 \
         -m "Creating tag ver-1-0-0

In contrast to CVS, you could now make modifications to the tagged version of your code (since subversion handles tags by convention simply as internal directories), but since tags are supposed to be a snapshot of the code at a particular time, that might not be good practice.

Summary

The subversion repository is essentially a large file system with revision control. One can check out directores (including subdirectories) at any level of that file system. By convention, the root of the file system has the structure as in the above diagram. The trunk always is the official release of the project, subdirectories in the branches directory correspond to branches, and subdirectories in the tags directory correspond to tags.

Merging Branches

Typically, after you worked on your development branch for a while and want to make the current version in there the new official release for your project, you want to "merge" the changes you made in the branch into the trunk branch. For this, you use the svn merge command.

An svn merge conceptually does an svn diff to get the difference between two copies of the code, and applies the difference as patch to the work copy, in which svn merge is performed, but it is more powerful than just obtaining the diff output and applying the patches yourself, since it will also rename and create files and directories, when this was within the changes that were done between the two copies.

In the example of maintaining a development branch devel for the active code development, you will have created a new branch devel branch as described above. You should write down somewhere, which the revision number was at which you split the development branch from the main trunk branch, or the revision number when you updated the official code release in trunk most recently. An easy way to do this is to include the revision number in the commit message when you first submit the new branch, or in the message for the commit when you submit the merges applied to the trunk version. One way to find out the revision number of a working copy, is to type svn update.

Say now that you want to update the trunk version to reflect the changes you have made in your develepment branch. The last change (or the creation of the development branch) has happened at revision number 123. In order to merge the changes that happened in the development branch devel into your local copy of the trunk version, you go into the base directory of the trunk version (e.g., Coin-Prjct/trunk, and there you type

svn merge -r 123 https://www.coin-or.org/svn/Coin-Prjct/branches/devel

This will get all the changes that happened in Coin-Prjct/branches/devel since revision number 123 and apply those changes to your local copy of trunk. If you have made no local modifications in trunk (and it is a good idea do keep it that way), everything should just work fine. If you have local modification in your trunk copy, you might encounter conflicts that you have to resolve, just as if you have done an svn commit and encountered conflicts (see the description of {{{svn commit}} here).