.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "VCS::CVS 3" .TH VCS::CVS 3 "2008-01-07" "perl v5.8.8" "User Contributed Perl Documentation" .SH "NAME" \&\f(CW\*(C`VCS::CVS\*(C'\fR \- Provide a simple interface to CVS (the Concurrent Versions System). .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& #!/usr/gnu/bin/perl -w .Ve .PP .Vb 1 \& use strict; .Ve .PP .Vb 1 \& use VCS::CVS; .Ve .PP .Vb 12 \& my($history) = 1; \& my($initialMsg) = 'Initial version'; \& my($noChange) = 1; \& my($nullTag) = ''; \& my($permissions) = 0775; # But not '0775'! \& my($project) = 'project'; \& my($projectSource) = 'projectSource'; \& my($raw) = 0; \& my($readOnly) = 0; \& my($releaseTag) = 'release_0.00'; \& my($vendorTag) = 'vendorTag'; \& my($verbose) = 1; .Ve .PP .Vb 1 \& # Note the anonymous hash in the next line, new as of V 1.10. .Ve .PP .Vb 6 \& my($cvs) = VCS::CVS -> new({ \& 'project' => $project, \& 'raw' => $raw, \& 'verbose' => $verbose, \& 'permissions' => $permissions, \& 'history' => $history}); .Ve .PP .Vb 3 \& $cvs -> createRepository(); \& $cvs -> populate($projectSource, $vendorTag, $releaseTag, $initialMsg); \& $cvs -> checkOut($readOnly, $nullTag, $project); .Ve .PP .Vb 3 \& print join("\en", @{$cvs -> update($noChange)}); \& print "\en"; \& print join("\en", @{$cvs -> history()}); .Ve .PP .Vb 1 \& exit(0); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" The \f(CW\*(C`VCS::CVS\*(C'\fR module provides an \s-1OO\s0 interface to \s-1CVS\s0. .PP \&\s-1VCS\s0 \- Version Control System \- is the prefix given to each Perl module which deals with some sort of source code control system. .PP I have seen \s-1CVS\s0 corrupt binary files, even when run with \s-1CVS\s0's binary option \-kb. So, since \s-1CVS\s0 doesn't support binary files, neither does \s-1VCS::CVS\s0. .PP Stop press: \s-1CVS\s0 V 1.10 (with \s-1RCS\s0 5.7) supports binary files. .PP Subroutines whose names start with a '_' are not normally called by you. .PP You need to be clear in your mind about the 4 directories involved: .IP "\(bu" 4 The directory where your source code resides before you import it into \s-1CVS\s0. It is used only once \- during the import phase. Call this \f(CW$projectSource\fR. .IP "\(bu" 4 The directory into which you check out a read-write copy of the repository, in order to edit that copy. Call this \f(CW$project\fR. You will spend up to 100% of your time working within this directory structure. .IP "\(bu" 4 The directory in which the repository resides. This is \f(CW$CVSROOT\fR. Thus \&\f(CW$projectSource\fR will be imported into \f(CW$CVSROOT\fR/$project. .IP "\(bu" 4 The directory into which you get a read-only copy of the repository, in order to, say, make and ship that copy. Call this \f(CW$someDir\fR. It must not be \f(CW$project\fR. .PP Note: You cannot have a directory called \s-1CVS\s0 in your home directory. That's just asking for trouble. .SH "INSTALLATION" .IX Header "INSTALLATION" You install \f(CW\*(C`VCS::CVS\*(C'\fR, as you would install any perl module library, by running these commands: .PP .Vb 4 \& perl Makefile.PL \& make \& make test \& make install .Ve .PP If you want to install a private copy of \f(CW\*(C`VCS::CVS\*(C'\fR in your home directory, then you should try to produce the initial Makefile with something like this command: .PP .Vb 3 \& perl Makefile.PL LIB=~/perl \& or \& perl Makefile.PL LIB=C:/Perl/Site/Lib .Ve .PP If, like me, you don't have permission to write man pages into unix system directories, use: .PP .Vb 1 \& make pure_install .Ve .PP instead of make install. This option is secreted in the middle of p 414 of the second edition of the dromedary book. .SH "WARNING re CVS bugs" .IX Header "WARNING re CVS bugs" The following are my ideas as to what constitutes a bug in \s-1CVS:\s0 .IP "\(bu" 4 The initial revision tag, supplied when populating the repository with \&'cvs import', is not saved into \f(CW$CVSROOT\fR/CVSROOT/val\-tags. .IP "\(bu" 4 The 'cvs tag' command does not always put the tag into 'val\-tags'. .IP "\(bu" 4 \&\f(CW'cvs checkout \-dNameOfDir'\fR fails if NameOfDir =~ /\e/$/. .IP "\(bu" 4 \&\f(CW'cvs checkout \-d NameOfDir'\fR inserts a leading space into the name of the directory it creates. .SH "WARNING re test environment" .IX Header "WARNING re test environment" This code has only been tested under Unix. Sorry. .SH "WARNING re project names 'v' directory names" .IX Header "WARNING re project names 'v' directory names" I assume your copy of the repository was checked out into a directory with the same name as the project, since I do a 'cd \f(CW$HOME\fR/$project' before running \&'cvs status', to see if your copy is up\-to\-date. This is because some activity is forbibben unless your copy is up\-to\-date. Typical cases of this include: .IP "\(bu" 4 \&\f(CW\*(C`checkOut\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`removeDirectory\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`setTag\*(C'\fR .SH "WARNING re shell intervention" .IX Header "WARNING re shell intervention" Some commands cause the shell to become involved, which, under Unix, will read your \&.cshrc or whatever, which in turn may set \s-1CVSROOT\s0 to something other than what you set it to before running your script. If this happens, panic... .PP Actually, I think I've eliminated such cases. You hope so. .SH "WARNING re Perl bug" .IX Header "WARNING re Perl bug" As always, be aware that these 2 lines mean the same thing, sometimes: .IP "\(bu" 4 $self \-> {'thing'} .IP "\(bu" 4 $self\->{'thing'} .PP The problem is the spaces around the \->. Inside double quotes, \*(L"...\*(R", the first space stops the dereference taking place. Outside double quotes the scanner correctly associates the \f(CW$self\fR token with the {'thing'} token. .PP I regard this as a bug. .ie n .SH "addDirectory($dir, $subDir\fP, \f(CW$message)" .el .SH "addDirectory($dir, \f(CW$subDir\fP, \f(CW$message\fP)" .IX Header "addDirectory($dir, $subDir, $message)" Add an existing directory to the project. .PP $dir can be a full path, or relative to the \s-1CWD\s0. .ie n .SH "addFile($dir, $file\fP, \f(CW$message)" .el .SH "addFile($dir, \f(CW$file\fP, \f(CW$message\fP)" .IX Header "addFile($dir, $file, $message)" Add an existing file to the project. .PP $dir can be a full path, or relative to the \s-1CWD\s0. .ie n .SH "checkOut($readOnly, $tag\fP, \f(CW$dir)" .el .SH "checkOut($readOnly, \f(CW$tag\fP, \f(CW$dir\fP)" .IX Header "checkOut($readOnly, $tag, $dir)" Prepare & perform 'cvs checkout'. .PP You call checkOut, and it calls _checkOutDontCallMe. .IP "\(bu" 4 $readOnly == 0 \-> Check out files as read\-write. .IP "\(bu" 4 $readOnly == 1 \-> Check out files as read\-only. .IP "\(bu" 4 $tag is Null \-> Do not call upToDate; ie check out repository as is. .IP "\(bu" 4 $tag is not Null \-> Call upToDate; Croak if repository is not up\-to\-date. .PP The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR .IP "\(bu" 4 $raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. .IP "\(bu" 4 $raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is converted to \s-1CVS\s0's form release_1_23. .PP $dir can be a full path, or relative to the \s-1CWD\s0. .SH "commit($message)" .IX Header "commit($message)" Commit changes. .PP Called as appropriate by addFile, removeFile and removeDirectory, so you don't need to call it. .SH "\fIcreateRepository()\fP" .IX Header "createRepository()" Create a repository, using the current \f(CW$CVSROOT\fR. .PP This involves creating these files: .IP "\(bu" 4 $ENV{'\s-1CVSROOT\s0'}/CVSROOT/modules .IP "\(bu" 4 $ENV{'\s-1CVSROOT\s0'}/CVSROOT/val\-tags .IP "\(bu" 4 $ENV{'\s-1CVSROOT\s0'}/CVSROOT/history .PP Notes: .IP "\(bu" 4 The 'modules' file contains these lines: .Sp .Vb 3 \& CVSROOT CVSROOT \& modules CVSROOT modules \& $self -> {'project'} $self -> {'project'} .Ve .Sp where \f(CW$self\fR \-> {'project'} comes from the 'project' parameter to \fInew()\fR .IP "\(bu" 4 The 'val\-tags' file is initially empty .IP "\(bu" 4 The 'history' file is only created if the 'history' parameter to \fInew()\fR is set. The file is initially empty .SH "\fIgetTags()\fP" .IX Header "getTags()" Return a reference to a list of tags. .PP See also: the \f(CW$raw\fR option to \fInew()\fR. .PP \&\f(CW\*(C`getTags\*(C'\fR does not take a project name because tags belong to the repository as a whole, not to a project. .SH "history({})" .IX Header "history({})" Report details from the history log, \f(CW$CVSROOT\fR/CVSROOT/history. .PP You must have used new({'history' => 1}), or some other mechanism, to create the history file, before \s-1CVS\s0 starts logging changes into the history file. .PP The anonymous hash takes any parameters 'cvs history' takes, and joins them with a single space. Eg: .PP .Vb 1 \& $cvs -> history(); .Ve .PP .Vb 1 \& $cvs -> history({'-e' => ''}); .Ve .PP .Vb 1 \& $cvs -> history({'-xARM' => ''}); .Ve .PP .Vb 1 \& $cvs -> history({'-u' => $ENV{'LOGNAME'}, '-x' => 'A'}); .Ve .PP but not .PP .Vb 1 \& $cvs -> history({'-xA' => 'M'}); .Ve .PP because it doesn't work. .SH "new({})" .IX Header "new({})" Create a new object. See the synopsis. .PP The anonymous hash takes these parameters, of which 'project' is the only required one. .IP "\(bu" 4 \&'project' => 'killerApp'. The required name of the project. No default .IP "\(bu" 4 \&'permissions' => 0775. Unix-specific stuff. Default. Do not use '0775'. .IP "\(bu" 4 \&'history' => 0. Do not create \f(CW$CVSROOT\fR/CVSROOT/history when \fIcreateRepository()\fR is called. Default .IP "\(bu" 4 \&'history' => 1. Create \f(CW$CVSROOT\fR/CVSROOT/history, which initiates 'cvs history' stuff .IP "\(bu" 4 \&'raw' => 0. Convert tags from \s-1CVS\s0 format to real format. Eg: release_1.23. Default. .IP "\(bu" 4 \&'raw' => 1. Return tags in raw \s-1CVS\s0 format. Eg: release_1_23. .IP "\(bu" 4 \&'verbose' => 0. Do not report on the progress of mkpath/rmtree .IP "\(bu" 4 \&'verbose' => 1. Report on the progress of mkpath/rmtree. Default .ie n .SH "populate($sourceDir, $vendorTag\fP, \f(CW$releaseTag\fP, \f(CW$message)" .el .SH "populate($sourceDir, \f(CW$vendorTag\fP, \f(CW$releaseTag\fP, \f(CW$message\fP)" .IX Header "populate($sourceDir, $vendorTag, $releaseTag, $message)" Import an existing directory structure. But, (sub) import is a reserved word. .PP Use this to populate a repository for the first time. .PP The value used for \f(CW$vendorTag\fR is not important; \s-1CVS\s0 discards it. .PP The value used to \f(CW$releaseTag\fR is important; \s-1CVS\s0 discards it (why?) but I force it to be the first tag in \f(CW$CVSROOT\fR/CVSROOT/val\-tags. Thus you should supply a meaningful value. Thus 'release_0_00' is strongly, repeat strongly, recommended. .PP The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR .IP "\(bu" 4 $raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. .IP "\(bu" 4 $raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is converted to \s-1CVS\s0's form release_1_23. .SH "removeDirectory($dir)" .IX Header "removeDirectory($dir)" Remove a directory from the project. .PP This deletes the directory (and all its files) from your working copy of the repository, as well as deleting them from the repository. .PP Warning: \f(CW$dir\fR will have \f(CW$CVSROOT\fR and \f(CW$HOME\fR prepended by this code. Ie: \f(CW$dir\fR starts from \- but excludes \- your home directory (assuming, of course, you've checked out into your home directory...). .PP You can't remove the current directory, or a parent. .ie n .SH "removeFile($dir, $file\fP, \f(CW$message)" .el .SH "removeFile($dir, \f(CW$file\fP, \f(CW$message\fP)" .IX Header "removeFile($dir, $file, $message)" Remove a file from the project. .PP This deletes the file from your working copy of the repository, as well as deleting it from the repository. .PP $dir can be a full path, or relative to the \s-1CWD\s0. \&\f(CW$file\fR is relative to \f(CW$dir\fR. .SH "\fIrunOrCroak()\fP" .IX Header "runOrCroak()" The standard way to run a system command and report on the result. .SH "setTag($tag)" .IX Header "setTag($tag)" Tag the repository. .PP You call setTag, and it calls _setTag. .PP The value of \f(CW$raw\fR used in the call to new influences the handling of \f(CW$tag:\fR .IP "\(bu" 4 $raw == 1 \-> Your tag is passed as is to \s-1CVS\s0. .IP "\(bu" 4 $raw == 0 \-> Your tag is assumed to be of the form release_1.23, and is converted to \s-1CVS\s0's form release_1_23. .SH "stripCVSDirs($dir)" .IX Header "stripCVSDirs($dir)" Delete all \s-1CVS\s0 directories and files from a copy of the repository. .PP Each user directory contains a \s-1CVS\s0 sub\-directory, which holds 3 files: .IP "\(bu" 4 Entries .IP "\(bu" 4 Repository .IP "\(bu" 4 Root .PP Zap 'em. .SH "\fIstatus()\fP" .IX Header "status()" Run cvs status. .PP Return a reference to a list of lines. .PP Only called by \fIupToDate()\fR, but you may call it. .SH "update($noChange)" .IX Header "update($noChange)" Run 'cvs \f(CW\*(C`\-q\*(C'\fR [\f(CW\*(C`\-n\*(C'\fR] update', returning a reference to a list of lines. Each line will start with one of [\s-1UARMC\s0?], as per the \s-1CVS\s0 docs. .PP $cvs \-> \fIupdate\fR\|(1) is a good way to get a list of uncommited changes, etc. .IP "\(bu" 4 $noChange == 0 \-> Do not add \f(CW\*(C`\-n\*(C'\fR to the cvs command. Ie update your working copy .IP "\(bu" 4 $noChange == 1 \-> Add \f(CW\*(C`\-n\*(C'\fR to the cvs command. Do not change any files .SH "\fIupToDate()\fP" .IX Header "upToDate()" .IP "\(bu" 4 return == 0 \-> Repository not up\-to\-date. .IP "\(bu" 4 return == 1 \-> Up\-to\-date. .ie n .SH "_checkOutDontCallMe($readOnly, $tag\fP, \f(CW$dir)" .el .SH "_checkOutDontCallMe($readOnly, \f(CW$tag\fP, \f(CW$dir\fP)" .IX Header "_checkOutDontCallMe($readOnly, $tag, $dir)" Checkout a current copy of the project. .PP You call checkOut, and it calls this. .IP "\(bu" 4 $readOnly == 0 \-> Check out files as read\-write. .IP "\(bu" 4 $readOnly == 1 \-> Check out files as read\-only. .SH "_fixTag($tag)" .IX Header "_fixTag($tag)" Fix a tag which \s-1CVS\s0 failed to add. .PP Warning: \f(CW$tag\fR must be in \s-1CVS\s0 format: release_1_23, not release_1.23. .ie n .SH "_mkpathOrCroak($self, $dir)" .el .SH "_mkpathOrCroak($self, \f(CW$dir\fP)" .IX Header "_mkpathOrCroak($self, $dir)" There is no need for you to call this. .SH "_readFile($file)" .IX Header "_readFile($file)" Return a reference to a list of lines. .PP There is no need for you to call this. .SH "_setTag($tag)" .IX Header "_setTag($tag)" Tag the current version of the project. .PP Warning: \f(CW$tag\fR must be in \s-1CVS\s0 format: release_1_23, not release_1.23. .PP You call setTag and it calls this. .ie n .SH "_validateObject($tag, $file\fP, \f(CW$mustBeAbsent)" .el .SH "_validateObject($tag, \f(CW$file\fP, \f(CW$mustBeAbsent\fP)" .IX Header "_validateObject($tag, $file, $mustBeAbsent)" Validate an entry in one of the \s-1CVS\s0 files 'module' or 'val\-tags'. .PP Warning: \f(CW$tag\fR must be in \s-1CVS\s0 format: release_1_23, not release_1.23. .SH "AUTHOR" .IX Header "AUTHOR" \&\f(CW\*(C`VCS::CVS\*(C'\fR was written by Ron Savage \fI\fR in 1998. .SH "LICENCE" .IX Header "LICENCE" Australian copyright (c) 1998\-2002 Ron Savage. .PP .Vb 4 \& All Programs of mine are 'OSI Certified Open Source Software'; \& you can redistribute them and/or modify them under the terms of \& The Artistic License, a copy of which is available at: \& http://www.opensource.org/licenses/index.html .Ve