CVS--Concurrent Versions System v1.12.12.1: Adding, removing, and renaming files and directories

This document was originally released under the GNU General Public License (GPL). All changes to it must also be released under the GPL, as well as the GNU Free Documentation License (which all contributions to this Wiki are released under).

| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Adding, removing, and renaming files and directories

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.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Adding files to a directory

To add a new file to a directory, follow these steps.

  • You must have a working copy of the directory. See section Getting the source.

  • Create the new file inside your working copy of the directory.

  • Use `cvs add filename' to tell CVS that you want to version control the file. If the file contains binary data, specify `-kb' (see section Handling binary files).

  • Use `cvs commit filename' to actually check in the file into the repository. Other developers cannot see the file until you perform this step.

You can also use the add command to add a new

directory.

Unlike most other commands, the add command is

not recursive. You have to explicitly name files and directories that you wish to add to the repository. However, each directory will need to be added separately before you will be able to add new files to those directories.

 
$ mkdir -p foo/bar
$ cp ~/backend.c foo/bar/backend.c
$ cvs add foo
$ cvs add foo/bar
$ cvs add foo/bar/backend.c
Command: cvs add kflag message files …

Schedule files to be added to the repository.

The files or directories specified with add must 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 the 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 commit command intervened. See section Removing files, for an example.

The `-k' option specifies the default way that

this file will be checked out; for more information see 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).


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Removing 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:

  • Make sure that you have not made any uncommitted modifications to the file. See section Viewing differences, for one way to do that. You can also use the status or update command. 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.

  • Remove the file from your working copy of the directory. You can for instance use rm.

  • Use `cvs remove filename' to tell CVS that you really want to delete the file.

  • Use `cvs commit filename' to actually perform the removal of the file from the repository.

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 specified to checkout or update.

Command: cvs remove 1 files …

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 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 cvs

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 add command.

 
$ 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 1.1.1.1, resurrected

If you realize your mistake before you run the

remove command you can use update to 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).


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Removing directories

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 cvs checkout, which will cause CVS to remove empty directories from working directories. (Note that cvs export always removes empty directories.) Probably the 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 removing it.

Note that `-P' is implied by the `-r' or `-D'

options of 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.

Because CVS copies removed files into the attic, you can restore them later using a merge. If you want to restore a whole directory, it can be a bit tricky, but it can be done.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Moving and renaming files

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.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

The Normal way to Rename

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 <var>old <var>new
$ cvs remove <var>old
$ cvs add <var>new
$ cvs commit -m "Renamed <var>old to <var>new" <var>old <var>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 tag' option to commit. For more information see Assigning revisions.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Moving the history file

This method is more dangerous, since it involves moving

files inside the repository. Read this entire section before trying it out!

 
$ cd $CVSROOT/<var>dir
$ mv <var>old,v <var>new,v

Advantages:

  • The log of changes is maintained intact.

  • The revision numbers are not affected.

Disadvantages:

  • Old releases cannot easily be fetched from the repository. (The file will show up as new even in revisions from the time before it was renamed).

  • There is no log information of when the file was renamed.

  • Nasty things might happen if someone accesses the history file while you are moving it. Make sure no one else runs any of the CVS commands while you move it.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Copying the history file

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/<var>dir
$ cp <var>old,v <var>new,v
# Remove the old file
$ cd ~/<var>dir
$ rm <var>old
$ cvs remove <var>old
$ cvs commit <var>old
# Remove all tags from <var>new
$ cvs update <var>new
$ cvs log <var>new             # Remember the non-branch tag names
$ cvs tag -d <var>tag1 <var>new
$ cvs tag -d <var>tag2 <var>new
…

By removing the tags you will be able to check out old

revisions.

Advantages:

  • Checking out old revisions works correctly, as long as you use `-r tag' and not `-D date' to retrieve the revisions.

  • The log of changes is maintained intact.

  • The revision numbers are not affected.

Disadvantages:

  • You cannot easily see the history of the file across the rename.


| < | | > |   | << | | Up | | >> |         |Top| |Contents| |Index| | ? |

Moving and renaming directories

The normal way to rename or move a directory is to

rename or move each file within it as described in The Normal way to Rename. Then check out with the `-P' option, as described in Removing directories.

Inform everyone who has a checked out copy of the directory that the directory will be renamed. They should commit all their changes in all their copies of the project containing the directory to be removed, and remove all their working copies of said project, before you take the steps below.

  1. Rename the directory inside the repository.
  2. Tell everyone that they can check out again and continue working.

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.


Contents#SEC_Contents|Contents]]|</td>

| << | | >> | |Index| | ? |

This document was generated by Derek Price on July, 20 2005 using texi2html 1.77.