Chapter 11: Source code control system (SCCS)

Table of contents

Chapter 11

Source code control system (SCCS)

Source Code Control System (SCCS) is a collection of UNIX system commands that maintain and track changes made to source code or documentation. SCCS is basically a file custodian. Under SCCS, whenever changes are made to a file, SCCS records those changes and maintains the original. SCCS can: These features are important if code and documentation undergo frequent changes due to maintenance or enhancement work. Whenever changes are applied to a file under SCCS control, only the latest set of changes are added to the SCCS image of that file. Using this approach, SCCS maintains successive versions, consuming minimal amounts of increased disk space. This allows for efficient use of resources and easy regeneration of previous file versions.

This chapter covers the following topics:

SCCS for beginners
How to create, retrieve, and update SCCS files

Delta numbering
How versions are numbered and named under SCCS

SCCS command conventions
Conventions and rules applied to SCCS commands

SCCS commands
Explanation of SCCS commands, with argument usage

SCCS files
How SCCS files are formatted, protected, and audited


NOTE: Installation and implementation of SCCS are not covered here.

SCCS for beginners

This section presents several terminal session fragments. The best way to learn SCCS is to use it.

Terminology

Files under SCCS are composed of one or more sets of changes applied to the original version of the file. A set of changes depends on all the previous sets. For SCCS to keep track of the changes, any alterations to a file are stored separately in another file called a delta.

Each delta is assigned a name known as an SCCS IDentification string (SID). An SID contains four components. The first two are the release and level numbers, separated by a period. The next two are the branch and sequence numbers, also separated by a period. This is explained in ``Delta numbering''.

The SID for any original file turned over to SCCS is composed of release number 1 and level number 1, stated as 1.1. The SID for the first set of changes made to that file (that is, its first delta) is release 1 and version 2, or 1.2. The next delta would be 1.3, the next 1.4, and so on. There will be more on delta numbering later. At this point, it is enough to know that, by default, SCCS assigns SIDs automatically.

Creating an SCCS file using admin

Using a text editor, create a file called lang, which contains a list of following programming languages:

C
PL/1
FORTRAN
COBOL
ALGOL

Custody of the lang file can be given to SCCS by using the admin(CP) (administer) command. The following command creates an SCCS file from the lang file:

admin -ilang s.lang

All SCCS file names must begin with s., therefore s.lang. The -i option, together with its value argument (lang), indicates that admin is to create a new SCCS file with the contents of the file lang.

The output of the admin command is:

No id keywords (cm7)

This is a warning message that can also be issued by other SCCS commands. Ignore it for now. Its significance is described later with the get(CP) command. In the following examples, this warning message is not shown, although it may be issued.

Remove the lang file. It is no longer needed because it now exists under SCCS as s.lang. Enter:

rm lang

Retrieving a file by means of get

Using the get command, retrieve the file s.lang:

get s.lang

The output of the get command is:

   1.1
   5 lines
This indicates that get has retrieved version 1.1 of the file, which is made up of five lines of text.

The retrieved file has been placed in a new file known as a `g-file'. SCCS forms the name of the g-file by deleting the prefix s. from the name of the SCCS file. Thus, the original lang file has been recreated.

An ls(C) command lists both lang and s.lang files in the directory. SCCS retains s.lang for other uses.

The get s.lang command creates lang as read-only, keeping no information regarding its creation. When a file is retrieved in the above manner, it cannot be edited. If changes are to be made to the file, use the get -e command as follows:

get -e s.lang

The get -e command causes SCCS to create lang for editing. It also places pertinent information about lang in another new file, called the `p-file' (p.lang, in this case), which is needed later by the delta(CP) command.

The get -e command prints additional status information including a message informing the user that a first delta has been created for this file. The SID is included in the get -e output:

   1.1
   new delta  1.2
   5 lines

Recording changes by using delta

Modify the lang file by adding two more programming languages:

SNOBOL
Ada

To record the changes made to lang, issue the following command:

delta s.lang

The following prompt appears:

comments?

Respond with a meaningful description of the changes just applied to the file. For example:

   comments? added more languages
The delta command now reads the p-file (p.lang) and determines what changes have occurred. It does this by performing its own get to retrieve the original version, and applying the diff(C) command. The delta command compares the original and the edited versions of the lang file: it determines the differences and stores those changes in s.lang. The p.lang and lang files, which are no longer needed, are automatically removed.

When this process is complete, delta outputs the following:

   1.2             (1.2 is the SID of the delta just created) 
   2 inserted      (indicates how many new lines are in the file)
   0 deleted       (indicates how many lines were deleted from the file)
   5 unchanged     (indicates unchanged lines in the file)

Additional information about get

As shown in the previous example, get retrieves the latest version of the file s.lang. This is accomplished by starting with the original version and successively applying the changes (deltas) in order until all have been applied. If the get command is issued now, it retrieves version 1.2 of the file s.lang. Any of the following invocations of get produces the same result:

get s.lang
get -r1 s.lang
get -r1.2 s.lang

The numbers following the -r are SIDs. When the level number of the SID (get -r s.lang) is omitted, the default is the highest level number existing within that specific release. The second command (get -r1 s.lang) requests the retrieval of the latest version of release 1. The third command specifically requests the retrieval of a particular version, release 1 level 2.

Whenever a significant change is made to a file, the usual identification method is to increase the release number (the first number of the SID). Because normal automatic numbering of deltas proceeds by incrementing the level number, the user must explicitly instruct SCCS to increment the release number. This is accomplished as follows:

get -e -r2 s.lang

Release 2 does not exist, so get retrieves the latest version before release 2. The get command also interprets this as a request to change the release number of the new delta to 2, thereby naming it 2.1 rather than 1.3. The output that follows indicates that version 1.2 has been retrieved, and 2.1 is the new delta version that will be created.

   1.2
   new delta 2.1
   7 lines
If the file is now edited (for example, by deleting COBOL from the list of languages) and delta is executed:

delta s.lang
comments? deleted COBOL from the list of languages

