|  | <HTML> | 
|  | <HEAD> | 
|  | <title>Branches in CVS</title> | 
|  | <META NAME="description" CONTENT="A paper on making branches in CVS"> | 
|  | <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | 
|  | <meta name="generator" content="emacs"> | 
|  | <META NAME="AUDIENCE" CONTENT="NBDEVELOPER"> | 
|  | <META NAME="TYPE" CONTENT="ARTICLE"> | 
|  | <META NAME="TOPIC" CONTENT="NB_ORG"> | 
|  | <meta name="nav_link" content="CVS Branches"> | 
|  | <meta name="nav_priority" content="2"> | 
|  | <link rel="stylesheet" type="text/css" HREF="../../netbeans.css"> | 
|  | </HEAD> | 
|  |  | 
|  | <BODY> | 
|  |  | 
|  | <h1>Branches in CVS</h1> | 
|  | <BR><FONT CLASS="smalltext"><a href="mailto:mryzl@netbeans.org">Martin Ryzl</a>, | 
|  | <a href="mailto:jglick@netbeans.org">Jesse Glick</a></FONT> | 
|  |  | 
|  | <P> | 
|  | CVS allows you to isolate changes onto a separate line of | 
|  | development, known as a branch. When you change files on a branch, those | 
|  | changes do not appear on the main trunk or other branches. | 
|  |  | 
|  | Later you can move changes from one branch to main trunk (or from main | 
|  | trunk to the branch) by merging. Merging involves first running cvs | 
|  | update -j, to merge the changes into the working directory. You can then | 
|  | commit that revision, and thus effectively copy the changes | 
|  | onto another branch. | 
|  |  | 
|  | <h2>When to create a new branch</h2> | 
|  | For NetBeans/Forte I see two possible reasons for creating a new branch: | 
|  |  | 
|  | <ol> | 
|  | <li>Official branch for a new release. Such a branch will be created by | 
|  | an experienced person who knows what he is doing and therefore it | 
|  | might be expected that there won't be any problem. | 
|  |  | 
|  | <li>Private branch(es) created by a developer. Such branches are | 
|  | typically used for unstable code that will be merged into the main | 
|  | trunk as soon as it will became stable. This document presents | 
|  | some recommendations that should be followed when someone will create | 
|  | a private branch. | 
|  | </ol> | 
|  |  | 
|  | <h2>Recommendations for working with branches</h2> | 
|  |  | 
|  | <ol> | 
|  | <li>Read carefully CVS documentation. It can be found at | 
|  | <a href="http://www.cvshome.org/docs/manual/index.html"> | 
|  | http://www.cvshome.org/docs/manual/index.html</a>. If you have any | 
|  | problem, don't hesitate to ask someone who can help you. | 
|  |  | 
|  | <h4>Other references:</h4> | 
|  | <ul> | 
|  | <li>CVS--Concurrent Versions System<br> | 
|  | <a href="http://www.delorie.com/gnu/docs/cvs/cvs_toc.html">http://www.delorie.com/gnu/docs/cvs/cvs_toc.html</a> | 
|  |  | 
|  | <li>CVS--Concurrent Versions System<br> | 
|  | <a href="http://web.mit.edu/afs/athena.mit.edu/project/gnu/doc/html/cvs_toc.html">http://web.mit.edu/afs/athena.mit.edu/project/gnu/doc/html/cvs_toc.html</a> | 
|  |  | 
|  | <li>Versioning and Branching With CVS<br> | 
|  | <a href="http://www2.cs.utah.edu/impulse/cvs/index.html">http://www2.cs.utah.edu/impulse/cvs/index.html</a> | 
|  |  | 
|  | <li>Cederqvist CVS manual<br> | 
|  | <a href="http://ximbiot.com/cvs/manual/">http://ximbiot.com/cvs/manual/</a> | 
|  |  | 
|  | <li>How to Use CVS<br /> | 
|  | <a href="http://owen.sj.ca.us/rkowen/howto/cvs.html">http://owen.sj.ca.us/rkowen/howto/cvs.html</a> | 
|  |  | 
|  | <li>CVS Introduction Lecture<br> | 
|  | <a href="http://www.cdt.luth.se/~peppar/presentations/cvs/">http://www.cdt.luth.se/~peppar/presentations/cvs/</a> | 
|  |  | 
|  | <li>Maintaining the ChangeLog<br> | 
|  | <a href="http://gnu.atnet.at/software/guile/changelogs/guile-changelogs_toc.html">http://gnu.atnet.at/software/guile/changelogs/guile-changelogs_toc.html</a> | 
|  | </ul> | 
|  |  | 
|  | <br> | 
|  | <li>Do not use any CVS expandable keywords ($Id$, $Log$, etc.), as these | 
|  | interact poorly with merges. For example, suppose that you have used | 
|  | $Revision$ in your code. And that you have two versions of the file | 
|  | with revisions 1.2, 1.1.2.1. Then you might get the following results | 
|  | from a merge: | 
|  |  | 
|  | <pre> | 
|  | <<<<<<< file1 | 
|  | key $Revision: 1.2 $ | 
|  | ======= | 
|  | key $Revision: 1.1.2.1 $ | 
|  | >>>>>>> 1.1.2.1 | 
|  | </pre> | 
|  |  | 
|  | If you <i>*really*</i> need to use CVS keywords, please, consult CVS | 
|  | documentation or (better) ask someone who knows how to do it. | 
|  | <p> | 
|  | <li>Make a tag (cvs tag) whenever you do anything at all interesting | 
|  | (esp. before and after any merge); it never hurts and it may save you | 
|  | later. Remember that tags are global, so choose them descriptively so | 
|  | they will not conflict. For example <b>unstable_rmi_merged_on_Sep_6</b> | 
|  | can be used. | 
|  | <p> | 
|  | It may be useful for example if you perform more sequential merges. | 
|  | Suppose you have an branch R1fix and you have completed the first step | 
|  | of your unstable development. You want to merge it into the main trunk | 
|  | and then continue development in unstable branch. After some time you | 
|  | will repeat merging, etc. | 
|  |  | 
|  | <pre> | 
|  | +-----+    +-----+    +-----+    +-----+    +-----+ | 
|  | ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk | 
|  | +-----+    +-----+    +-----+    +-----+    +-----+ | 
|  | !                           * | 
|  | !                          * (merge) | 
|  | !                         * | 
|  | !   +---------+    +---------+    +---------+ | 
|  | Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 ! | 
|  | +---------+    +---------+    +---------+ | 
|  |  | 
|  | </pre> | 
|  | If you just  use the <i>cvs update -j R1fix m.c</i> command again, | 
|  | CVS will attempt to merge again the changes which you have already | 
|  | merged, which can have undesirable side effects. | 
|  | <p> | 
|  | If you tag <b>R1fix</b> branch after every merge into the trunk, it is | 
|  | possible to use the new tag in merge command and merge only what was | 
|  | changed since the last merge. | 
|  | <p> | 
|  | <li>When you make modifications and check them in, change as few lines as | 
|  | possible (e.g. do not reindent the whole file just for fun), and don't | 
|  | mix unrelated changes in a single commit; these will make merging go | 
|  | more smoothly and reduce the chance of error. | 
|  | <p> | 
|  | <li>Use branches if you need to do some unstable development - it is good | 
|  | for you because you can store all your versions and CVS server is | 
|  | probably backed up, it is good for other people because your code | 
|  | doesn't break builds. But do not use a lot of local unstable branches, | 
|  | because they may be hard to keep track of. If you need to do some | 
|  | unstable development for a while and need a branch, then use one. | 
|  | </ol> | 
|  |  | 
|  | <h2>How to work with branches</h2> | 
|  |  | 
|  | <ol> | 
|  | <li>create a new branch | 
|  | <ul> | 
|  | <li> | 
|  | <i>cvs tag new_branch_name_root</i><br> | 
|  | <i>cvs tag -b -r new_branch_name_root new_branch_name</i> | 
|  | <p> | 
|  | it creates a tag for main trunk (before the merge) and then it | 
|  | creates a branch based on the current revisions in the working | 
|  | copy, assigning that branch the name `new_branch_name'. | 
|  | <p> | 
|  | Example:<br> | 
|  | <i>cvs tag rmi_root</i><br> | 
|  | <i>cvs tag -b -r rmi_root unstable_rmi</i> | 
|  | <p> | 
|  | creates a new unstable branch for rmi module to main trunk | 
|  | <p> | 
|  | <li> | 
|  | <i>cvs tag -r some_existing_branch new_branch_root</i><br> | 
|  | <i>cvs tag -b -r new_branch_root new_branch_name</i> | 
|  | <p> | 
|  | <b>-r new_branch_root</b> says that this branch should be rooted at | 
|  | the revision that corresponds to the tag <b>new_branch_root</b>. It need not be | 
|  | the most recent revision -- it's often useful to split a branch off | 
|  | an old revision (for example, when fixing a bug in a past release | 
|  | otherwise known to be stable). | 
|  | <p> | 
|  | Example:<br> | 
|  | <i>cvs tag -r boston boston_rmi</i><br> | 
|  | <i>cvs tag -b -r boston_rmi unstable_rmi_boston</i> | 
|  | <p> | 
|  | creates a new unstable branch for rmi based on current boston | 
|  | branch | 
|  | <p> | 
|  | <b>Note:</b> difference between <i>tag</i> and <i>rtag</i> is that | 
|  | <i>tag</i> command adds a tag to checked out version of files | 
|  | whereas <i>rtag</i> uses the most recent versions in the repository. | 
|  | These can have different effects, e.g. if someone checks in new | 
|  | stuff while you are working. | 
|  | <p> | 
|  | </ul> | 
|  | <li>access to an existing branch | 
|  | <ul> | 
|  | <li> | 
|  | <i>cvs checkout -r branch_name</i> | 
|  | <p> | 
|  | Example:<br> | 
|  | <i>cvs checkout -r boston</i> | 
|  | <p> | 
|  | <li> | 
|  | <i>cvs update [-r branch_name]</i> | 
|  | <p> | 
|  | the above command switches to the specified branch name - it merges | 
|  | any changes. | 
|  | <p> | 
|  | <b>Note:</b> do not use <i>update -r</i>. It is potentially very | 
|  | confusing (although it does do exactly what it says, usually you | 
|  | don't really want to do that). Always check out branches into | 
|  | separate, clearly labeled directories. For example, ~/src/boston for | 
|  | boston branch, ~/src/jaga for main trunk, etc. Make a fresh checkout of | 
|  | the whole repository, with most stuff on the trunk and just your | 
|  | unstable code on the branch. | 
|  | <p> | 
|  | Example:<br> | 
|  | <i>cd unstable_rmi</i><br> | 
|  | <i>cvs checkout nbsrc</i><br> | 
|  | <i>cvs checkout -r unstable_rmi rmi</i><br> | 
|  | ...<br> | 
|  | <i>cvs update</i><br> | 
|  | </ul> | 
|  | <p> | 
|  | <li>merging | 
|  | <ul> | 
|  | <li> | 
|  | <i>cvs tag before_merge</i></br> | 
|  | <i>cvs update -j branch_name test.java</i></br> | 
|  | <i>cvs rtag -r branch_name branch_name_merged_on_date</i></br> | 
|  | <i>cvs commit -m proper message"</i> | 
|  | <i>cvs tag after_merge</i></br> | 
|  | <p> | 
|  | merges all changes on branch to the main trunk, tags it and commit | 
|  | to CVS. It is also possible to used revision numbers instead of | 
|  | tags but tags makes work with merging more smooth. | 
|  | <p> | 
|  | <li> | 
|  | <i>cvs tag before_merge_on_date</i><br> | 
|  | <i>cvs update -j branch_name_merged_on_date -j branch_name</i><br> | 
|  | <i>cvs rtag -r branch_name branch_name_merged_on_date</i><br> | 
|  | <i>cvs commit -m proper message"</i> | 
|  | <i>cvs tag after_merge_on_date</i><br> | 
|  | <p> | 
|  | merges all changes since specified merge to the main trunk, | 
|  | tags it and commit to CVS. | 
|  | <p> | 
|  | Example:<br> | 
|  | <i>cd jaga/rmi</i><br> | 
|  | <i>cvs tag before_merge_Sep_10</i><br> | 
|  | <i>cvs update -j unstable_rmi_merged_on_Sep_6 -j unstable_rmi</i><br> | 
|  | <i>cvs rtag -r unstable_rmi unstable_rmi_merged_on_Sep_10</i><br> | 
|  | <i>cvs commit -m "merged a new feature"</i> | 
|  | <i>cvs tag after_merge_Sep_10</i><br> | 
|  | <p> | 
|  | It is also possible to merge main trunk into a branch. This is | 
|  | conceptually probably harder, but follows the same principles. | 
|  | Suppose an example that you are working on unstable branch and | 
|  | someone else has been checked some fixes into the main trunk. You | 
|  | want to integrate these fixes into your code too but not to | 
|  | affect the main trunk with your unstable code and later to merge your | 
|  | unstable code to the main trunk. | 
|  | <p> | 
|  | Example:<br> | 
|  |  | 
|  | ## create an unstable branch<br> | 
|  | <i>cvs rtag unstable_root my_module</i><br> | 
|  | <i>cvs rtag -b -r unstable_root unstable my_module</i><br> | 
|  | <i>mkdir unstable</i><br> | 
|  | <i>cd unstable</i><br> | 
|  | <i>cvs checkout -r unstable my_module</i><br> | 
|  | ## some work in the branch whereas someone else has fixed trunk<br> | 
|  | ## merge the trunk to the branch<br> | 
|  | <i>cvs rtag main_trunk_fixed my_module</i><br> | 
|  | <i>cvs tag unstable_before_merging_main_trunk_fixed</i><br> | 
|  | <i>cvs update -j unstable_root -j main_trunk_fixed</i><br> | 
|  | [resolve conflicts and commit]<br> | 
|  | <i>cvs tag unstable_after_merging_main_trunk_fixed</i><br> | 
|  | ## some work in both main trunk and the branch<br> | 
|  | ## finally, merge the branch to the trunk<br> | 
|  | <i>cd stable</i><br> | 
|  | <i>cvs checkout my_module</i><br> | 
|  | <i>cvs tag before_merge_unstable</i><br> | 
|  | <i>cvs update -j main_trunk_fixed -j unstable</i><br> | 
|  | [resolve conflicts and commit]<br> | 
|  | <i>cvs tag after_merge_unstable</i><br> | 
|  |  | 
|  | <P> | 
|  | Suppose the following example: | 
|  |  | 
|  | <pre> | 
|  | /- 1 | 2 | M1 | 5              (branch) | 
|  | root | 
|  | \- 3 | 4 | 6 | 7 | M2               (trunk) | 
|  | </pre> | 
|  |  | 
|  | Numbers are changes (revisions) made by user. Suppose that every | 
|  | revision is stored as a diff to previous revision.<br> | 
|  | M1 is a result of merging the trunk (rev. 4) to the branch.<br> | 
|  | M2 is a result of merging the branch (rev. 5)to the trunk. | 
|  | <P> | 
|  | So current status at M1 is root+1+2+3+4,  status at 5 is | 
|  | root+1+2+3+4+5 and status at 7 is root+3+4+6+7. | 
|  | <P> | 
|  | Finally M2 is created (cvs update -j 4 -j branch) as <status at 7> | 
|  | + (<status at 5> - <status at 4>) = root+3+4+6+7 + | 
|  | (root+1+2+3+4+5 -(root+3+4)) = root+3+4+6+7 + (root+1+2+3+4+5 - root-3-4)) | 
|  | = root+3+4+6+7 + (+1+2+5) = root+1+2+3+4+5+6+7 | 
|  | <P> | 
|  | In practice, hovewer, update -j -j literally takes the two revisions you | 
|  | asked for, and more or less runs diff3 on them and your working file. | 
|  | It does not know or care what changes you made where--that is your job. | 
|  | cvs update always runs a single merge, it does not do anything in steps. | 
|  | The example above show how one can check whether result of merging would | 
|  | be what he wants. | 
|  | </ul> | 
|  | </ul> | 
|  |  | 
|  | </BODY> | 
|  | </HTML> |