Copyright ©2001 by John Cawley III. This document may be freely copied, distributed and archived provided it is copied entire and unmodified and the copyright statement remains intact.
Last modified: 2003-05-04. The current version of this document is available at http://www.Thistlehaven.net/J3. Email comments and questions about this document to j3@pobox.com.
|
CVS Usage Notes: |
||
|
|
Basic Usage: quick reference to common commands
|
|
|
|
Simple Branching: simple branching isn't too hard |
|
|
|
Hazards in Branching: when you begin to update from the trunk, or to merge into the trunk multiple times, things get strange |
|
|
|
Complex Branching: some rules of thumb for complex branching |
|
|
|
|
|
|
|
|
|
Quick Reference for Common Commands:

Create Repository: this is generally done once only, and might well have already been done for you
Import a Project: optional step; allows you to add a project and multiple subdirectories and files in one blow
Check out a Project:
- create a working subdirectory and cd into it, then execute this command
- you may indicate that a specific release be checked out (for recreating past
or alternate versions of the project)
- while in this working direcotory, you no longer need to specify the
repository as it is "remembered" for you
Determine What Has
Changed: since a project was checked out:
- U = Updated in repository since checkout
- M = Modified in checked-out version
- C = Conflict -- updated and modified in incompatible ways
- A = Added
- R = Removed
- ? = Uknown to repository
Add or Remove a File From
a Project:
- if a file is added or removed, it takes effect upon the next Check In
- subdirectories may be added
- if you do not specify the -f flag on the remove command, you must have
already deleted the file yourself
Check In Project: checks your code in
Tag a Release: assign an English name, under which the current versions of all files will be remembered; can be used to later restore a previous version of the code to a working directory
Export a Project: releases a version (usually tagged) for use, for example for beta testing or production; similar to "co", but without the CVS subdirectory clutter

Notes
Overview: the goal of this approach is to keep a trunk that is "clean" (ie always exportable to a production area) and to do subproject work on branches that may become "dirty" for a time; each subproject is branched off the trunk (and not off another subbranch -- this keeps things simpler); when the subprojects are completed (and "clean"), they are merged back into the trunk, which then acquires the features that the subproject added
#1 Tag Prior to Branch: Tag the trunk just prior to the
branch for later emergency use. From a working directory created to hold this
branch:
cvs -d {PathRepos} co -d
. {Project}
cvs tag Start{Subprj}{yyyymmdd}Beg
#2 Create Branch: create the subproject branch. From
the branch working directory:
cvs tag -b {SubPrj}
cvs update -r {SubPrj}
cvs tag Start{Subprj}{yyyymmdd}End # strictly speaking, unnecessary
#3 Updates May Occur on the Trunk: updates may continue to occur on the trunk while the branch is being worked on (eg from other branches being merged upon their completion)
#4 Tag Branch Prior to
Merge: this may be
needed later for emergencies or for complex branching if this branch must be
resurrected; from the branch working directory :
cvs tag Finish{Subprj}{yyyymmdd}Beg
#5 Merge Branch and Tag
Trunk at this Point:
merge the branch back into the trunk, resolving any conflicts, and tag the
trunk for later emergency/complex use; from a trunk working directory:
cvs update -j {Subprj}
cvs ci -m "Finish {Subprj} {YYYY.MM.DD}"
cvs tag Finish{Subprj}{yyyymmdd}End
#6 Note That Branch Deaths Are Soft: note that branches do not die -- they are merely "laid down " when you are done using them and are not picked up again simply because of programmer and project self-discipline
#7 Quick Reference: branch names are generally treated as
the tip of that branch
cvs update -j {Tag} this takes all changes from the branch's root to its tip
and merges them
cvs update -j {Tag1} -j {Tag2}
this takes all changes
from Tag1 to Tag2 and merges them
if Tag2 is a branch name, it implies the tip of that branch

Notes
Overview: when merging a branch into the trunk more than once, care must be taken to not duplicate the modifications from the first merge in with the second merge. Note that this discussion applies also to the mirror image of the situation described -- ie merges from the trunk into the subproject branch behave similarly.
#1: This is the first merge and is accomplished via the following statements:
from the branch working
directory:
cvs tag From{Subprj}{yyyymmdd}Beg
(alternately: cvs tag -r Start{Subprj}{yyyymmdd}End
-r From{Subprj}{yyyymmdd}Beg
)
from the trunk working
directory:
cvs update -j {Subprj}
cvs ci -m "Merged Subprj into trunk, {YYYY.MM.DD}"
cvs tag From{Subprj}{yyyymmdd}End
#2: The second merge cannot consist of all changes from the beginning of the branch to its tip, as part of those hav e already been applied and will cause spurious conflicts if they are attempted a second time. In other words, the following statement will indicate conflicts:
...
from the trunk working directory:
cvs update -j {Subprj} (wrong!)
#3: The correct way to accomplish the subsequent merge is via the
following statements:
from the branch working
directory:
cvs tag From{Subprj}{yyyymmdd2}Beg
from the trunk working
directory:
cvs update -j From{Subprj}{yyyymmdd}Beg
-j From{Subprj}{yyyymmdd2}Beg
cvs ci -m "Merged Subprj into Trunk {YYYY.MM.DD2}";
cvs tag From{Subprj}{yyyymmdd2}End

Notes
Overview: this diagram illustrates common usage with multiple alternating merges to and from a branch. With this behavior, the changes applied are from the beginning of the merge in the opposite direction to the beginning of this merge.
#1 Merge from subprj: This is accomplished via the following statements:
from the subproject/branch
working directory:
cvs tag From{Subprj}{yyyymmdd2}Beg
from the trunk working
directory:
cvs update -j To{Subprj}{yyyymmdd}Beg
-j From{Subprj}{yyyymmdd2}Beg
cvs ci -m "Merged from Subprj into trunk, {YYYY.MM.DD2}"
cvs tag From{Subprj}{yyyymmdd2}End
#2 Merge to subprj: This is accomplished via the following statements:
from the branch working
directory:
cvs tag To{Subprj}{yyyymmdd3}Beg
from the subproject/trunk
working directory:
cvs update -j From{Subprj}{yyyymmdd2}Beg
-j To{Subprj}{yyyymmdd3}Beg
cvs ci -m "Merged to Subprj from Trunk {YYYY.MM.DD3}";
cvs tag To{Subprj}{yyyymmdd3}End