Then the delta's output is:

   2.1
   0 inserted
   1 deleted
   6 unchanged
Deltas can now be created in release 2 (deltas 2.2, 2.3, and so on), or another new release can be created in a similar manner.

Delta numbering

Deltas may be thought of as the nodes of a tree in which the root node is the initial version of the file. The root node (original file) is normally named 1.1 and successor deltas (nodes) are named 1.2, 1.3, 1.4, and so on. The two numbers in these names are the first two components of an SID, known as the `release' and `level' numbers, respectively. SCCS automatically names new deltas by incrementing the level numbers whenever a delta is made.

In addition, if a release number is incremented, indicating a major change, the new release number is applied to all subsequent deltas. (An example of this evolutionary process is represented in Figure 11-1, ``Evolution of an SCCS file''.) 

Figure 11-1 Evolution of an SCCS file

This is the normal sequential development of an SCCS file, with each delta dependent on the preceding deltas. Such a structure is called the trunk of an SCCS tree.

There are situations that require branching an SCCS tree. That is, changes are planned for a given delta that are not dependent on all previous deltas. For example, consider a program in production, at version 1.3, and for which development work on release 2 is already in progress. Release 2 may already have a delta in progress as shown in Figure 11-1, ``Evolution of an SCCS file''. Assume that a problem is reported in version 1.3 that cannot wait for correction until release 2. The changes necessary to correct the problem are applied as a delta to version 1.3. This creates a new version that will then be released to the user, but does not affect the changes being applied for release 2 (that is, deltas 1.4, 2.1, 2.2, and so on). This new delta is the first node of a new branch of the tree.

Branch delta names always have four SID components: the same release number and level number as the trunk delta, plus a branch number and sequence number. The format is as follows:

release.level.branch.sequence

The branch number of the first delta branching off any trunk delta is always 1, and its sequence number is also 1. For example, the full SID for a delta branching off trunk delta 1.3 will be 1.3.1.1. As other deltas on that same branch are created, only the sequence number changes: 1.3.1.2, 1.3.1.3, and so forth. This is shown in Figure 11-2, ``Tree structure with branch deltas'': 

Figure 11-2 Tree structure with branch deltas

The branch number is incremented only when a delta is created that starts a new branch off an existing branch, as shown in Figure 11-3, ``Extended branching concept''. As this secondary branch develops, the sequence numbers of its deltas are incremented (1.3.2.1, 1.3.2.2, and so on), but the secondary branch number remains the same. 

Figure 11-3 Extended branching concept

The concept of branching may be extended to any delta in the tree, and the numbering of the resulting deltas proceeds as shown here. SCCS allows the generation of complex tree structures. Although this capability has been provided for certain specialized uses, the SCCS tree should be kept as simple as possible.

SCCS command conventions

SCCS commands accept two types of arguments:

A key letter represents an option that begins with a minus (-) sign, followed by a lowercase letter and, in some instances, a value.

File arguments, which may be file or directory names, specify the file(s) that the SCCS command is to process. Naming a directory is equivalent to naming all the SCCS files contained in the directory, in which case non-SCCS files and files which are unreadable are silently ignored.

In general, a filename argument may not begin with a minus sign. If a filename - (a single minus sign) is specified, the command reads the standard input (usually your terminal) for lines and takes each line as the name of an SCCS file to be processed. The standard input is read until end-of-file. This feature is often used in pipelines with, for example, the commands find(C) and ls(C).

Key letters are processed before filenames. Therefore, the placement of key letters is arbitrary; that is, they may be interspersed with file names. File names, however, are processed left to right. Somewhat different conventions apply to what(CP), sccsdiff(CP), and val(CP), detailed later under SCCS commands and documented in their respective manual pages.

Certain actions of various SCCS commands are controlled by flags appearing in SCCS files. Some of these flags are discussed, but for a complete description see admin(CP).

There is distinction between real user and effective user when discussing various actions of SCCS commands. For now, assume that the person logged into the UNIX system is both the real and effective user. See passwd(C) for more about real and effective users.

x-files and z-files

All SCCS commands that modify an SCCS file do so by writing a copy called the `x-file'. This is done to ensure that the SCCS file is not damaged if processing terminates abnormally. SCCS names the x-file by replacing the s. prefix of the SCCS filename with an x. prefix. The x-file is created in the same directory as the SCCS file, given the same mode (see chmod(C)) and owned by the effective user. When processing is complete, the old SCCS file is destroyed, and the modified x-file is renamed (with x. replaced by s.) and becomes the new SCCS file.

To prevent simultaneous updates to an SCCS file, the same modifying commands also create a lock-file called the `z-file'. SCCS forms its name by replacing the s. prefix of the SCCS filename with a z. prefix. The z-file contains the process number of the command that created it, and its existence prevents other commands from processing the SCCS file. The z-file is created with access permission mode 444 (read only) in the same directory as the SCCS file, and is owned by the effective user. Like the x-file, the z-file exists only for the duration of the execution of the command that creates it.

In general, users can ignore x-files and z-files. They are useful only in the event of system crashes or similar situations.

SCCS commands

This section describes the major features of the SCCS commands along with their most common arguments. Full descriptions with details of all arguments are presented in their respective manual pages.

Here is a quick-reference overview of the commands:



admin
initializes SCCS files, manipulates their descriptive text, and controls delta creation rights 

cdc
changes the commentary associated with a delta 

comb
combines consecutive deltas into one to reduce the size of an SCCS file 

delta
applies deltas (changes) to SCCS files and creates new versions 

get
retrieves versions of SCCS files 

help
provides an explanation of error messages 

prs
prints portions of an SCCS file in user-specified format 

rmdel
removes a delta from an SCCS file; allows removal of deltas created by mistake

sact
prints information about files that are currently out for editing 

sccsdiff
shows differences between any two versions of an SCCS file 

unget
undoes the effect of a get -e before the file is changed 

val
validates an SCCS file 

vc
a filter that may be used for version control 

what
searches any UNIX system file(s) for all occurrences of a special pattern and prints out what follows it; useful in identifying information inserted by the get command 

