In the course of a project, one will often add new files. Likewise with removing or renaming, or with directories. The general concept to keep in mind in all these cases is that instead of making an irreversible change you want CVS to record the fact that a change has taken place, just as with modifying an existing file. The exact mechanisms to do this in CVS vary depending on the situation.
To add a new file to a directory, follow these steps.
You can also use the
add command to add a new
Unlike most other commands, the
add command is
not recursive. You cannot even type `cvs add
foo/bar'! Instead, you have to
$ cd foo $ cvs add bar
-mmessage] files ...
Schedule files to be added to the repository.
The files or directories specified with
already exist in the current directory. To add a whole
new directory hierarchy to the source repository (for
example, files received from a third-party vendor), use
import command instead. See section import--Import sources into CVS, using vendor branches.
The added files are not placed in the source repository
until you use
commit to make the change
permanent. Doing an
add on a file that was
removed with the
remove command will undo the
effect of the
remove, unless a
command intervened. See section Removing files, for an
The `-k' option specifies the default way that this file will be checked out; for more information see section Substitution modes.
The `-m' option specifies a description for the
file. This description appears in the history log (if
it is enabled, see section The history file). It will also be
saved in the version history inside the repository when
the file is committed. The
log command displays
this description. The description can be changed using
`admin -t'. See section admin--Administration. If you omit the
`-m description' flag, an empty string will
be used. You will not be prompted for a description.
For example, the following commands add the file `backend.c' to the repository:
$ cvs add backend.c $ cvs commit -m "Early version. Not yet compilable." backend.c
When you add a file it is added only on the branch which you are working on (see section Branching and merging). You can later merge the additions to another branch if you want (see section Merging can add or remove files).
Directories change. New files are added, and old files disappear. Still, you want to be able to retrieve an exact copy of old releases.
Here is what you can do to remove a file, but remain able to retrieve old revisions:
updatecommand. If you remove the file without committing your changes, you will of course not be able to retrieve the file as it was immediately before you deleted it.
When you commit the removal of the file, CVS
records the fact that the file no longer exists. It is
possible for a file to exist on only some branches and
not on others, or to re-add another file with the same
name later. CVS will correctly create or not create
the file, based on the `-r' and `-D' options
Schedule file(s) to be removed from the repository (files which have not already been removed from the working directory are not processed). This command does not actually remove the file from the repository until you commit the removal. For a full list of options, see section Quick reference to CVS commands.
Here is an example of removing several files:
$ cd test $ rm *.c $ cvs remove cvs remove: Removing . cvs remove: scheduling a.c for removal cvs remove: scheduling b.c for removal cvs remove: use 'cvs commit' to remove these files permanently $ cvs ci -m "Removed unneeded files" cvs commit: Examining . cvs commit: Committing .
As a convenience you can remove the file and
remove it in one step, by specifying the `-f'
option. For example, the above example could also be
done like this:
$ cd test $ cvs remove -f *.c cvs remove: scheduling a.c for removal cvs remove: scheduling b.c for removal cvs remove: use 'cvs commit' to remove these files permanently $ cvs ci -m "Removed unneeded files" cvs commit: Examining . cvs commit: Committing .
If you execute
remove for a file, and then
change your mind before you commit, you can undo the
remove with an
$ ls CVS ja.h oj.c $ rm oj.c $ cvs remove oj.c cvs remove: scheduling oj.c for removal cvs remove: use 'cvs commit' to remove this file permanently $ cvs add oj.c U oj.c cvs add: oj.c, version 220.127.116.11, resurrected
If you realize your mistake before you run the
remove command you can use
resurrect the file:
$ rm oj.c $ cvs update oj.c cvs update: warning: oj.c was lost U oj.c
When you remove a file it is removed only on the branch which you are working on (see section Branching and merging). You can later merge the removals to another branch if you want (see section Merging can add or remove files).
In concept removing directories is somewhat similar to removing files--you want the directory to not exist in your current working directories, but you also want to be able to retrieve old releases in which the directory existed.
The way that you remove a directory is to remove all
the files in it. You don't remove the directory
itself; there is no way to do that.
Instead you specify the `-P' option to
cvs update or
which will cause CVS to remove empty
directories from working directories.
cvs export always removes empty directories.)
best way to do this is to always specify `-P'; if
you want an empty directory then put a dummy file (for
example `.keepme') in it to prevent `-P' from
Note that `-P' is implied by the `-r' or `-D'
checkout. This way
CVS will be able to correctly create the directory
or not depending on whether the particular version you
are checking out contains any files in that directory.
Moving files to a different directory or renaming them is not difficult, but some of the ways in which this works may be non-obvious. (Moving or renaming a directory is even harder. See section Moving and renaming directories.).
The examples below assume that the file old is renamed to new.
The normal way to move a file is to copy old to new, and then issue the normal CVS commands to remove old from the repository, and add new to it.
$ mv old new $ cvs remove old $ cvs add new $ cvs commit -m "Renamed old to new" old new
This is the simplest way to move a file, it is not
error-prone, and it preserves the history of what was
done. Note that to access the history of the file you
must specify the old or the new name, depending on what
portion of the history you are accessing. For example,
cvs log old will give the log up until the
time of the rename.
When new is committed its revision numbers will start again, usually at 1.1, so if that bothers you, use the `-r rev' option to commit. For more information see section Assigning revisions.
This method is more dangerous, since it involves moving files inside the repository. Read this entire section before trying it out!
$ cd $CVSROOT/dir $ mv old,v new,v
This way also involves direct modifications to the repository. It is safe, but not without drawbacks.
# Copy the RCS file inside the repository $ cd $CVSROOT/dir $ cp old,v new,v # Remove the old file $ cd ~/dir $ rm old $ cvs remove old $ cvs commit old # Remove all tags from new $ cvs update new $ cvs log new # Remember the non-branch tag names $ cvs tag -d tag1 new $ cvs tag -d tag2 new ...
By removing the tags you will be able to check out old revisions.
The normal way to rename or move a directory is to rename or move each file within it as described in section The Normal way to Rename. Then check out with the `-P' option, as described in section Removing directories.
If you really want to hack the repository to rename or delete a directory in the repository, you can do it like this:
$ cd $CVSROOT/parent-dir $ mv old-dir new-dir
If someone had a working copy the CVS commands will cease to work for him, until he removes the directory that disappeared inside the repository.
It is almost always better to move the files in the directory instead of moving the directory. If you move the directory you are unlikely to be able to retrieve old releases correctly, since they probably depend on the name of the directories.
Go to the first, previous, next, last section, table of contents.