Thursday, July 12, 2012

CVS - Simple explanation of Trunk, Branch and Tag

Copied from URL - http://www.bioinf.uni-freiburg.de/~mmann/HowTo/cvs_branches.html



CVS Branch and Tag Primer

Jeff Semke
Pittsburgh Supercomputing Center
4/21/98

In attempting to construct a CVS repository containing multiple versions of original NetBSD source distributions, as well as our own custom modifications to each of these, I found that the CVS man page was vague and unclear.
This document assumes general familiarity with the CVS system, including the concepts of modules, the repository, and basic checkout and commit operations.
Branches and tags are very different things, though they appear similar on the outside. Understanding the difference is the key to being able to support a multi-branched repository that can change as our custom code is modified for all versions of NetBSD.
The main concepts that are addressed in this document are:
Tree structure
Code in a CVS repository can be thought of as a tree. The tree shape is not based on the directory structure of the code, but rather on the versions of the code.
Trunk
As code gets modified and is committed back to the repository, it adds another revision to extend the tree. If no branches are specified when checking out working directories, the tree simply grows in a line along the main trunk of the tree.
Tags
A tag can be used to name a particular revision of the code. This tag can later be used to compare different revisions, to go back to an earlier version, or to specify a place to create a branch.
Branches
Branches allow different development paths to be tried. They can be created from the main trunk, or from other branches.

1. The trunk of the tree

    As the code gets modified, each revision extends the trunk of the tree. The trunk itself is named only by the module name, not by tags or branches. You can get a copy of the latest revision of the main trunk to work on with the command
      cvs checkout my_module
    This creates a working directory called my_module, and it contains the files and subdirectories of my_module. After you make your changes, you enter them into a new revision on the main trunk with the command
      cvs commit

2. Branches

    2.1 Creating a Branch

    Branches can be added to the repository tree in order to allow different development paths to be tried, or to add parallel development of code to different base versions. To create a branch, you can use
      cvs tag
    or
      cvs rtag
    with the -b option.
    Do not be fooled! Even though the same commands can be used to create tags, branches are completely different than tags.

      2.1.1 rtag

      To create a branch from the main trunk of my_module at the revision that was last committed, use the command
        cvs rtag -b Branchname my_module
      To create a branch from a tagged revision of my_module, use the command
        cvs rtag -r Tagname -b Branchname my_module
      Both commands immediately create a branch in the repository without requiring a cvs commit to enact. You do not need to be in a checked-out working directory to do this.

      2.1.2 tag

      If you are in a working directory, you can create a new branch in the branch or trunk from which you checked out your working directory (not including the changes you've made to your working directory since the last commit) by using the command
        cvs tag -b Branchname
      Like rtag, the change is immediate, and does not wait for a commit command.
      Your working directory remains on the old branch, at a point after the branch you just created. To move your working directory to the new branch, use the command
        cvs update -r Branchname
      When you are finished making changes to your working directory, save it as the next revision on the new branch with
        cvs commit

      2.1.3 Both rtag and tag

      Note that both rtag and tag work directly on the repository and take effect immediately without a commit command. Rtag takes effect at the specified place (the end of the main trunk by default), while tag takes effect at the place where the working directory was checked out or last committed.

    2.2 Checking Out a Branch to Work On

      To check out the latest revision of a branch to work on, use the command
        cvs checkout -r Branchname my_module
      When you do a cvs commit, the changes are merged in on the branch from which they were checked out.

    2.3 General

      Note that branch names refer to the latest revision of the branch they are on, not the state they were in when the branch was created.

3. Tags


    A tag provides a means to name a certain revision of the code, or take a "snapshot" of it at a certain point in time. This tag only applies a named handle to the code at that point in time, it does not create a new branch of code.

    3.1 Creating a Tag

      In order to name the current end of the main trunk of a module, use the command
        cvs rtag Tagname my_module
      In order to name the current end of a branch of a module, use the command
        cvs rtag -r Branchname Tagname my_module
      Otherwise, to name the code that your working directory was checked out from (without the changes you made to your working directory since the last commit), use the command
        cvs tag Tagname

    3.2 Using a Tagged version of code

      You can check out tagged versions of code with the command
        cvs checkout -r Tagname my_module
      This creates a working directory with the code as it was when the tag was created. While branch names refer to the latest code at the end of a branch (and as such, are dynamic), tag names refer to the static version of code that existed upon the tag's creation. As a result, you cannot commit changes back into the tree at the tagged place that you checked them out from.
      If desired, a new branch can be created at the place the tag was applied, then changes can be committed into the new branch as follows:
        cvs rtag -r Tagname NewBranchname my_module
        cvs update -r NewBranchname

        Finish changes to the working directory, then
        cvs commit
      To access this version of the code again later (along with any changes that were made by others since you last accessed it), use
        cvs checkout -r NewBranchname my_module

4. Merging branches

    4.1 Using Update

    cvs update -j TagOrBranch1 -j TagOrBranch2 my_module
    The above command will locate the differences between TagOrBranch1 and TagOrBranch2. Of the lines that are different between them, the lines in TagOrBranch2 will be patched, or merged, into the sources in your working directory.
    An annoying problem that I have not yet solved is that new files that appear in TagOrBranch2 but not in TagOrBranch1 do not get created by the merge. The only thing I know of to get these files into the new version is to checkout TagOrBranch2, copy the files into the merged working directory, and do
      cvs add filename

    4.2 Using Checkout

    cvs checkout -j TagOrBranch1 -j TagOrBranch2 my_module
    The above command will locate the differences between TagOrBranch1 and TagOrBranch2. Of the lines that are different between them, the lines in TagOrBranch2 will be patched, or merged, into the latest revision on the main trunk of my_module.
    In order to have these differences merged into a different branch, and then have that branch checked out, use
      cvs checkout -r BranchToMergeTo -j TagOrBranch1 -j TagOrBranch2 my_module
    Like update, file that were created between TagOrBranch1 and TagOrBranch2 do not get created automatically.

No comments:

Post a Comment