Error messages

SCCS commands produce error messages on the diagnostic output in this format:

ERROR [name-of-file-being-processed]: message text (code)
The code in parentheses can be used as an argument to the help(CP) command to obtain a further explanation of the message. Detection of a fatal error during the processing of a file causes the SCCS command to stop processing that file and proceed with the next file specified.

help command

The help(CP) command provides an explanation of the error messages. For example:

get lang

This error message is displayed:

   ERROR [lang]: not an SCCS file (co1)
For more information on this error message, use the help command in conjunction with the error code (co1), for example:

help co1

This provides the following explanation of why get lang produced an error message:

   co1:
   "not an SCCS file"
   A file that you think is an SCCS file
   does not begin with the characters "s.".
The help command, along with an error code, will provide assistance in understanding the meaning of most SCCS messages.

get command

The get(CP) command creates a file containing a specified version of an SCCS file. The version is retrieved by beginning with the initial version and then applying deltas, in order, until the desired version is obtained. The resulting file is called the `g-file'. It is created in the current directory and owned by the real user. The mode assigned to the g-file depends on how the get command is used.

The most common use of get is:

get s.abc

This retrieves the latest version of file abc from the SCCS file tree trunk and produces (for example) on the standard output:

   1.3
   67 lines
   No id keywords (cm7)
This means version 1.3 of file s.abc has been retrieved (assuming 1.3 is the latest trunk delta), it has 67 lines of text, and no ID keywords have been substituted in the file.

The generated g-file (file abc) is given access permission mode 444 (read only). This particular way of using get produces g-files only for inspection, compilation, and so on. It is not intended for editing (making deltas).

When several files are specified, the same information is output for each one. For example, enter:

get s.abc s.xyz

It produces:

   s.abc:
   1.3
   67 lines
   No id keywords (cm7)

s.xyz: 1.7 85 lines No id keywords (cm7)

ID keywords in SCCS

In generating a g-file for compilation, it is useful to record the date and time of creation, the version retrieved, and the module's name within the g-file. This information can eventually appear in a load module when one is created. SCCS provides a convenient mechanism for doing this automatically. Identification (ID) keywords appearing anywhere in the generated file are replaced by appropriate values according to the definitions of those ID keywords. The format of an ID keyword is an uppercase letter enclosed by percent signs (%).

%I%

In this example, I is the ID keyword replaced by the SID of the retrieved version of a file. Similarly, %H% is the current date in MM/DD/YY format and %M% is the name of the g-file. When get is executed on an SCCS file containing the following PL/1 declaration:

   DCL ID CHAR(100) VAR INIT('%M% %I% %H%');
The PL/1 declaration produces the following:
   DCL  ID  CHAR(100)  VAR  INIT(&vprime;MODNAME  2.3  07/18/85&vprime;);
For a complete list of the approximately 20 ID keywords provided, see get(CP).

When no ID keywords are substituted by get, the following message is issued:

   No id keywords (cm7)
This message is normally treated as a warning by get, although the presence of the SCCS file i flag causes it to be treated as an error. For a complete list of the SCCS file flags, see admin(CP).

Retrieval of different versions

The version of an SCCS file that get retrieves is the most recently created delta of the highest-numbered trunk release. However, any other version can be retrieved with get -r by specifying the version's SID. The following command retrieves version 1.3 of file s.abc and produces the sample message on the standard output:

   get  -r1.3  s.abc
   1.3
   64 lines
A branch delta can be retrieved similarly, as demonstrated with the following command and sample output:
   get  -r1.5.2.3  s.abc
   1.5.2.3
   234 lines
When an SID is specified and the particular version does not exist in the SCCS file, an error message results.

The level number can be omitted, causing the retrieval of the trunk delta with the highest level number within the given release. The following command and sample output illustrate:

   get  -r3  s.abc
   3.7
   213 lines
If the specified release does not exist, get retrieves the trunk delta with the highest level number within the highest-numbered existing release that is lower than the given release. In the following example, release 9 is specified for retrieval. However, since the specified release does not exist, trunk delta 7.6 is retrieved as the latest version of file s.abc below release 9.
   get  -r9  s.abc
   7.6
   420 lines
For details on numbering by delta's see ``Delta numbering''.

Similarly, omitting the sequence number, for example, results in the retrieval of the branch delta with the highest sequence number on the given branch. (If the given branch does not exist, an error message results.)

   get  -r4.3.2  s.abc
   4.3.2.8
   89 lines
The get -t command retrieves the latest (top) version of a particular release when no -r is used or when its value is simply a release number. The latest version is the delta produced most recently, independent of its location on the SCCS file tree. The following command (and sample output) illustrate this for a case where the most recent delta in release 3 is 3.5:
   get  -r3  -t  s.abc
   3.5
   59 lines
However, if branch delta 3.2.1.5 were the latest delta (created after delta 3.5), the same command might produce:
   3.2.1.5
   46 lines

Updating source

The get -e command indicates an intent to make a delta. First, get checks the following conditions:

A failure of any of the first three conditions causes the processing of the corresponding SCCS file to terminate.

If the above checks succeed, get -e causes the creation of a g-file in the current directory with mode 644 (readable by everyone, writable only by the owner) owned by the real user. If a writable g-file already exists, get terminates with an error. This is to prevent inadvertent destruction of a g-file while it is being edited for the purpose of making a delta. Any ID keywords appearing in the g-file are not substituted by get -e because the generated g-file is subsequently used to create another delta. Replacement of ID keywords causes them to be permanently changed in the SCCS file. As a direct result of this, get does not check for presence of ID keywords in the g-file. The following message is never output when get -e is used.

   No id keywords (cm7)
In addition, get -e causes the creation (or updating) of a p-file that is used to pass information to the delta command.

For example:

get -e s.abc

The output of this command is:

   1.3
   new delta 1.4
   67 lines


Undoing a get -e

There may be times when a file is erroneously retrieved for editing, such as when there is really no editing that needs to be done at the time. In such cases, the unget(CP) command cancels the delta reservation that was set up. For example, enter either of the following commands:

unget -r1.4 s.abc
unget s.abc

These commands produce:

   1.4

Additional get options

If get -r and/or -t keys are used together with the -e option, the version retrieved for editing is specified with -r and/or -t.

The get -i and -x commands specify a list of deltas to be included and excluded, respectively. (See get(CP) for the syntax of such a list.) Including a delta means forcing its changes to be included in the retrieved version. This is useful in applying the same changes to more than one version of the SCCS file. Excluding a delta means forcing it not to be applied. This may be used to undo the effects of a previous delta in the version to be created.

Whenever deltas are included or excluded, get checks for possible interference with other deltas. For example, two deltas can interfere when each one changes the same line of the retrieved g-file. A warning shows the range of lines within the retrieved g-file where the problem may exist.


NOTE: The user should examine the g-file to determine what the problem is and take appropriate corrective steps (such as edit the file).

The get -i and get -x commands should be used with care.

The get -k command has two uses. The first is to regenerate a g-file that may have been accidentally removed or corrupted after get -e. The second use is to generate a g-file in which the replacement of ID keywords has been suppressed. A g-file generated by get -k is identical to one produced by the get -e command. However, no processing related to the p-file takes place.

Concurrent edits of different SID

The ability to retrieve different versions of an SCCS file allows several deltas to be in progress at any given time. This means that several get -e commands may be executed on the same file unless two executions retrieve the same version or multiple concurrent edits are allowed.

The p-file created by get -e is named by automatic replacement of the SCCS filename's prefix s. with p.. It is created in the same directory as the SCCS file, given mode 644 (readable by everyone, writable only by the owner), and owned by the effective user. The p-file contains the following information for each delta that is still in progress:

The first execution of get -e causes the creation of a p-file for the corresponding SCCS file. Subsequent executions simply update the p-file with a line containing the above information. Before updating, however, get checks to assure that the SID of the version to be retrieved has not already been retrieved (unless multiple concurrent edits are allowed). If the check succeeds, the user is informed that other deltas are in progress, and processing continues. If the check fails, an error message results.

It should be noted that concurrent executions of get must be carried out from different directories. Subsequent executions from the same directory attempt to overwrite the g-file, which is an SCCS error condition. In practice, this problem does not arise because each user normally has a different working directory.

For a discussion of how different users are permitted to use SCCS commands on the same files, see ``Protection''.
Table 11-1, ``Determination of new SID'' shows the possible SID components a user can specify with get (left-most column), the version that is then retrieved by get, and the resulting SID for the delta, which delta creates (right-most column). 

Table 11-1 Determination of new SID

 ---------------------------------------------------------------------
|----------|---------|------------------|-----------|----------------|
|    SID   |  b key-|       Other      |     SID   |   SID of delta |
| specified|  letter |     conditions   |  retrieved|  to be created |
|  in get |   used+ |                  |   by get  |     by delta   |
|----------|---------|------------------|-----------|----------------|
| none++   |    no   |  R defaults to mR|  mR.mL    |  mR.(mL+1)     |
| none++   |    yes  |  R defaults to mR|  mR.mL    |  mR.mL.(mB+1).1|
|----------|---------|------------------|-----------|----------------|
| R        |    no   |  R > mR          |  mR.mL    |  R.1§          |
| R        |    no   |  R = mR          |  mR.mL    |  mR.(mL+1)     |
| R        |    yes  |  R > mR          |  mR.mL    |  mR.mL.(mB+1).1|
| R        |    yes  |  R = mR          |  mR.mL    |  mR.mL.(mB+1).1|
| R        |        |  R< mR and R     |  hR.mL  |  hR.mL.(mB+1).1|
|          |         |  does not exist  |           |                |
| R        |        |  Trunk successor |  R.mL     |  R.mL.(mB+1).1 |
|          |         |  number in       |           |                |
|          |         |  release > R,    |           |                |
|          |         |  and R exists    |           |                |
|----------|---------|------------------|-----------|----------------|
| R.L.     |    no   |  No trunk        |  R.L      |  R.(L+1)       |
|          |         |  successor       |           |                |
| R.L.     |    yes  |  No trunk        |  R.L      |  R.L.(mB+1).1  |
|          |         |  successor       |           |                |
| R.L      |        |  Trunk successor |  R.L      |  R.L.(mB+1).1  |
|          |         |  in release >= R |           |                |
|----------|---------|------------------|-----------|----------------|
| R.L.B    |    no   |  No branch       |  R.L.B.mS |  R.L.B.(mS+1)  |
|          |         |  successor       |           |                |
| R.L.B    |    yes  |  No branch       |  R.L.B.mS |  R.L.(mB+1).1  |
|          |         |  successor       |           |                |
|----------|---------|------------------|-----------|----------------|
| R.L.B.S  |    no   |  No branch       |  R.L.B.S  |  R.L.B.(S+1)   |
|          |         |  successor       |           |                |
| R.L.B.S  |    yes  |  No branch       |  R.L.B.S  |  R.L.(mB+1).1  |
|          |         |  successor       |           |                |
| R.L.B.S  |        |  Branch successor|  R.L.B.S  |  R.L.(mB+1).1  |
|--------------------------------------------------------------------|
| Footnotes , +, ++, §, and  on next page.                        |
|--------------------------------------------------------------------|
Footnotes to Table 11-1, ``Determination of new SID'':

R, L, B, and S mean release, level, branch, and sequence numbers in the SID, and m means maximum. For example, R.mL means the maximum level number within release R. R.L.(mB+1).1 means the first sequence number on the new branch (that is, the maximum branch number plus 1) of level L within release R. Note that, if the SID specified is R.L, R.L.B, or R.L.B.S, then each of these specified SID numbers must exist.

+
The -b option is effective only if the SCCS file b flag is present. An entry of - means `irrelevant'. See admin(CP) for a discussion of the b flag.

