Basic Perforce FAQ
Note - the intended audience for this FAQ is a person using Perforce for software development. There's a separate FAQ for system administrators, and eventually we'll have one for advanced Perforce users.
This FAQ assumes that there is a Perforce Administrator who knows some of the more complex parts of Perforce, who can provide help, counseling, and deal with policy-specific issues. This FAQ is taken from an initial set of questions provided by Richard Geiger and Jeff Bowles.- Where do I begin?
- What is S.C.M.?
- How do I check out a source tree?
- How do I make a change to a file and check it in?
- What if I have a favorite editor and want to use it when I do a change submission?
- How do I add a new directory?
- How do I remove a directory?
- How do I check out some older version of a file?
- How do I check out an entire tree as of some date?
- How do I check out an entire tree corresponding to some build or release?
- How do I compare a working file to the base?
- How do I compare a whole tree to the base?
- How do I get my favorite diff behaviors with p4 diff?
- How do I update a tree from the base?
- How do I compare a working file to an older version (other than the base)?
- How do I get a list of all files I have open on all my client workspaces?
- How do I examine the change log for a file?
- How do I abandon my changes and pick up a clean copy from the base?
- How do I propagate an individual change made in one branch to another?
- I created a file that begins with a dash, and want to 'p4 delete' it and cannot. What can I do?
- How do I delete a client workspace?
- How do I move a client workspace?
- I can't "p4 sync" a particular file. What might be going on?
Initial List
Getting and modifying files
Comparing what you've gotten to the reference copy
Getting information about a file or workspace
Abandoning work and starting over
Changing your workspace (moving it, deleting it)
Miscellaneous problems
- Where do I begin?
- What is S.C.M.?
- How do I check out a source tree?
- How do I make a change to a file and check it in?
- Open the file for the 'edit' operation - you can open more than one file at a time;
- Do the editing in your favorite editor, and make the contents of the files into what you want.
- Submit the modifications as one 'atomic' change so that they're available to other people.
- What if I have a favorite editor and want to use it when I do a change submission?
- How do I add a new directory?
- How do I remove a directory?
- How do I check out some older version of a file?
- How do I check out an entire tree as of some date?
- How do I check out an entire tree corresponding to some build or release?
- How do I compare a working file to the base?
- How do I compare a whole tree to the base?
- How do I get my favorite diff behaviors with p4 diff?
- How do I update a tree from the base?
- That there's something to get - if you have already updated directory to the most recent revisions and nothing's been changed since, p4 sync won't retrieve the revisions again. ( p4 sync -f directory/...#have will do that.)
-
That directory is located under your local
Perforce's client root. The command...
-
That directory is mapped in from the Perforce
depot using your client specification. The command...
- How do I compare a working file to an older version (other than the base)?
- How do I get a list of all files I have open on all my client workspaces?
- How do I examine the change log for a file?
- How do I abandon my changes and pick up a clean copy from the base?
- How do I propagate an individual change made in one branch to another?
-
I created a file that begins with a dash, and
want to 'p4 delete' it and cannot. What can I do?
Let's say that the name of the file is "-filename".
Run "p4 delete dummy -filename" to delete the file - ignore the comment about the dummy filename, its purpose is to stop the option/argument processing and let everything else on the command line be interpreted as filenames.
Or, you could run "p4 delete ./-filename", which uses the Unix directory separator ('/') to construct a filename that refers to the same file, but doesn't begin with a dash. (NT uses might use '\'.)
- How do I delete a client workspace?
- Set $P4CLIENT to the name of the workspace, or
make sure that every command you run for this task uses the syntax
p4 -c workspacename cmd
- Run p4 opened to make sure that no files are opened for any operations in this workspace. If there are, use the command...
- Remove the workspace entry on the Perforce server...
- Remove the files and directories on the local disk that correspond to the client area.
- How do I move a client workspace?
- Figure out the new client "root". Let's say it's "/home/jojo/newroot".
- If you're using the Windows GUI program against this particular Perforce client, exit the GUI.
- Move the entire subtree from its old place to "/home/jojo/newroot".
- I can't "p4 sync" a particular file. What might be going on?
- The other files it gets are in the directory //depot/main/jam/... If that's the case, you're up against upper-case/lower-case issues. (The NT version of the server ignores case; the Unix version of the server does not.) If this is the case, it'll be easiest to go to a Unix client and rename the file to be in the same directory as the files that are succeeding. ("p4 help rename" gives the steps for renaming a file.)
- You might not have permissions on this file from this IP address for this user. Use "p4 protect -o" and "p4 where" to make sure that isn't the case.
- The client spec might not be mapping that file as you expect.
The command "p4 where //depot/MAIN/jam/jam.c"
will process
the argument filename through the client spec [processing] code to
tell you where it would be mapped.
- The top-most revision of that file might be a "delete" revision, so that there's nothing to get(!). ("p4 files //depot/MAIN/jam/jam.c" will tell you the type of the top-most revision of the file.)
- There might be nothing to get, because it thinks you have the most recent revision. "p4 have //depot/MAIN/jam/jam.c" will tell you if you already have a revision for that file, or at least whether the database thinks you do. ("p4 sync -f //depot/MAIN/jam/jam.c" will force getting a fresh revision.)
- The top-most revision of that file might be a "delete" revision, so that there's nothing to get(!). ("p4 files //depot/MAIN/jam/jam.c" will tell you the type of the top-most revision of the file.)
Start with chapters #3-5 of the user's guide - that's referred to as the Quick Start to the product. All of the documentation is on-line.
It's probably best to create a small workspace (the term is "client")
to play in, so that you can experiment with a few files and not necessarily
the 16,000 files that you're planning to manage with source control.
Short answer: it's a way to maintain revisions of files so that you can easily recreate a version of a file from any moment in time.
The "S.C.M." translates to "Source Code Management" or perhaps "Software Code Management" or "Software Control Management" - the better systems let you manage large sets of files, have multiple people working with the same body of files (a development team of 1 person isn't much fun), and work on different platforms (such as Windows/NT and Unix) transparently.
There are a lot of S.C.M. products around - this FAQ won't try to spend a lot of time enumerating them or contrasting them.
Another way to phrase the question is "How do I get files and begin editing them?". This question will answer the first part of the question - the next FAQ will answer the rest.
To get a set of files...
Each of the following cases assumes you have a "Perforce client" (a.k.a. 'workspace') already. If not, see the FAQ to create one.Case #1: you need to get all the files - the most recent revision of each file.
- Type
p4 sync
That will get you a read-only copy of the "head "revision of every file that your client can see.
- You'll want to "cd" (chdir) to the directory you want to get.
Then type p4 sync ... to get the files that should go into that directory.
For example:
cd directoryname
p4 sync ...
That will get you a read-only copy of the "head" revision of every file in that directory and its subdirectories that your client can see.
- If the label name is "BUILD_28", you'll be updating your client (a.k.a.
workspace) the "the revision of each file that is included in label 'BUILD_28'."
Note that this means that your local copy of files not included in 'BUILD_28'
are removed.
Some examples:
p4 sync @BUILD_28 | Update the local copies of files on the current client to be the exact revision specified in label "BUILD_28". The local copy of files not included in the label, but managed by Perforce, are removed from the client. |
cd directoryname
p4 sync ...@BUILD_28 |
Update the local copies of files in directoryname (and underneath
that tree) on the current client to be the exact revision specified
in label "BUILD_28".
The local copy in directoryname (and underneath that tree) of files not included in the label, but managed by Perforce, are removed from the client. Files not under directoryname aren't touched. |
p4 sync directoryname/...@BUILD_28 | Should do exactly the same thing as the previous example. (Neat, huh?) |
To edit a set of files...
Normally, you will edit a file using three steps:Step #1:
- The basic edit command is
p4 edit filename
or,
p4 edit filename1 filename2 (and so on)
and occasionally,
p4 edit directoryname/... (edit all files in `directoryname' and its subdirectories)
Step #2:
- Do the editing using your favorite editor - Perforce isn't directly
involved in this step. You can always run through "Step #1" on other
files, if you decide you need to edit more files.
In Perforce, the 'working' copy of the file is a local copy stored in the "client area". The modified contents are sent back to the server only when you do a 'p4 submit'.
Step #3:
- The basic "submit my changes" command is:
p4 submit (submit all modifications)
or, occasionally,
p4 submit filename (submit only this one file's modifications, leave the rest checked out)
When you run...
p4 submit
...you'll be dumped into the editor, to write a description of why
you made these changes. See the manual for more details.
You can either set the environment variable "P4EDITOR" to be the name of the editor you want to run, or if you're on Windows/NT, use:
p4 set P4EDITOR=commandname
You don't need to add a directory, explicitly. You simply add files in that directory, using
cd directoryname
p4 add
filename
or,
p4 add directoryname/filename1 directoryname/filename2 (and so on)
The final step, which is to run p4 submit , will make these new files available to other Perforce clients.
Perforce infers the existence of new directories whenever it sees a new directory it hasn't seen before.
You don't need to remove a directory, explicitly. You simply
remove files in that directory, using
cd directoryname
p4 delete
filename
or,
p4 delete
directoryname/filename1 directoryname/filename2
(and so on)
and occasionally,
p4 delete
directoryname/... (remove
all files in `directoryname' and its subdirectories)
The penultimate step, which is to run p4 submit , will these deletions to other Perforce clients.
The final step is to remove the empty directories on your client: "p4 delete / p4 submit" removed the files, but not the directories.
You'll need to retrieve that revision first, then p4 edit the file. That's the easy part. The hard part is deciding how to submit the change. (Let's save that for later in the answer.)
For example, if you want to edit revision #12 of xyz.java, you'll need
to type:
p4 sync
xyz.java#12
p4 edit
xyz.java
The first command, of course, isn't needed if you already have revision #12 of xyz.java. (You can tell which revision you have by typing p4 files xyz.java .
You'll be told, when you run p4
edit xyz.java, that you're not editing
the most recent revision and that you'll need to resolve later revisions
prior to submitting your changes. (If
you think about it, that makes sense.)
Now the file's opened for "edit", and you can do whatever you want
to the file. Submitting it, however, is going to be a problem: you don't
want to inadvertently overwrite the contents of later revisions of the
files.
Case #1: you really do want to overwrite the later revisions
for some reason.
- When you run the command...
p4 submit
you'll be told that the your changes need to be resolved against more
recent revisions prior to submitting. Write down the change number
it gives in the error message (e.g. "submit -c 12345"), although you
can always find it again by running the command p4
changes -s pending .
- From another question
in this FAQ: use p4 revert filename
to discard the modifications you've made
to filename and retrieve a fresh copy of the exact same revision
you had prior to typing p4 edit
filename .
For release 98.2...
- There's an entry in the release
notes that says:
Wherever revision specifications are supported, @date and "@datetime" can now be used in addition to @change and @label. The format for date is YYYY/MM/DD, and the format for datetime is YYYY/MM/DD:HH:MM:SS. If no time is given, midnight is assumed. |
- That means that the command p4 sync
...@1998/09/02 will retrieve all
files that map to the current directory (and its subdirectories!), at the
revisions that were current at midnight on September 2, 1998.
For releases prior to 98.2...
- You'll need to use p4
changes to find the change
number immediately prior to the desired date, and then use the command
p4 sync ...@changenum to
retrieve the fileset you want.
In general, you'll need to have a piece of data from your build person: the label name used for that build. (You can always hunt for it, using the command p4 labels .)
If the label is release3.2label, you can update your client area to this by typing:
p4 sync @release3.2label
This will update your client to this label, removing
local copies of files that aren't in the label.
If you want subdirectory xyz to be updated, but no other directories
on your client, you would type:
p4 sync
xyz/...@release3.2label
Use p4 diff filename , which will compare the local copy of a file you've opened for edit or an integrate operation against the revision of the file you were original given.
For example, say you've opened xyz.java using the command:
p4 edit
xyz.java
To see your modifications, type:
p4 diff
xyz.java
Note that this is not comparing your local copy of the file against
the most recent changes that other people have checked in - it's comparing
against the revision you were working against. (That's p4
diff filename#head .)
Use p4 diff directory/... , which will compare the local copy of every file in directory that is opened for edit or an integrate operation against the revision of the file you were original given.
For example, say you've opened xyz.java and z.java
in directory dir1 using the command:
p4 edit
dir1/xyz.java dir1/z.java
To see your modifications, type:
p4 diff
dir1/...
Note that this is not comparing your local copy of the file against
the most recent changes that other people have checked in - it's comparing
against the revision you were working against. (That's p4
diff dir1/...#head .)
The environment variable $DIFF is the command line that's run when you run:
p4 diff file1 file2
If, for example, the command "diff -c" produces "context output format", then the sequence:
DIFF="diff
-c"
export
DIFF
p4 diff
file1 file2
will produce that type of output for the differences between the two files.
Note that p4
diff2 file1 file2 doesn't
honor this variable, because the "diff" operation is run on the server
and only the formatted output is returned to the user.
Use p4 sync directory/... , which will retrieve the most recent revision of every file in directory (and its subdirectories!) that you haven't already got a copy of.
This makes several assumptions:
p4 info
will tell you what your client's root directory is.
cd directory
p4 where xxx
will product output that looks something like:
xxx - file(s) not in client
view.
if the directory's not included in your client
view. (You'll want to see the documentation for help on this, but you'll
know where to start: client specification.)
Use p4 diff filename#revision , which will compare the working copy of a file you've opened for edit or an integrate operation against the revision of the file you specify using "#revision".
For example, say you've opened xyz.java using the command:
p4 edit
xyz.java
Various "diff" commands follow:
p4 diff xyz.java | Compares your working copy against the revision your edits are on - if you are editing revision #4 of a file, this will compare your working copy against revision #4. |
p4 diff xyz.java#2 | Compares your working copy against the revision #2. |
p4 diff xyz.java#head | Compares your working copy against the most recent revision in the depot. |
If your username is joe, then the following command will show you your opened files for all workspaces:
p4 opened -a | grep joe
If you don't have "grep" (i.e. you're on Windows) you'll need to search
the output of p4 opened
for this.
Use p4 filelog filename to get the list of revisions since a file was created in a particular codeline.
Use p4 changes -i directory/... to get the list of change numbers since a file stored originally in Perforce.
You'll recall that the difference between a revision
and a change number is that the revision is specific to a file...
x.c#1
(revision #1 of file x.c)
x.c#2
(revision #2 of file x.c)
y.java#1
(revision #1 of file y.java)
y.java#2
(revision #2 of file y.java)
y.java#3
(revision #3 of file y.java)
The change number is a list of revisions that
got changed as part of one atomic change to the Perforce depot. For example,
change #12345 might be a change to add comments to x.c and y.java, and
this change might've created revision #2 of x.c and #3 of y.java.
Use p4 revert filename to discard the modifications you've made to filename and retrieve a fresh copy of the exact same revision you had prior to typing p4 edit filename .
Use p4 revert directory/... to discard all the modifications you've made to any file in directory (or its subdirectories).
Let's say you have a main codeline, and a child codeline ("branch") called methusalah.
If you wanted to propogate change number 900 from the main codeline to methusalah,
you'd type:
- p4 integrate -b methusalah @900,@900
Of course, if you wanted to propogate change number 902 from methusalah to
the main codeline, you'd type:
- p4 integrate -b methusalah -r
@902,@902
It's a good idea to include the original change
number in the change description for the integration.
Use p4 client -d workspacename to do this. The steps are:
p4 revert filelist
... to revert them.
p4 client
-d workspacename
It's easy, but requires a little planning.
Run p4 client , which will dump you into the editor - you'll be changing the client specification. Change the "Root:" field to the name "/home/jojo/newroot" and save the file.
Let's say that you can retrieve all the files in the directory (using the depot name syntax) //depot/MAIN/jam/ except the file //depot/MAIN/jam/jam.c.
It could be several things: