<html>
<head>
<title>P4 Overview</title>
</head>
<body>
<h1>Copyright</h1>
<pre>
Copyright (C) 1997 Capella Computers Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
<A HREF="License.html">GNU General Public License</A> for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
</pre>
<h1>Version</h1>
This is version 0.1 of the wrappers, dated 7/97. It has just emerged from
preliminary testing and is being used by the developers in
Capella Computers Ltd. It is likely that numerous small problems will
be detected and corrected during the next few months. When no change will
be made to the system for a reasonable period of time (two months?), the
first stable release (1.0) will be "formally" declared.
<p>
If you have any questions, discovered any bugs,
would like the most up-to-date
version, or have any other sort of feedback, contact
the author,
<A HREF="mailto:oren@capella.co.il"><EM>oren@capella.co.il</EM></A>.
<h1>Introduction</h1>
This document gives a brief overview of the <b>perl</b> <b>p4</b> wrappers.
The purpose of these wrappers is to implement a particular development
process on top of the generic <b>p4</b> services. This process is an
adaptation of the process enforced by <b>aegis</b>. <b>Aegis</b> is a
free software available on the net, and is much more robust and complete
then this set of wrappers. If you develop on UNIX platforms and you can use
NFS to link the developer's workstations, you should probably use <b>aegis</b>.
<p>
A deliberate design choice made when implementing these wrappers was
not to attempt any form of co-existance with other practices. This allowed
the wrappers to rely on a particular structuring of the depot, thereby
allowing better protection schemes and higher-level baviour. As a result,
the wrappers completely replace the built-in <b>p4</b> interface, with
a few notable exceptions which will be listed below.
<p>
The wrappers are implemented in <b>perl</b> and as such are rather portable.
However, they invoke a few external programs (such as <b>cp</b>, <b>rm</b>
and <b>mkdir</b>). While the access to these programs is isolated, it is
not exactly trivial to port the system to DOS, for example. However, you
can obtain all the necessary programs (including a shell) as free software
from GNU project or as commercial software (from MKS, for example).
<h1>Basic Concepts</h1>
The overview for <b>aegis</b> contains a good tutorial of the basic
concepts. It is also recommended that you become familiar with the
basic <b>p4</b> concepts before you read this overview.
<ul>
<li>
The definitive sources of the system reside in <tt>//depot/baseline/...</tt>.
<li>
The baseline always "works". In practical terms
it means that there is a perl script, <tt>verify.pl</tt>, in the top level
directory of the baseline, and that running it is guaranteed to succeed.
Note that this file is part of the baseline and can be changed like any
other source file.
<li>
Development is done in terms of <i>jobs</i>. The best way to view a job
is as a transaction on the sources database. Like a transaction, it must
ensure that it brings the database to a consistent state (as defined by
<tt>verify.pl</tt>). It is atomic - either it is applied in full or it
is rejected completely. And like in any database, the transactions are
serialized.
<li>
The integration of a job into the baseline creates a new system <i>version</i>.
The result of serializing the jobs is to create a system history which is a
linear sequence of such versions, where it seems <i>as if</i> each job
begun with the version created by the previous job, made some changes,
and created the next version.
</ul>
<h1>Job Life Cycle</h2>
The trick is, of course, how to enable a team of programmers to work
on several jobs at once and still maintain the above benefits.
The best way to understand this process is to follow the life cycle of a job.
<dl>
<dt><b>new</b>
<dd>
This is a status of a newly created job. At this point, the job exists
as a simple <b>p4</b> job.
<ul>
</ul>
<dt><b>work</b>
<dd>
Only a single developer can work on a job (a developr may, of course, work
on several jobs simultanously). For the developer to be able to work,
a new branch is created and populated with the current baseline version.
The new branch is named
<tt>//depot/</tt><i>user</i><tt>/</tt><i>job</i><tt>-</tt><i>attempt</i><tt>/</tt>.
<p>
The <i>attempt</i>
number is incremented whenever a developer undoes everything, returning
the job to the <b>new</b> state. If the same developer starts development
later on, <b>p4</b> demands we use a different branch and directory name,
hence the count.
<p>
The developer's work is done inside a <b>p4</b> change.
This change is submitted to
<b>p4</b> when the job is submitted to review.
<dt><b>review</b>
<dd>
When development is done, and the job is verified, it is moved to this state.
At this stage, all files modified by the job are locked, so no two active jobs
which are at this stage or onwards can touch the same file. This is necessary
since such jobs will be sent to integration without further synchronization
with the baseline.
<p>
Sadly, it is not possible to use the built-on <b>p4</b> file locking mechanism
for this, since it only allows associating a lock with an active change which
actually tries to modify the locked files. Instead, there's a dummy <b>p4</b>
job which holds in its description the list of all locked files.
<dt><b>fail</b>
<dd>
The system supports the notion of a code review. At the moment, anyone
(even the developer itself) can change the review status of a job. <b>Aegis</b>
does a much better job here (as in some other places) by limiting this to
developers which are specially denoted as reviewers, and also optionally
blocks a developer from reviewing himself.
<p>
At any rate, a review may fail the job. In this case, the developer is
expected to resume working on it. Note that this means that a new change will
be opened, and this change does not necessarily touch all the files which
were touched by the previous one, which means the built-in <b>p4</b> reports
for change file lists are not sufficient by themselves to describe what has
been done in a particular job.
<dt><b>pass</b>
<dd>
At this stage, the job comes to the attention of the integrator. In
<b>aegis</b>, this can be any developer who has been assigned the task.
In <b>p4</b>, you need to specify a special user (called <tt>integ</tt>)
to handle the task. This means an extra <b>p4</b> license. However, Perforce
were kind enough to give us (Capella Computers) an extra license so we
could rotate the task between the developers.
<p>
At any rate, the integrator chooses between the jobs at this stage to
decide which job to integrate next. This may have consequences on developers
working on other changes, so the choice is not always easy.
<dt><b>integ</b>
<dd>
Only one job can be at this stage at any given time. This is the job that
is being integrated into the baseline. The integration consists of opening
a new change, in which the development branch is merged into the baseline.
Note that this is a simple merge - there are never any conflicts (due to
the file locks mentioned before). In theory, it should be possible to merge
more then one branch in the same change, though this is not currently
implemented. Again, there is no danger of conflicts.
<p>
The resulting baseline version is re-verified (using <tt>verify.pl</tt>). This
is necessary since the verification done by the developer was on his machine,
and may have passed due to his special development environment or due to
other external factors. The integration verification is the last line of
defense - any problem that gets by it will go straight into the baseline.
<p>
Once it passes verification, the change is submitted, a new baseline version
is created, the job file locks are released, and there's no going back.
Of course, you can easily
recreate a previous version of the baseline. But development from this point
on would build on the version just created.
<p>
The baseline version created is given the label <tt>L</tt><i>version</i> which
can be used to refer to this version in various commands (e.g., <tt>p4fp</tt>).
Note that the version number is different from the job number, and is always
increasing by one for each integration.
<dt><b>clear</b>
<dd>
Since <b>aegis</b> assumes file-system access to all development hosts, it
cleans up all the development directories when a job is integrated. One of
the nice points about <b>p4</b> is that it works through any Tcp/Ip connection.
This means that the developer needs to do something on his own host to clean
things up - both the development branch and the development directory. Note
that since there's no point in keeping history of the branch files, the
branch files are truly obliterated.
<dt><b>done</b>
<dd>
Once a job is cleared, there's nothing left to do. It is still possible
to edit the job description, but any changes to the sources require opening
a new job.
</dl>
<h1>Commands</h1>
<h2>Copyright</h2>
In order to follow the spirit of the GPL, the following command, useless
as they may seem to developers, are provided:
<dl>
<dt><tt>p4notice</tt>
<dd>This displays a short copyright notice, and refers to the copy of the
GPL which is supposed to be distributed with the software.
</dl>
<h2>Environment</h2>
There are a several environment variables which are used by
the wrappers. With the exception of <tt>P4JOB</tt>, they are all mandatory.
<dl>
<dt><tt>P4ROOT</tt>
<dd>
The root directory of the client's view.
<dt><tt>P4PATH</tt>
<dd>
Where the wrappers are installed.
<dt><tt>P4PORT</tt>
<dd>
The Tcp/Ip address (including the port) of the <b>p4</b> server.
<dt><tt>P4CLIENT</tt>
<dd>
The identity of the current client.
<dt><tt>P4USER</tt>
<dd>
The identity of the current user.
<dt><tt>P4JOB</tt>
<dd>
The number of the default job (optional). Serves as the default job
number for any command which takes such an argument.
</dl>
The environment can be manipulated by the following commands:
<dl>
<dt>
<dt><tt>p4el</tt>
<dd>
List all relevant environment variables.
<dt><tt>p4ej [</tt><i>job</i><tt>]</tt>
<dd>
Print (if given no argument) or set the default job; a value of '<tt>-</tt>'
means
unsetting the variable altogether.
<dt><tt>p4eu [</tt><i>user</i><tt>]</tt>
<dd>
Print (if given no argument) or set the current user id. This command should
not be used by most users.
</dl>
There are additional environment variables used, which are not <b>p4</b>
specific.
<dl>
<dt><tt>TEMP</tt>
<dd>
Where to create temporary directories. Mandatory.
<dt><tt>EDITOR</tt>
<dd>
How to edit text files. Is only used by <tt>p4je</tt>, but you really want
to set it anyway (is used by a lot of utilities).
<dt><tt>DIFF</tt>
<dd>
How to diff text files. Used by <tt>p4rdiff</tt> and by some
<b>p4</b> commands. The safe bet is to set it - after all, any system
has a reasonable built-in <b>diff</b>, even if you need to get it of the net.
<dt><tt>MERGE</tt>
<dd>
How to merge text files. You can do without it if you don't ask for a merged
version during conflict resolution, which is a good idea anyway. Using the
edit option is sufficient, really.
</dl>
<h2>Report</h2>
The following are read-only operations which should be available for
all users on all clients, unless stated otherwise.
<dl>
<dt><tt>p4dh</tt>
<dd>
List all the changes in the depot, from recent to ancient. The output
is the raw output of <b>p4</b>. Todo: format output as a report.
<dt><tt>p4dv [</tt><i>release-specifier</i><tt>]</tt>
<dd>
Print depot baseline directory. This requires you to have a copy of the
baseline on the current client. Such a copy can be obtained
by using <tt>p4fg</tt>. It takes as argument any valid <b>p4</b> release
specifier, such as <tt>@L</tt><i>version-number</i>.
<dt><tt>p4fh [</tt><i>file-pattern</i><tt>] ...</tt>
<dd>
Display file history (as a list of jobs). Todo: list the system version
number as well as the job number. It takes as argument any file pattern
recognized by <b>p4</b>. Typically you just give it the path name(s) of
the files in the development or baseline directories, which <b>p4</b>
translates automatically to its internal file name specification.
<dt><tt>p4jd [</tt><i>job</i><tt>]</tt>
<dd>
Get job details. It could probably be in a better format.
<dt><tt>p4je [</tt><i>job</i><tt>]</tt>
<dd>
Edit job data. This one is very dangerous. As long as you only
change the description, you are safe; otherwise you can really shoot
yourself in the foot. Todo: provide a safer way to edit just the
description.
<dt><tt>p4jf [</tt><i>job</i><tt>]</tt>
<dd>
Get list of job file operations - that is, the files changed in this job,
and the operation performed on each (<b>add</b>/<b>delete</b>/<b>edit</b>).
If the job is in <b>work</b> mode, this will
only work on the development machine. Otherwise, it will work anywhere
(very important for reviewers).
<dt><tt>p4jh [</tt><i>job</i><tt>]</tt>
<dd>
History of a job (a list of changes). Same problems as the depot
history command.
<dt><tt>p4jl [</tt><i>filter</i><tt>] ...</tt>
<dd>
List jobs. By default, shows all jobs, but accepts a multitude of filtering
commands. These commands are applied in the order they are given. A '<tt>+</tt>' turns
on a set of jobs, a '<tt>-</tt>' turns it off. If the first command
is a '<tt>+</tt>', then
it is assumed you start with the empty set; if it is a '<tt>-</tt>',
it is assumed
you start with the complete set. The '<tt>+/-Status</tt>'
command turns on/off the
listing of jobs of any status. '<tt>+/-New</tt>' controls listing of new jobs,
and likewise for any other job status.
<p>
It is also possible to filter by user: '<tt>+/-u </tt><i>user</i>'
will turn on/off the
set of jobs for the specified user, where '<tt>User</tt>' means
all users, and '<tt>Me</tt>'
means the current user. You can mix filtering by status and by user; for
example, <tt>p4jl -done -u me</tt> lists all the jobs which aren't done
and are owned by the current user.
<p>
Any of the keyworks can be shortened to its first letter; the previous
example can be written as <tt>p4jl -d -u m</tt>.
<p>
Just for fun, a set of shell functions for common cases is provided:
<dl compact>
<dt><tt>p4jln</tt>
<dd>Is equivalent to <tt>p4jl +n</tt>
<dt><tt>p4jlw</tt>
<dd>Is equivalent to <tt>p4jl +w</tt>
<dt><tt>p4jlr</tt>
<dd>Is equivalent to <tt>p4jl +r</tt>
<dt><tt>p4jlf</tt>
<dd>Is equivalent to <tt>p4jl +f</tt>
<dt><tt>p4jlp</tt>
<dd>Is equivalent to <tt>p4jl +p</tt>
<dt><tt>p4jli</tt>
<dd>Is equivalent to <tt>p4jl +i</tt>
<dt><tt>p4jlc</tt>
<dd>Is equivalent to <tt>p4jl +c</tt>
<dt><tt>p4jld</tt>
<dd>Is equivalent to <tt>p4jl +d</tt>
<dt><tt>p4jlu</tt>
<dd>Is equivalent to <tt>p4jl +u</tt>; requires an argument.
<dt><tt>p4jlm</tt>
<dd>Is equivalent to <tt>p4jl +u me</tt>
</dl>
<dt><tt>p4uh [</tt><i>user</i><tt>]</tt>
<dd>
History of a user (a list of changes). Same problems as the depot
history command.
<dt><tt>p4ul</tt>
<dd>
all users. Again, the unformatted output of the <b>p4</b> command.
<dt><tt>p4vl</tt>
<dd>
List all versions of the depot, which job created them, who was the
developr and so on.
</dl>
The following are file commands which are not commonly used. Unlike
any other command, they take as first argument either <tt>baseline</tt>
or a job number (which is <tt>P4JOB</tt> by default). They use this
argument to construct the necessary prefix for the file pattern
passed to <b>p4</b>. By default, this pattern is <tt>...</tt>.
<p>
When applied to files of a job, these commands work only for the developer
on the development client if the job is in <b>work</b> state, and for
anyone anywhere if the job is in <b>review</b>/<b>pass</b>/<b>fail</b> state.
In the second case, the (default) pattern <tt>...</tt> is taken to mean
all the files opened in this job, and not all the files. In order to get
all the files, specify the <tt>....</tt> (add another '<tt>.</tt>').
<dl>
<dt><tt>p4fg [</tt><i>job</i><tt>|baseline] [</tt><i>file-pattern</i><tt>][</tt><i>release-specifier</i><tt>] ...</tt>
<dd>Get depot file(s). For example, <tt>p4fg baseline @L7</tt> would
bring version 7 of the whole depot to the current client.
<p>
If you got files you want to get rid of, the only way is to get them with
a release specifier of '<tt>#none</tt>'. This removes the files from the
client.
<dl>
<dt><tt>p4fp [</tt><i>job</i><tt>|baseline] [</tt><i>file-pattern</i><tt>][</tt><i>release-specifier</i><tt>] ...</tt>
<dd>Print depot file(s). For example, <tt>p4fp baseline verify.pl@L7</tt> would
print the contents of <tt>verify.pl</tt> as it was in version 7 of the system.
<dl>
<dt><tt>p4fr [</tt><i>job</i><tt>|baseline] [</tt><i>file-pattern</i><tt>][</tt><i>release-specifier</i><tt>] ...</tt>
<dd>Refresh unopened file(s).
For example, <tt>p4fr verify.pl</tt> would
refresh <tt>verify.pl</tt> from the depot, in case it was deleted
by mistake using <b>rm</b>, for example.
</dl>
<h2>New Jobs</h2>
<dl>
<dt><tt>p4jn </tt><i>title</i><tt> [</tt><i>issue</i><tt>] ...</tt>
<dd>
Create a new job. The first argument is the job's title (if it contains
multiple words, put quotes around it so it will be a single argument), and
a list of issue id (for recording relevant entries in an external
issue-tracking system).
<dt><tt>p4jnu [</tt><i>job</i><tt>]</tt>
<dd>
Undo new job creation. This only works on <b>new</b> jobs, and onliterates
them from the system. This is the only way to delete a job.
</dl>
<h2>Work Jobs</h2>
With the exception of <tt>p4wb</tt>, all these commands will only work
for the developer on the development client, for obvious reasons.
<h3>Job Commands</h3>
<dl>
<dt><tt>p4wb [</tt><i>job</i><tt>]</tt>
<dd>
Start working on a new job. Creates the branch, creates a development directory
in the current client and populates it. Will work for any developer
anywhere (except <b>integ</b>, which isn't really a developer). The
current user and client become the development user and client for this job.
<dt><tt>p4wbu [</tt><i>job</i><tt>]</tt>
<dd>
Undo working on a job. Removes the branch and the development directory; all
work is lost forever, unless previouly backed up.
Increases the attempt counter by one.
<dt><tt>p4we [</tt><i>job</i><tt>]</tt>
<dd>
End working on a job. It first verifies the job (as per <tt>p4wv</tt>), and
then locks all relevant files and submits the job for review.
<dt><tt>p4weu [</tt><i>job</i><tt>]</tt>
<dd>
Undo end of working on a job. Which means you've just remembered something
which will cause the reviewer to fail the job anyway, so you quickly withraw
the submission and fix it, hoping nobody noticed :-) Or, you haven't
remembered, and the job has been failed; you need to restart work to
fix whatever is wrong.
<dt><tt>p4ws [</tt><i>job</i><tt>]</tt>
<dd>
Synchronize a development directory with updated baseline. This expects
the developer to interact with <b>resolve</b> to handle potential
conflict. The best way is to edit each file - <b>p4</b> is kind
enough to insert very clear markers into the source files, which allow
resolving the conflicts using any text editor.
<dt><tt>p4wv [</tt><i>job</i><tt>]</tt>
<dd>
Verify work on a job. Basically, a predictor whether <tt>p4we</tt> will
work or not, but can also be used as an easy way to invoke <b>make</b>
or whatever.
</dl>
<h3>File Commands</h3>
<dl>
<dt><tt>p4fd [</tt><i>job</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
Open a file for deletion. Informs <b>p4</b> that the specified file will
not be included in the version created by this job. <em>Will remove
the specified file</em>.
<dt><tt>p4fdiff [</tt><i>job</i><tt>] [</tt><i>diff-flags</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
Diff edited file from baseline. This one also works for the integrator
when the job is in <b>integ</b> mode, as it is useful for last-moment
reviews. <b>P4</b> allows certain flags to be specified for <b>diff</b>
in this command; see the description of the <b>diff</b> command.
<dt><tt>p4fe [</tt><i>job</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
Open a file for editing. Informs <b>p4</b> that the specified file will
be changed in the version created by this job. It will make the file
writable (files are read-only by default).
<dt><tt>p4fn [</tt><i>job</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
Open a new file for editing. Informs <b>p4</b> that the specified file
will be added in the version created by this job. Does not actually create
or modify the file.
<dt><tt>p4fu [</tt><i>job</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
Undo operation on an opened file. Informs <b>p4</b> that whatever has been
said about the file is not true, whatever the operation was. <b>p4</b>
restores the file to its original state (which means refreshing it if it
was deleted or edited). It will not delete files which were added.
</dl>
<h2>Review Job</h2>
These commands can be run by any developer (except <b>integ</b>, which is
not really a decveloper). It would have been nice to limit them just to
developers designated as reviewers, and prevent a developer from reviewing
himself, but as fooling the system is so easy (just set <tt>P4USER</tt>),
what's the point?
<dl>
<dt><tt>p4rdiff [</tt><i>job</i><tt>] [</tt><i>diff-flags</i><tt>] </tt><i>file-name</i><tt>...</tt>
<dd>
View difference for a file for a job. <b>P4</b> is not kind enough to let
us difference any two files in the depot (not that I know of, anyway), so
you first have to get all the modified files from the development branch
by using <tt>p4fg </tt><i>job</i>. The bonus is that you can use any
<b>diff</b> program, and give it any flags you like.
<dt><tt>p4rfail [</tt><i>job</i><tt>]</tt>
<dd>
Fail a reviewed job; additional work should be done by the developer.
In theory,
there should be no "bugs" where (assuming that the <tt>verify.pl</tt>
script runs a good set of regression tests). Even so, there are issues
of style, design, performance, and so on.
While failing their jobs won't make you popular with other developers,
passing bad code won't make you popular with the integrator.
<dt><tt>p4rpass [</tt><i>job</i><tt>]</tt>
<dd>
Pass a review job (clearing it for integration). By this the reviewer is
taking as much responsibility for the submitted code as the developer. This
keeps the reviewers honest :-)
</dl>
<h2>Integration Job</h2>
<dl>
<dt><tt>p4ib [</tt><i>job</i><tt>]</tt>
<dd>
Start integration of a job. This creates a local integration directory
(ruining whatever copy of the baseline you had), and merges the changes
from the development branch. Due to <b>p4</b> bug #350, this causes
getting all the added branch files as well, so you'll have to get rid of
them manually later. This bug is really a pain in the rear echelon.
<dt><tt>p4ibu [</tt><i>job</i><tt>]</tt>
<dd>
Undo begin integration of a job. Restores the local baseline copy
to the latest version, removes the integration change, and so on.
<dt><tt>p4ie [</tt><i>job</i><tt>]</tt>
<dd>
End integration of a job. This is the point of no return. It does a verify
first, of course, as per <tt>p4iv</tt>, for what it is worth. If a bug made
it this far, it can bask in the warm fuzzy certainty it will take a lot of
time and effort to root it out...
<dt><tt>p4iv [</tt><i>job</i><tt>]</tt>
<dd>
Verify integration of a job. Basically, run <tt>verify.pl</tt> and hope
it checks the right things.
</dl>
<h2>Clear Job</h2>
<dl>
<dt><tt>p4ic [</tt><i>job</i><tt>]</tt>
<dd>
Clear integrated job directories. As you've noticed, the above process
leaves a lot of junk after the job is integrated. All the reviewers and
the integrator need to do <tt>p4fg </tt><i>job</i><tt> #none</tt>, for starters.
Then the developer can destroy the whole works, obliterating the branch.
</dl>
<h2>Locks</h2>
In principle, none of these commands should ever be used. The world
being an imperfect place, it is very probable that sometimes scripts will
crash leaving hanging locks and other inconsistencies.
The following commands allow access to the lock operations, so it would
be easy to recover from broken/hanging locks. Other inconsistencies
require manual care using the raw <b>p4</b> interface.
<dl>
<dt><tt>p4ld</tt>
<dd>
Lock the whole depot. Note that this only stops operations which try
to lock the whole depot; operations that only lock a single job will succeed.
<dt><tt>p4ldu</tt>
<dd>
Unlock the whole depot.
<dt><tt>p4lf</tt>
<dd>
List all locked files by all jobs.
<dt><tt>p4lj [</tt><i>job</i><tt>]</tt>
<dd>
Lock a single job. Note that this will succeed regardless of whether the
whole depot is locked.
<dt><tt>p4lju [</tt><i>job</i><tt>]</tt>
<dd>
Unlock a single job.
<dt><tt>p4ll</tt>
<dd>
List all (job, depot) locks.
</dl>
<h1>Starting</h1>
<h2>Set Up New Depot</h2>
<ul>
<li>
Start with a completely blank depot.
<li>
Initialize the relevant environment variables. The file <tt>lib/p4init</tt>
contains a base you can start from. You should probably include this
initialization in your shell's startup file (<tt>.profile</tt> or whatever).
<li>
Make sure you set the <tt>P4SHIFTER</tt> environment variable before invoking
<tt>p4funcs</tt>. This will allow you to switch to being another user - in
particular, the integrator (<b>integ</b>).
<li>
Use <tt>p4eu integ</tt> to become the integrator. You should probably
move to the <tt>lib</tt> directory so invoking the <b>p4</b> client directly
would be easy. It is intentionally not placed in the path.
<li>
Run <tt>p4 depot depot</tt> and create the depot (optional).
<li>
Run <tt>p4 user</tt> and create the user <b>integ</b>.
<li>
Run <tt>p4 protect</tt> and set up the protection scheme. It should look like:
<pre>
read integ <i>ip-mask</i> //depot/...
write integ <i>ip-mask</i> //depot/baseline/...
super integ <i>ip-mask</i> //depot/...
read <i>user</i> <i>ip-mask</i> //depot/...
write <i>user</i> <i>ip-mask</i> //depot/<i>user</i>/...
...
</pre>
<li>
Run <tt>p4 client</tt> to create your client.
The default view is fine. Make sure
that the root agrees with the <tt>P4ROOT</tt> environment.
<li>
Create the first version of the <tt>verify.pl</tt> file:
<ul compact>
<li>
<tt>mkdir -p $P4ROOT/baseline</tt>
<li>
<tt>$EDITOR $P4ROOT/baseline/verify.pl</tt>
<br>
Anything will do in there, as long as it
doesn't call <tt>die</tt> or <tt>exit</tt>.
<li>Add it using <tt>p4 add //depot/baseline/verify.pl</tt>.
<li>Submit the first change using <tt>p4 submit</tt>.
</ul>
<li>Run <tt>p4eu </tt><i>your-name</i> to become yourself again.
</ul>
<h2>Add New Developer</h2>
In order to add a new developer (and his client) to the system:
<ul>
<li>
As <b>integ</b>, add the new user to
the protection lists, using <tt>p4 protect</tt>.
<li>
As the new developer, copy the <tt>p4init</tt> file into the shell
startup file, with the appropriate customizations. Apply it.
<li>
Call <tt>p4 user</tt> to create the user.
<li>
Call <tt>p4 client</tt> to create the client.
</ul>
<h1>Caveats</h1>
This is the second try at getting the system right. The first was intended
to be a much thinner set of wrappers on top of <b>p4</b>, with the goal
to use as much of the built-in <b>p4</b> commands as possible. This turned
out to be a huge headache, due to problems with almost anything - change lists,
file locks, job status...
<p>
The result is that you have to do things through the wrappers exclusively.
It is true that a few of them are just calls to built-in <b>p4</b>
commands, but you've got to go through them in order to get the arguments
right.
<p>
An exception to the above is setting things up. There's no automated way to
set up the initial dept, create a new user, a new client, and so on. This
is not too bad since such operations are rare.
<p>
A second problem is that these wrappers go only so far. There is some
missing functionality, the output of commands is not consistent (some
is the raw outpout from <b>p4</b>, some is formatted reports), and so on.
<p>
The implementation is not very fast, either. It is not that they are
terribly slow, but compared to the lightning-quick response of the raw
<b>p4</b> interface, they seem a drag. Most of the delays are due to
the horribly inefficent way locks are implemented. If <b>p4</b>
allows locking unopened files (or even better, nonexisting files),
this could be speeded up by a huge factor.
</body>