1995-10-28 21:07:39 +00:00
|
|
|
.de Id
|
|
|
|
.ds Rv \\$3
|
|
|
|
.ds Dt \\$4
|
|
|
|
..
|
1999-08-27 23:37:10 +00:00
|
|
|
.Id $FreeBSD$
|
1995-10-28 21:07:39 +00:00
|
|
|
.ds i \&\s-1ISO\s0
|
|
|
|
.ds r \&\s-1RCS\s0
|
|
|
|
.ds u \&\s-1UTC\s0
|
|
|
|
.if n .ds - \%--
|
|
|
|
.if t .ds - \(em
|
|
|
|
.TH CI 1 \*(Dt GNU
|
|
|
|
.SH NAME
|
|
|
|
ci \- check in RCS revisions
|
|
|
|
.SH SYNOPSIS
|
|
|
|
.B ci
|
|
|
|
.RI [ options ] " file " .\|.\|.
|
|
|
|
.SH DESCRIPTION
|
|
|
|
.B ci
|
|
|
|
stores new revisions into \*r files.
|
|
|
|
Each pathname matching an \*r suffix
|
|
|
|
is taken to be an \*r file.
|
|
|
|
All others
|
|
|
|
are assumed to be working files containing new revisions.
|
|
|
|
.B ci
|
|
|
|
deposits the contents of each working file
|
|
|
|
into the corresponding \*r file.
|
|
|
|
If only a working file is given,
|
|
|
|
.B ci
|
|
|
|
tries to find the corresponding \*r file in an \*r subdirectory
|
|
|
|
and then in the working file's directory.
|
|
|
|
For more details, see
|
|
|
|
.SM "FILE NAMING"
|
|
|
|
below.
|
|
|
|
.PP
|
|
|
|
For
|
|
|
|
.B ci
|
|
|
|
to work, the caller's login must be on the access list,
|
|
|
|
except if the access list is empty or the caller is the superuser or the
|
|
|
|
owner of the file.
|
|
|
|
To append a new revision to an existing branch, the tip revision on
|
|
|
|
that branch must be locked by the caller. Otherwise, only a
|
|
|
|
new branch can be created. This restriction is not enforced
|
|
|
|
for the owner of the file if non-strict locking is used
|
|
|
|
(see
|
|
|
|
.BR rcs (1)).
|
|
|
|
A lock held by someone else can be broken with the
|
|
|
|
.B rcs
|
|
|
|
command.
|
|
|
|
.PP
|
|
|
|
Unless the
|
|
|
|
.B \-f
|
|
|
|
option is given,
|
|
|
|
.B ci
|
|
|
|
checks whether the revision to be deposited differs from the preceding one.
|
|
|
|
If not, instead of creating a new revision
|
|
|
|
.B ci
|
|
|
|
reverts to the preceding one.
|
|
|
|
To revert, ordinary
|
|
|
|
.B ci
|
|
|
|
removes the working file and any lock;
|
|
|
|
.B "ci\ \-l"
|
|
|
|
keeps and
|
|
|
|
.B "ci\ \-u"
|
|
|
|
removes any lock, and then they both generate a new working file much as if
|
|
|
|
.B "co\ \-l"
|
|
|
|
or
|
|
|
|
.B "co\ \-u"
|
|
|
|
had been applied to the preceding revision.
|
|
|
|
When reverting, any
|
|
|
|
.B \-n
|
|
|
|
and
|
|
|
|
.B \-s
|
|
|
|
options apply to the preceding revision.
|
|
|
|
.PP
|
|
|
|
For each revision deposited,
|
|
|
|
.B ci
|
|
|
|
prompts for a log message.
|
|
|
|
The log message should summarize the change and must be terminated by
|
|
|
|
end-of-file or by a line containing
|
|
|
|
.BR \&. "\ by"
|
|
|
|
itself.
|
|
|
|
If several files are checked in
|
|
|
|
.B ci
|
|
|
|
asks whether to reuse the
|
|
|
|
previous log message.
|
|
|
|
If the standard input is not a terminal,
|
|
|
|
.B ci
|
|
|
|
suppresses the prompt
|
|
|
|
and uses the same log message for all files.
|
|
|
|
See also
|
|
|
|
.BR \-m .
|
|
|
|
.PP
|
|
|
|
If the \*r file does not exist,
|
|
|
|
.B ci
|
|
|
|
creates it and
|
|
|
|
deposits the contents of the working file as the initial revision
|
|
|
|
(default number:
|
|
|
|
.BR 1.1 ).
|
|
|
|
The access list is initialized to empty.
|
|
|
|
Instead of the log message,
|
|
|
|
.B ci
|
|
|
|
requests descriptive text (see
|
|
|
|
.B \-t
|
|
|
|
below).
|
|
|
|
.PP
|
|
|
|
The number
|
|
|
|
.I rev
|
|
|
|
of the deposited revision can be given by any of the options
|
|
|
|
.BR \-f ,
|
|
|
|
.BR \-i ,
|
|
|
|
.BR \-I ,
|
|
|
|
.BR \-j ,
|
|
|
|
.BR \-k ,
|
|
|
|
.BR \-l ,
|
|
|
|
.BR \-M ,
|
|
|
|
.BR \-q ,
|
|
|
|
.BR \-r ,
|
|
|
|
or
|
|
|
|
.BR \-u .
|
|
|
|
.I rev
|
|
|
|
can be symbolic, numeric, or mixed.
|
|
|
|
Symbolic names in
|
|
|
|
.I rev
|
|
|
|
must already be defined;
|
|
|
|
see the
|
|
|
|
.B \-n
|
|
|
|
and
|
|
|
|
.B \-N
|
|
|
|
options for assigning names during checkin.
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is
|
|
|
|
.BR $ ,
|
|
|
|
.B ci
|
|
|
|
determines the revision number from keyword values in the working file.
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
begins with a period,
|
|
|
|
then the default branch (normally the trunk) is prepended to it.
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is a branch number followed by a period,
|
|
|
|
then the latest revision on that branch is used.
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is a revision number, it must be higher than the latest
|
|
|
|
one on the branch to which
|
|
|
|
.I rev
|
|
|
|
belongs, or must start a new branch.
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is a branch rather than a revision number,
|
|
|
|
the new revision is appended to that branch. The level number is obtained
|
|
|
|
by incrementing the tip revision number of that branch.
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
indicates a non-existing branch,
|
|
|
|
that branch is created with the initial revision numbered
|
|
|
|
.IB rev .1\f1.\fP
|
|
|
|
.br
|
|
|
|
.ne 8
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is omitted,
|
|
|
|
.B ci
|
|
|
|
tries to derive the new revision number from
|
|
|
|
the caller's last lock. If the caller has locked the tip revision of a branch,
|
|
|
|
the new revision is appended to that branch.
|
|
|
|
The new revision number is obtained
|
|
|
|
by incrementing the tip revision number.
|
|
|
|
If the caller locked a non-tip revision, a new branch is started at
|
|
|
|
that revision by incrementing the highest branch number at that revision.
|
|
|
|
The default initial branch and level numbers are
|
|
|
|
.BR 1 .
|
|
|
|
.PP
|
|
|
|
If
|
|
|
|
.I rev
|
|
|
|
is omitted and the caller has no lock, but owns
|
|
|
|
the file and locking
|
|
|
|
is not set to
|
|
|
|
.IR strict ,
|
|
|
|
then the revision is appended to the
|
|
|
|
default branch (normally the trunk; see the
|
|
|
|
.B \-b
|
|
|
|
option of
|
|
|
|
.BR rcs (1)).
|
|
|
|
.PP
|
|
|
|
Exception: On the trunk, revisions can be appended to the end, but
|
|
|
|
not inserted.
|
|
|
|
.SH OPTIONS
|
|
|
|
.TP
|
|
|
|
.BI \-r rev
|
|
|
|
Check in revision
|
|
|
|
.IR rev .
|
|
|
|
.TP
|
|
|
|
.BR \-r
|
|
|
|
The bare
|
|
|
|
.B \-r
|
|
|
|
option (without any revision) has an unusual meaning in
|
|
|
|
.BR ci .
|
|
|
|
With other \*r commands, a bare
|
|
|
|
.B \-r
|
|
|
|
option specifies the most recent revision on the default branch,
|
|
|
|
but with
|
|
|
|
.BR ci ,
|
|
|
|
a bare
|
|
|
|
.B \-r
|
|
|
|
option reestablishes the default behavior of releasing a lock and
|
|
|
|
removing the working file, and is used to override any default
|
|
|
|
.B \-l
|
|
|
|
or
|
|
|
|
.B \-u
|
|
|
|
options established by shell aliases or scripts.
|
|
|
|
.TP
|
|
|
|
.BR \-l [\f2rev\fP]
|
|
|
|
works like
|
|
|
|
.BR \-r ,
|
|
|
|
except it performs an additional
|
|
|
|
.B "co\ \-l"
|
|
|
|
for the
|
|
|
|
deposited revision. Thus, the deposited revision is immediately
|
|
|
|
checked out again and locked.
|
|
|
|
This is useful for saving a revision although one wants to continue
|
|
|
|
editing it after the checkin.
|
|
|
|
.TP
|
|
|
|
.BR \-u [\f2rev\fP]
|
|
|
|
works like
|
|
|
|
.BR \-l ,
|
|
|
|
except that the deposited revision is not locked.
|
|
|
|
This lets one read the working file
|
|
|
|
immediately after checkin.
|
|
|
|
.RS
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.BR \-l ,
|
|
|
|
bare
|
|
|
|
.BR \-r ,
|
|
|
|
and
|
|
|
|
.B \-u
|
|
|
|
options are mutually exclusive and silently override each other.
|
|
|
|
For example,
|
|
|
|
.B "ci\ \-u\ \-r"
|
|
|
|
is equivalent to
|
|
|
|
.B "ci\ \-r"
|
|
|
|
because bare
|
|
|
|
.B \-r
|
|
|
|
overrides
|
|
|
|
.BR \-u .
|
|
|
|
.RE
|
|
|
|
.TP
|
|
|
|
.BR \-f [\f2rev\fP]
|
|
|
|
forces a deposit; the new revision is deposited even it is not different
|
|
|
|
from the preceding one.
|
|
|
|
.TP
|
|
|
|
.BR \-k [\f2rev\fP]
|
|
|
|
searches the working file for keyword values to determine its revision number,
|
|
|
|
creation date, state, and author (see
|
|
|
|
.BR co (1)),
|
|
|
|
and assigns these
|
|
|
|
values to the deposited revision, rather than computing them locally.
|
|
|
|
It also generates a default login message noting the login of the caller
|
|
|
|
and the actual checkin date.
|
|
|
|
This option is useful for software distribution. A revision that is sent to
|
|
|
|
several sites should be checked in with the
|
|
|
|
.B \-k
|
|
|
|
option at these sites to
|
|
|
|
preserve the original number, date, author, and state.
|
|
|
|
The extracted keyword values and the default log message can be overridden
|
|
|
|
with the options
|
|
|
|
.BR \-d ,
|
|
|
|
.BR \-m ,
|
|
|
|
.BR \-s ,
|
|
|
|
.BR \-w ,
|
|
|
|
and any option that carries a revision number.
|
|
|
|
.TP
|
|
|
|
.BR \-q [\f2rev\fP]
|
|
|
|
quiet mode; diagnostic output is not printed.
|
|
|
|
A revision that is not different from the preceding one is not deposited,
|
|
|
|
unless
|
|
|
|
.B \-f
|
|
|
|
is given.
|
|
|
|
.TP
|
|
|
|
.BR \-i [\f2rev\fP]
|
|
|
|
initial checkin; report an error if the \*r file already exists.
|
|
|
|
This avoids race conditions in certain applications.
|
|
|
|
.TP
|
|
|
|
.BR \-j [\f2rev\fP]
|
|
|
|
just checkin and do not initialize;
|
|
|
|
report an error if the \*r file does not already exist.
|
|
|
|
.TP
|
|
|
|
.BR \-I [\f2rev\fP]
|
|
|
|
interactive mode;
|
|
|
|
the user is prompted and questioned
|
|
|
|
even if the standard input is not a terminal.
|
|
|
|
.TP
|
|
|
|
.BR \-d "[\f2date\fP]"
|
|
|
|
uses
|
|
|
|
.I date
|
|
|
|
for the checkin date and time.
|
|
|
|
The
|
|
|
|
.I date
|
|
|
|
is specified in free format as explained in
|
|
|
|
.BR co (1).
|
|
|
|
This is useful for lying about the checkin date, and for
|
|
|
|
.B \-k
|
|
|
|
if no date is available.
|
|
|
|
If
|
|
|
|
.I date
|
|
|
|
is empty, the working file's time of last modification is used.
|
|
|
|
.TP
|
|
|
|
.BR \-M [\f2rev\fP]
|
|
|
|
Set the modification time on any new working file
|
|
|
|
to be the date of the retrieved revision.
|
|
|
|
For example,
|
|
|
|
.BI "ci\ \-d\ \-M\ \-u" "\ f"
|
|
|
|
does not alter
|
|
|
|
.IR f 's
|
|
|
|
modification time, even if
|
|
|
|
.IR f 's
|
|
|
|
contents change due to keyword substitution.
|
|
|
|
Use this option with care; it can confuse
|
|
|
|
.BR make (1).
|
|
|
|
.TP
|
|
|
|
.BI \-m "msg"
|
|
|
|
uses the string
|
|
|
|
.I msg
|
|
|
|
as the log message for all revisions checked in.
|
|
|
|
By convention, log messages that start with
|
|
|
|
.B #
|
|
|
|
are comments and are ignored by programs like GNU Emacs's
|
|
|
|
.B vc
|
|
|
|
package.
|
|
|
|
Also, log messages that start with
|
|
|
|
.BI { clumpname }
|
|
|
|
(followed by white space) are meant to be clumped together if possible,
|
|
|
|
even if they are associated with different files; the
|
|
|
|
.BI { clumpname }
|
|
|
|
label is used only for clumping,
|
|
|
|
and is not considered to be part of the log message itself.
|
|
|
|
.TP
|
|
|
|
.BI \-n "name"
|
|
|
|
assigns the symbolic name
|
|
|
|
.I name
|
|
|
|
to the number of the checked-in revision.
|
|
|
|
.B ci
|
|
|
|
prints an error message if
|
|
|
|
.I name
|
|
|
|
is already assigned to another
|
|
|
|
number.
|
|
|
|
.TP
|
|
|
|
.BI \-N "name"
|
|
|
|
same as
|
|
|
|
.BR \-n ,
|
|
|
|
except that it overrides a previous assignment of
|
|
|
|
.IR name .
|
|
|
|
.TP
|
|
|
|
.BI \-s "state"
|
|
|
|
sets the state of the checked-in revision to the identifier
|
|
|
|
.IR state .
|
|
|
|
The default state is
|
|
|
|
.BR Exp .
|
|
|
|
.TP
|
|
|
|
.BI \-t file
|
|
|
|
writes descriptive text from the contents of the named
|
|
|
|
.I file
|
|
|
|
into the \*r file,
|
|
|
|
deleting the existing text.
|
|
|
|
The
|
|
|
|
.I file
|
|
|
|
cannot begin with
|
|
|
|
.BR \- .
|
|
|
|
.TP
|
|
|
|
.BI \-t\- string
|
|
|
|
Write descriptive text from the
|
|
|
|
.I string
|
|
|
|
into the \*r file, deleting the existing text.
|
|
|
|
.RS
|
|
|
|
.PP
|
|
|
|
The
|
|
|
|
.B \-t
|
|
|
|
option, in both its forms, has effect only during an initial checkin;
|
|
|
|
it is silently ignored otherwise.
|
|
|
|
.PP
|
|
|
|
During the initial checkin, if
|
|
|
|
.B \-t
|
|
|
|
is not given,
|
|
|
|
.B ci
|
|
|
|
obtains the text from standard input,
|
|
|
|
terminated by end-of-file or by a line containing
|
|
|
|
.BR \&. "\ by"
|
|
|
|
itself.
|
|
|
|
The user is prompted for the text if interaction is possible; see
|
|
|
|
.BR \-I .
|
|
|
|
.PP
|
|
|
|
For backward compatibility with older versions of \*r, a bare
|
|
|
|
.B \-t
|
|
|
|
option is ignored.
|
|
|
|
.RE
|
|
|
|
.TP
|
|
|
|
.B \-T
|
|
|
|
Set the \*r file's modification time to the new revision's time
|
|
|
|
if the former precedes the latter and there is a new revision;
|
|
|
|
preserve the \*r file's modification time otherwise.
|
|
|
|
If you have locked a revision,
|
|
|
|
.B ci
|
|
|
|
usually updates the \*r file's modification time to the current time,
|
|
|
|
because the lock is stored in the \*r file
|
|
|
|
and removing the lock requires changing the \*r file.
|
|
|
|
This can create an \*r file newer than the working file in one of two ways:
|
|
|
|
first,
|
|
|
|
.B "ci\ \-M"
|
|
|
|
can create a working file with a date before the current time;
|
|
|
|
second, when reverting to the previous revision
|
|
|
|
the \*r file can change while the working file remains unchanged.
|
|
|
|
These two cases can cause excessive recompilation caused by a
|
|
|
|
.BR make (1)
|
|
|
|
dependency of the working file on the \*r file.
|
|
|
|
The
|
|
|
|
.B \-T
|
|
|
|
option inhibits this recompilation by lying about the \*r file's date.
|
|
|
|
Use this option with care; it can suppress recompilation even when
|
|
|
|
a checkin of one working file should affect
|
|
|
|
another working file associated with the same \*r file.
|
|
|
|
For example, suppose the \*r file's time is 01:00,
|
|
|
|
the (changed) working file's time is 02:00,
|
|
|
|
some other copy of the working file has a time of 03:00,
|
|
|
|
and the current time is 04:00.
|
|
|
|
Then
|
|
|
|
.B "ci\ \-d\ \-T"
|
|
|
|
sets the \*r file's time to 02:00 instead of the usual 04:00;
|
|
|
|
this causes
|
|
|
|
.BR make (1)
|
|
|
|
to think (incorrectly) that the other copy is newer than the \*r file.
|
|
|
|
.TP
|
|
|
|
.BI \-w "login"
|
|
|
|
uses
|
|
|
|
.I login
|
|
|
|
for the author field of the deposited revision.
|
|
|
|
Useful for lying about the author, and for
|
|
|
|
.B \-k
|
|
|
|
if no author is available.
|
|
|
|
.TP
|
|
|
|
.BI \-V
|
|
|
|
Print \*r's version number.
|
|
|
|
.TP
|
|
|
|
.BI \-V n
|
|
|
|
Emulate \*r version
|
|
|
|
.IR n .
|
|
|
|
See
|
|
|
|
.BR co (1)
|
|
|
|
for details.
|
|
|
|
.TP
|
|
|
|
.BI \-x "suffixes"
|
|
|
|
specifies the suffixes for \*r files.
|
|
|
|
A nonempty suffix matches any pathname ending in the suffix.
|
|
|
|
An empty suffix matches any pathname of the form
|
|
|
|
.BI RCS/ path
|
|
|
|
or
|
|
|
|
.IB path1 /RCS/ path2.
|
|
|
|
The
|
|
|
|
.B \-x
|
|
|
|
option can specify a list of suffixes
|
|
|
|
separated by
|
|
|
|
.BR / .
|
|
|
|
For example,
|
|
|
|
.B \-x,v/
|
|
|
|
specifies two suffixes:
|
|
|
|
.B ,v
|
|
|
|
and the empty suffix.
|
|
|
|
If two or more suffixes are specified,
|
|
|
|
they are tried in order when looking for an \*r file;
|
|
|
|
the first one that works is used for that file.
|
|
|
|
If no \*r file is found but an \*r file can be created,
|
|
|
|
the suffixes are tried in order
|
|
|
|
to determine the new \*r file's name.
|
|
|
|
The default for
|
|
|
|
.IR suffixes
|
|
|
|
is installation-dependent; normally it is
|
|
|
|
.B ,v/
|
|
|
|
for hosts like Unix that permit commas in filenames,
|
|
|
|
and is empty (i.e. just the empty suffix) for other hosts.
|
|
|
|
.TP
|
|
|
|
.BI \-z zone
|
|
|
|
specifies the date output format in keyword substitution,
|
|
|
|
and specifies the default time zone for
|
|
|
|
.I date
|
|
|
|
in the
|
|
|
|
.BI \-d date
|
|
|
|
option.
|
|
|
|
The
|
|
|
|
.I zone
|
|
|
|
should be empty, a numeric \*u offset, or the special string
|
|
|
|
.B LT
|
|
|
|
for local time.
|
|
|
|
The default is an empty
|
|
|
|
.IR zone ,
|
|
|
|
which uses the traditional \*r format of \*u without any time zone indication
|
|
|
|
and with slashes separating the parts of the date;
|
|
|
|
otherwise, times are output in \*i 8601 format with time zone indication.
|
|
|
|
For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
|
|
|
|
eight hours west of \*u,
|
|
|
|
then the time is output as follows:
|
|
|
|
.RS
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
|
|
|
|
.ne 4
|
|
|
|
\f2option\fP \f2time output\fP
|
|
|
|
\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
|
|
|
|
\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
|
|
|
|
\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
|
|
|
|
.ta 4n +4n +4n +4n
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.LP
|
|
|
|
The
|
|
|
|
.B \-z
|
|
|
|
option does not affect dates stored in \*r files,
|
|
|
|
which are always \*u.
|
|
|
|
.SH "FILE NAMING"
|
|
|
|
Pairs of \*r files and working files can be specified in three ways
|
|
|
|
(see also the
|
|
|
|
example section).
|
|
|
|
.PP
|
|
|
|
1) Both the \*r file and the working file are given. The \*r pathname is of
|
|
|
|
the form
|
|
|
|
.IB path1 / workfileX
|
|
|
|
and the working pathname is of the form
|
|
|
|
.IB path2 / workfile
|
|
|
|
where
|
|
|
|
.IB path1 /
|
|
|
|
and
|
|
|
|
.IB path2 /
|
|
|
|
are (possibly different or empty) paths,
|
|
|
|
.I workfile
|
|
|
|
is a filename, and
|
|
|
|
.I X
|
|
|
|
is an \*r suffix.
|
|
|
|
If
|
|
|
|
.I X
|
|
|
|
is empty,
|
|
|
|
.IB path1 /
|
|
|
|
must start with
|
|
|
|
.B RCS/
|
|
|
|
or must contain
|
|
|
|
.BR /RCS/ .
|
|
|
|
.PP
|
|
|
|
2) Only the \*r file is given. Then the working file is created in the current
|
|
|
|
directory and its name is derived from the name of the \*r file
|
|
|
|
by removing
|
|
|
|
.IB path1 /
|
|
|
|
and the suffix
|
|
|
|
.IR X .
|
|
|
|
.PP
|
|
|
|
3) Only the working file is given.
|
|
|
|
Then
|
|
|
|
.B ci
|
|
|
|
considers each \*r suffix
|
|
|
|
.I X
|
|
|
|
in turn, looking for an \*r file of the form
|
|
|
|
.IB path2 /RCS/ workfileX
|
|
|
|
or (if the former is not found and
|
|
|
|
.I X
|
|
|
|
is nonempty)
|
|
|
|
.IB path2 / workfileX.
|
|
|
|
.PP
|
|
|
|
If the \*r file is specified without a path in 1) and 2),
|
|
|
|
.B ci
|
|
|
|
looks for the \*r file first in the directory
|
|
|
|
.B ./RCS
|
|
|
|
and then in the current
|
|
|
|
directory.
|
|
|
|
.PP
|
|
|
|
.B ci
|
|
|
|
reports an error if an attempt to open an \*r file fails for an unusual reason,
|
|
|
|
even if the \*r file's pathname is just one of several possibilities.
|
|
|
|
For example, to suppress use of \*r commands in a directory
|
|
|
|
.IR d ,
|
|
|
|
create a regular file named
|
|
|
|
.IB d /RCS
|
|
|
|
so that casual attempts to use \*r commands in
|
|
|
|
.I d
|
|
|
|
fail because
|
|
|
|
.IB d /RCS
|
|
|
|
is not a directory.
|
|
|
|
.SH EXAMPLES
|
|
|
|
Suppose
|
|
|
|
.B ,v
|
|
|
|
is an \*r suffix and the current directory contains a subdirectory
|
|
|
|
.B RCS
|
|
|
|
with an \*r file
|
|
|
|
.BR io.c,v .
|
|
|
|
Then each of the following commands check in a copy of
|
|
|
|
.B io.c
|
|
|
|
into
|
|
|
|
.B RCS/io.c,v
|
|
|
|
as the latest revision, removing
|
|
|
|
.BR io.c .
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ft 3
|
|
|
|
ci io.c; ci RCS/io.c,v; ci io.c,v;
|
|
|
|
ci io.c RCS/io.c,v; ci io.c io.c,v;
|
|
|
|
ci RCS/io.c,v io.c; ci io.c,v io.c;
|
|
|
|
.ft
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.PP
|
|
|
|
Suppose instead that the empty suffix
|
|
|
|
is an \*r suffix and the current directory contains a subdirectory
|
|
|
|
.B RCS
|
|
|
|
with an \*r file
|
|
|
|
.BR io.c .
|
|
|
|
The each of the following commands checks in a new revision.
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ft 3
|
|
|
|
ci io.c; ci RCS/io.c;
|
|
|
|
ci io.c RCS/io.c;
|
|
|
|
ci RCS/io.c io.c;
|
|
|
|
.ft
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.SH "FILE MODES"
|
|
|
|
An \*r file created by
|
|
|
|
.B ci
|
|
|
|
inherits the read and execute permissions
|
|
|
|
from the working file. If the \*r file exists already,
|
|
|
|
.B ci
|
|
|
|
preserves its read and execute permissions.
|
|
|
|
.B ci
|
|
|
|
always turns off all write permissions of \*r files.
|
|
|
|
.SH FILES
|
|
|
|
Temporary files are created in the directory containing
|
|
|
|
the working file, and also in the temporary directory (see
|
|
|
|
.B \s-1TMPDIR\s0
|
|
|
|
under
|
|
|
|
.BR \s-1ENVIRONMENT\s0 ).
|
|
|
|
A semaphore file or files are created in the directory containing the \*r file.
|
|
|
|
With a nonempty suffix, the semaphore names begin with
|
|
|
|
the first character of the suffix; therefore, do not specify an suffix
|
|
|
|
whose first character could be that of a working filename.
|
|
|
|
With an empty suffix, the semaphore names end with
|
|
|
|
.B _
|
|
|
|
so working filenames should not end in
|
|
|
|
.BR _ .
|
|
|
|
.PP
|
|
|
|
.B ci
|
|
|
|
never changes an \*r or working file.
|
|
|
|
Normally,
|
|
|
|
.B ci
|
|
|
|
unlinks the file and creates a new one;
|
|
|
|
but instead of breaking a chain of one or more symbolic links to an \*r file,
|
|
|
|
it unlinks the destination file instead.
|
|
|
|
Therefore,
|
|
|
|
.B ci
|
|
|
|
breaks any hard or symbolic links to any working file it changes;
|
|
|
|
and hard links to \*r files are ineffective,
|
|
|
|
but symbolic links to \*r files are preserved.
|
|
|
|
.PP
|
|
|
|
The effective user must be able to
|
|
|
|
search and write the directory containing the \*r file.
|
|
|
|
Normally, the real user must be able to
|
|
|
|
read the \*r and working files
|
|
|
|
and to search and write the directory containing the working file;
|
|
|
|
however, some older hosts
|
|
|
|
cannot easily switch between real and effective users,
|
|
|
|
so on these hosts the effective user is used for all accesses.
|
|
|
|
The effective user is the same as the real user
|
|
|
|
unless your copies of
|
|
|
|
.B ci
|
|
|
|
and
|
|
|
|
.B co
|
|
|
|
have setuid privileges.
|
|
|
|
As described in the next section,
|
|
|
|
these privileges yield extra security if
|
|
|
|
the effective user owns all \*r files and directories,
|
|
|
|
and if only the effective user can write \*r directories.
|
|
|
|
.PP
|
|
|
|
Users can control access to \*r files by setting the permissions
|
|
|
|
of the directory containing the files; only users with write access
|
|
|
|
to the directory can use \*r commands to change its \*r files.
|
|
|
|
For example, in hosts that allow a user to belong to several groups,
|
|
|
|
one can make a group's \*r directories writable to that group only.
|
|
|
|
This approach suffices for informal projects,
|
|
|
|
but it means that any group member can arbitrarily change the group's \*r files,
|
|
|
|
and can even remove them entirely.
|
|
|
|
Hence more formal projects sometimes distinguish between an \*r administrator,
|
|
|
|
who can change the \*r files at will, and other project members,
|
|
|
|
who can check in new revisions but cannot otherwise change the \*r files.
|
|
|
|
.SH "SETUID USE"
|
|
|
|
To prevent anybody but their \*r administrator from deleting revisions,
|
|
|
|
a set of users can employ setuid privileges as follows.
|
|
|
|
.nr n \w'\(bu'+2n-1/1n
|
|
|
|
.ds n \nn
|
|
|
|
.if \n(.g .if r an-tag-sep .ds n \w'\(bu'u+\n[an-tag-sep]u
|
|
|
|
.IP \(bu \*n
|
|
|
|
Check that the host supports \*r setuid use.
|
|
|
|
Consult a trustworthy expert if there are any doubts.
|
|
|
|
It is best if the
|
|
|
|
.B seteuid
|
|
|
|
system call works as described in Posix 1003.1a Draft 5,
|
|
|
|
because \*r can switch back and forth easily
|
|
|
|
between real and effective users, even if the real user is
|
|
|
|
.BR root .
|
|
|
|
If not, the second best is if the
|
|
|
|
.B setuid
|
|
|
|
system call supports saved setuid
|
|
|
|
(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990);
|
|
|
|
this fails only if the real or effective user is
|
|
|
|
.BR root .
|
|
|
|
If \*r detects any failure in setuid, it quits immediately.
|
|
|
|
.IP \(bu \nn
|
|
|
|
Choose a user
|
|
|
|
.I A
|
|
|
|
to serve as \*r administrator for the set of users.
|
|
|
|
Only
|
|
|
|
.I A
|
|
|
|
can invoke the
|
|
|
|
.B rcs
|
|
|
|
command on the users' \*r files.
|
|
|
|
.I A
|
|
|
|
should not be
|
|
|
|
.B root
|
|
|
|
or any other user with special powers.
|
|
|
|
Mutually suspicious sets of users should use different administrators.
|
|
|
|
.IP \(bu \nn
|
|
|
|
Choose a pathname
|
|
|
|
.I B
|
|
|
|
to be a directory of files to be executed by the users.
|
|
|
|
.IP \(bu \nn
|
|
|
|
Have
|
|
|
|
.I A
|
|
|
|
set up
|
|
|
|
.I B
|
|
|
|
to contain copies of
|
|
|
|
.B ci
|
|
|
|
and
|
|
|
|
.B co
|
|
|
|
that are setuid to
|
|
|
|
.I A
|
|
|
|
by copying the commands from their standard installation directory
|
|
|
|
.I D
|
|
|
|
as follows:
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ne 3
|
|
|
|
\f3mkdir\fP \f2B\fP
|
|
|
|
\f3cp\fP \f2D\fP\^\f3/c[io]\fP \f2B\fP
|
|
|
|
\f3chmod go\-w,u+s\fP \f2B\fP\f3/c[io]\fP
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.IP \(bu \nn
|
|
|
|
Have each user prepend
|
|
|
|
.I B
|
|
|
|
to their path as follows:
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ne 2
|
|
|
|
\f3PATH=\fP\f2B\fP\f3:$PATH; export PATH\fP # ordinary shell
|
|
|
|
\f3set path=(\fP\f2B\fP \f3$path)\fP # C shell
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.IP \(bu \nn
|
|
|
|
Have
|
|
|
|
.I A
|
|
|
|
create each \*r directory
|
|
|
|
.I R
|
|
|
|
with write access only to
|
|
|
|
.I A
|
|
|
|
as follows:
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ne 2
|
|
|
|
\f3mkdir\fP \f2R\fP
|
|
|
|
\f3chmod go\-w\fP \f2R\fP
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.IP \(bu \nn
|
|
|
|
If you want to let only certain users read the \*r files,
|
|
|
|
put the users into a group
|
|
|
|
.IR G ,
|
|
|
|
and have
|
|
|
|
.I A
|
|
|
|
further protect the \*r directory as follows:
|
|
|
|
.LP
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
.ne 2
|
|
|
|
\f3chgrp\fP \f2G R\fP
|
|
|
|
\f3chmod g\-w,o\-rwx\fP \f2R\fP
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.IP \(bu \nn
|
|
|
|
Have
|
|
|
|
.I A
|
|
|
|
copy old \*r files (if any) into
|
|
|
|
.IR R ,
|
|
|
|
to ensure that
|
|
|
|
.I A
|
|
|
|
owns them.
|
|
|
|
.IP \(bu \nn
|
|
|
|
An \*r file's access list limits who can check in and lock revisions.
|
|
|
|
The default access list is empty,
|
|
|
|
which grants checkin access to anyone who can read the \*r file.
|
|
|
|
If you want limit checkin access,
|
|
|
|
have
|
|
|
|
.I A
|
|
|
|
invoke
|
|
|
|
.B "rcs\ \-a"
|
|
|
|
on the file; see
|
|
|
|
.BR rcs (1).
|
|
|
|
In particular,
|
|
|
|
.BI "rcs\ \-e\ \-a" A
|
|
|
|
limits access to just
|
|
|
|
.IR A .
|
|
|
|
.IP \(bu \nn
|
|
|
|
Have
|
|
|
|
.I A
|
|
|
|
initialize any new \*r files with
|
|
|
|
.B "rcs\ \-i"
|
|
|
|
before initial checkin, adding the
|
|
|
|
.B \-a
|
|
|
|
option if you want to limit checkin access.
|
|
|
|
.IP \(bu \nn
|
|
|
|
Give setuid privileges only to
|
|
|
|
.BR ci ,
|
|
|
|
.BR co ,
|
|
|
|
and
|
|
|
|
.BR rcsclean ;
|
|
|
|
do not give them to
|
|
|
|
.B rcs
|
|
|
|
or to any other command.
|
|
|
|
.IP \(bu \nn
|
|
|
|
Do not use other setuid commands to invoke \*r commands;
|
|
|
|
setuid is trickier than you think!
|
|
|
|
.SH ENVIRONMENT
|
|
|
|
.TP
|
|
|
|
.B \s-1RCSINIT\s0
|
|
|
|
options prepended to the argument list, separated by spaces.
|
|
|
|
A backslash escapes spaces within an option.
|
|
|
|
The
|
|
|
|
.B \s-1RCSINIT\s0
|
|
|
|
options are prepended to the argument lists of most \*r commands.
|
|
|
|
Useful
|
|
|
|
.B \s-1RCSINIT\s0
|
|
|
|
options include
|
|
|
|
.BR \-q ,
|
|
|
|
.BR \-V ,
|
|
|
|
.BR \-x ,
|
|
|
|
and
|
|
|
|
.BR \-z .
|
|
|
|
.TP
|
|
|
|
.B \s-1TMPDIR\s0
|
|
|
|
Name of the temporary directory.
|
|
|
|
If not set, the environment variables
|
|
|
|
.B \s-1TMP\s0
|
|
|
|
and
|
|
|
|
.B \s-1TEMP\s0
|
|
|
|
are inspected instead and the first value found is taken;
|
|
|
|
if none of them are set,
|
|
|
|
a host-dependent default is used, typically
|
|
|
|
.BR /tmp .
|
|
|
|
.SH DIAGNOSTICS
|
|
|
|
For each revision,
|
|
|
|
.B ci
|
|
|
|
prints the \*r file, the working file, and the number
|
|
|
|
of both the deposited and the preceding revision.
|
|
|
|
The exit status is zero if and only if all operations were successful.
|
|
|
|
.SH IDENTIFICATION
|
|
|
|
Author: Walter F. Tichy.
|
|
|
|
.br
|
|
|
|
Manual Page Revision: \*(Rv; Release Date: \*(Dt.
|
|
|
|
.br
|
|
|
|
Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
|
|
|
|
.br
|
|
|
|
Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
|
|
|
|
.SH "SEE ALSO"
|
|
|
|
co(1),
|
|
|
|
ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
|
|
|
|
rcsintro(1), rcsmerge(1), rlog(1), setuid(2), rcsfile(5)
|
|
|
|
.br
|
|
|
|
Walter F. Tichy,
|
|
|
|
\*r\*-A System for Version Control,
|
|
|
|
.I "Software\*-Practice & Experience"
|
|
|
|
.BR 15 ,
|
|
|
|
7 (July 1985), 637-654.
|
|
|
|
.br
|