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.
$ 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.
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.
~/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.
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.
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
~/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 | 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 |
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!
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.