Until now, I’ve only really used distributed version control software; Mercurial in college and Git since I got a Github account. I started working at Cisco and started using Perforce. It’s been a little weird, but I think I’m getting the hang of it.
My Environment
I set Perforce’s P4CONFIG
variable in my .bashrc
to let me put a config file at the root of each of my Perforce
repositories. This let’s me easily change my server, username, client, etc. for each repository.
At work I like to have a client for each branch we work on; this lets me do just that.
My Perforce settings in my .bashrc
# Perforce
export P4CONFIG=.p4config
export P4IGNORE=.p4ignore
export P4EDITOR=vim
You might have noticed the P4IGNORE
variable in my .bashrc
.
P4IGNORE
files work just like .gitignore
.
One of my .p4config
files
P4PORT=workshop.perforce.com:1666
P4USER=zachwhaley
P4CLIENT=project
Bash Completion
The bash completion in Git is really convenient, but unfortunately Perforce’s CLI program doesn’t come with a bash completion script. So I made my own.
Distributing Perforce
Perforce is not a distributed version control system (unless you’ve upgraded to Perforce Helix, in which case you should be using the Git integration), but there are ways to make it seem like it is.
Write All the Files!
So the Perforce settings at my work force all local files to be readonly by default. I feel like this hinders my programming flow and is just unnecessary. So I changed it.
The option to make all files writeable is in your Perforce client, which can be viewed with the following command.
$ p4 client
This will open your client settings in an editor to be viewed and changed. If you don’t like the default editor you can change this
by setting the Perforce variable P4EDITOR
in your bash environment, like below. This can also be set in your .bashrc
like I did above.
$ export P4EDITOR=vim # For Unix users
$ p4 set P4EDITOR=vim # For (Mac)OSX users
$ p4 client
In the client settings, change the Option noallwrite to allwrite, and save the file.
# A Perforce Client Specification.
# ...
# A bunch of stuff is here
Client: project
Update: 2014/04/07 15:32:56
Access: 2014/04/07 19:57:03
Owner: zachwhaley
Host: zachs-computer
Description:
Created by zachwhaley.
Root: /project
Options: allwrite noclobber nocompress unlocked nomodtime normdir
SubmitOptions: submitunchanged
LineEnd: local
View:
//depot/zachwhaley/project/... //project/...
This will save the client settings, but your files won’t become writeable just yet.
Perform a complete sync to update all your repository’s file’s permissions.
# Make sure any uncomitted changes to the repo are saved off somehow,
# before executing the next step.
$ cd /to/root/of/repo/
$ p4 sync -f ... # The ... means do this recursively starting here
You can now change any file you want! But what happens when It’s time to commit a change?
Reconcile with Lord Server
After I’ve made my changes to the code (for better or worse), I’ll run p4 status
.
Just like Git, this command tells you what has been modified, added, or deleted from the server’s code base.
$ p4 status
bar.cpp - reconcile to add //depot/zachwhaley/project/bar.cpp#1
bar.hpp - reconcile to add //depot/zachwhaley/project/bar.hpp#1
foo.cpp - reconcile to edit //depot/zachwhaley/project/foo.cpp#2
Unlike Git, Perforce has no idea how the files changed, only that these files are different from the server’s files.
I still have to tell Lord Server which files I want to change and how. Since I’m happy with the files listed, it is time to reconcile with Lord Server and tell them what I have done.
$ p4 reconcile
//depot/zachwhaley/project/bar.cpp#1 - opened for add
//depot/zachwhaley/project/bar.hpp#1 - opened for add
//depot/zachwhaley/project/foo.cpp#2 - opened for edit
Perforce has now opened (checked out) the files for me.
Use p4 opened
To see a list of your open files. And p4 diff
to see code changes for open files
$ p4 opened
//depot/zachwhaley/project/bar.cpp#1 - add default change (text)
//depot/zachwhaley/project/bar.hpp#1 - add default change (text)
//depot/zachwhaley/project/foo.cpp#2 - edit default change (text)
$ p4 diff foo.cpp
==== //depot/zachwhaley/project/foo.cpp#2 - /project/foo.cpp ====
33a34,42
> // p4 ain't that bad
Change, Submit, and Go Home
When I’m finally ready to commit my code, I create a change.
I use Perforce changes like Git staging. They are similar in that they identify what is going to change, without actually making the change happen. They are not similar in that I have to create a change description (commit message) when creating the change. Don’t worry though, this description can be changed before submission
p4 change
will open an editor where I add my description and specify which files go with this change.
$ p4 change
# A Perforce Change Specification.
# ...
# A bunch of stuff is here
Change: new
Client: project
User: zachwhaley
Status: new
Description:
<enter description here>
Files:
//depot/zachwhaley/project/bar.cpp # add
//depot/zachwhaley/project/bar.hpp # add
//depot/zachwhaley/project/foo.cpp # edit
A change number will be printed after I save my new change.
$ p4 change
Change 1010 created with 3 open file(s).
This number uniquely identifies this change and can be used to edit the change description, add or remove files to the change, etc.
$ p4 change 1010 # Edit change 1010
$ p4 revert -c 1010 somedir/* # Reverts files in somedir that belong to change 1010
$ p4 edit -c 1010 perf.py # Adds a file to be edited in change 1010
$ p4 update # Merges your code with changes from others
Now to submit my change
$ p4 submit -c 1010
Code has been checked into the Mother Repo, and I am done.
Thanks!
A big thanks to G Weiss and Matt Attaway.