Using CVS or other SCM
**********************

This docuement is a summary of common CVS usage, see `cvs(1)`_ for details.
Please read the man page to make sure we are talking the same language.

While the commands for GIT and other SCMs vary the general principles
are the same. 

Concurrent Version Control (CVS)
================================

`Cvs(1)`_ is a front end to the `rcs(1)`_ revision control system. CVS
provides revision control for an entire tree rather than just a single
directory, and supporst multiple edits concurrently.

The repository for CVS is kept under $CVSROOT and is just the same tree
hierarchy containing the RCS revision (,v) files.

Most people do not need to know any of this - but it can be handy.


Common usage
============


checkout a copy of a module
---------------------------

Unless your admin has set up a modules file, a module is just a directory
under $CVSROOT.::

	$ cvs checkout named

would check out $CVSROOT/named/* into ./named after which you can
start editing to your hearts content.


commiting changes
-----------------

In general your edits remain totally private until you commit them to the
repository ($CVSROOT). Ideally, this should be done whenever a consistent set
of changes is ready. 

Sometimes the changes to be made are considerable and
should not be reflected in the main branch (what gets checked out by default)
for some time, in these cases a branch can be made to hold the changes until
they are ready to be merged back into the main branch.


Normally though you just want to commit your changes to the same branch that
you checked out. You simply::

	$ cvs commit -m'a useful comment decribing the change' file1 ...

If file1 etc are omitted, then all changed files under the current
point in the tree are committed. If the comment is omitted, you will be
dropped into $EDITOR to provide one.

pre-commit checks
~~~~~~~~~~~~~~~~~

CVS can be setup to do very clever things when people commit changes. This is
easily setup, but arranging for a program to run when a commit is requested.
The program can do anything it likes, and indicates via its exit status
whether the commit should proceed or not. See `DNS regression testing`_ for
an example.


what changed?
-------------

Before you commit changes it is always a good idea to see what they are. You
can use::

	$ cvs diff -cb

to see all the changes you have made in your copy of the tree. If
you nominate one or more files on the command line only those files will
be diff'd. You can do fancy things like::

	$ cvs diff -cb -r1.2 file1
	$ cvs diff -cb -D yesterday file2

would show the diffs between the current version of file1 and
version 1.2 of the same file then show the changes made to file2 since
yesterday. See `cvs(1)`_ for all the details on *date_spec*. In addition
you often want to see the commit comments that have been made::

	$ cvs log file1

will display the commit history of file3, so you see why the
changes since version 1.2 were made. In some environments, changes
cannot be committed into CVS without a change docket, and these are
recorded against the change and therefor show up in the log.


adding files to the repository
------------------------------

To add a file, just create it using whatever tools take your fancy (vi, emacs
etc) and then::

	$ cvs add newfile
	$ cvs commit -m"explain why I added newfile" newfile

removing files from the repository
----------------------------------

Sometimes a file needs to be removed::

	$ rm file6
	$ cvs remove file6
	$ cvs commit -m"why I removed file6" file6

The file is not actually deleted from the repository, it is moved
into the Attic (incase someone wants to restore it later). To truely
delete the file, use **delete** instead of **remove**, but *be very very
sure that is what you want* (usually it is not).


keeping in sync
---------------

If multiple people are working on separately checked out versions of the
tree, it is important to keep in sync. CVS makes this easy.

Whenever appropriate - such as when you have no outstanding changes and want
to start editing something run::

	$ cvs update

Which will ensure that you have an up to date copy of the tree. It
will also warn you about files you have modified, created and not added
etc.


conflicts
~~~~~~~~~

If you have modified a file and it has been changed in the repository (by
someone else committing their changes) CVS will merge your changes into the
updated file. In more than 90% of cases, the merge is achieved successfully
as there are no conflicting changes. In the few cases where there are
conflicts, CVS will bring them to your attention and you need to resolve them
before committing the file.

*It is therefore vitally important to pay attention to what CVS says.*


undoing changes
---------------

Sometimes you commit a change and later want to back it out. There are
several ways of doing this, most require use of the underlying rcs commands
`co(1)`_ or `rcs(1)`_. The approach used depends on how recent the change
that needs to be backed out is.


back out uncommitted changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is achieved by simply removing the edited file and then updating::

	$ rm file1
	$ cvs update

most recent commit needs to be backed out
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This is preferably done by checking out the prior version of the file and re-
committing it with a comment to indicate why the previous change is being
backed out. This is most easily done by using the underlying rcs command
`co(1)`_::

	$ co -p1.2 `cat CVS/Repository`/file1,v > file1
	$ cvs diff file1
	$ cvs commit -m"reverted to version 1.2 which worked" file1

The -p1.2 option to co tells it to check out version 1.2 of file1
to stdout. The CVS/Repository file contains the location of the rcs
files (,v) for the working directory.


intermediate change needs to be backed out
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If say the current version of file1 is 1.4 and the change made for 1.2 needs
to be undone::

	$ cvs diff -cb -r1.1 -r1.2 file1 > diffs
	$ patch -R < diffs

In the above example, diffs contains the changes from version 1.1
to 1.2, the patch command is then used to apply the diffs in reverse
(-R). If patch succeeds, then the offending change has been successfully
removed and file1 can be committed.

The patch may fail to apply though if subsequent changes cause conflicts. In
which case patch will create a file1.reg file which contains the patches that
it could not apply. Time for some hand editing.

--------


The lastest version of this page can be found at:
 http://www.crufty.net/help/dns/cvs.htm

:Author: sjg@crufty.net */\* imagine something very witty here \*/*
:Revision: $Id: cvs.txt,v 1.1 2016/04/10 19:30:12 sjg Exp $
:Copyright: `1997-2016 Simon J. Gerraty`_ 

.. _`1997-2016 Simon J. Gerraty`: http://www.crufty.net/misc/copyrght.html
.. _`cvs(1)`: cvs_1.htm
.. _`rcs(1)`: rcs_1.htm
.. _`DNS regression testing`: DNSMmagic.htm#regress
.. _`co(1)`: co_1.htm