The release hR is the highest existing release that is lower than the specified, nonexistent release R.

++
This case applies if the SCCS file d (default SID) flag is not present. If the d flag is present in the file, the SID is interpreted as though specified on the command line. Therefore, one of the other cases in this figure applies.

§
This forces the creation of the first delta in a new release.

Concurrent edits of same SID

Under normal conditions, more than one get -e for the same SID is not permitted. That is, delta must be executed before a subsequent get -e is executed on the same SID.

Multiple concurrent edits are allowed if the SCCS file j flag is set. For example:

get -e s.abc

This produces:

   1.1
   new delta 1.2
   5 lines
This can be immediately followed by (without an intervening delta):

get -e s.abc

This produces:

   1.1
   new delta 1.1.1.1
   5 lines
In this case, a delta after the first get produces delta 1.2 (assuming that 1.1 is the most recent trunk delta), and a delta after the second get produces delta 1.1.1.1.

Key letters that affect output

The get -p command causes the retrieved text to be written to the standard output, rather than to a g-file. In addition, all output normally directed to the standard output (such as the SID of the version retrieved and the number of lines retrieved) is directed instead to the diagnostic output. The get -p command creates a g-file with an arbitrary name, as in:

get -p s.abc > arbitrary-filename

The get -s command suppresses output normally directed to the standard output, such as the SID of the retrieved version and the number of lines retrieved, but it does not affect messages normally directed to the diagnostic output. The get -s command prevents nondiagnostic messages from appearing on the user's terminal and is often used with -p to pipe the output, as in:

