CVSLINES(1)CVSLINES(1)NAMEcvslines - a CVS wizard to help manage parallel development
SYNOPSIScvslines [status] [-l|-R] file|dir ...
cvslines checkout [-d dir] line module | -t module
cvslines commit [-n] [-l|-R] [-x|-X] [-b] [-o] [-i] [-q]
[-a] [-f msgfile | -m msg ]
[-all[-line...] | -only[+line...]]
file|dir ...
DESCRIPTIONcvslines is, in effect, a "wizard" helper for use with the standard
cvs(1) command. cvslines helps users of cvs modules representing mul‐
tiple parallel "lines of development" to manage the task of merging
changes from one such line into others at commit time, as appropriate.
These lines of development (hereafter referred to simply as "lines")
typically represent different releases of a software system. (These are
often thought of as "branches". However, cvslines reserves the term
"branch" to refer to the more precise definitions as they are used in
rcs(1) and cvs).
OPTIONScvslines supports the following options:
-l Like the cvs -l option: only act on files in the current direc‐
tory, (rather than recursively into any subdirectories).
-R Like the cvs -R option: perform the action recursively, down
through the tree rooted at the current directory. (This is the
default, but -R can be useful to override a "$Norecurse=1;"
placed in the ~/.cvslinesrc file).
-n ["cvslines commit" only] Like the cvs -n option: cvslines will
execute the commit planning phase as usual, any will show the
steps that would be carried out to implement the commit plan,
but will not actually execute them.
-x This option disables the "[press Return to]:" prompts that cvs‐
lines normally presents to the user at each step in executing
the commit plan.
-X This option enables the "[press Return to]:" prompts. The
prompts are enabled by default, but -X can be useful to to over‐
ride a "$Noaskexec=1;" placed in the ~/.cvslinesrc file).
-b This option tells cvslines to run in "batch" mode. This has the
effects of:
(1) Allowing cvslines to function when the standard IO
streams are not a tty;
(2) Making cvslines require that a log message be supplied
with either a -m or -f option, and the lines to be commit
to be specified with either a -all or -only option;
(3) cvslines will always skip a commit for which merge con‐
flicts are detected, and produce a summary show the list
of files so skipped at the end of the cvslines execution.
(4) forces on the -x option; and
(5) Causes the "Proceed?" prompt at the end of the planning
phase for each file to be skipped.
-o This option requests that cvslines status only display informa‐
tion about lines that are members of the same "lines group" as
the one represented by the current working tree. (See the
"LINES GROUPS" section, below, for more information about "lines
groups".
-i This option turns off the "sticky answers" feature. (By
default, cvslines will only ask about whether a commit should be
applied to a given line of development once, the first time the
line is encountered; if a cvslines commit operation acts upon
more than a single file, then the same answer will be assumed
for each subsequent file. The -i option causes cvslines to ask
whether the commit should be applied for each line on a per-file
basis.
-q Causes cvslines to be less verbose. The following messages will
be suppressed:
(1) The per-file preamble:
cvslines: making commit plan for:
file: ...
cvs info: ...
line spec spec rev cur rev
---------- -------------- ---------------------- ----------
.
.
.
(2) The "Action Plan" summary:
Action plan:
.
.
.
-a Turn off lines groups awareness altogether (i.e., consider all
lines to be part of a single lines group, disregarding any lines
groups defined in cvslines.config.
-f msgfile
This option tells cvslines to use the text found in msgfile as
the log message to be supplied for each cvs commit operation
performed.
-m msg This option tells cvslines to use the text msg as the log mes‐
sage to be supplied for each cvs commit operation performed.
-all[-line...]
The -all option tells cvslines to assume an answer of "yes" to
all "should this change also be applied to line..." and/or
"should should file also be included in line..." questions that
arise during a "cvslines commit" operation. The optional set of
trailing -line arguments allow you to explicitly specify excep‐
tions, i.e., the names of lines of development for which the
answer "no" should be used. For example, "-all-R1.0" would
specify that the answer "yes" should be assumed for all lines
except one named "R1.0".
-only[+line...]
This option is the inverse of the "-all" option: it tells cvs‐
lines to assume an answer of "no" to all "should this change
also be applied to line..." and/or "should should file also be
included in line..." questions, except for any lines named by
+line arguments.
-d dir This option, defined only for the cvslines checkout subcommand,
is passed along as a -d option to the cvs checkout command,
causing the named module to be checked out into a directory
called dir.
-t module
This option, defined only for the cvslines checkout subcommand,
requests that cvslines merely display the set of known line
entries from the cvslines.config file for the named module.
THE cvslines.config FILE
To inform cvslines about the set of lines that are under its manage‐
ment, each cvs module under cvslines control has one (or more) cvs‐
lines.config file(s), in the module's top-level repository direc‐
tory(s).
The cvslines.config file is typically set up by your cvs administrator;
most other users can safely skip this section.
If a cvs module is defined to include multiple files and/or directo‐
ries, then the cvslines.config file should be replicated in the root of
each directory specified. E.g., for a $CVSROOT/CVSROOT/modules entry of
tmod
You would need a single cvslines.config file
$CVSROOT/tmod/cvslines.config
For a module defined as
tmod dir1 file1.c file1.h
tmod dir2 file2.c file2.h
you would need to replicate the cvslines.config file as
$CVSROOT/dir1/cvslines.config
$CVSROOT/dir2/cvslines.config
(For convenience of administration, you could make the multiple cvs‐
lines.config files be links to the same file).
For example, for a module "tmod", this would be "$CVSROOT/tmod/cvs‐
lines.config".
The cvslines.config file has the following format
#
# This is an example cvslines.config file. It also serves as the
# official documentation for the format of cvslines.config files.
#
# Each cvs module repository for which cvslines is to be used gets
# a cvslines.config file in the root of the repository tree (where
# the RCS ,v files for the cvs module are kept).
#
# The file consists of two segments...
#
# I. The user list.
#
# This specifies the set of users that should be doing commits for
# this module using the "cvslines commit" facility. (When such
# users try to directly execute "cvs commit", they'll be remined to
# use "cvslines commit", instead).
#
# Each line is "~<loginname>" or "!~<loginname>". The special
# entry "~ALL" means "all users". "!~<loginname> means that the
# specified user should *never* be reminded to use "cvslines
# commit".
#
~ALL
# II. The lines declarations.
#
# Other entries specify lines of development known to this
# module. Each line is four whitespace-separated fields
#
# name the name of the line [max 10 chars]
#
# spec the cvs specification, identifying revisions on that
# line for a given file. It must be either a cvs branch
# tag or "head". [max 14 chars]
#
# state the development state for the line.
# [Currently, nothing uses this].
#
# opts a set of comma separated options that apply to this
# line. Currently, only "+<name>" is defined. This
# causes cvslines to make the default for the "include
# these changes in <line>" "yes" for the <name> line.
# Use "-" for an empty options field if you also need
# to specify an lgroup.
#
# lgroup the "lines group" tag. The default lgroup name is
# "" (empty), so you need not specify anything here
# if you are not going to define additional lgroups.
#
#name spec state opts lgroup
R1.2 head dev
R1.1 R1_1_BRANCH dev +R1.2
R1.0 R1_0_BRANCH qa
THE $CVSROOT/commitinfo ENTRIES
In order to tell cvs that a given module should have commits controlled
via the "cvslines commit" command (rather than directly via the normal
"cvs commit" command), cvslines uses a pair of entries in the $CVS‐
ROOT/commitinfo file, for example
^tmod$ /usr/local/bin/cvslines_check
^tmod/ /usr/local/bin/cvslines_check
This causes cvs to execute the cvslines_check command for each direc‐
tory containing files to be committed when changes to files in the
"tmod" module are committed.
THE cvslines checkout COMMAND
The "cvslines checkout" command can be used to make cvslines translate
the specified line name into the correct cvs branch tag for checking
out a tree for a given line of development. The translated name is
supplied in a "cvs checkout" command, which is displayed and then auto‐
matically executed for you. E.g.:
% cvslines checkout R1.1 mod
cvs checkout -r R1_1_BRANCH mod
cvs checkout: Updating mod
U mod/file1
U mod/file2
cvs checkout: Updating mod/dir1
U mod/dir1/file3
cvs checkout: Updating mod/dir1/dir2
U mod/dir1/dir2/file4
You can use "cvslines checkout -t module" to get a list of the line
names known for a specified module:
% cvslines checkout -t mod
R1.2 head dev
R1.1 R1_1_BRANCH dev
R1.0 R1_0_BRANCH qa
THE cvslines status COMMAND
The "cvslines status" command (which is what you get by default if you
just type "cvslines" without naming a subcommand) reports on the status
of each line of development for each cvs-controlled file, as specified
by the named files and/or directories. The file and directory argu‐
ments work just like they do in cvs: a directory name will cause all
files in the directory to be reported (with directory recursion), and a
file name will only do the named file. The "-l" option can be used to
inhibit directory recursion, or the "-R" option to explicitly enable
it.
For each file it reports on, "cvslines status" will show, for each line
under cvslines control (as specified in the cvslines.config file for
the module), the line name, the cvs branch specification, the actual
numeric value represented by this specification, and the current RCS
revision for the line.
For example:
% cvslines-l
./file1
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
R1.2 head 1.2 1.2
>> R1.1 R1_1_BRANCH 1.2.0.4 1.2
R1.0 R1_0_BRANCH 1.2.0.2 1.2
./file2
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
R1.2 head 1.2 1.2
>> R1.1 R1_1_BRANCH 1.2.0.2 1.2
R1.0 R1_0_BRANCH 1.1.1.1.0.2 1.1.1.1
(The ">>" tags show that these lines are the ones represented by the
working tree from within which cvslines was invoked.)
For lines that do not currently include the file, the spec rev will be
shown as "head" or "none", for lines specified as "head" or with a
branch tag, respectively. The value for "cur rev" for either will be
shown as "none":
% cvslines Newfile
./Newfile
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
R1.2 head head none
R1.1 R1_1_BRANCH none none
>> R1.0 R1_0_BRANCH 1.1.0.2 1.1.2.1
If multiple "lines groups" are defined (See the "LINES GROUPS" section,
below), then (by default) "cvslines status" will indicate lines that
are not members of the same lines group as the current working tree's,
with an "xx" tag before the line names:
% ../../../cvslines status file2
cvslines: *** running from "/n/makita/users/rmg/cvs/tools/cvslines" ***
./file2
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
>> R1.2 head 1.2 1.2
xx projX R_projX 1.2.0.4 1.2
xx projY R_projY 1.2.0.6 1.2
R1.1 R1_1_BRANCH 1.2.0.2 1.2.2.1
R1.0 R1_0_BRANCH 1.1.1.1.0.2 1.1.1.1.2.1
THE cvslines commit COMMAND - EXAMPLE
This section explains in broad terms how "cvslines commit" works. For a
more detailed discussion, including how newly added files are handled
and other special cases, please see the next section.
To employ cvslines for a module, commits of changes to files in the
module should be done via "cvslines commit", instead of the usual "cvs
commit" command.
In order to help remind users of this convention, attempts to commit
files with "cvs commit" for a module under cvslines control will result
in a message like:
% cvs commit
cvs commit: Examining .
cvslines:
Commits for this module should be done via the "cvslines commit"
command.
To force a "cvs commit" command from this module without cvslines
commit checks, run cvs with $CVSLINES_NOCHECK set in the environment.
cvs commit: Pre-commit check failed
cvs [commit aborted]: correct above errors first!
To actually do the commit, you use "cvslines commit". You can name
individual files and/or directories (which are treated recursively by
default), just as you would with the ordinary cvs commit command. The
"-l" option inhibits directory recursion.
You can force cvslines to allow you to do a direct cvs commit by run‐
ning "cvs commit" with the variable $CVSLINES_NOCHECK set in the envi‐
ronment.
"cvslines commit" operates in two phases.
In the first ("planning") phase, it asks you, for each file, whether
the changes being committed should also be applied to the other lines
of development that contain the file. Based on your answers, cvslines
decides on the proper cvs actions to take.
In the second ("execution") phase, cvslines helps you to execute the
plans created in the first phase, supplying you with the command lines
required and allowing you to execute them.
Here's an example, in which a single file is being committed. First,
cvslines presents a summary of the current status of the file, with a
line for each line of development in the module under cvslines control.
The line prefixed with ">>" is the one represented by the file in the
working directory. Other lines that contain the file are prefixed with
either "u?" or "m?", indicating that the change would be applied with
an update or a merge, should it also need to be applied to that line of
development. (I.e., lines prefixed with "u?" have not yet diverged
with respect to the one represented by the file in the working direc‐
tory). The tag "a?" is used to indicate that a file being added by a
commit might be applicable to another line.
% cvslines commit file2
cvslines: making commit plan for:
file: /n/makita/users/rmg/cvs_xmpl/mod_1.1/file2
cvs info: 1.2/Sun Aug 4 05:02:54 1996//R1_1_BRANCH
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
u? R1.2 head 1.2 1.2
>> R1.1 R1_1_BRANCH 1.2.0.2 1.2
m? R1.0 R1_0_BRANCH 1.1.1.1.0.2 1.1.1.1
Next, cvslines asks whether, for each of the other lines of develop‐
ment, you wish to also apply the changes to that line, and then pro‐
poses an "Action plan" based on the responses:
Should these changes also be applied to...
R1.0 (y n) [n]? y
R1.2 (y n) [n]? y
NOTE:
This check-in would normally (i.e., without cvslines) cause a
new RCS branch to be created.
But, since you also want to apply the revision to all the other
non-branched lines that share revision "1.2", it will be
better to apply the change as a new revision to the "1"
branch, and then update the branch tags for other lines. This will
help minimize actual divergence for this file in lines that don't
need to diverge yet. This is reflected in the commit plan shown
below.
Action plan:
R1.0 : update with a revision merge and commit [1.1.1.1.2.1]
R1.1 : update with a branch tag update [1.3]
R1.2 : update with a commit [1.3]
Proceed (y n) [n]?
The action plans show, for each line that wants to get the changes, how
they will be applied, and the RCS revision number that would result.
In the example above, the user wants the changes to go into all of the
lines containing the file. cvslines has decided that this will require
two commits, one to create revision 1.3 (which will update the R1.1 and
R1.2 lines), and one (based on a merge) to create revision 1.1.1.2.1
(which will update the R1.0 line).
If the user agrees to the action plan, cvslines will move into the exe‐
cution phase. (In this example, there was only one file being commit‐
ted, so the execution phase for "file2" follows the planning phase
directly. Had there been other files involved in the commit, their
planning phases would be performed prior to the execution phases for
any of them).
By default, cvslines displays each action it will take, and waits for
the user to type a Return for confirmation before proceeding.
You can disable these confirmation prompts either by running "cvslines
commit" with the -x option, or by placing the line "$Noaskexec=1; 1;"
in your ~/.cvslinesrc file.
However, it's recommended that you go ahead and allow the confirma‐
tions, as it will help you to understand more about how cvslines uses
cvs.
Continuing our example, cvslines begins to execute the plan for
"file2":
Proceed (y n) [n]? y
cvslines: wrote /n/makita/users/rmg/cvs_xmpl/mod_1.1/cvslines.plan
cvslines: executing plans for directory "/n/makita/users/rmg/cvs_xmpl/mod_1.1"...
cvslines: executing plan for file /n/makita/users/rmg/cvs_xmpl/mod_1.1/file2/file2...
cvslines: committing new revision 1.3...
cvslines: [press Return to]> mv -f file2 file2.cvslines.23654.save
(The user presses Return in order to tell cvslines to proceed)
cvslines: [press Return to]> cvs update -A file2
cvs update: warning: file2 was lost
U file2
cvslines: [press Return to]> mv -f file2.cvslines.23654.save file2
cvslines: [press Return to]> cvs commit file2
(The user enters the CVS log message in the usual manner)
Checking in file2;
/u/rmg/cvs_xmpl/cvs/mod/file2,v <-- file2
new revision: 1.3; previous revision: 1.2
done
cvslines: merging to new revision 1.1.1.1.2.1...
cvslines: [press Return to]> cvs update -r R1_0_BRANCH file2
U file2
cvslines: [press Return to]> cvs update -j 1.2 -j 1.3 file2
RCS file: /u/rmg/cvs_xmpl/cvs/mod/file2,v
retrieving revision 1.2
retrieving revision 1.3
Merging differences between 1.2 and 1.3 into file2
rcsmerge: warning: conflicts during merge
cvslines: merge conflicts detected.
cvslines: skip or edit (s e) [e]?
cvslines: [press Return to]> emacs file2
(The user is placed into $EDITOR to resolve merge conflicts)
cvslines: commit, skip or edit (c s e) [c]?
cvslines: [press Return to]> cvs commit -F cvslines.logmsg file2
Checking in file2;
/u/rmg/cvs_xmpl/cvs/mod/file2,v <-- file2
new revision: 1.1.1.1.2.1; previous revision: 1.1.1.1
done
cvslines: set branch tag "R1_1_BRANCH" to revision 1.3...
cvslines: [press Return to]> cvs tag -F -r 1.3 -b R1_1_BRANCH file2
T file2
cvslines: restoring working tag to "R1_1_BRANCH"...
cvslines: [press Return to]> rm -f file2; cvs update -r R1_1_BRANCH file2
cvs update: warning: file2 was lost
U file2
%
In the example above, the steps taken to include the changes in the
R1.0 line demonstrate how cvslines handles merging. In this case, the
CVS merge facility detected merge conflicts, which must be resolved by
the user before committing the file. In such cases, cvslines allows the
user to either edit the file and proceed, or to "skip" the commit, in
which case a copy of the partially merged file will be saved for later
attention, and further actions relying on that revision will be
skipped. For example, has the user chosen "skip" in the example above:
cvslines: merge conflicts detected.
cvslines: skip or edit (s e) [e]? s
cvslines: [press Return to]> rm -f file2-conflicts_R1_0_BRANCH; cp file2 file2-conflicts_R1_0_BRANCH
THE cvslines commit COMMAND - BRANCH TAG UPDATES
This section documents, in greater detail, how cvslines handles partic‐
ular cases that can arise in carrying out the action plans it has gen‐
erated.
In general, cvslines will try to avoid actions that would result in the
creation of new RCS branches where the tip of the branch doesn't really
differ from the tip of its parent branch. This can occur with cvs-con‐
trolled modules, for example, when a release branch has been declared
(by branch-tagging the files), and a change is applied in a branched
working directory.
Normally, this will result in the creation of a new RCS branch, since
(as far as cvs knows), the change represents a change that should be
applied to the branch, only. This is fine, if indeed the same change
needn't be carried forward into the new version of the software (on the
parent RCS branch). But, if the change is also desired on the parent
branch, it will need to be checked in separately there, too. This
results in two distinct RCS revisions that are actually identical.
(Except perhaps, in their RCS ident information expansions).
Furthermore, this consigns all such future changes (that need to go
onto both branches) to needing a pair of check-ins, one for each
branch.
cvslines avoids this situation, where possible, by using the strategy
of checking in the changes to the tip of the existing RCS branch, and
simply updating the branch tag in the branched line of development.
This could also be done manually, of course, if the user remembers to
think about it beforehand, and knows the right set of cvs commands to
use. cvslines helps out by reminding the user about the situation, and,
based on the user's desire about applying the change to both branches,
by supplying the necessary cvs commands in order to make the commit go
onto the parent branch and to update the branch tags.
cvslines can handle the situation described above equally well from a
working directory corresponding to either line of development.
THE cvslines commit COMMAND - MERGES
In other cases, when the revisions on the tips of different lines have
previously diverged, cvslines can still help out with the mechanics of
merging a set of changes and checking them in appropriately. It does
this using a "cvs update -jrev1 -jrev2" command, which in turn uses the
rcsmerge(1) command.
When merge conflicts are detected, the user is given the opportunity to
either edit the conflicts out of the file, and continue with the check-
in, or to save away a copy of the file containing the conflicts, to be
dealt with later.
cvslines will properly handle cases where changes are merged onto the
tip of an existing RCS branch, and/or lines that exist as branch tags
attached to such a branch.
THE cvslines commit COMMAND - ADDED FILES
cvslines can also help when new files are being added to a module. As
for commits of changes modifying existing files, cvslines asks the user
whether newly added files being committed into the module should also
be included in the other lines of development, and arranges to do the
right things, based on the user's answers. For example...
% cvs add Newfile
cvs add: scheduling file `Newfile' for addition on branch `R1_1_BRANCH'
cvs add: use 'cvs commit' to add this file permanently
% cvslines commit Newfile
cvslines: making commit plan for:
file: /n/makita/users/rmg/cvs_xmpl/mod_1.1/Newfile
cvs info: 0/Initial Newfile//R1_1_BRANCH
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
a? R1.2 head (none) (none)
>> R1.1 R1_1_BRANCH (none) (none)
a? R1.0 R1_0_BRANCH (none) (none)
Should this file be included in...
R1.0 (y n) [n]?
R1.2 (y n) [n]? y
Action plan:
R1.0 : will not be updated
R1.1 : update with a branch tag create [1.1]
R1.2 : update with a commit [1.1]
Proceed (y n) [n]? y
cvslines: wrote /n/makita/users/rmg/cvs_xmpl/mod_1.1/cvslines.plan
cvslines: executing plans for directory "/n/makita/users/rmg/cvs_xmpl/mod_1.1"...
cvslines: executing plan for file /n/makita/users/rmg/cvs_xmpl/mod_1.1/Newfile/Newfile...
cvslines: committing new revision 1.1...
cvslines: fool cvs into doing the right thing (don't panic!)...
cvslines: [press Return to]> mv -f CVS/Tag CVS/Tag-
cvslines: [press Return to]> mv -f Newfile Newfile.cvslines.6313.save
cvslines: [press Return to]> cvs remove Newfile
cvs remove: removed `Newfile'
cvslines: [press Return to]> mv -f Newfile.cvslines.6313.save Newfile
cvslines: [press Return to]> cvs add Newfile
cvs add: scheduling file `Newfile' for addition
cvs add: use 'cvs commit' to add this file permanently
cvslines: [press Return to]> cvs commit Newfile
(The user enters the CVS log message in the usual manner)
RCS file: /u/rmg/cvs_xmpl/cvs/mod/Newfile,v
done
Checking in Newfile;
/u/rmg/cvs_xmpl/cvs/mod/Newfile,v <-- Newfile
initial revision: 1.1
done
cvslines: [press Return to]> mv -f CVS/Tag- CVS/Tag
cvslines: set branch tag "R1_1_BRANCH" to revision 1.1...
cvslines: [press Return to]> cvs tag -F -r 1.1 -b R1_1_BRANCH Newfile
T Newfile
cvslines: restoring working tag to "R1_1_BRANCH"...
cvslines: [press Return to]> rm -f Newfile; cvs update -r R1_1_BRANCH Newfile
cvs update: warning: Newfile was lost
U Newfile
% cvslines Newfile
./Newfile
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
R1.2 head 1.1 1.1
>> R1.1 R1_1_BRANCH 1.1.0.2 1.1
R1.0 R1_0_BRANCH none none
%
Note that cvslines had to go through some slight contortions in order
to convince cvs to add the file as a new revision on the main trunk,
rather than initially onto a branch, as a "normal" cvs commit would do
in this situation. The result is, nonetheless, what was desired; the
file now exists in both lines of development, and remains undiverged.
THE cvslines commit COMMAND - NEWLY IMPORTED FILES
There is one case where cvslines will actually move a branch tag from a
second-level RCS branch back onto the trunk. This happens for files
that have not been modified with any check-ins since being added to a
module for the first time with "cvs import".
Here's what such a file looks like:
% cvslines file3
./file3
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
>> R1.2 head 1.1 1.1
R1.1 R1_1_BRANCH 1.1.1.1.0.4 1.1.1.1
R1.0 R1_0_BRANCH 1.1.1.1.0.2 1.1.1.1
This is the state that a file is in following a cvs import, and two
subsequent branch taggings (but before any changes have ever been
checked in.)
Note that, as far as CVS is concerned, the branched revisions are
branched off of the "vendor's release" (at revision 1.1.1.1), not off
of the head revision (1.1). But, in reality, of course, no divergence
has taken place.
In order to prevent actual branching, a cvslines commit to a file in
this state will treat the file as if branches were off of the trunk.
It alerts you to this by placing a "*" character next to the "spec rev"
reported for such a line:
% cvslines commit file3
cvslines: making commit plan for:
file: /n/makita/users/rmg/cvs_xmpl/mod_1.2/dir1/file3
cvs info: 1.1.1.1/Sun Aug 4 04:52:58 1996//head
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
>> R1.2 head 1.1 1.1
u? R1.1 R1_1_BRANCH *1.1.0.2 1.1
u? R1.0 R1_0_BRANCH *1.1.0.2 1.1
Should these changes also be applied to...
R1.0 (y n) [n]? y
R1.1 (y n) [n]? y
Action plan:
R1.0 : update with a branch tag update [1.2]
R1.1 : update with a branch tag update [1.2]
R1.2 : update with this commit [1.2]
Proceed (y n) [n]? y
cvslines: wrote /n/makita/users/rmg/cvs_xmpl/mod_1.2/dir1/cvslines.plan
cvslines: executing plans for directory "/n/makita/users/rmg/cvs_xmpl/mod_1.2/dir1"...
cvslines: executing plan for file /n/makita/users/rmg/cvs_xmpl/mod_1.2/dir1/file3/file3...
cvslines: committing new revision 1.2...
cvslines: [press Return to]> cvs commit file3
(The user enters the CVS log message in the usual manner)
Checking in file3;
/u/rmg/cvs_xmpl/cvs/mod/dir1/file3,v <-- file3
new revision: 1.2; previous revision: 1.1
done
cvslines: set branch tag "R1_0_BRANCH" to revision 1.2...
cvslines: [press Return to]> cvs tag -F -r 1.2 -b R1_0_BRANCH file3
T file3
cvslines: set branch tag "R1_1_BRANCH" to revision 1.2...
cvslines: [press Return to]> cvs tag -F -r 1.2 -b R1_1_BRANCH file3
T file3
%
As shown above, when you choose to update such a branch, the branch tag
gets moved onto the new revision checked in on the trunk, properly re-
uniting the (as yet undiverged) branches with the trunk.
MULTIPLE head LINEScvslines can also help to detect the time at which a new line should be
declared for a module (i.e., by branching tagging the entire module).
To use it this way, you can have multiple line names sharing the speci‐
fier "head".
When a user committing a change to any line specified by "head"
declines to include the change in all such lines, then cvslines balks,
and recommends that the module actually be branched.
When using such multiple "head" lines, cvslines needs a way to know,
when in a working tree representing one of the "head" lines, which one
it's in. (There's no way to infer this from normal cvs administrative
files as there is for trees representing branch lines). "cvslines sta‐
tus" will simply show all lines set to "head" as being the current
line:
% cvslines file1
./file1
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
>> R1.2.1 head 1.2 1.2
>> R1.2 head 1.2 1.2
R1.1 R1_1_BRANCH 1.2.0.4 1.2
R1.0 R1_0_BRANCH 1.2.0.2 1.2
When it can't resolve the line name in this situation, "cvslines com‐
mit" will report:
% cvslines commit
cvslines: making commit plan for:
file: /n/makita/users/rmg/cvs_xmpl/mod_1.2/file1
cvs info: 1.2/Sun Aug 4 04:58:18 1996//head
cvslines: problem:
Can't resolve the line name for the file
/n/makita/users/rmg/cvs_xmpl/mod_1.2/file1
Please correct this by setting the $CVSLINE environment variable,
or creating a .../CVS/cvsline file at the top of your working tree,
and try again.
In order to handle this and allow the commit to proceed, cvslines will
look for either
1) A file called "CVS/cvsline" relative to any directory from the
working directory, up to "/", containing the line name declaring
the identity of the line represented by the tree. (Usually such
a file will be placed in the root directory of the working
tree). -or-
2) A environment variable "$CVSLINE", set to the line name.
In the event that a user attempts a commit, specifying that the changes
are not wanted on all of the lines that share the head of the trunk,
then cvslines will recommend:
% CVSLINE="R1.2" cvslines commit
cvslines: making commit plan for:
file: /n/makita/users/rmg/cvs_xmpl/mod_1.2/file1
cvs info: 1.2/Sun Aug 4 04:58:18 1996//head
line spec spec rev cur rev
---------- -------------- ---------------------- ----------------------
u? R1.2.1 head 1.2 1.2
>> R1.2 head 1.2 1.2
u? R1.1 R1_1_BRANCH 1.2.0.4 1.2
u? R1.0 R1_0_BRANCH 1.2.0.2 1.2
Should these changes also be applied to...
R1.0 (y n) [n]? y
R1.1 (y n) [n]? y
R1.2.1 (y n) [n]?
cvslines: problem:
You have indicated that you want some, but not all, of the
non-branched lines on branch "1" to get this revision.
In this case, the line(s) that should not get the revision should
probably be moved onto a branch before applying this revision.
This is a significant operation, which must be applied to all of the
files in the module. Please consult with Release Engineering before
proceeding with these changes.
THE $HOME/.cvslinesrc file
cvslines users can alter the default behavior of cvslines to some
extent by creating entries in a file name ".cvslinesrc" in their home
directories.
Currently, the following defaults can be changed:
$Norecurse=1; # Don't recurse (like cvs -l) by default
$Noaskexec=1; # Don't prompt "[press Return to]" (like -x)
$Noexec=1; # Don't actually attempt commits (like -n)
$Noconfirm=1; # Don't prompt for plan confirmation ("Proceed?")
$Verbose=0; # Don't be as verbose (like -q)
$Batch=1; # Use "batch" mode (like -b)
$Showall=0; # Don't show lines from other lgroups (like -o)
$Stickyans=0; # Prompt for each line, per-file (like -i)
The last line of the .cvslinesrc file must be "1;".
If you've flipped one of the above defaults in your $HOME/.cvslinesrc,
then the alternate behavior can usually be requested by using one of
the other associated option letters.
For example, if you have the following $HOME/.cvslinesrc file:
% cat ~/.cvslinesrc
$Noaskexec=1;
1;
%
then, for you, the default will be not to use the "[press Return to]"
prompts. If you do want the prompts for a particular invocation, you
can say "cvslines commit -X ...".
LINES GROUPS
Sometimes, an organization may wish to reserve certain lines of devel‐
opment for projects as being logically separate from others. That is,
some group may need to work on one or more lines of development where
the norm is to rarely merge updates onto other lines. cvslines helps to
support this model by using a feature called "lines groups".
Lines groups are defined by designating line group names in the cvs‐
lines.config file. Every line is a member of exactly one lines group.
By default (i.e., if the lgroup field for a line in the cvslines.config
file is empty), then line is a member of the default lines group ("").
"cvslines commit" will only ask whether a change should be committed to
other lines in the same lines group as the one for the working tree in
which cvslines commit is invoked.
Normally, cvsline status will show the status for all lines. (It does,
however, indicate lines outside of the current working tree's lines
group with an "xx" tag). The -o option restricts it to showing the
status only for lines in the same group as that of the working tree
from which it is invoked.
Similarly, when summarizing a file's status, "cvslines commit" normally
indicates lines that are outside of the current working tree's lines
group with an "xx"-tagged entry. The -o option eliminates the display
of lines from other lines groups.
The -a option may be used to turn off the lines groups feature alto‐
gether. This can be useful when, working within a tree representing
one of multiple lines groups, you wish to propagate a change to lines
outside of the group.
CVSLINES AND REMOTE CVScvslines will work properly in "remote cvs" mode, using the "ext"
method. Currently, cvslines does not support remote cvs with authenti‐
cation.
CVSLINES HACKERY
Occassionally, you may want to do a commit specifically to some other
line than the one represented by the tree you are working in. (I.e., a
commit only to that line, instead of the working tree's line plus some
other(s)). This situation often arises when you've deferred the recon‐
cilation of merge conflicts discovered during a previous cvslines com‐
mit.
To do this, you can use the following trick, which allows you to change
the "current" line of development for a single file within a tree orig‐
inally checked out from another.
In this example, assume that the tree we're working in is using the
line of development on the head of the RCS trunk, and suppose that we
want to resolve merge conflicts detected during an attempt to merge
changes to "fileX" into the R1_1_BRANCH version, and which we chose not
to resolve during that commit. (cvslines has therefore saved the par‐
tially merged file as "fileX-conflicts-R1_1_BRANCH").
1. Remove the existing version of the file, and use 'cvs update
-A|-r branchtag' to move the file on to the other line. (Use
'-A' if the other line is the head of the RCS trunk, or '-r
branchtag, otherwise). E.g.,
% rm -f fileX; cvs update -r R1_1_BRANCH fileX
cvs update: warning: fileX was lost
U fileX
(At this point, CVS and cvslines will behave as if this file has
been checked out into an R1_1_BRANCH tree).
2. Next, edit the file to make it as you wish to commit it. In our
example, the previous commit had saved the partially merged
file, so we use:
% mv fileX-conflicts_R1_1_BRANCH fileX
% edit fileX to resolve the merge conflicts
% cvslines commit fileX
3. Finally, be sure to put the file back into the proper line rep‐
resented by the working tree:
% rm -f fileX cvs update -A fileX
cvs update: warning: fileX was lost
U fileX
CVSLINES ACTION CATALOG
These are the actions that cvslines may propose for a given line:
update with this commit
The line will be updated with a "natural" commit, i.e., the com‐
mit that would happen in this instance without any intervention
by cvslines.
update with a branch tag create
The line will be updated with the creation of a new branch tag.
(Used when new files are added to a branch line).
update with a branch tag update
The line will be updated by moving an existing branch tag up to
a new revision.
update with a revision merge and commit
The line will be updated by merging the changes represented by
the new revision into the tip of an existing branch, and then
committing them.
update with a commit
This line will be updated with a commit (other than the "natu‐
ral" commit.) This is used for adding new files onto lines on
the trunk, when done from a working tree which represents a
branched line.
STRUCTUREcvslines is written in perl. In order to minimize the perl compilation
times for the "status", "check" and "commit" subcommands, the code is
broken up into a common module, and three subcommand-specific modules
that are "require"ed as needed. These must all exist in the same
directory.
Also, a symbolic link "cvslines_check -> cvslines" needs to exist. This
allows cvslines to be invoked by the standard CVS commitinfo file hook,
to run the "check" subcommand.
BUGScvslines currently doesn't do "cvs remove"s. You have to make sure they
happen in all applicable lines "by hand".
FILES
$CVSROOT/CVSROOT/commitinfo
$CVSROOT/module/cvslines.config
/usr/local/bin/cvslines
/usr/local/bin/cvslines-status
/usr/local/bin/cvslines-commit
/usr/local/bin/cvslines-check
/usr/local/bin/cvslines_check
$HOME/.cvslinesrc
$Id: cvslines.1,v 1.2 2002/04/19 13:26:39 irockel Exp $
2002/04/19 CVSLINES(1)