home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-04-17 | 34.1 KB | 1,609 lines |
- .\" Copyright (c) 1986 The Regents of the University of California.
- .\" All rights reserved.
- .\"
- .\" Redistribution and use in source and binary forms, with or without
- .\" modification, are permitted provided that the following conditions
- .\" are met:
- .\" 1. Redistributions of source code must retain the above copyright
- .\" notice, this list of conditions and the following disclaimer.
- .\" 2. Redistributions in binary form must reproduce the above copyright
- .\" notice, this list of conditions and the following disclaimer in the
- .\" documentation and/or other materials provided with the distribution.
- .\" 3. All advertising materials mentioning features or use of this software
- .\" must display the following acknowledgement:
- .\" This product includes software developed by the University of
- .\" California, Berkeley and its contributors.
- .\" 4. Neither the name of the University nor the names of its contributors
- .\" may be used to endorse or promote products derived from this software
- .\" without specific prior written permission.
- .\"
- .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- .\" SUCH DAMAGE.
- .\"
- .\" @(#)sccs.me 6.4 (Berkeley) 4/17/91
- .\"
- .eh '\fRPS1:14-%\fP''\fRAn Introduction to the Source Code Control System\fP'
- .oh '\fRAn Introduction to the Source Code Control System\fP''\fRPS1:14-%\fP'
- .ds S \s-1SCCS\s0
- .ds I \s-1SID\s0
- .nr bi 8n
- .ev 1 \" only for keeps
- .ss 16
- .ev
- .\".he '\*S Introduction''%'
- .+c
- .(l C
- .sz 14
- .b
- An Introduction to the
- Source Code Control System
- .sz
- .r
- .sp
- Eric Allman
- .i "Project Ingres"
- .i "University of California at Berkeley"
- .)l
- .sp 3
- .pp
- .(f
- This is version 1.21 of this document.
- It was last modified on 12/5/80.
- .)f
- This document gives a quick introduction
- to using the Source Code Control System
- (\*S).
- The presentation is geared to programmers
- who are more concerned with
- what
- to do to get a task done
- rather than how it works;
- for this reason some of the examples
- are not well explained.
- For details of what the magic options do,
- see the section on
- .q "Further Information" .
- .(l F
- This is a working document.
- Please send any comments or suggestions
- to eric@Berkeley.Edu.
- .)l
- .sh 1 "Introduction"
- .pp
- \*S is a source management system.
- Such a system maintains a record of versions of a system;
- a record is kept with each set of changes
- of what the changes are,
- why they were made,
- and who made them and when.
- Old versions can be recovered,
- and different versions can be maintained simultaneously.
- In projects with more than one person,
- \*S will insure that two people are not
- editing the same file at the same time.
- .pp
- All versions of your program,
- plus the log and other information,
- is kept in a file called the
- .q "s-file" .
- There are three major operations
- that can be performed on the s-file:
- .np
- Get a file for compilation (not for editing).
- This operation retrieves a version of the file
- from the s-file.
- By default, the latest version is retrieved.
- This file is intended for compilation, printing, or whatever;
- it is specifically NOT intended to be edited
- or changed in any way;
- any changes made to a file retrieved
- in this way will probably be lost.
- .np
- Get a file for editing.
- This operation also retrieves a version of the file
- from the s-file,
- but this file is intended to be edited and then
- incorporated back into the s-file.
- Only one person may be editing a file at one time.
- .np
- Merge a file back into the s-file.
- This is the companion operation to (2).
- A new version number is assigned,
- and comments are saved explaining why this change was made.
- .sh 1 "Learning the Lingo"
- .pp
- There are a number of terms that are worth learning
- before we go any farther.
- .sh 2 "S-file"
- .pp
- The s-file
- is a single file that holds all the different versions
- of your file.
- The s-file is stored in
- differential format;
- .i i.e. ,
- only the differences between versions are stored,
- rather than the entire text of the new version.
- This saves disk space
- and allows selective changes to be removed later.
- Also included in the s-file
- is some header information for each version,
- including the comments given by the person who
- created the version explaining why the changes were made.
- .sh 2 "Deltas"
- .pp
- Each set of changes to the s-file
- (which is approximately [but not exactly!] equivalent
- to a version of the file)
- is called a
- .i delta .
- Although technically a delta only includes the
- .i changes
- made,
- in practice
- it is usual for
- each delta to be made with respect to
- all the deltas that have occurred before\**.
- .(f
- \**This matches normal usage, where the previous changes are not saved
- at all,
- so all changes are automatically based on all other changes
- that have happened through history.
- .)f
- However,
- it is possible to get a version of the file
- that has selected deltas removed out of the middle
- of the list of changes \*-
- equivalent to removing your changes later.
- .sh 2 "\*I's (or, version numbers)"
- .pp
- A \*I
- (\*S Id)
- is a number that represents a delta.
- This is normally a two-part number
- consisting of a
- .q release
- number and a
- .q level
- number.
- Normally the release number stays the same,
- however,
- it is possible to move into a new release
- if some major change is being made.
- .pp
- Since all past deltas are normally applied,
- the \*I of the final delta applied
- can be used to represent a version number of the file
- as a whole.
- .sh 2 "Id keywords"
- .pp
- When you get a version of a file
- with intent to compile and install it
- (\c
- .i i.e. ,
- something other than edit it),
- some special keywords are expanded inline
- by \*S.
- These
- .i "Id Keywords"
- can be used to include the current version number
- or other information into the file.
- All id keywords are of the form
- .b % \c
- .i x \c
- .b % ,
- where
- .i x
- is an upper case letter.
- For example,
- .b %\&I\&%
- is the \*I of the latest delta applied,
- .b %\&W\&%
- includes the module name,
- \*I,
- and a mark that makes it findable by a program,
- and
- .b %\&G\&%
- is the date of the latest delta applied.
- There are many others,
- most of which are of dubious usefulness.
- .pp
- When you get a file for editing,
- the id keywords are not expanded;
- this is so that after you put them back in to the s-file,
- they will be expanded automatically on each new version.
- But notice: if you were to get them
- expanded accidently,
- then your file would appear to be the same version
- forever more,
- which would of course defeat the purpose.
- Also,
- if you should install a version of the program
- without expanding the id keywords,
- it will be impossible to tell what version it is
- (since all it will have is
- .q %\&W\&%
- or whatever).
- .sh 1 "Creating \*S Files"
- .pp
- To put source files
- into
- \*S
- format, run the following shell script from csh:
- .(b
- mkdir SCCS save
- foreach i (*.[ch])
- sccs admin \-i$i $i
- mv $i save/$i
- end
- .)b
- This will put the named files
- into s-files
- in the subdirectory
- .q SCCS
- The files will be removed from the current directory
- and hidden away in the directory
- .q save ,
- so the next thing you will probably want to do
- is to get all the files
- (described below).
- When you are convinced that
- \*S has correctly created the s-files,
- you should remove the directory
- .q save .
- .pp
- If you want to have id keywords in the files,
- it is best to put them in before you create the s-files.
- If you do not,
- .i admin
- will print
- .q "No Id Keywords (cm7)" ,
- which is a warning message only.
- .sh 1 "Getting Files for Compilation"
- .pp
- To get a copy of the latest version
- of a file,
- run
- .(b
- sccs get prog.c
- .)b
- \*S will respond:
- .(b
- 1.1
- 87 lines
- .)b
- meaning that version 1.1 was retrieved\**
- .(f
- \**Actually,
- the \*I of the final delta applied was 1.1.
- .)f
- and that it has 87 lines.
- The file
- .i prog.c
- will be created
- in the current directory.
- The file will be read-only
- to remind you that you are not
- supposed to change it.
- .pp
- This copy of the file
- should not be changed,
- since \*S is unable
- to merge the changes
- back into the s-file.
- If you do make changes,
- they will be lost the next time
- someone does a
- .i get .
- .sh 1 "Changing Files (or, Creating Deltas)"
- .sh 2 "Getting a copy to edit"
- .pp
- To edit a source file,
- you must first get it,
- requesting permission to edit it\**:
- .(f
- \**The
- .q "edit"
- command is equivalent to using the \-e
- flag to
- .i "get" ,
- as:
- .(l
- sccs get \-e prog.c
- .)l
- Keep this in mind when reading other documentation.
- .)f
- .(b
- sccs edit prog.c
- .)b
- The response will be the same as with
- .i get
- except that it will also say:
- .(b
- New delta 1.2
- .)b
- You then edit it,
- using a standard text editor:
- .(b
- vi prog.c
- .)b
- .sh 2 "Merging the changes back into the s-file"
- .pp
- When the desired changes are made,
- you can put your changes into the
- \*S
- file using the
- .i delta
- command:
- .(b
- sccs delta prog.c
- .)b
- .pp
- Delta will prompt you for
- .q "comments?"
- before it merges the changes in.
- At this prompt you should type a one-line description
- of what the changes mean
- (more lines can be entered by ending each line
- except the last with a backslash\**).
- .(f
- \**Yes, this is a stupid default.
- .)f
- .i Delta
- will then type:
- .(b
- 1.2
- 5 inserted
- 3 deleted
- 84 unchanged
- .)b
- saying that delta 1.2 was created,
- and it inserted five lines,
- removed three lines,
- and left 84 lines unchanged\**.
- .(f
- \**Changes to a line are counted as a line deleted
- and a line inserted.
- .)f
- The
- .i prog.c
- file will be removed;
- it can be retrieved
- using
- .i get .
- .sh 2 "When to make deltas"
- .pp
- It is probably unwise to make a delta
- before every recompilation or test;
- otherwise,
- you tend to get a lot of deltas with comments like
- .q "fixed compilation problem in previous delta"
- or
- .q "fixed botch in 1.3" .
- However,
- it is very important to delta everything
- before installing a module for general use.
- A good technique is to edit the files you need,
- make all necessary changes and tests,
- compiling and editing as often as necessary
- without making deltas.
- When you are satisfied that you have a working version,
- delta everything being edited,
- re-get them,
- and recompile everything.
- .sh 2 "What's going on: the info command"
- .pp
- To find out what files where being edited,
- you can use:
- .(b
- sccs info
- .)b
- to print out all the files being edited
- and other information such as the name of the user
- who did the edit.
- Also,
- the command:
- .(b
- sccs check
- .)b
- is nearly equivalent to the
- .i info
- command,
- except that it is silent if nothing is being edited,
- and returns non-zero exit status if anything is being edited;
- it can be used in an
- .q install
- entry in a makefile
- to abort the install
- if anything has not been properly deltaed.
- .pp
- If you know that everything being edited should be deltaed,
- you can use:
- .(b
- sccs delta \`sccs tell\`
- .)b
- The
- .i tell
- command is similar to
- .i info
- except that only the names of files being edited
- are output,
- one per line.
- .pp
- All of these commands take a
- .b \-b
- flag
- to ignore
- .q branches
- (alternate versions, described later)
- and the
- .b \-u
- flag to only give files being edited by you.
- The
- .b \-u
- flag takes an optional
- .i user
- argument,
- giving only files being edited by that user.
- For example,
- .(b
- sccs info \-ujohn
- .)b
- gives a listing of files being edited by john.
- .sh 2 "ID keywords"
- .pp
- Id keywords can be inserted into your file
- that will be expanded automatically by
- .i get .
- For example,
- a line such as:
- .(b
- static char SccsId[] = "%\&W\&%\et%\&G\&%";
- .)b
- will be replaced with something like:
- .(b
- static char SccsId[] = "@\&(#)prog.c 1.2 08/29/80";
- .)b
- This tells you
- the name and version
- of the source file
- and the time the delta was created.
- The string
- .q "@\&(#)"
- is a special string
- which signals the beginning
- of an
- \*S
- Id keyword.
- .sh 3 "The what command"
- .pp
- To find out what version of a program
- is being run,
- use:
- .(b
- sccs what prog.c /usr/bin/prog
- .)b
- which will print all strings
- it finds that
- begin with
- .q "@\&(#)" .
- This works on all types of files,
- including binaries and libraries.
- For example, the above command will output something like:
- .(b
- prog.c:
- prog.c 1.2 08/29/80
- /usr/bin/prog:
- prog.c 1.1 02/05/79
- .)b
- From this I can see
- that the source that I have in prog.c
- will not compile into the same version
- as the binary in /usr/bin/prog.
- .sh 3 "Where to put id keywords"
- .pp
- ID keywords can be inserted anywhere,
- including in comments,
- but
- Id Keywords that are compiled into the object module
- are especially useful,
- since it lets you find out what version of
- the object is being run,
- as well as the source.
- However,
- there is a cost:
- data space is used up to store
- the keywords,
- and on small address space machines
- this may be prohibitive.
- .pp
- When you put id keywords into header files,
- it is important that you assign them to different variables.
- For example, you might use:
- .(b
- static char AccessSid[] = "%\&W\&% %\&G\&%";
- .)b
- in the file
- .i access.h
- and:
- .(b
- static char OpsysSid[] = "%\&W\&% %\&G\&%";
- .)b
- in the file
- .i opsys.h .
- Otherwise,
- you will get compilation errors because
- .q SccsId
- is redefined.
- The problem with this is that if the header file
- is included by many modules that are loaded together,
- the version number of that header file is included
- in the object module many times;
- you may find it more to your taste
- to put id keywords in header files
- in comments.
- .sh 2 "Keeping \*I's consistent across files"
- .pp
- With some care,
- it is possible to keep the \*I's consistent
- in multi-file systems.
- The trick here is to always
- .i edit
- all files
- at once.
- The changes can then be made
- to whatever files are necessary
- and then all files
- (even those not changed)
- are redeltaed.
- This can be done fairly easily
- by just specifying the name of the directory
- that the \*S files are in:
- .(b
- sccs edit SCCS
- .)b
- which will
- .i edit
- all files in that directory.
- To make the delta, use:
- .(b
- sccs delta SCCS
- .)b
- You will be prompted for comments only once.
- .sh 2 "Creating new releases"
- .pp
- When you want to create a new release
- of a program,
- you can specify the release number you want to create
- on the
- .i edit
- command.
- For example:
- .(b
- sccs edit \-r2 prog.c
- .)b
- will cause the next delta to be in release two
- (that is,
- it will be numbered 2.1).
- Future deltas will automatically be in release two.
- To change the release number
- of an entire system,
- use:
- .(b
- sccs edit \-r2 SCCS
- .)b
- .sh 1 "Restoring Old Versions"
- .sh 2 "Reverting to old versions"
- .pp
- Suppose that after delta 1.2
- was stable
- you made and released a delta 1.3.
- But this introduced a bug,
- so you made a delta 1.4 to correct it.
- But 1.4 was still buggy,
- and you decided you wanted to go back
- to the old version.
- You could
- revert to delta 1.2
- by choosing the \*I in a get:
- .(b
- sccs get \-r1.2 prog.c
- .)b
- This will produce a version of
- .i prog.c
- that is delta 1.2
- that can be reinstalled so that work can proceed.
- .pp
- In some cases you don't know
- what the \*I of the delta you want is.
- However,
- you can revert to the version of the program
- that was running as of a certain date
- by using the
- .b \-c
- (cutoff) flag.
- For example,
- .(b
- sccs get \-c800722120000 prog.c
- .)b
- will retrieve whatever version was current
- as of July 22, 1980
- at 12:00 noon.
- Trailing components can be stripped off
- (defaulting to their highest legal value),
- and punctuation can be inserted in the obvious
- places;
- for example,
- the above line could be equivalently stated:
- .(b
- sccs get \-c"80/07/22 12:00:00" prog.c
- .)b
- .sh 2 "Selectively deleting old deltas"
- .pp
- Suppose that you later decided
- that you liked the changes in delta 1.4,
- but that delta 1.3 should be removed.
- You could do this by
- .i excluding
- delta 1.3:
- .(b
- sccs edit \-x1.3 prog.c
- .)b
- When delta 1.5 is made,
- it will include the changes made
- in delta 1.4,
- but will exclude the changes made
- in delta 1.3.
- You can exclude a range of deltas
- using a dash.
- For example,
- if you want to get rid of 1.3 and 1.4
- you can use:
- .(b
- sccs edit \-x1.3\-1.4 prog.c
- .)b
- which will exclude all deltas from 1.3 to 1.4.
- Alternatively,
- .(b
- sccs edit \-x1.3\-1 prog.c
- .)b
- will exclude a range of deltas
- from 1.3 to the current highest delta in release 1.
- .pp
- In certain cases when using
- .b \-x
- (or
- .b \-i ;
- see below)
- there will be conflicts
- between versions;
- for example, it may be necessary
- to both include and delete
- a particular line.
- If this happens,
- \*S always prints out a message
- telling the range of lines effected;
- these lines should then be examined very carefully
- to see if the version \*S got
- is ok.
- .pp
- Since each delta
- (in the sense of
- .q "a set of changes" )
- can be excluded at will,
- that this makes it most useful
- to put each semantically distinct change
- into its own delta.
- .sh 1 "Auditing Changes"
- .sh 2 "The prt command"
- .pp
- When you created a delta,
- you presumably gave a reason for the delta
- to the
- .q "comments?"
- prompt.
- To print out these comments later,
- use:
- .(b
- sccs prt prog.c
- .)b
- This will produce
- a report
- for each delta
- of the \*I,
- time and date of creation,
- user who created the delta,
- number of lines inserted, deleted, and unchanged,
- and the comments associated with the delta.
- For example, the output of the above command might be:
- .(b
- D 1.2 80/08/29 12:35:31 bill 2 1 00005/00003/00084
- removed "-q" option
- .sp \n(psu
- D 1.1 79/02/05 00:19:31 eric 1 0 00087/00000/00000
- date and time created 80/06/10 00:19:31 by eric
- .)b
- .sh 2 "Finding why lines were inserted"
- .pp
- To find out
- why you inserted lines,
- you can get a copy of the file
- with each line
- preceded by the \*I that created it:
- .(b
- sccs get \-m prog.c
- .)b
- You can then find out
- what this delta did
- by printing the comments using
- .i prt .
- .pp
- To find out what lines are associated with a particular delta
- (\c
- .i e.g. ,
- 1.3),
- use:
- .(b
- sccs get \-m \-p prog.c \(bv grep \'^1.3\'
- .)b
- The
- .b \-p
- flag causes \*S to output the generated source
- to the standard output rather than to a file.
- .sh 2 "Finding what changes you have made"
- .pp
- When you are editing a file,
- you can find out what changes you have made using:
- .(b
- sccs diffs prog.c
- .)b
- Most of the ``diff'' flags can be used.
- To pass the
- .b \-c
- flag,
- use
- .b \-C .
- .pp
- To compare two versions that are in deltas,
- use:
- .(b
- sccs sccsdiff -r1.3 -r1.6 prog.c
- .)b
- to see the differences between delta 1.3 and delta 1.6.
- .sh 1 "Shorthand Notations"
- .pp
- There are several sequences of commands that get
- executed frequently.
- .i Sccs
- tries to make it easy to do these.
- .sh 2 "Delget"
- .pp
- A frequent requirement is to make a delta of some file
- and then get that file.
- This can be done by using:
- .(b
- sccs delget prog.c
- .)b
- which is entirely equivalent to using:
- .(b
- sccs delta prog.c
- sccs get prog.c
- .)b
- The
- .q deledit
- command is equivalent to
- .q delget
- except that the
- .q edit
- command is used
- instead of the
- .q get
- command.
- .sh 2 "Fix"
- .pp
- Frequently, there are small bugs
- in deltas,
- e.g., compilation errors,
- for which there is no reason to maintain an audit trail.
- To
- .i replace
- a delta, use:
- .(b
- sccs fix \-r1.4 prog.c
- .)b
- This will get a copy of delta 1.4 of prog.c for you to edit
- and then delete delta 1.4 from the \*S file.
- When you do a delta of prog.c,
- it will be delta 1.4 again.
- The \-r flag must be specified,
- and the delta that is specified must be a leaf delta,
- i.e., no other deltas may have been made subsequent
- to the creation of that delta.
- .sh 2 "Unedit"
- .pp
- If you found you edited a file
- that you did not want to edit,
- you can back out by using:
- .(b
- sccs unedit prog.c
- .)b
- .sh 2 "The \-d flag"
- .pp
- If you are working on a project
- where the \*S code is in a directory somewhere,
- you may be able to simplify things
- by using a shell alias.
- For example,
- the alias:
- .(b
- alias syssccs sccs \-d/usr/src
- .)b
- will allow you to issue commands such as:
- .(b
- syssccs edit cmd/who.c
- .)b
- which will look for the file
- .q "/usr/src/cmd/SCCS/who.c" .
- The file
- .q who.c
- will always be created in your current directory
- regardless of the value of the \-d flag.
- .sh 1 "Using \*S on a Project"
- .pp
- Working on a project with several people
- has its own set of special problems.
- The main problem occurs when two people
- modify a file at the same time.
- \*S prevents this by locking an s-file
- while it is being edited.
- .pp
- As a result,
- files should not be reserved for editing
- unless they are actually being edited at the time,
- since this will prevent other people on the project
- from making necessary changes.
- For example,
- a good scenario for working might be:
- .(b
- sccs edit a.c g.c t.c
- vi a.c g.c t.c
- # do testing of the (experimental) version
- sccs delget a.c g.c t.c
- sccs info
- # should respond "Nothing being edited"
- make install
- .)b
- .pp
- As a general rule,
- all source files should be deltaed
- before installing the program for general use.
- This will insure that it is possible
- to restore any version in use at any time.
- .sh 1 "Saving Yourself"
- .sh 2 "Recovering a munged edit file"
- .pp
- Sometimes you may find
- that you have destroyed or trashed
- a file that you were trying to edit\**.
- .(f
- \**Or given up and decided to start over.
- .)f
- Unfortunately,
- you can't just remove it
- and re-\c
- .i edit
- it;
- \*S keeps track
- of the fact
- that someone is trying to edit it,
- so it won't let you do it again.
- Neither can you just get it using
- .i get ,
- since that would expand the Id keywords.
- Instead,
- you can say:
- .(b
- sccs get \-k prog.c
- .)b
- This will not expand the Id keywords,
- so it is safe to do a delta
- with it.
- .pp
- Alternately,
- you can
- .i unedit
- and
- .i edit
- the file.
- .sh 2 "Restoring the s-file"
- .pp
- In particularly bad circumstances,
- the \*S file itself
- may get munged.
- The most common way this happens
- is that it gets edited.
- Since \*S keeps a checksum,
- you will get errors every time you read the file.
- To fix this checksum, use:
- .(b
- sccs admin \-z prog.c
- .)b
- .sh 1 "Using the Admin Command"
- .pp
- There are a number of parameters that can be set
- using the
- .i admin
- command.
- The most interesting of these are flags.
- Flags can be added by using the
- .b \-f
- flag.
- For example:
- .(b
- sccs admin \-fd1 prog.c
- .)b
- sets the
- .q d
- flag to the value
- .q 1 .
- This flag can be deleted by using:
- .(b
- sccs admin \-dd prog.c
- .)b
- The most useful flags are:
- .nr ii 7n
- .ip "b"
- Allow branches to be made using the
- \-b
- flag to
- .i edit .
- .ip "d\fISID\fP"
- Default \*I to be used on a
- .i get
- or
- .i edit .
- If this is just a release number
- it constrains the
- version
- to a particular release only.
- .ip "i"
- Give a fatal error
- if there are no Id Keywords in a file.
- This is useful to guarantee that a version of the
- file does not get merged into the s-file
- that has the Id Keywords inserted as constants
- instead of internal forms.
- .ip "y"
- The
- .q type
- of the module.
- Actually,
- the value of this flag is unused by \*S
- except that it replaces the
- .b %\&Y\&%
- keyword.
- .pp
- The
- .b \-t\fIfile\fR
- flag can be used
- to store descriptive text
- from
- .i file .
- This descriptive text might be the documentation
- or a design and implementation document.
- Using the
- .b \-t
- flag insures that if the \*S file is sent,
- the documentation will be sent also.
- If
- .i file
- is omitted,
- the descriptive text is deleted.
- To see the descriptive text,
- use
- .q "prt \-t" .
- .pp
- The
- .i admin
- command can be used safely
- any number of times on files.
- A file need not be gotten
- for
- .i admin
- to work.
- .sh 1 "Maintaining Different Versions (Branches)"
- .pp
- Sometimes it is convenient
- to maintain an experimental version of a program
- for an extended period
- while normal maintenance continues
- on the version in production.
- This can be done using a
- .q branch.
- Normally deltas continue in a straight line,
- each depending on the delta before.
- Creating a branch
- .q "forks off"
- a version of the program.
- .pp
- The ability to create branches
- must be enabled in advance using:
- .(b
- sccs admin \-fb prog.c
- .)b
- The
- .b \-fb
- flag can be specified when the
- \*S file is first created.
- .sh 2 "Creating a branch"
- .pp
- To create a branch, use:
- .(b
- sccs edit \-b prog.c
- .)b
- This will create a branch
- with (for example) \*I 1.5.1.1.
- The deltas for this version
- will be numbered
- 1.5.1.\c
- .i n .
- .sh 2 "Getting from a branch"
- .pp
- Deltas in a branch are normally not included
- when you do a get.
- To get these versions,
- you will have to say:
- .(b
- sccs get \-r1.5.1 prog.c
- .)b
- .sh 2 "Merging a branch back into the main trunk"
- .pp
- At some point you will have finished the experiment,
- and if it was successful
- you will want to incorporate it into the release version.
- But in the meantime
- someone may have created a delta 1.6
- that you don't want to lose.
- The commands:
- .(b
- sccs edit \-i1.5.1.1\-1.5.1 prog.c
- sccs delta prog.c
- .)b
- will merge all of your changes
- into the release system.
- If some of the changes conflict,
- get will print an error;
- the generated result
- should be carefully examined
- before the delta is made.
- .sh 2 "A more detailed example"
- .pp
- The following technique might be used
- to maintain a different version of a program.
- First,
- create a directory to contain the new version:
- .(b
- mkdir ../newxyz
- cd ../newxyz
- .)b
- Edit a copy of the program
- on a branch:
- .(b
- sccs \-d../xyz edit prog.c
- .)b
- When using the old version,
- be sure to use the
- .b \-b
- flag to info, check, tell, and clean
- to avoid confusion.
- For example, use:
- .(b
- sccs info \-b
- .)b
- when in the directory
- .q xyz .
- .pp
- If you want to save a copy of the program
- (still on the branch)
- back in the s-file,
- you can use:
- .(b
- sccs -d../xyz deledit prog.c
- .)b
- which will do a delta on the branch
- and reedit it for you.
- .pp
- When the experiment is complete, merge it back into the s-file
- using delta:
- .(b
- sccs -d../xyz delta prog.c
- .)b
- At this point you must decide whether this version
- should be merged back into the trunk
- (\c
- .i i.e.
- the default version),
- which may have undergone changes.
- If so, it can be merged using the
- .b \-i
- flag to
- .i edit
- as described above.
- .sh 2 "A warning"
- .pp
- Branches should be kept to a minimum.
- After the first branch from the trunk,
- \*I's are assigned rather haphazardly,
- and the structure gets complex fast.
- .sh 1 "Using \*S with Make"
- .pp
- \*S and make can be made to work together
- with a little care.
- A few sample makefiles
- for common applications are shown.
- .pp
- There are a few basic entries that every makefile
- ought to have.
- These are:
- .nr ii 1i
- .ip a.out
- (or whatever the makefile generates.)
- This entry regenerates whatever this makefile is
- supposed to regenerate.
- If the makefile regenerates many things,
- this should be called
- .q all
- and should in turn
- have dependencies on everything
- the makefile can generate.
- .ip install
- Moves the objects to the final
- resting place,
- doing any special
- .i chmod 's
- or
- .i ranlib 's
- as appropriate.
- .ip sources
- Creates all the source files from \*S files.
- .ip clean
- Removes all files from the current directory
- that can be regenerated from \*S files.
- .ip print
- Prints the contents of the directory.
- .lp
- The examples shown below are only partial examples,
- and may omit some of these entries
- when they are deemed to be obvious.
- .pp
- The
- .i clean
- entry should not remove files that can be
- regenerated from the \*S files.
- It is sufficiently important to have the
- source files around at all times
- that the only time they should be removed
- is when the directory is being mothballed.
- To do this, the command:
- .(b
- sccs clean
- .)b
- can be used.
- This will remove all files for which an s-file
- exists,
- but which is not being edited.
- .sh 2 "To maintain single programs"
- .pp
- Frequently there are directories with several
- largely unrelated programs
- (such as simple commands).
- These can be put into a single makefile:
- .(b
- LDFLAGS= \-i \-s
- .sp \n(psu
- prog: prog.o
- $(CC) $(LDFLAGS) \-o prog prog.o
- prog.o: prog.c prog.h
- .sp \n(psu
- example: example.o
- $(CC) $(LDFLAGS) \-o example example.o
- example.o: example.c
- .sp \n(psu
- \&.DEFAULT:
- sccs get $<
- .)b
- The trick here
- is that the .DEFAULT rule
- is called every time
- something is needed
- that does not exist,
- and no other rule exists to make it.
- The explicit dependency of the
- .b \&.o
- file on the
- .b \&.c
- file is important.
- Another way of doing the same thing is:
- .(b
- SRCS= prog.c prog.h example.c
- .sp \n(psu
- LDFLAGS= \-i \-s
- .sp \n(psu
- prog: prog.o
- $(CC) $(LDFLAGS) \-o prog prog.o
- prog.o: prog.h
- .sp \n(psu
- example: example.o
- $(CC) $(LDFLAGS) \-o example example.o
- .sp \n(psu
- sources: $(SRCS)
- $(SRCS):
- sccs get $@
- .)b
- There are a couple of advantages to this approach:
- (1) the explicit dependencies of the .o on the .c files are
- not needed,
- (2) there is an entry called "sources" so if you want to get
- all the sources you can just say
- .q "make sources" ,
- and
- (3) the makefile is less likely to do confusing things
- since it won't try to
- .i get
- things that do not exist.
- .sh 2 "To maintain a library"
- .pp
- Libraries that are largely static
- are best updated using explicit commands,
- since
- .i make
- doesn't know about updating them properly.
- However,
- libraries that are in the process of being developed
- can be handled quite adequately.
- The problem is that the .o files
- have to be kept out of the library
- as well as in the library.
- .(b
- # configuration information
- OBJS= a.o b.o c.o d.o
- SRCS= a.c b.c c.c d.s x.h y.h z.h
- TARG= /usr/lib
- .sp \n(psu
- # programs
- GET= sccs get
- REL=
- AR= \-ar
- RANLIB= ranlib
- .sp \n(psu
- lib.a: $(OBJS)
- $(AR) rvu lib.a $(OBJS)
- $(RANLIB) lib.a
- .sp \n(psu
- install: lib.a
- sccs check
- cp lib.a $(TARG)/lib.a
- $(RANLIB) $(TARG)/lib.a
- .sp \n(psu
- sources: $(SRCS)
- $(SRCS):
- $(GET) $(REL) $@
- .sp \n(psu
- print: sources
- pr *.h *.[cs]
- clean:
- rm \-f *.o
- rm \-f core a.out $(LIB)
- .)b
- .pp
- The
- .q "$(REL)"
- in the get
- can be used to get old versions
- easily; for example:
- .(b
- make b.o REL=\-r1.3
- .)b
- .pp
- The
- .i install
- entry includes the line
- .q "sccs check"
- before anything else.
- This guarantees that all the s-files
- are up to date
- (\c
- .i i.e. ,
- nothing is being edited),
- and will abort the
- .i make
- if this condition is not met.
- .sh 2 "To maintain a large program"
- .(b
- OBJS= a.o b.o c.o d.o
- SRCS= a.c b.c c.y d.s x.h y.h z.h
- .sp \n(psu
- GET= sccs get
- REL=
- .sp \n(psu
- a.out: $(OBJS)
- $(CC) $(LDFLAGS) $(OBJS) $(LIBS)
- .sp \n(psu
- sources: $(SRCS)
- $(SRCS):
- $(GET) $(REL) $@
- .)b
- (The
- .i print
- and
- .i clean
- entries are identical to the previous case.)
- This makefile requires copies of the source and object files
- to be kept during development.
- It is probably also wise to include lines of the form:
- .(b
- a.o: x.h y.h
- b.o: z.h
- c.o: x.h y.h z.h
- z.h: x.h
- .)b
- so that modules will be recompiled
- if header files change.
- .pp
- Since
- .i make
- does not do transitive closure on dependencies,
- you may find in some makefiles lines like:
- .(b
- z.h: x.h
- touch z.h
- .)b
- This would be used in cases where file z.h
- has a line:
- .(b
- #include "x.h"
- .)b
- in order to bring the mod date of z.h in line
- with the mod date of x.h.
- When you have a makefile such as above,
- the
- .i touch
- command can be removed completely;
- the equivalent effect will be achieved
- by doing an automatic
- .i get
- on z.h.
- .sh 1 "Further Information"
- .pp
- The
- .i "SCCS/PWB User's Manual"
- gives a deeper description
- of how to use \*S.
- Of particular interest
- are the numbering of branches,
- the l-file,
- which gives a description of what deltas were used on a get,
- and certain other \*S commands.
- .pp
- The \*S manual pages
- are a good last resort.
- These should be read by software managers
- and by people who want to know
- everything about everything.
- .pp
- Both of these documents were written without the
- .i sccs
- front end in mind,
- so most of the examples are slightly different from those
- in this document.
- .bp
- .sz 12
- .ce
- .b "Quick Reference"
- .sz
- .sp 2
- .sh 1 Commands 1
- .pp
- The following commands should all be preceded with
- .q sccs .
- This list is not exhaustive;
- for more options see
- .i "Further Information" .
- .ip get 9n
- Gets files for compilation (not for editing).
- Id keywords are expanded.
- .ba 9n
- .nr ii 8n
- .ip \-r\fI\*I\fP
- Version to get.
- .ip \-p
- Send to standard output rather than to the actual file.
- .ip \-k
- Don't expand id keywords.
- .ip \-i\fIlist\fP
- List of deltas to include.
- .ip \-x\fIlist\fP
- List of deltas to exclude.
- .ip \-m
- Precede each line with \*I of creating delta.
- .ip \-c\fIdate\fP
- Don't apply any deltas created after
- .i date.
- .ba
- .ip edit 9n
- Gets files for editing.
- Id keywords are not expanded.
- Should be matched with a
- .i delta
- command.
- .ba 9n
- .nr ii 8n
- .ip \-r\fI\*I\fP
- Same as
- .i get .
- If
- .i \*I
- specifies a release that does not yet exist,
- the highest numbered delta is retrieved
- and the new delta is numbered with
- .i \*I .
- .ip \-b
- Create a branch.
- .ip \-i\fIlist\fP
- Same as
- .i get .
- .ip \-x\fIlist\fP
- Same as
- .i get .
- .ba
- .ip delta 9n
- Merge a file gotten using
- .i edit
- back into the s-file.
- Collect comments about why this delta was made.
- .ip unedit 9n
- Remove a file that has been edited previously
- without merging the changes into the s-file.
- .ip prt 9n
- Produce a report of changes.
- .ba 9n
- .nr ii 5n
- .ip \-t
- Print the descriptive text.
- .ip \-e
- Print (nearly) everything.
- .ba
- .ip info 9n
- Give a list of all files being edited.
- .ba 9n
- .nr ii 5n
- .ip \-b
- Ignore branches.
- .ip \-u[\fIuser\fP]
- Ignore files not being edited by
- .i user .
- .ba
- .ip check 9n
- Same as
- .i info ,
- except that nothing is printed if nothing is being edited
- and exit status is returned.
- .ip tell 9n
- Same as
- .i info ,
- except that one line is produced per file being edited containing
- only the file name.
- .ip clean 9n
- Remove all files that can be regenerated from the
- s-file.
- .ip what 9n
- Find and print id keywords.
- .ip admin 9n
- Create or set parameters on s-files.
- .ba 9n
- .nr ii 8n
- .ip \-i\fIfile\fP
- Create, using
- .i file
- as the initial contents.
- .ip \-z
- Rebuild the checksum in case
- the file has been trashed.
- .ip \-f\fIflag\fP
- Turn on the
- .i flag .
- .ip \-d\fIflag\fP
- Turn off (delete) the
- .i flag .
- .ip \-t\fIfile\fP
- Replace the descriptive text
- in the s-file with the contents of
- .i file .
- If
- .i file
- is omitted,
- the text is deleted.
- Useful for storing documentation
- or
- .q "design & implementation"
- documents to insure they get distributed with the
- s-file.
- .lp
- Useful flags are:
- .ip b
- Allow branches to be made using the \-b flag to
- .i edit.
- .ip d\fI\*I\fP
- Default \*I to be used
- on a
- .i get
- or
- .i edit .
- .ip i
- Cause
- .q "No Id Keywords"
- error message
- to be a fatal error rather than a warning.
- .ip t
- The module
- .q type ;
- the value of this flag replaces the
- .b %\&Y\&%
- keyword.
- .ba
- .ip fix 9n
- Remove a delta and reedit it.
- .ip delget 9n
- Do a
- .i delta
- followed by a
- .i get .
- .ip deledit 9n
- Do a
- .i delta
- followed by an
- .i edit .
- .sh 1 "Id Keywords"
- .nr ii 6n
- .ip "%\&Z\&%"
- Expands to
- .q @\&(#)
- for the
- .i what
- command to find.
- .ip "%\&M\&%"
- The current module name,
- .i e.g.,
- .q prog.c .
- .ip "%\&I\&%"
- The highest \*I applied.
- .ip "%\&W\&%"
- A shorthand for
- .q "%\&Z\&%%\&M\&% <tab> %\&I\&%" .
- .ip "%\&G\&%"
- The date of the delta
- corresponding to the
- .q "%\&I\&%"
- keyword.
- .ip "%\&R\&%"
- The current release number,
- .i i.e. ,
- the first component of the
- .q "%\&I\&%"
- keyword.
- .ip "%\&Y\&%"
- Replaced by the value of the
- .b t
- flag
- (set by
- .i admin ).
-