get -p -s s.abc | pg

The get -g command suppresses the retrieval of the text of an SCCS file. This is useful in several ways. It may be used to verify a particular SID in an SCCS file. For example:

get -g -r4.3 s.abc

This outputs the SID 4.3 if it exists in the SCCS file s.abc, or an error message if it does not.

Another use of get -g is in regenerating a p-file that may have been accidentally destroyed, as in:

get -e -g s.abc

The get -l command causes SCCS to create an `l-file'. It is named by replacing the s. of the SCCS filename with l., created in the current directory with mode 444 (read only) and owned by the real user. The l-file contains a table showing the deltas used in constructing a particular version of the SCCS file. See get(CP) for a description of the delta table format.

The following command generates an l-file, showing the deltas applied to retrieve version 2.3 of file s.abc.

get -r2.3 -l s.abc

Specifying p with -l, for example, results in the output being written to the standard output, rather than to the l-file.

get -lp -r2.3 s.abc

The get -g command can be used with -l to suppress the retrieval of the text. For example:

get -g -l s.abc

The get -m command identifies the changes applied to an SCCS file. Each line of the g-file is preceded by the SID of the delta that caused the line to be inserted. The SID is separated from the text of the line by a tab character.

The get -n command causes each line of a g-file to be preceded by the value of the ID keyword and a tab character. This is most often used in a pipeline with grep(C). For example, to find all lines that match a given pattern in the latest version of each SCCS file in a directory, the following can be executed:

get -p -n -s directory | grep pattern

If both -m and -n are specified, each line of the generated g-file is preceded by the value of the %M% ID keyword and a tab (the effect of -n), and is followed by the line in the format produced by -m. Because use of -m and/or -n causes the contents of the g-file to be modified, such a g-file must not be used for creating a delta. Therefore, neither -m nor -n may be specified together with get -e.


NOTE: See get(CP) for a full description of additional key letters.

delta command

The delta(CP) command incorporates changes made to a g-file into the corresponding SCCS file (that is, to create a delta and, therefore, a new version of the file).

The delta command requires the existence of a p-file (created by means of get -e). It examines the p-file to verify the presence of an entry containing the user's login name. If none is found, an error message results.

The delta command performs the same permission checks that get -e performs. If all checks are successful, delta determines what has been changed in the g-file by comparing it, using diff(C), with its own temporary copy of the g-file as it was before editing. This temporary copy of the g-file is called the d-file, and is obtained by performing an internal get on the SID specified in the p-file entry.

The required p-file entry is the one containing the login name of the user executing delta, because the user who retrieved the g-file must be the one who creates the delta. However, in the case of multiple concurrent edits, if the login name of the user appears in more than one entry, then the same user has executed get -e more than once on the same SCCS file. Then, delta -r must be used to specify the SID that uniquely identifies the p-file entry. This entry becomes the one used to obtain the SID of the delta to be created.

In practice, the following is the most common use of delta:

delta s.abc

This command results in the following prompt:

   comments?
The user replies with a description of why the delta is being made, ending the reply with a new-line character. The user's response may be up to 512 characters long with new-lines (not intended to terminate the response) escaped by backslashes (\).

If the SCCS file v flag is present, delta first prompts with:

   MRs?
Modification Requests (MRs), is a formal way of asking for corrections or enhancements to a file. After the MRs is specified, the standard output is then read for MR numbers. These are separated by blanks and/or tabs, ending with a new-line character. In some controlled environments where changes to source files are tracked, deltas are permitted only when initiated by a trouble report/ticket, change request, and so on, collectively known as MRs. Recording MR numbers within deltas is a way of enforcing the rules of the change-management process.

The delta -y and/or delta -m commands can be used to enter comments and MR numbers on the command line rather than through the standard input, for example:

delta -y"descriptive comment" -m"mrnum1 mrnum2" s.abc

In this case, the prompts for comments and MRs are not printed, and the standard input is not read. These two key letters are useful when delta is executed from within a shell procedure. See sh(C).


NOTE: The delta -m command is allowed only if the SCCS file v flag is present.

All comments and MR numbers, whether solicited by a delta or supplied by keys, are recorded as part of the entry for the delta being created. They are applicable to all SCCS files specified with the same invocation of the delta.

If delta is used with more than one file argument and the first file named has an SCCS file v flag, all files named must have this flag. Similarly, if the first file named does not have the flag, none of the files named may have it.

When delta processing is complete, the standard output displays the SID of the new delta (from the p-file) and the number of lines inserted, deleted, and left unchanged. Here is an example:

   1.4
   14 inserted
   7 deleted
   345 unchanged
If line counts do not agree with the user's perception of the changes made to a g-file, it may be because there are various ways to describe a set of changes, especially if lines are moved around in the g-file. However, the total number of lines in the new delta (the number inserted plus the number left unchanged) should always agree with the number of lines in the edited g-file.

If, in the process of making a delta, delta finds no ID keywords in the edited g-file, the following message is issued after the prompts for commentary but before any other output:

   No id keywords (cm7)
This means that any ID keywords that may have existed in the SCCS file have been replaced by their values or deleted during the editing process. This could be caused by: In any case, the delta is created unless there is an SCCS file i flag present (meaning the error should be treated as fatal), in which case the delta is not created.

After the processing of an SCCS file is complete, the corresponding p-file entry is removed from the p-file. All updates to the p-file are made to a temporary copy, the `q-file,' whose use is similar to that of the x-file. If there is only one entry in the p-file, then the p-file itself is removed.

