Perforce Revision Control

Perforce Revision Control

Terence Parr

Introduction

Perforce is a simple yet extremely powerful revision control system (RCS), whose purpose is to manage multiple people working on the same set of files. An RCS tracks all changes to a file so you can back up to prior versions. It also acts as a versioned back up scheme.

Perforce is uses a client-server architecture. You notify perforce when you want to add or edit files on your local disk and then, after doing your changes, you submit them to the central repository. At that time, another team member can sync his/her local disk to the updated repository. Programmers still work independently, but you share files via the central repository.

Importantly, this "submit" is done as a single transaction. That means that if the submit fails for lack of net connection in the middle of the submit, perforce will roll back the submit command. You can try again later without worrying about doubly submitting files.

This lecture is only concerned with using perforce as a single programmer, not as a team member. We will extend the techniques described herein when we discuss team use of perforce.

Tasks

Get a file into the system

$ cd ~/depot
$ mkdir test
$ cd test
$ vi A.java B.java
...
$ ls
A.java    B.java
$ p4 add A.java
//depot/cs342/parrt/test/A.java#1 - opened for add
$ p4 add *.java
//depot/cs342/parrt/test/A.java#1 - currently opened for add
//depot/cs342/parrt/test/B.java#1 - opened for add

At this point, you have 2 Java files in the change list. The depot won't commit these changes until you submit.

When you type p4 submit, an editor pops up with the submit description file like this:

# A Perforce Change Specification.
# ...
Change: new

Client: parrt.localhost

User:   parrt

Status: new

Description:
        add test files

Files:
        //depot/cs342/parrt/test/A.java     # add
        //depot/cs342/parrt/test/B.java     # add

You fill in the description and save/exit the file/editor. You'll see:

Change 6 created with 4 open file(s).
Submitting change 6.
Locking 4 files ...
add //depot/cs342/parrt/test/A.java#1
add //depot/cs342/parrt/test/B.java#1
Change 6 submitted.

Edit / submit file(s)

File A.java just has a comment let's say:

/** A */

If you want to edit A.java, say this:

$ p4 edit A.java
//depot/cs342/parrt/test/A.java#1 - opened for edit

then edit A.java to be:

/** A */
public class A {
}

You can see what changes you've made since the last commited change:

~/USF/depot/cs342/test $ p4 diff A.java
==== //depot/cs342/parrt/test/A.java#1 - /Users/parrt/USF/depot/cs342/test/A.java ====
1a2,3
> public class A {
> }

To commit your changes, type this:

~/USF/depot/cs342/test $ p4 submit

You'll see an editor open with:

...
Description:
        <enter description here>

Files:
        //depot/cs342/parrt/test/A.java     # edit

After saving/exiting, you'll see:

Change 7 created with 1 open file(s).
Submitting change 7.
Locking 1 files ...
edit //depot/cs342/parrt/test/A.java#2
Change 7 submitted.

Get change history for a file

~/USF/depot/cs342/test $ p4 changes A.java
Change 7 on 2003/10/21 by parrt@parrt.localhost 'added code '
Change 6 on 2003/10/21 by parrt@parrt.localhost 'add test files '

Using p4 changes -u parrt A.java limits listed changes to only those done by parrt.

Delete a file

Deleting a file is like an edit and can be reverted before committing it.

~/USF/depot/cs342/test $ ls
A.java    B.java    templates
~/USF/depot/cs342/test $ p4 delete B.java
//depot/cs342/parrt/test/B.java#1 - opened for delete
~/USF/depot/cs342/test $ ls
A.java    templates
~/USF/depot/cs342/test $ p4 revert B.java
//depot/cs342/parrt/test/B.java#1 - was delete, reverted
~/USF/depot/cs342/test $ ls
A.java    B.java

To commit, use p4 submit as always. You can always bring the file back later as perforce merely changes the state of the file in the depot--it doesn't actually delete anything.

Rename or move a file

Copy to new file, add that file, delete old one. This is the simplest way.

~/USF/depot/cs342/test $ cp B.java C.java
~/USF/depot/cs342/test $ p4 add C.java
//depot/cs342/parrt/test/C.java#1 - opened for add
~/USF/depot/cs342/test $ p4 delete B.java
//depot/cs342/parrt/test/B.java#1 - opened for delete
~/USF/depot/cs342/test $ p4 submit
Change 8 created with 2 open file(s).
Submitting change 8.
Locking 2 files ...
delete //depot/cs342/parrt/test/B.java#2
add //depot/cs342/parrt/test/C.java#1
Change 8 submitted.
~/USF/depot/cs342/test $ ls
A.java    C.java

Making sure your local disk is up-to-date

~/USF/depot/cs342/test $ p4 sync
File(s) up-to-date.

Going to another box though with a depot->client mapping, you'll see:

[parrt@nexus depot]$ p4 info
User name: parrt
Client name: parrt.nfs
Client host: nexus.cs.usfca.edu
Client root: /home/parrt/depot
...
[parrt@nexus depot]$ p4 sync
//depot/cs342/parrt/test/A.java#2 - added as /home/parrt/depot/test/A.java
//depot/cs342/parrt/test/C.java#1 - added as /home/parrt/depot/test/C.java

Command summary

command description
p4 help commands list all commands
p4 help command get help on command
p4 info Are my P4 parameters set properly? Is server up?
p4 add file Announce intention to add a file to the depot
p4 submit Submit all changes (add,edit,delete) to depot
p4 submit dir/... Submit all changes (add,edit,delete) to depot from dir on down
p4 sync Make my disk look like the depot (pulls in changes from your team members)
p4 sync dir/... Make my disk look like the depot from dir on down team members
p4 revert file Throw away changes you have made to that file
p4 changes file describe changes made to this file

Client Management

How perforces know what the depot<->local-disk mapping is

I have set up a user account in the perforce depot and a client for each user called user.nfs. The user is your user@cs.usfca.edu name. Your client looks like:

Client: user.nfs
Owner:  user
Root:   /home/user/depot
View:
        //depot/cs342/user... //user.nfs/...

which means that the user directory for cs342 in the central repository is mapped to your /home/user/depot directory.

I have set up the protections as follows:

        write user alagor * //depot/cs342/alagor/...
        write user cbean * //depot/cs342/cbean/...
        write user cfrasche * //depot/cs342/cfrasche/...
        write user defendio * //depot/cs342/defendio/...
        write user jchan * //depot/cs342/jchan/...
        write user jendo * //depot/cs342/jendo/...
        write user llim * //depot/cs342/llim/...
        write user rstevens * //depot/cs342/rstevens/...
        write user uchan * //depot/cs342/uchan/...
        write user cchu * //depot/cs342/...
        super user afedosov * //...
        super user parrt * //...

meaning for example, that uchan only has access to //depot/cs342/uchan and below.

Please set your password by using p4 user command!

How perforce knows which depot to talk to

You must have file /home/user/depot/.p4 with the following info:

P4CLIENT=user.nfs
P4USER=user
P4PASSWD=
P4PORT=phantom:1666

For perforce to know to look in this "hidden" file (due to the prefix of a dot), you must have

export P4CONFIG='.p4'

in your .bash_profile or whatever.

With this set up, then you cannot accidentally add files outside of /home/user/depot/... directory subtree.