home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

  Previous section   Next section

3.7 Removing Files from the Repository

The cvs remove command is used to mark a file as removed in the repository. The file isn't actually removed from the repository; it simply is stored in a special directory called Attic, so that its earlier revisions can be recalled. The file is no longer sent to sandboxes, and it is removed from existing sandboxes at the next cvs update, which displays the message cvs server: filename is no longer in the repository.

A removal must be committed before it affects the repository. If you notice that you accidentally removed a file you need (before you run cvs commit), you can use cvs add to undo the removal and then use cvs update to retrieve the removed file. This process leaves no record in the repository. Similarly, if a file has been added but not committed, cvs remove undoes the addition and leaves no record in the repository.

If someone else modifies a removed file before the removal is committed, the commit will fail and report a conflict. Resolve the conflict by unremoving the file with cvs add, checking the changes with cvs update or cvs diff, and removing the file again if desired. I strongly recommend speaking with the person who modified the file before you resolve such a conflict, lest you remove a file that should be retained.

To use cvs remove on a file, the file must not exist in the sandbox or you must call the cvs remove command with -f. Usually, I delete the file from the sandbox before running cvs remove.

The syntax for cvs remove is:

cvs [cvs-options] remove [command-options] filename

cvs remove has the following options:

-f

Delete the file from the sandbox.

-l

Perform a local, nonrecursive operation on this directory only.

-R

Perform recursive operation on all subdirectories as well as the current directory (default).

Example 3-15 shows a file being removed. Notice that the file is removed from the sandbox using the Unix rm command. Only then can you use cvs remove (unless you specify the -f option).

Example 3-15. Using cvs remove
bash-2.05a$ ls
CVS  main.c  wizzard.h
bash-2.05a$ rm main.c
bash-2.05a$ cvs remove main.c
cvs server: scheduling `main.c' for removal
cvs server: use 'cvs commit' to remove this file permanently

cvs remove is affected by tags, and CVS cannot remove a file that has a sticky tag or a sticky date. Chapter 4 explains sticky tags and dates in detail. Here we will discuss only how they affect file removal.

When a file is retrieved using a tag name or a date, the file in the sandbox reflects the state of the repository at the time the tag or date occurred. Such files are not intended to be changed: they're only static representations of the past. This implies that such files can't be removed, either.

When you try to remove a nonremovable sticky-tagged file, CVS issues an error message such as the following: cvs server: cannot remove file `filename' which has a numeric sticky tag of `1.3'. Correct this error by using cvs update -A; then remove the file.

If a file has a nonbranch sticky tag, cvs remove removes the tag from the file in the sandbox. A comment in the code implies that this behavior may change in future, so if you wish to remove a sticky tag use cvs update -A instead of cvs remove.

3.7.1 Retrieving Removed Files

Retrieving a removed file is similar to retrieving a previous revision of a file. If you need to look at a file without making changes, use either:

cvs update -r revision

or:

cvs checkout -r revision

If you need to make changes, there are three methods you can use to bring the removed file back into active service. Methods 1 and 2 are essentially the same, differing mostly in whether the file is added before or after the data is retrieved. Method 3 uses file merging to accomplish the task and should not be used on binary files.

3.7.1.1 Method 1

Method 1 creates an empty file of the same name, uses cvs add to declare the file active, and then uses cvs update -j to replace the empty file with the file as it was just prior to the removal. The steps are as follows:

  1. Use touch filename to create a file of the specified name.

  2. Use cvs add filename to make the name active again.

  3. Use cvs update -j revision with the revision number immediately before the deletion. This replaces the empty file with the file as it was prior to being removed.

    If you choose the revision number that corresponds to the deletion, the following error message is returned: cvs server: `filename' is no longer in the repository.

  4. Use cvs commit to commit the newly restored file to the repository.

Example 3-16 illustrates this method by retrieving main.c, which was previously removed using cvs remove.

Example 3-16. Retrieving a removed file, method 1
bash-2.05a$ touch main.c
bash-2.05a$ cvs add main.c
cvs server: re-adding file main.c (in place of dead revision 1.3)
cvs server: use 'cvs commit' to add this file permanently
bash-2.05a$ cvs update -j 1.2 main.c
A main.c
bash-2.05a$ cvs commit
Checking in main.c;, 307C written
/var/lib/cvs/wizzard/src/main.c,v  <--  main.c
new revision: 1.4; previous revision: 1.3
done
3.7.1.2 Method 2

Method 2 uses cvs update to retrieve the file to stdout, sends stdout to a file of the same name as the removed file, and then uses cvs add to restore the file to the repository. The steps are as follows:

  1. Use cvs update -r previous_revision -p filename > filename, where previous_revision is the revision just before the file was removed.

  2. Use cvs add filename to make the name active again.

  3. Use cvs commit to commit the newly restored file to the repository.

Example 3-17 shows this method of retrieving a removed file.

Example 3-17. Retrieving a removed file, method 2
bash-2.05a$ cvs update -r 1.5 -p main.c > main.c
=  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  = 
Checking out main.c
RCS:  /var/lib/cvs/wizzard/src/Attic/main.c,v
VERS: 1.5
***************
bash-2.05a$ cvs add main.c
cvs server: re-adding file main.c (in place of dead revision 1.6)
cvs server: use 'cvs commit' to add this file permanently
bash-2.05a$ cvs commit
Checking in main.c;, 314C written
/var/lib/cvs/wizzard/src/main.c,v  <--  main.c
new revision: 1.7; previous revision: 1.6
done
3.7.1.3 Method 3

Method 3 merges the removed file with the unremoved file just before its removal. The steps are as follows:

  1. Use cvs update -j deletion_revision -j previous_revision filename. Be aware of the order of the -j arguments; it's important to put the revision number that refers to the deletion first.

  2. Use cvs commit to commit the newly restored file to the repository.

Example 3-18 shows this method of retrieving a removed file.

Example 3-18. Retrieving a removed file, method 3
bash-2.05a$ cvs update -j 1.8 -j 1.7 main.c
U main.c
bash-2.05a$ cvs commit
Checking in main.c;, 323C written
/var/lib/cvs/wizzard/src/main.c,v  <--  main.c
new revision: 1.9; previous revision: 1.8
done

3.7.2 Removing Directories

CVS doesn't include any mechanism for removing directories from a repository. Any directory that contained files at a point in a project's history should be retained so that earlier revisions of the project can be retrieved.

If a directory is deprecated and its contents are no longer needed for the project, use cvs remove to empty the directory and its subdirectories of files other than the contents of the CVS subdirectory. To prevent these empty directories from being added to the sandbox, use the -P flag to the cvs update and cvs checkout commands. The -P flag instructs CVS not to download empty directories to the sandbox.

The -d command option to update and checkout brings down all directories that are in the repository but not the sandbox, including empty directories.

Use both -d and -P to bring down all nonempty directories.

To remove a directory that has never contained any files, or to remove any directory completely, you need to edit the repository, as described in Chapter 6.


  Previous section   Next section
Top