In addition, delta removes the edited g-file unless -n is specified. For example, the following command keeps the g-file after processing:

delta -n s.abc

The delta -s command suppresses all output normally directed to the standard output, other than comments? and MRs? prompts. Thus, use of -s with -y (and/or -m) causes delta not to read the standard input or write the standard output.

The changes made to the g-file constitute the delta and may be printed on the standard output by using delta -p. The format of this output is similar to that produced by diff(C).

admin command

The admin(CP) command administers SCCS files; that is, it creates new SCCS files and changes the parameters of existing ones. When an SCCS file is created, its parameters are initialized by use of key letters with admin, or are assigned default values if no key letters are supplied. The same key letters are used to change the parameters of existing SCCS files.

Two key letters are used in detecting and correcting corrupted SCCS files. (See ``Auditing''.)

Newly created SCCS files are given access permission mode 444 (read only), and are owned by the effective user. Only a user with write permission in the directory containing the SCCS file may use the admin command on that file.

Creation of SCCS files

An SCCS file can be created by executing the following command:

admin -ifirst s.abc

The value first with the -i option is the name of the file from which the text of the initial delta of the SCCS file, s.abc, is to be taken. Omission of a value with -i indicates that admin is to read the standard input for the text of the initial delta.

The following command is equivalent to the previous example:

admin -i s.abc < first

If the text of the initial delta does not contain ID keywords, admin issues the following warning message:

   No id keywords (cm7)
However, if the command also sets the SCCS file i flag (not to be confused with the -i command line option), then the message is treated as an error and the SCCS file is not created. Only one SCCS file may be created at a time using admin -i.

The -r option used in conjunction with admin creates a release number for the first delta.

admin -ifirst -r3 s.abc

This command specifies that the first delta should be named 3.1 rather than the normal 1.1. Because -r has meaning only when creating the first delta, its use is permitted only with -i.

Inserting commentary for the initial delta

When an SCCS file is created, the user may want to record why this was done. Comments (admin -y) and/or MR numbers (-m) can be entered in exactly the same way as a delta.

If the -y option is omitted, a comment line of the following form is generated:

   date  and  time  created  yy/mm/dd  hh:mm:ss by  logname
If it is desired to supply MR numbers (admin -m), the SCCS file v flag must be set by means of the -f command line option. The v flag simply determines whether MR numbers must be supplied when using any SCCS command that modifies a delta commentary. For example:

admin -ifirst -mmrnum1 -fv s.abc


NOTE: -y and -m are effective only if a new SCCS file is being created.

Initialization and modification of SCCS file parameters

Part of an SCCS file is reserved for descriptive text, usually a summary of the file's contents and purpose. It can be initialized or changed by using admin -t.

When an SCCS file is first being created and -t is used, it must be followed by the name of a file from which the descriptive text is to be taken. For example, the following command specifies that the descriptive text is to be taken from file desc.

admin -ifirst -tdesc s.abc

When processing an existing SCCS file, -t specifies that the descriptive text (if any) currently in the file is to be replaced with the text in the named file. Omission of the filename after the -t key letter results in the removal of the descriptive text from the SCCS file. For example:

admin -t s.abc

The flags of an SCCS file may be initialized or changed by admin -f or deleted by means of -d.

SCCS file flags direct certain actions of the various commands. (See admin(CP) for a description of all the flags.) For example, the i flag specifies that a warning message (stating that there are no ID keywords contained in the SCCS file) should be treated as an error. The d (default SID) flag specifies the default version of the SCCS file to be retrieved by the get command.

The admin -f command sets flags and, if desired, their values. In the following example, the i and m (module name) flags are set.

admin -ifirst -fi -fmmodname s.abc

The value modname specified for the m flag is the value that the get command uses to replace the %M% ID keyword. (In the absence of the m flag, the name of the g-file is used as the replacement for the %M% ID keyword.) Several -f key letters may be supplied on a single admin, and they may be used whether the command is creating a new SCCS file or processing an existing one.

The admin -d command deletes a flag from an existing SCCS file. For example:

admin -dm s.abc

This command removes the m flag from the SCCS file. Several -d key letters may be used with one admin and may be intermixed with -f.

SCCS files contain a list of login names and/or group IDs of users who are allowed to create deltas. This list is empty by default, allowing anyone to create deltas. To create a user list (or add to an existing one), use admin -a. For example:

admin -axyz -awql -a1234 s.abc

This adds the login names xyz and wql and the group ID 1234 to the list. The admin -a command may be used whether creating a new SCCS file or processing an existing one.

The admin -e command (erase) removes login names or group IDs from the list.

prs command

The prs(CP) command prints all or part of an SCCS file on the standard output. If prs -d is used, the output is in a format called data specification. Data specification is a string of SCCS file data key words (not to be confused with get ID keywords) interspersed with optional user text.

Data keywords are replaced by appropriate values, according to their definitions.

:I:

In this example, I is defined as the data keyword replaced by the SID of a specified delta. Similarly, :F: is the data keyword for the SCCS filename currently being processed, and :C: is the comment line associated with a specified delta. All parts of an SCCS file have an associated data keyword. For a complete list, see prs(CP).

There is no limit to the number of times a data keyword can appear in a data specification. For example:

