6.4. Repository Structure
A CVS repository is composed of the project directories, and the special CVSROOT administrative directory. All the general CVS administrative files and configuration files are kept in CVSROOT. Most of the project-specific CVS administrative files are kept in CVSROOT as well, but there are exceptions, which are detailed next.
The project directories contain the project's files and subdirectories. The project's files are stored in RCS format and have a ,v file suffix.
Any project directory or subdirectory may contain Attic or CVS directories. An Attic subdirectory stores any file from the directory it's part of that doesn't exist on the trunk (the main development line for the file). A CVS subdirectory stores metadata for the files in its directory.
The server also stores files in a temporary directory set by either the TMPDIR environment variable or the -T command-line option. These files are under a directory called cvs-serverPID, where PID is the process ID of the server. If the server is shut down and unable to clean up after itself, the files may be left in place. They can be removed safely if there is no CVS process running with the relevant process ID.
6.4.1. Attic Subdirectory
The Attic subdirectory stores files that have been removed from the trunk (the main line of development), or that were never added to the trunk. If a file exists on only one or more branches, it is kept in the Attic. Each Attic subdirectory contains files that are related to the directory the Attic is in.
CVS manages the Attic itselfyou need to be conscious of it only on the rare occasions when you are editing the repository directly.
6.4.2. CVS Subdirectory
The repository contains CVS subdirectories, which contain the file fileattr, which lists the file attributes of the files in the parent directory. The file attributes are settings for the cvs watch commands. In later versions of CVS, the fileattr file may be used for other attributes or the CVS subdirectory may be used for other files.
The format for fileattr is one line per attribute, each line containing information as follows:
entry-type filename (tab) attribute-name = attribute-value [;attribute-name = attribute-value...]
Attribute names starting with an underscore (_) are reserved for CVS. Future versions of CVS may allow user-defined attributes, but they're not currently permitted.
The F entry type specifies that a line contains attributes for a file. The D entry type with no filename specifies that the line contains default attributes for all files in the directory that includes the CVS subdirectory.
These are the supported attributes:
Example 6-2 shows a fileattr file.
Example 6-2. CVS/fileattr
CVS uses read and write locks to prevent processes from simultaneously writing to or reading from the same repository files. These locks are signaled by the presence of a file or directory with a specific name pattern in project directories. Most CVS users never need to know about these locks; the only time end users will notice the locks is when two people try to commit to the same directory simultaneously, or when a CVS process crashes and leaves a spurious lock file. However, information on CVS's locks is useful to repository administrators who may want to lock a repository when backing the repository up, or may want to write software to interact with the repository.
CVS locks the repository one directory at a time, each lock locking a directory, its Attic and CVS subdirectories, and all files in that directory. A lock does not lock subdirectories, so to lock an entire directory tree, each subdirectory must be locked individually.
These are the file and directory names that indicate CVS locks:
Holding a master lock prohibits programs (such as the freeze script shown later) that honor such locks from creating new locks in the locked directory. Any program that honors the locks will not read from or write to a file unless it has locked the directory the file is in. Master locks are directories, because in most operating systems, directory creation is done as a single operation and can't be interrupted by another process.
A read lock is a nonexclusive lock, which permits others to read files while the directory is locked but not to write to them. You create a master lock before you create a read lock, to ensure that no one else locks the directory while you are trying to lock it. You can release the master lock once you have your read lock, to allow others to read the files as well.
To obtain a read lock:
A write lock is an exclusive lock, which prohibits others from reading or writing the files while you hold the lock. CVS prohibits reading or writing by having processes that use a write lock also hold the master lock until after they release the write lock. The write-lock file exists primarily to provide the process ID, so that you can identify which process is holding the lock if you need to clear it.
To obtain a write lock:
If you are trying to lock multiple directories simultaneously and you encounter an existing lock, you should release all the locks you have obtained before waiting and trying again. This approach helps avoid deadlocks.
A deadlock occurs when two processes attempt to lock multiple directories and each is holding one directory locked while attempting to lock a directory that the other is holding. Such a deadlock prevents either process from continuing.