This chapter steps through straightforward use of the PERFORCE client interface. We assume that you have read and are familiar with the concepts as described in Chapter 1. We also assume that you or your PERFORCE administrator have started the PERFORCE server, installed the PERFORCE client program, and made the adjustments to your environment described in Chapter 8, "Administration Guide."
To create a PERFORCE client workspace, invoke the p4 client command. This command brings up a simple text form in your favorite editor ($EDITOR). On the the form are fields laid out with simple one word tags, and values for each of those fields. The first time you run the p4 client command on your client host, PERFORCE will fill in the form with default values.
Client: spice Description: Created by jake. Root: /usr/local/src View: //depot/... //spice/... ~ ~
These fields and their default values are:
When you exit your editor, the form is parsed by PERFORCE, checked for errors, and then saved as the new client definition. If there are errors, PERFORCE emits an error message and you must try again. Changing the client specification has no immediate affect on the client workspace. It remains unchanged until the client specification, and in particular the client view, is employed by subsequent commands.
There are some simple rules for the syntax of the form: keywords must be against the left margin and end with a ":", and values must either be on the same line as the keyword or indented by a tabstop on the lines below the keword. Only the keywords already present on the form are recognized. Some keywords take a single value (e.g. Client:), some take a block of text (e.g. Description:), and some take a list of lines (e.g. View:).
You can use the p4 client command at any time to modify your client workspace. You will notice on subsequent invocations of the p4 client command there is an additional field on the form: the date of the last modification. You can also look at another client's definition by giving the client's name on the command line, but in this case the values on the form cannot be modified.
There is an important distinction between changing the client's root and changing the client's view. If you change the root, PERFORCE assumes that you will (manually) relocate the files as well. If you change the view and then synchronize the client with the depot, PERFORCE will delete and add files as necessary to make the client workspace reflect the view. That is, the client's root value serves to insulate PERFORCE from the large scale organization of the client host's filesystem, while the view determines the layout of the client workspace managed by PERFORCE.
All updates to files in the depot happen in the context of a PERFORCE "change," and adding files is no exception. First you prepare the change by "opening" files, then you submit it.
To prepare a change that comprises newly added files, you open files with the p4 add command. The p4 add command tells PERFORCE that new files are to be added to the depot. PERFORCE gives new files revision number 1. PERFORCE doesn't transfer the files to the depot until you submit the change with the p4 submit command.
% p4 add jam/doc/* //depot/jam/doc/Jambase.5#1 - opened for add //depot/jam/doc/Jambase.ps#1 - opened for add //depot/jam/doc/Jamfile.5#1 - opened for add //depot/jam/doc/Jamfile.ps#1 - opened for add //depot/jam/doc/Porting#1 - opened for add //depot/jam/doc/RELNOTES#1 - opened for add //depot/jam/doc/jam.1#1 - opened for add //depot/jam/doc/jam.ps#1 - opened for add %
The p4 submit command brings up a change specification form, in a similar format to the client specification. The fields of a change specification are:
Change: new Client: spice User: jake Status: pending Description: Adding jam doc files. Files: //depot/jam/doc/Jambase.5 //depot/jam/doc/Jambase.ps //depot/jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.ps //depot/jam/doc/Porting //depot/jam/doc/RELNOTES //depot/jam/doc/jam.1 //depot/jam/doc/jam.ps ~ ~
When you exit the editor, PERFORCE will parse the form and check for errors. If there are no errors, PERFORCE then takes the following steps to submit the change:
If any of these steps fail, PERFORCE aborts the submission and reverts to the beginning of the step that failed. For example, if some of the files cannot be locked then none of them are locked, but the files are still associated with the newly-created change. This keeps the depot and client in consistent states, but also moves the change as close as possible towards submission.
It is possible to force many of these steps to take place well in advance of submitting the change. We'll discuss that later.
Change 1 created with 8 open files. Submitting change 1. Locking 8 files ... add //depot/jam/doc/Jambase.5#1 add //depot/jam/doc/Jambase.ps#1 add //depot/jam/doc/Jamfile.5#1 add //depot/jam/doc/Jamfile.ps#1 add //depot/jam/doc/Porting#1 add //depot/jam/doc/RELNOTES#1 add //depot/jam/doc/jam.1#1 add //depot/jam/doc/jam.ps#1 Change 1 submitted. %
A client that submits files is assumed to have those files, but if we started off with an empty client we would have to populate it with files from the depot. You do so with the p4 get command. The p4 get command maps all depot files through the client view, compares the result against the current client contents, and then adds, updates, or deletes files as necessary in the client workspace to bring the client contents in sync with the view. p4 get displays the file's revision number next to each file name, and PERFORCE accepts this syntax any place where it makes sense to provide a revision number.
% p4 get //depot/jam/doc/Jambase.5#1 - added as /usr/local/src/jam/doc/Jambase.5 //depot/jam/doc/Jambase.ps#1 - added as /usr/local/src/jam/doc/Jambase.ps //depot/jam/doc/Jamfile.5#4 - added as /usr/local/src/jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.ps#1 - added as /usr/local/src/jam/doc/Jamfile.ps //depot/jam/doc/Porting#1 - added as /usr/local/src/jam/doc/Porting //depot/jam/doc/RELNOTES#1 - added as /usr/local/src/jam/doc/RELNOTES //depot/jam/doc/jam.1#1 - added as /usr/local/src/jam/doc/jam.1 //depot/jam/doc/jam.ps#1 - added as /usr/local/src/jam/doc/jam.ps %
You can also just preview what p4 get would do without transferring the files with the p4 get -n command:
% p4 get -n
p4 get -n normally emits the same messages as the p4 get command, but doesn't really update anything.
You can also see what your client workspace currently has with the p4 have command:
% p4 have
% p4 have //depot/jam/doc/Jambase.5 //depot/jam/doc/Jambase.5#1 - /usr/local/src/jam/doc/Jambase.5 % % p4 have //depot/jam/doc/j... //depot/jam/doc/jam.1#1 - /usr/local/src/jam/doc/jam.1 //depot/jam/doc/jam.ps#1 - /usr/local/src/jam/doc/jam.ps % % p4 have jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.5#4 - /usr/local/src/jam/doc/Jamfile.5 % % p4 have jam/doc/P* //depot/jam/doc/Porting#1 - /usr/local/src/jam/doc/Porting %
These commands - p4 get and p4 have - are two commands that name both the depot and client file in their output. Most commands just mention the depot file name.
Many PERFORCE commands can have their activities restricted to the files that are listed on the command line; their default behavior is to affect all files. You can give the file names either in local syntax or PERFORCE depot syntax, and you can use local or PERFORCE wildcards.
Where it makes sense, you can also provide revision numbers on the file names. You can append these to any sort of file name: local or PERFORCE syntax, specific or wildcarded.
If you provide a revision number that doesn't exist for a file, PERFORCE pretends the file doesn't exist. In the case of p4 get, it will delete the file from your client workspace. If you don't provide a revision number at all, such as we did in the previous p4 get example, PERFORCE uses the head revision.
% p4 get jam/doc/J...#1 //depot/jam/doc/Jamfile.5#1 - updating /usr/local/src/jam/doc/Jamfile.5 % % p4 get jam/doc/"*file*"#2 //depot/jam/doc/Jamfile.5#2 - updating /usr/local/src/jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.ps#1 - deleted as /usr/local/src/jam/doc/Jamfile.ps %
Once files are in the depot, they can be modified in any PERFORCE client workspace that has copies of the files. Our sample client workspace already has the files, so we can change them. All updates to files in the depot happen in the context of a PERFORCE "change." First you prepare the change, then you submit it.
To prepare a change that comprises newly updated files, you open files with the p4 edit command. The p4 edit command does little more than tell PERFORCE that you will be modifying the file you last got and then turn on write permission on the file.
At any time, you can throw away your changes and get back the revision of the file you had with the p4 revert command. The p4 revert command is one of the few that requires a file name, rather than just by default reverting all open files. The reason for this is simple: it discards any work you have made to your open file, and you should be explicit about such an action. If you want to revert all open files, you can use wildcards.
If you want to delete a file rather than edit it, you open the file with the p4 delete command. The p4 delete command tells PERFORCE that upon submission the depot file is to be considered deleted at its next revision. The file will appear not to exist in any client views if a user tries to get that revision. Users can, however, refer to previous revisions of the file or, if the file is later re-added, subsequent revisions. The p4 delete command also removes the file from the client workspace. Up until submission, the client copy can be restored with p4 revert.
% p4 edit jam/doc/Jamfile.* //depot/jam/doc/Jamfile.5#1 - opened for edit //depot/jam/doc/Jamfile.ps#1 - opened for edit %
% p4 revert jam/doc/Jamfile.ps //depot/jam/doc/Jamfile.ps#1 was edit, reverted %
% p4 delete jam/doc/Jamfile.ps //depot/jam/doc/Jamfile.ps#1 - opened for delete % p4 revert jam/doc/Jamfile.ps //depot/jam/doc/Jamfile.ps#1 was delete, reverted %
At any time, you can see what opened files you have with the p4 opened command, and compare your version with the depot with the p4 diff command. The p4 diff command by default compares all opened files against the revision at which they were opened, but you can list explicit files and their revisions on the commmand line.
Once you are satisfied with your change, you can submit it with the p4 submit command as we showed when adding the files.
% p4 opened //depot/jam/doc/Jamfile.5#1 - (text) edit, default change % p4 diff ==== //depot/jam/doc/Jamfile.5#1 - /usr/local/src/jam/doc/Jamfile.5 ==== 35c35 < This description goes with \fBJam\fR Release 2.0. --- > This description goes with \fBJam\fR Release 2.1. %
One of the actions of the p4 submit command is to lock all files that are part of the change. This guarantees that the files in the client workspace will be the next revisions of the files in the depot. Your submission may fail if another client workspace has one of the files locked, or if a another client workspace has submitted a new revision of one of the files while you had it opened.
You can acquire locks on your open files before your submit any time after you open them with the p4 lock command. By doing so, you can ensure that no users in other client workspaces prevent you from being able to submit your files. The p4 unlock releases the lock acquired by p4 lock, allowing other users in other client workspaces to submit their changes. The p4 revert also releases the lock, in addition to reverting the file to its pre-opened revision.
The p4 opened command reports files that are locked in addition to being opened.
% p4 edit jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.5#2 - opened for edit % p4 delete jam/doc/Jamfile.ps //depot/jam/doc/Jamfile.ps#1 - opened for delete % p4 lock //depot/jam/doc/Jamfile.5 - locking //depot/jam/doc/Jamfile.ps - locking % p4 opened //depot/jam/doc/Jamfile.5#2 - (text) edit, default change *locked* //depot/jam/doc/Jamfile.ps#1 - (text) delete, default change *locked* % p4 unlock jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.5 - unlocking % p4 revert ... //depot/jam/doc/Jamfile.5#2 was edit, reverted //depot/jam/doc/Jamfile.ps#1 was delete, unlocked and reverted %
One of the actions of the p4 submit command is to create a change, acquiring a description and list of files from the user and assigning a change number. You can create a change in advance of submitting it by using the p4 change command. More importantly, you can have more than one change awaiting submission. Such changes are called "pending changes." In addition to the p4 change command itself, the p4 add, p4 delete, p4 edit, p4 integrate, p4 lock, p4 reopen, p4 revert, p4 submit, and p4 unlock commands all take a -c change flag to deal with pending changes. Without the -c flag, these commands all assume the "default" change (that is, they affect files that are not associated with any pending change).
Like p4 submit, the p4 change command brings into your editor a new change specification. Included in this specification is a file list containing any opened files not already associated with a pending change. If no files are currently opened, this list is omitted and PERFORCE creates a pending change with no associated files. As with p4 submit, you can delete files from this list if you don't want to associate them with the new change.
You can reedit the description of a pending change by reissuing the p4 change command with the -c change flag. You cannot, however, add more files to the change this way. To associate a newly opened file with a pending change you give the -c change flag to the p4 add, p4 delete, or p4 edit commands. You can move an already opened file from one pending change to another with the p4 reopen -c change command.
The p4 changes command normally lists all changes; you can view just pending changes with p4 changes -s pending. Additionally, p4 opened will display the change number (if any) associated with all open files.
When you submit a pending change with p4 submit, PERFORCE may renumber it. It will do this as necessary to ensure that the newly submitted change number is higher than all changes submitted before. This guarantees that numbers of submitted changes always increase with time, so that change numbers reflect the linear history of the depot.
% p4 change [ editing session ] Change 3 created. % p4 edit -c 3 jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.5#2 - opened for edit % p4 lock -c 3 //depot/jam/doc/Jamfile.5 - locking % p4 submit -c 3 Submitting change 3. edit //depot/jam/doc/Jamfile.5#3 Change 3 submitted. %
PERFORCE supports normal text files as well as binary, "large text" files, and symbolic links.
Binary files are read and written differently than text files on operating systems such as Windows/NT; they are never merged; and when compared with p4 diff they are only reported to be the same or different.
Large text files are read and written as text files, but otherwise treated like binary files: they are never merged or compared. Generated text files such as Postscript can be saved as large text files.
Symbolic links are read and written as symbolic links on UNIX systems that support them; on other operating systems, they are treated as small text files. They are treated as small text files in the depot.
PERFORCE also recognises text and binary files with the execute bit set. These are treated as variations of text and binary files.
When you p4 add a file, PERFORCE first determines if the file is a regular file or a symbolic link, and then examines the first part of the file to try to determine whether is it text or binary. If it finds any non-text characters (characters other than whitespace and printable characters), the file is considered binary; otherwise, the file is considered text.
The detected file type can be overridden by using p4 add -t type. Type is one of "binary", "text", "ltext", "xbinary", "xtext", or "symlink".
A file's type is inherited from one revision to the next. A file can be opened with a different type for the new revision by using p4 edit -t type.
If a file is already opened with p4 add or p4 edit, its type can be changed by using p4 reopen -t type.
The p4 opened command reports the type of the opened file.
The p4 revert command returns a file opened with p4 add, p4 edit, or p4 delete back to its state before it was opened, releasing any lock on the file and refreshing the contents of the file in the client workspace. Files that were opened with p4 add are not deleted but rather "abandoned." That is, PERFORCE no longer knows about them but they are left in the client workspace. The p4 revert command only affects opened files.
The p4 refresh command refreshes the contents of an un-opened file in the client workspace. p4 refresh is mostly a recovery tool for bringing the client workspace back into sync with the depot after accidentally removing or damaging files managed by PERFORCE.
Normally, users are expected to work with a functioning network connection to the PERFORCE server host. As they edit files, they are supposed to announce their intentions with p4 edit. It is possible for users to work entirely detached from the PERFORCE server, manually changing the permissions on files and editing them.
PERFORCE provides a facility for finding files that have changed without its prior knowledge. This is in the form of flags to p4 diff that modify its actions in specific ways:
As with other PERFORCE commands, p4 diff can limit its operations to files matching patterns given on the command line.
% p4 diff -se > CHANGED % p4 -x CHANGED edit //depot/jam/doc/Jamfile.5#2 - opened for edit %
% p4 diff -sd > DELETED % p4 -x DELETED delete //depot/jam/doc/Jamfile.ps#1 - opened for delete %
A change submission normally starts with the current head revision to create the new head revision. But sometimes this is not the case: if the client workspace has a revision other than the head revision when the user opens the file, or if the client workspace has the head revision but another user has submitted a new head revision first, then the user must merge any revisions between the opened revision and the head revision.
In PERFORCE, merging always happens in two steps: first the merge is scheduled; then it is resolved. Both steps occur on open files. PERFORCE schedules merging if you open for p4 edit a file that is not at the head revision, or if you p4 get an opened file which has a new head revision. The p4 submit fails if any files to be submitted have scheduled but unresolved merges, or if a new head revision has been submitted since you opened the file with p4 edit or invoked p4 get on the opened file.
% p4 get jam/doc/Jamfile.5#1 //depot/jam/doc/Jamfile.5#1 - updating /usr/local/src/jam/doc/Jamfile.5 % p4 edit jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.5#3 - opened for edit ... //spice/jam/doc/Jamfile.5 - must resolve //depot/jam/doc/Jamfile.5#2-3 %
You satisfy scheduled merges with the p4 resolve command. This command performs the three-way file merge between the revision you originally got onto your client workspace, the current head revision, and the revision you currently have in your client workspace. PERFORCE refers to the three versions as "base," "theirs," and "yours." p4 resolve reports the number of blocks of lines that were changed in their version and your version, the number of blocks that were changed identically in both versions, and the number of blocks that had conflicting changes. Based on this, it selects which version would be most sensible to keep. Normally this selection is just a suggestion. p4 resolve then iteratively prompts you with a list of options. They are:
h Print some help page.
If you skip a resolution, it will simply show up again on the next p4 resolve invocation. The p4 revert command discards any scheduled merges, in addition to releasing locks and refreshing the client file.
In any of the the files participating in the merge are binary and not text, then a three-way merge is not possible. In this case, the p4 resolve command does not merge the files. Instead, it simply presents the two versions and lets you select between them.
p4 resolve selects the most sensible version and offers it as a suggested action in []'s on the prompt line. You can have p4 resolve automatically accept non-conflicting merges with p4 resolve -a. This skips any merges with conflicts in them. p4 resolve -a -f accepts even conflicting merges. It is important that you edit the file subsequently to remove the conflict markers.
You can view pending resolves with the p4 resolve -n command. This produces the same output as p4 resolve, but doesn't actually do the merging. You can view completed resolves (before they are submitted) with the p4 resolved command.
% p4 resolve //spice/jam/doc/Jamfile.5 - merging //depot/jam/doc/Jamfile.5#2-3 Diff chunks: 1 yours + 1 theirs + 0 both + 0 conflicting Accept (a) Edit (e) Diff (d) Merge (m) Skip(s) Help(?) [am]: dy 35c35 < This description goes with \fBJam\fR Release 2.0. --- > This description goes with \fBJam\fR Release 2.1. Accept (a) Edit (e) Diff (d) Merge (m) Skip(s) Help(?) [am]: dt 1c1 < .TH JAMFILE 5 "10 March 1995" --- > .TH JAMFILE 5 "10 October 1995" Accept (a) Edit (e) Diff (d) Merge (m) Skip(s) Help(?) [am]: d 1c1 < .TH JAMFILE 5 "10 March 1995" --- > .TH JAMFILE 5 "10 October 1995" Accept (a) Edit (e) Diff (d) Merge (m) Skip(s) Help(?) [am]: a //spice/jam/doc/Jamfile.5 - resolved. %
The list of files a client workspace has gotten, along with their revision number, can be saved in a label. A label does not reflect the contents of opened files, but rather only those whose contents were gotten from the depot. A label can later be used to reproduce the state of the client workspace.
A label, like a client or a branch, has an associated view. This view limits what depot files are to be included in the label. A label view is like a client view, except that the right hand side of each mapping is a file name in the label's namespace (//label/...). [This name is not important, except that it must constitute a valid mapping: only the file name in the depot is used.]
A label view is created and maintained with the p4 label command. The default view is to map the whole depot into the label. This includes the whole client, which is a usable default.
Label: save1 Owner: jake Description: Created by jake. View: //depot/jam/... //save1/... ~ ~
Once a label view is created, the p4 labelsync command fills the label with the depot names and revisions of the files in the client workspace. p4 labelsync must be invoked with the -l label flag. Subsequent invocations of p4 labelsync will cause the label to refect the current client workspace contents. Only the label owner may use p4 labelsync; the owner can be changed with the p4 label command.
If a file name is given to p4 labelsync its behavior changes somewhat. Instead of synchronizing the label to reflect the client workspace contents exactly, the label is updated with respect to the named file. If the file was not in the label, it is added. If it was in the label, it is updated. The file name may contain wildcards. If a revision is given with a file name to be added to a label, p4 labelsync changes its behavior further. Instead of making the label reflect the revision of the file that the client has, the named revision of the file in the depot is used. By using named files with revision numbers, labels can be made to reflect any arbitrary collection of files in the depot.
Files can be deleted from a label by using p4 labelsync -d. If a file is named on the command line, only that file is affected. If no file is named, the whole label is cleared.
% p4 labelsync -l save1 //depot/jam/doc/Jambase.5#1 - added //depot/jam/doc/Jambase.ps#1 - added //depot/jam/doc/Jamfile.5#4 - added //depot/jam/doc/Jamfile.ps#1 - added //depot/jam/doc/Porting#1 - added //depot/jam/doc/RELNOTES#2 - added //depot/jam/doc/jam.1#1 - added //depot/jam/doc/jam.ps#1 - added %
The p4 get, p4 diff, p4 files, p4 integrate, and p4 print commands all permit file names on the command line and presume that they refer to the head revisions of the files. If a revision specification is given, a revision other than the head can be referenced. A revision specification is tacked onto the end of the file name, and is one of seven varieties:
In all cases, if a file doesn't exist at the given revision number it appears as if the file doesn't exist at all. Thus using a label to refer to a file that isn't in the label is indistinguishable from referring to file that doesn't exist at all.
A revision specification can be given without a file name. This limits the command's action to the specified revision of all files in the depot or in the client's workspace.
% p4 get jam/...#1 //depot/jam/doc/Jamfile.5#1 - updating /usr/local/src/jam/doc/Jamfile.5 //depot/jam/doc/RELNOTES#1 - updating /usr/local/src/jam/doc/RELNOTES %
% p4 get jam/...@5 //depot/jam/doc/Jamfile.5#4 - updating /usr/local/src/jam/doc/Jamfile.5 %
% p4 get jam/...@save1 //depot/jam/doc/RELNOTES#2 - updating /usr/local/src/jam/doc/RELNOTES %
% p4 files //depot/...@save1 //depot/jam/doc/Jambase.5#1 (text) add change 1 //depot/jam/doc/Jambase.ps#1 (text) add change 1 //depot/jam/doc/Jamfile.5#4 (text) edit change 4 //depot/jam/doc/Jamfile.ps#1 (text) add change 1 //depot/jam/doc/Porting#1 (text) add change 1 //depot/jam/doc/RELNOTES#2 (text) edit change 6 //depot/jam/doc/jam.1#1 (text) add change 1 //depot/jam/doc/jam.ps#1 (text) add change 1 %
% p4 get #none //depot/jam/doc/Jambase.5#3 - deleted as /usr/local/src/jam/doc/Jambase.5 //depot/jam/doc/Jambase.ps#2 - deleted as /usr/local/src/jam/doc/Jambase.ps //depot/jam/doc/Jamfile.5#5 - deleted as /usr/local/src/jam/doc/Jamfile.5 //depot/jam/doc/Jamfile.ps#2 - deleted as /usr/local/src/jam/doc/Jamfile.ps //depot/jam/doc/Jamnotes#1 - deleted as /usr/local/src/jam/doc/Jamnotes //depot/jam/doc/Porting#2 - deleted as /usr/local/src/jam/doc/Porting //depot/jam/doc/RELNOTES#3 - deleted as /usr/local/src/jam/doc/RELNOTES //depot/jam/doc/jam.1#2 - deleted as /usr/local/src/jam/doc/jam.1 //depot/jam/doc/jam.ps#2 - deleted as /usr/local/src/jam/doc/jam.ps %
Clients, labels, and branches can each be deleted from the system, by passing the -d name to the p4 client, p4 label, or p4 branch command.
Deleting a client does not delete any files from the client workspace, but removes the records of any opened or locked files, the records of any pending integrations, and the records of files gotten by the client. Deleting a label removes the records of files in the label. In all cases, deleting a client, label, or branch deletes the specification and the view.
The list of clients, labels, and branches present in the system can be displayed with the p4 clients, p4 labels, and p4 branches commands.
All of the client commands that use text forms, p4 branch, p4 change, p4 client, and p4 label, have optional flags for batch use. Normally these commands produce a form, bring it into the user's editor, and then parse and save the edited form. The -o flag causes these commands instead to dump the form onto the standard output. The -i flag causes these commands to read the form from the standard input.
Additionally, the p4 submit command takes a -i flag as well. This allows it to read its form from the standard input. An batched submit might then read:
% p4 change -o | sed 's/<.*>/description/' | p4 submit -i
The sed(1) command is used to replace the blank description with a real one.
Not all client commands must be run in the context of a client workspace.
The following commands can be used without having to create a client first:
branch branches client clients describe fix job label labels protect review user user
The following commands can be used without a client, but only if they are not passed arguments referring to local files:
changes diff2 filelog files fixes integrated jobs print review
The following command always requires a client:
change diff get have integrate labelsync lock open opened refresh release reopen resolve submit unlock where
The p4 help command provides for some on-line help for each of the p4 client commands.
The p4 info command displays what the server knows about the client (the user name, the client name, and the client directory) and some server information (the server's address, version, and license data).
The p4 where command displays how files in the current directory map through the client view into the depot namespace. This can be used to test the client view. The p4 where command can also take a file name as a argument In this case, it displays the mapping for the named file. This works even if the file doesn't actually exist in the depot.
This chapter describes PERFORCE's jobs facility, which provides for a simple defect tracking system,or for integration to an external defect tracking system. A job is generic term for work that is intended to be performed against the files in the depot. It is analogous to a defect report, a system improvement request, or change order.
PERFORCE's defect tracking amounts to three activities: creating and managing the jobs, associating the jobs with actual changes, and reporting. Reporting is discussed in Chapter 4, "Reporting."
A job consists of a job name, a status, and owner, and description. The job name and description contain the user's data. The job name can be supplied by the user or created automatically by PERFORCE: if a job is created without a name (or with the name "new"), PERFORCE creates a job with the name "jobN", with N replaced by a six-digit sequence number. The job description is arbitrary text supplied by the user.
The purpose of status and owner is to facilitate associating jobs with changes. At change submission time, the user is presented a list of all open jobs he owns. Status is one of three values:
The owner is just a user name: only that user will see the job on his change submission form. Any user can manually associate a job with a change, but only the owner can do so automatically when submitting a change.
All of these fields are created with the p4 job command. Like p4 change and others, p4 job brings a form into the editor for the user to edit.
Job: job000040
Owner: jake
Status: open Description: The widget that represents the microphone on the screen doesn't look right, and it should be changed to look more realistic.
~ ~ ~
After a job has been created it can be edited again with the p4 job command. Its owner and description can be changed arbitrarily. The status can be changed to any of its three legal values. The name cannot be changed.
A list of recorded jobs can be displayed with the p4 jobs command. It can limit its output to jobs with a specified state by using the -s status flag.
Individual jobs can be deleted with p4 job -d name.
The p4 job command supports flags for batch processing. The -o flag causes the job form to be dumped onto the standard output. The -i flag causes the form to be read from the standard input.
There are two ways of associating jobs with changes: through change creation with the p4 change and p4 submit commands, or directly with the p4 fix command.
When a change form is created by the p4 change or p4 submit command, any open jobs owned by the submitting user are included on the form as a list of jobs to be closed when the change is submitted. The user may delete jobs from this list if they are not addressed by the change and are to remain open. Whether a job is associated with a change via the p4 change or p4 submit command, the job is not closed until the change is actually submitted. Normally, this is implied by the p4 submit command, but it is possible that the submit may abort after the change is created and the jobs associated with it.
The p4 fix command allows any jobs - open or closed - to be associated with any changes - pending or submitted. If the job is open and the change has already been submitted, the job is closed. If the job is already closed, it remains closed. If the job is open and the change is pending, the job is closed when the change is submitted.
Because the jobs remain open until the change is submitted, it is possible (and permitted) to have a single job associated with multiple pending changes. When the first change is submitted, the job will be closed and remain closed when the subsequent changes are submitted. The job can be manually reopened by editing it with the p4 job command.
The list of associations between jobs and changes can be listed with the p4 fixes command. It can limit its output in three ways: by change with the -c change option; by job with the -j job option; and by files affected by changes associated with jobs by naming the files on the command line.
PERFORCE has a variety of reporting commands and other display-only commands - commands that update neither the client workspace nor the depot. Some of these commands have been covered already. The sections of this chapter lists the reporting commands and subsequent sections discuss some scenarios in which the reporting commands are useful.
Reporting commands that are specific to branching and integration are discussed more thoroughly in Chapter 5, "Branching and Integration"
The first set of reporting commands are those that deal directly with the revision history of individual files and with the change history of the depot. Most take an optional list of files to limit their reporting to just those files. If no argument is given, the commands report all relevant files:
The next set of reporting commands are those for describing branch, change, client, and label definitions. Each of the p4 branch, p4 change, p4 client, p4 job, p4 label, and p4 user commands can optionally take a -o name flag. This flag tells these commands to print the definition for the named entity on the standard output, rather than bringing the definition into the user's editor.
Each of these commands also has a plural form that lists all known definitions of the corresponding type.
The final set of reporting commands are four commands that take a -n flag to prevent them from doing their job. Instead, they just report what they would do:
% p4 diff #head
This section describes how to use the reporting commands to dig useful information out of the PERFORCE database.
% p4 files //depot/main/... show head revisions of files
% p4 files @labelname dump contents of label % p4 files @clientname show have list of client % p4 files @234 show depot state at change 234
The p4 filelog command gives the linear revision history of individual files. It includes integration history (as described in Chapter 5, "Branching and Integration"). The p4 filelog command normally gives a short fragment of the change description associated with the changes that bring about each revision. The -l flag causes the full change description to be displayed.
% p4 diff2 Jamfile#2 Jamfile compare rev 2 against the head % p4 diff2 ...@33 ...@40 differences between changes 33 and 40 % p4 diff2 //depot/main/... //depot/r827/... compare branches
% p4 changes rcs/... #show all changes affecting rcs subdirectory
% p4 changes @labelname
% p4 changes rpc/...@200,@300 # range of changes % p4 changes @release1,@release2 # compare labels
% p4 changes //depot/r827/...@701,#head
% p4 changes //depot/main/... > changes-in-main % p4 changes //depot/r827/... > changes-in-r827 % diff changes-in-main changes-in-r827
This could be used to uncover what changes have been made to r827 that haven't been integrated back into main.
The p4 changes command can also limit its output to pending or submitted changes only, using the -s status option. It can also be made to display the full text of the change description rather than just the single line with the -l flag.
p4 jobs normally lists all jobs and p4 fixes normally lists all associations between jobs and changes. Both of these commands can scope their output to affected files just as p4 changes does. In both cases, the named file is used to limit the changes that are considered. In the case of p4 jobs, only jobs associated with the selected changes are listed. With p4 fixes, only fixes by the selected changes are listed.
In addition to scoping its output to affected files, p4 fixes can limit its output by change with the -c change option and by job with the -j job option. The p4 jobs command can also limit its output to open, suspended, or closed jobs only, using the -s status option. p4 jobs can also be made to display the full text of the job description with the -l flag.
Each time a user accesses the PERFORCE depot, the list of known users is updated. If the user is new to the system, he is added to the list. If the user is an existing one and he hasn't accessed the depot in the last hour, his access time is updated. The p4 users command lists all known users, along with their full names, email addresses, and access times. The p4 users command can limit its output to a single user or set of users by providing a (wildcarded) name as an argument.
PERFORCE's Inter-file branchingTM mechanism makes branches by copying files around in the depot and giving the new files new names. Once the files have been copied, PERFORCE can orchestrate propagating changes from the original files to the new and back again. The same integration mechanism handles both the initial creation of branched files and their subsequent updating. Integration happens within the context of normal PERFORCE changes. That is, the p4 integrate command only opens files: you must submit these files for the integration to take effect.
A branched file's name is related to the original file's name by a branch view. A branch view is much like a client view, except that the mappings have depot files on both the left and right: on the left are the source files and on the right are the target files. A branch view is created and maintained with the p4 branch command. The default view is to map the whole depot directly back into itself, which is not useful. You must provide your intended view by replacing the view line with your own. This example says that the files under //depot/jam/doc are to be branched into //depot/jam1.0/doc:
Branch: r1 Description: Created by jake. View: //depot/jam/doc/... //depot/jam1.0/doc/... ~ ~
Once a branch view has been created, it can be used to branch and update the target files in the view. The p4 integrate command orchestrates this, opening the target files on the client as necessary. The p4 integrate command must be invoked with the -b branch flag.
p4 integrate only acts on files that are the intersection of target files in the branch view and in the client view. If file names are given on the command line, p4 integrate further limits its actions to those target files. The source files of a branch need not be in the client view.
p4 integrate performs the following steps:
p4 integrate will reverse the sense of the branch view (turning source files into target files and vice versa) if the -r flag is given. This allows a branch view to be used bi-directionally.
The actions on the files opened by integrate are one of the following:
If any files were opened for integrate, then the user must perform the merges with the p4 resolve command. This is the same command used to merge in the head revision when a file is opened with p4 edit, but some special cases arise when the merge is driven by p4 integrate.
The p4 resolve command allows you to accept any of the three files in the merge as the result: your local file, the source file of the merge, or the programmatically merged result. In files opened with p4 edit, the only thing that matters is accepting the right text. With integration, there is an advantage to accepting the right version (if the text among various versions are the same). The order of preference is as follows:
p4 resolve computes the preferred version based on whether there were changes or conflicts, using the following algorithm: if there were no changes to yours, accept theirs. If there were no changes to theirs, accept yours. Otherwise, accept result of merge. p4 resolve displays the result of this selection in its prompt.
Unlike p4 edit, a file opened for integrate is left read-only. This is to indicate that the file should only be changed during the p4 resolve process. Limiting the change of a file to incorporate only integrations allows PERFORCE to suppress the need to integrate the change back into the source file. Sometimes it takes more than one editing session to get a merge working. You can revisit a resolved file with the p4 reresolve command. If necessary, the file's action can be "downgraded" to edit by reopening the file with p4 edit. In that case, the integration will no longer considered a pure integration (see below).
The p4 resolve command can automate merges. The -a causes p4 resolve to accept the most preferred version, but skips any files that have textual conflicts. The -f flag causes p4 resolve to accept merges with conflicts as well.
In some cases, p4 resolve cannot perform a normal, three-way merge based on a common ancestor. Normally the first time a source file is integrated the target file is created with p4 integrate's branch action, and subsequent times the last integrated revision serves as the basis for merging the new revisions. But if you integrate a source file into a target file that already exists (that is, the target file was manually added with p4 add or branched from another file), there is no basis revision for the merge. In this case, p4 resolve must do a two-way merge, where it uses the your file as the base of the merge. In a two-way merge, all changes appear as "theirs" and there can be no conflicts.
After using p4 integrate and (if necessary) p4 resolve, the opened files may be submitted as with any other change. Files opened for integration can be submitted with files opened manually, and branches can be submitted at the same time as updates. Submitting the files causes the pending integration records to be recorded permanently, so that they can affect subsequent integrations.
Reverting opened files that have pending integrations drops the record of those integrations.
The p4 integrate command can integrate specific revisions of source files, rather than just those that haven't been integrated before. To limit the integration to specific revisions, append a revision range specification to the target file name on the command line. The revision range specification can appear alone if no target file name is necessary. If the revision range is only a single revision, that serves as the highest revision to be integrated. The revision specification can as usual use revision numbers, change numbers, labels, etc.
It should be noted that when a revision range is appended to a file name on p4 integrate's command line, the file name refers to the target file while the revision range refers to the source file.
% p4 integrate -b r1 //depot/jam1.0/doc/Jambase.5#1 - branch from //depot/jam/doc/Jambase.5#1 //depot/jam1.0/doc/Jambase.ps#1 - branch from //depot/jam/doc/Jambase.ps#1 //depot/jam1.0/doc/Jamfile.5#1 - branch from //depot/jam/doc/Jamfile.5#1-4 //depot/jam1.0/doc/Jamfile.ps#1 - branch from //depot/jam/doc/Jamfile.ps#1 //depot/jam1.0/doc/Porting#1 - branch from //depot/jam/doc/Porting#1 //depot/jam1.0/doc/RELNOTES#1 - branch from //depot/jam/doc/RELNOTES#1 //depot/jam1.0/doc/jam.1#1 - branch from //depot/jam/doc/jam.1#1 //depot/jam1.0/doc/jam.ps#1 - branch from //depot/jam/doc/jam.ps#1 % p4 submit
% p4 integrate -b r1 //depot/jam1.0/doc/RELNOTES#1 - get and edit from //depot/jam/doc/RELNOTES#2 % p4 resolve //spice/jam1.0/doc/RELNOTES - merging //depot/jam/doc/RELNOTES#2 Diff chunks: 0 yours + 1 theirs + 0 both + 0 conflicting Accept (at/ay/a) Edit (et/ey/e) Diff (dt/dy/d) Merge (m) Skip(s) Help(?): at //spice/jam1.0/doc/RELNOTES - resolved. % p4 submit
% p4 integrate -b b2 //depot/jam2.0/...@save1 //depot/jam2.0/doc/Jambase.5#1 - branch from //depot/jam/doc/Jambase.5#1 //depot/jam2.0/doc/Jambase.ps#1 - branch from //depot/jam/doc/Jambase.ps#1 //depot/jam2.0/doc/Jamfile.5#1 - branch from //depot/jam/doc/Jamfile.5#1-4 //depot/jam2.0/doc/Jamfile.ps#1 - branch from //depot/jam/doc/Jamfile.ps#1 //depot/jam2.0/doc/Porting#1 - branch from //depot/jam/doc/Porting#1 //depot/jam2.0/doc/RELNOTES#1 - branch from //depot/jam/doc/RELNOTES#1-2 //depot/jam2.0/doc/jam.1#1 - branch from //depot/jam/doc/jam.1#1 //depot/jam2.0/doc/jam.ps#1 - branch from //depot/jam/doc/jam.ps#1 %
PERFORCE keeps track of integrated files by associating integration records with each revision of each file. The integration record states what revisions of what source file were integrated into the target file. (The integration action (branch, integrate, or delete) is part of the file's revision record, not the integration record.) Note that each integration record can include more than one revision from the source file, but the revisions must be contiguous: integration records record a revision range.
In most cases, a pure integration occurs. This is when the change to the target file incorporates only revisions integrated from a single source file. When a pure integration is submitted, an extra integration record is created to suppress the need to integrate the new revision of the target file back into the source file. This record is called a reverse integration record.
An integration becomes impure in one of two circumstances: if the user downgrades the integrate to edit by reopening the file with p4 edit, or if changes from more than one source file are integrated into a target file. The latter means that the user has to issue the p4 integrate command more than once, and that the target files in the branch views refer to the same files. An impure integration doesn't generate a reverse integration record, and so the resulting change will have to be integrated back into the source file(s).
The integration records distinguish among different types of integrations. They are:
These file commands allow you to track the integration history that PERFORCE records whenever changes are propagated among files:
The p4 integrate command computes what changes (specifically, what revisions of what individual files) need to be propagated to the target files in a branch view. Normally it opens the target files for the appropriate action, and the changed target files can be submitted in a regular change. To see what p4 integrate would do without actually opening any files, you can use the -n flag.
Once the p4 integrate command is run for real, some files may need to be merged before they can be submitted. The p4 resolve command does this merging. To see what needs to be merged without actually merging, you can pass p4 resolve the -n flag.
After files are merged with the p4 resolve command, the records of the completed merges can be viewed with the p4 resolved command.
Once integrated and resolved files are submitted, the resolve records become part of the permanent integration history. They can be viewed with the p4 integrated command.
The report from p4 integrated includes some detail for each individual set of revisions that were integrated. These are sample lines of output:
//depot/main/p4/Jamrules#57 - copy from //depot/r827/p4/Jamrules#2-4 //depot/r827/p4/Jamrules#4 - copy into //depot/main/p4/Jamrules#57
The first line indicates that revision 57 of the target file (the "main" branch) was the integration of revisions 2 through 4 of the source file (the "r827" branch). The second line is the reverse integration record to reflect the fact that the source file at revision 4 has in essence revision 57 of the target file. The words "from" and "into" indicate whether it is normal or reverse integration record.
The p4 filelog command give the linear revision history of individual files. It includes in its output the integration history at each revision.
PERFORCE includes provisions for automating change review, where users can receive email when files they are interested in change. There are four components to change review:
PERFORCE tracks the name of each user that accesses the depot. On a user's first access, a default user specification is created: the user's full name is simply user, the user's email address becomes user@client, and an empy review list is created. The email address and full name appear in the output of p4 review and p4 reviews for the change review daemon to address review email, and the review list is used by p4 reviews to determine which users review each change.
Users can edit their user specifications with the p4 user command.
User: jake Email: jake@chicago.il.usa FullName: Jake Blues Reviews: //depot/jam/... //depot/.../Jamfile
~ ~
The p4 users command displays all known users, listing their email address, full name, and access time.
The review daemon's job is to poll the PERFORCE depot for unreviewed changes, get the list of reviewers for each change, get the change description, and send out email. The review daemon need not run on the same host as the PERFORCE server: it merely needs access to the p4 client command to invoke p4 review, p4 reviews, and p4 describe.
A boilerplate review daemon, perfreview.perl, is available from the PERFORCE SOFTWARE Web Server at http://www.perforce.com. It requires Perl 4 and Sendmail in order to run. It can also be used as a template for a customized review daemon.
In order to use the p4 review command, the review daemon must run as a user with review access; this is a protection level documented in Chapter 7, "Protections." If protections are not enabled (the default), all users have review access.
The p4 review and p4 reviews commands can be used in custom applications other than change review.
The p4 review command works by keeping a counter of the highest numbered reviewed change; this is compared against the highest numbered submitted change to produce the list of unreviewed changes. p4 review can acutally keep any number of counters, as each counter has a name. The change review daemon uses the counter named "review". A possible use of a second counter would be to automate the uploading of fix information into an external defect tracking system on change submission. Periodically a daemon could use the p4 review command to list new changes and then p4 fixes to get the list of jobs fixed by the newly submitted changes. This information could be fed into the defect tracking system, notifying it that certain jobs have been completed.
p4 reviews normally provides the list of reviewers for the files affected by a numbered change. It can also report the reviewers of any files provided as arguments on the command line. This makes it possible for a user to find the reviewers of any arbitrary set of files.
This chapter describes how to use PERFORCE protections to prevent unauthorized or inadvertant access to the depot. By default, any user can access or update all files in the depot. Once protections are enabled, only listed users on listed hosts may access specified files in the depot, and their access can be limited to list, read, write, review, or superuser access. Access is granted to selected files using file patterns with wildcards.
The access levels are defined as follows:
Protections are created and edited with the p4 protect command. Before this command is first run, there are no protections against access to the depot. On its first invocation, it creates a default protections table that gives all users on all hosts write access and the invoking user on all hosts superuser acccess. Therefore it is possible for any user to seize superuser privileges on an unprotected depot. (This can be remedied by the simple administrative action of removing the db.protect table in the PERFORCE server root directory.)
The p4 protect brings the protections table into the user's editor. It is a form consisting of one field "Protections", and that field can contain any number of protections line. Each line has four words on it:
A user has the union of the access rights granted by lines in the protections table that match his user name and client IP address. The protections table can only grant access, not deny it.
A simple protections table is shown below:
Protections: read * 206.14.52.* //depot/... write jake 206.14.52.* //depot/... super jake 206.14.52.193 //depot/... " " "
The following table lists for each PERFORCE command the access level needed to run the command.
Command Access Command Access Level Level add write job * write branch * write jobs * list branches list label * write change write labels * list changes list labelsync write * client * list lock write clients list open write * delete write opened list describe read print read describe list protect * super -s diff read refresh read diff2 read reopen write edit write reresolve write files list resolve write filelog list resolved write fix * write revert write fixes * list review * review get read reviews * list have list submit write help none user * list info none users * list integrate write where * none integrate list d
* - These commands only require access to any files in the depot, as they don't operate on specific files.
In order to use the p4 integrate command, the user must have write access to both the source and target files of the branch view.
The change review daemon runs at the access level of the user who invokes it (typically root), not at the access level of the users receiving email. Thus the contents of the review mail should not include the contents of files unless it is safe for all users to see those files. A user needs only list access in order to invoke the p4 user command to subscribe to review changes to files.
Lack of list access causes file names to be elided from all output. Even p4 describe will not include files to which the user does not have list access. If a user makes a direct reference to an inaccessible then PERFORCE issues the message "Protected namespace."