prs -d":I: this is the top delta for :F: :I:" s.abc

This produces the following output:

   2.1 this is the top delta for s.abc 2.1
Information can be obtained from a single delta by specifying its SID using prs -r. For example:

prs -d":F:: :I: comment line is: :C:" -r1.4 s.abc

This produces the following output:

   s.abc:  1.4 comment line is:THIS IS A COMMENT
If -r is not specified, the value of the SID defaults to the most recently created delta.

In addition, information from a range of deltas may be obtained with -l or -e. Using prs -e substitutes data keywords for the SID designated by means of -r and all deltas created earlier, while prs -l substitutes data keywords for the SID designated by means of -r and all deltas created later. For example:

   prs  -d:I: -r1.4  -e  s.abc
This produces output such as:
   1.4
   1.3
   1.2.1.1
   1.2
   1.1
Another example is:

prs -d:I: -r1.4 -l s.abc

This produces output such as:

   3.3
   3.2
   3.1
   2.2.1.1
   2.2
   2.1
   1.4
Substitution of data keywords for all deltas of the SCCS file may be obtained by specifying both -e and -l.

sact command

The sact(CP) command is like a special form of the prs command that produces a report about files that are out for editing. The command takes only one type of argument: a list of file or directory names. The report shows the SID of any file in the list that is out for editing, the SID of the impending delta, the login of the user who executed the get -e command, and the date and time the get -e was executed. It is a useful command for an administrator.

rmdel command

The rmdel(CP) command allows removal of a delta from an SCCS file. Its use should be reserved for deltas in which incorrect global changes were made. The delta to be removed must be a leaf delta. That is, it must be the most recently created delta on its branch or on the trunk of the SCCS file tree. In Figure 11-3, ``Extended branching concept'', only deltas 1.3.1.2, 1.3.2.2, and 2.2 can be removed. Only after they are removed can deltas 1.3.2.1 and 2.1 be removed.

To remove a delta, the effective user must have write permission in the directory containing the SCCS file. In addition, the real user must be either the one who created the delta being removed or the owner of the SCCS file and its directory.

The -r key letter is mandatory with rmdel. It specifies the complete SID of the delta to be removed. For example, to specify the removal of trunk delta 2.3, use the command:

rmdel -r2.3 s.abc

Before removing the delta, rmdel checks that the release number (%R%) of the given SID satisfies the relation:

   floor lessthan or equalto R lessthan or equalto ceiling
The rmdel command also checks the SID to make sure it is not for a version on which a get for editing has been executed and whose associated delta has not yet been made. In addition, the login name or group ID of the user must appear in the file's user list (or the user list must be empty). Also, the release specified cannot be locked against editing. That is, if the SCCS file l flag is set, the release must not be contained in the list. (See admin(CP).) If these conditions are not satisfied, processing is terminated, and the delta is not removed.

Once a specified delta has been removed, its type indicator in the delta table of the SCCS file is changed from D (delta) to R (removed).

cdc command

The cdc(CP) command changes the commentary made when the delta was created. It is similar to the rmdel command (for instance, -r and full SID are necessary), although the delta need not be a leaf delta.

cdc -r3.4 s.abc

The above example specifies that the commentary of delta 3.4 is to be changed. New commentary is then prompted for, as with delta.

The old commentary is kept, but it is preceded by a comment line indicating that it has been superseded, and the new commentary is entered ahead of the comment line. The inserted comment line records the login name of the user executing cdc and the time of its execution.

The cdc command also allows for the insertion of new MR numbers as well as the deletion of old MR numbers (using the "!" prefix). The following command inserts mrnum3 and deletes mrnum1 for delta 1.4.

cdc -r1.4 s.abc

MRs? mrnum3 !mrnum1
(The `MRs?' prompt appears only if v flag has been set.)

comments?
deleted wrong MR number and inserted correct MR number


NOTE: An MR is described in ``delta command''.

what command

The what(CP) command finds identifying information within any UNIX system file whose name is given as an argument. No key letters are accepted. The what command searches the given file(s) for all occurrences of the string @(#), which is the replacement for the %Z% ID keyword. (See get(CP).) It prints on the standard output whatever follows the string until the first double quote ("), greater than (>), backslash (\), new-line, or nonprinting NULL character.

For example, an SCCS file called s.prog.c (a C language program) contains the following line:

   char  id[]= "%W%";
After the following command is used, the resulting g-file could be compiled to produce prog.o and a.out:

get -r3.4 s.prog.c

Then, the following command is executed:

what prog.c prog.o a.out

   prog.c:
     prog.c:  3.4
   prog.o:
     prog.c:  3.4
   a.out:
     prog.c:  3.4
The string searched for by what need not be inserted by means of an ID keyword of get; you can insert it in any convenient manner.

sccsdiff command

The sccsdiff(CP) command determines (and prints on the standard output) the differences between any two versions of an SCCS file. The versions to be compared are specified with sccsdiff -r in the same way as with get -r. SID numbers must be specified as the first two arguments. Any following key letters are interpreted as arguments to the pr(C) command (which prints the differences), and must appear before any filenames. The SCCS file(s) to be processed are named last. Directory names and a name `-' (a single minus sign) are not acceptable to sccsdiff.

The following is an example of the format of sccsdiff:

sccsdiff -r3.4 -r5.6 s.abc

The differences are printed the same way as by diff(C).

comb command

The comb(CP) command lets the user try to reduce the size of an SCCS file. It generates a shell procedure (see sh(C)). on the standard output, which reconstructs the file by discarding unwanted deltas and combining other specified deltas. (It is not recommended that comb be used as a matter of routine.)

In the absence of any key letters, comb preserves only leaf deltas and the minimum number of ancestor deltas necessary to preserve the shape of an SCCS tree. The effect of this is to eliminate middle deltas on the trunk and on all branches of the tree. Thus, in Figure 11-3, ``Extended branching concept'' deltas 1.2, 1.3.2.1, 1.4, and 2.1 would be eliminated.

Some of the key letters options used with this command are as follows:

comb -s
generates a shell procedure that produces a report of the percentage space (if any) the user will save. This is often useful as an advance step.

comb -p
specifies the oldest delta the user wants preserved.

comb -c
specifies a list of deltas the user wants preserved. All other deltas are discarded. (See get(CP) for its syntax.)
The shell procedure generated by comb is not guaranteed to save space. A reconstructed file may even be larger than the original. Note, too, that the shape of an SCCS file tree can be altered by the reconstruction process.

val command

The val(CP) command determines whether a file is an SCCS file meeting the characteristics specified by certain key letters. It checks for the existence of a particular delta when the SID for that delta is specified with -r.

The string following -y or -m checks the value set by the t or the m SCCS file flags, respectively. See admin(CP) for descriptions of these flags.

The val command treats the special argument -- differently than other SCCS commands. It allows val to read the argument list from the standard input instead of from the command line: the standard input is read until an end-of-file (<Ctrl>d) is entered. This permits one val command with different values for key letters and file arguments. For example:

val - -yc -mabc s.abc -mxyz -ypl1 s.xyz

val first checks whether file s.abc has a value c for its type flag and value abc for the module name flag. Once this is done, val processes the remaining file, in this case, s.xyz.

The val command returns an 8-bit code. Each bit set shows a specific error. (See val(CP) for a description of errors and codes.) In addition, an appropriate diagnostic is printed, unless suppressed by -s. A return code of 0 means all files meet the characteristics specified.

vc command

The vc(CP) command is an awk-like tool used for version control of sets of files. While it is distributed as part of the SCCS package, it does not require the files it operates on to be under SCCS control. See vc(CP) for a complete description of the command.

SCCS files

The following topics are discussed in this section:

Protection
Describes the protection mechanisms used by SCCS files

Formatting
Explains the structure and format of SCCS files

Auditing
Recommends procedures for auditing SCCS files

Protection

SCCS relies on the capabilities of the UNIX system for most of the protection mechanisms required to prevent unauthorized changes to SCCS files, that is, changes by non-SCCS commands. The only protection features directly provided by SCCS are:

Files created by the admin command are given access permission mode 444 (read only). This mode should remain unchanged because it prevents modification of SCCS files by non-SCCS commands. Directories containing SCCS files should be given mode 755, which allows only the owner of the directory to modify it.

SCCS files should be kept in directories containing only SCCS files and any temporary files created by SCCS. This simplifies their protection and auditing. Directories should contain logical groupings of SCCS files: for example, subsystems of the same large project.

SCCS files must have only one link (name) because commands that modify an SCCS file do so by creating a copy of the file (see ``SCCS command conventions''). When processing is completed, the x-file is automatically renamed with an s. prefix. If the old file had more than one link, the renaming would break them. Rather than process these files, SCCS commands produce an error message.

When only one person uses SCCS, the real and effective user IDs are the same; the user ID owns the directories containing SCCS files. Therefore, SCCS can be used directly without any preliminary preparation.

When several users with unique user IDs are assigned SCCS responsibilities, one user ID should be selected as the owner of the SCCS files. This person is responsible for all administration (admin) of the SCCS files. This limits the privileges and permissions allowed to other users. To work around this limitation, it is recommended that a project-dependent user interface be set up allowing other (non-SCCS administrator) users access to the get, delta, and rmdel SCCS commands.

The interface program must be owned by the SCCS administrator and must have the set-user-ID-on-execution bit on. (See chmod(C)). This assures that the effective user ID is that of the SCCS administrator. The owner of an SCCS file can modify it at will. Other users whose login names or group IDs are in the user list for that file (but are not the owner) are given the necessary permissions only for the duration of the execution of the interface program. Thus, they may modify SCCS only with delta and, possibly, rmdel and cdc.

Formatting

SCCS files are composed of lines of ASCII text arranged in six parts as follows:

Checksum
Line containing the logical sum of all the characters of the file (not including the checksum itself).

Delta table
Information about each delta, such as type, SID, date and time of creation, and commentary.

User names
List of login names and/or group IDs of users who are allowed to modify the file by adding or removing deltas.

Flags
Indicators that control certain actions of SCCS commands.

Descriptive text
Usually a summary of the contents and purpose of the file.

Body
Text administered by SCCS, intermixed with internal SCCS control lines.
Details on these file sections can be found in sccsfile(FP). The checksum is discussed next under ``Auditing''.

Since SCCS files are ASCII files, they can be processed by non-SCCS commands like ed(C), grep(C), and cat(C). This is convenient when an SCCS file must be modified manually (such as when a delta's time and date were recorded incorrectly because the system clock was set incorrectly), or when a user wants simply to look at the file.


NOTE: Be careful when modifying SCCS files with non-SCCS commands.

Auditing

When a system or hardware malfunction destroys an SCCS file, any command issues an error message. Commands also use the checksum stored in an SCCS file to determine whether the file has been corrupted since it was last accessed (possibly by having lost one or more blocks or by having been modified with ed(C)). No SCCS command processes a corrupted SCCS file except the admin command with -h or -z, as described below.

SCCS files should be audited for possible corruptions on a regular basis. The simplest and fastest way to do an audit is to use admin -h and specify all SCCS files. Either command works:

admin -h s.file1 s.file2 ...
admin -h directory1 directory2 ...

If the new checksum of any file is not equal to the checksum in the first line of that file, the following message is produced for that file:

   corrupted file (co6)
The process continues until all specified files have been examined. When examining directories (as in the second example above), the checksum process does not detect missing files. A simple way to learn whether files are missing from a directory is to execute the ls(C) command periodically, and compare the outputs. Any file whose name appeared in a previous output but not in the current one no longer exists.

When a file has been corrupted, the way to restore it depends on the extent of the corruption. If damage is extensive, the best solution is to contact the local UNIX system operations group and request that the file be restored from a backup copy. If the damage is minor, repair through editing may be possible. After such a repair, the admin command must be executed:

admin -z s.file

The purpose of this command is to recompute the checksum and bring it into agreement with the contents of the file. After this command is executed, any corruption that existed in the file is no longer detectable.