Any sufficiently advanced technology is indistinguishable from magic.
-- Arthur C. Clarke, (Clarke's third law)

Introduction

How do you use perforce? Some like to stuff as much as possible in the repository, in the hopes that it will be useful to have it all in one place. Others like to keep it minimalistic as to not bog down the server too much. I've already written a little bit about the things that might be good to consider setting up a perforce server (look at the article here), but once it's up and running you might want to have a look at how you are using it.

Perforce is very good at two things, speed and integration. At these two points it's a good competitor with the other solutions out there. Having these two things should be an incentive to start taking advantage of it. The speed and integration comes at some costs though, the speed is severely impacting the way you can work offline and the integration is only as good as you tell perforce that you make changes.

A source control system is only as good as you let it be, if you never tell it what you're doing, it will never pick it up. On the same note, if you are not shaping your workflow around what it can handle, you experience with the system will not be so good. So here are a couple of practical tips that you should consider adopting.

Organizing staged third party libraries

If you are using third party source libraries it's most probable that you might want to do minor changes to them. This can be easy or really painful. The painful way is to simply check the source code in and change it inplace. Yes, it might seem like the right way to go. [Ok, the really painful way is to not check it into perforce at all, and leave it on the side but we're not quite that ehrm, out looking for new ways of pain are we?] The easier way to do this is to have a stage directory where you place the distribution each time a new drop comes out. From there you branch it to the place where you want to use it. At this final place, you can also do changes.

//depot/external/packages/zlib/... # usable copy
//depot/external/drop/zlib/... #drop distributions here
//depot/internal/mygame/... # uses //depot/external/packages/zlib/include

Now every time you get a new drop you can do this:

This will let you track how the third party library changed between revisions, if they added any files, where they had bug fixes etc. It will also in most cases just resolve your changes automatically, and only ever require integration when your local patches overlap with the thirdparty vendor and then it's a very good idea indeed to look at what didn't merge properly.

Automate tedious tasks

There are a lot of powerful idioms you can use when developing in a team. One of the things that the history lets you do is to easily jump back and forth between versions of the files. Some companies frown upon people who check in and run. This is really just a small annoyance, it might not be considered polite but in the end it's not really a big deal as long as that person is buying into the fact that people can revert his changelist if it turned out that it broke something somehow. Reverting individual changelists is really quite involved in perforce, it feels a little like Maya, they give you the bare bones and then you have to fill in the details yourself. This one thing should perhaps be built in, but then again maybe the secret behind maya's and perforce's success lies within them not putting these features in.

One of the most annoying things about software is the whole feature feedback loop that inevitably leads to the demise of all software. Remember the old winamp 2.x? It was small, sleek and useable. It did what I wanted from it, play mp3's. Then it started adding feature after feature and now it's probably capable of taking over the work a'la Skynet. This can probably apply to most software out there that has been around for a while. It makes me a little sad that my laptop is not powerful enough to run the gmail integrated client without eating up all the available cpu! And that is a freaking email client. We have all these hard to imagine powerful computers and we're all running bloated java programs on them that does very little but waste cycles doing nothing. Ok, a little bit harsh, but the truth is inching closer and closer. At my old university they used the 64 core Cray supercomputers with a full load of ... a java vm running a FEM stress analysis program. A java app! That should have been criminal.

Automating common tasks like reverting a changelist is pretty easy (even easier if you download the excellent script here.). But seriously, some automation should definitely be there, just so that your programmers can get over the mental barrier of doing something conceptually easy, but very involved in details.

Don't use the default integration

The default integration with visual studio frankly blows. It easily blows large medicine balls through a very small garden hose. It's not even perforce's fault as far as I can tell. It's just that the model for the source control plugins in visual studio are all modeled after the workflow in SourceSafe. Now people might argue that SourceSafe is perfectly all right. Yes. It is. As much as CVS is all right. That is, for a very limited project with one programmer or two it might work. But for anything in a professional production environment, please. Since you're reading this I assume that you're already happily in the perforce camp.

But if you don't use the default integration, will that not leave you doing an awful lot of work? Well, there are alternatives that are not quite as retarded as the default plugin. Some of them include:

Use the file integration

Moving files around in perforce is quite easy. The main thing to overcome is the fact that you want to use it. Don't move files behind perforce's back. To copy a file from one location to another, simply use the "file integration" command. If you want to move it, simply delete the old copy. There is even a menu command in perforce to do this called "rename", but it's really just a shortcut to the integrate/delete two stage operation.

Try to keep the mappings simple

One of the much touted things in perforce is the client mappings and the fact that they can pretty much transform the repository to any crazy setup you might have on the clients. Try to resist the urge to use this feature for anything that's not dead simple. As soon as you have more than a couple of lines in you clientspec things becomes messy. I once worked at a place where they had 40-50 lines of mappings for different libraries and projects. It was incredibly complex and completely unnecessary. Try to keep it simple and in one depot. Multi depot development also is a little bit of a mind warp.

One of the good things about the clientspec is that it lets you specify exclude patterns. So if you want to not sync to source maya files or psd files, you can specify those. Those same clientmappins also applies to files you add, so if you add exclusion filters on common intermediate files (or those pesky .user/.suo/.ncb files) then you will never accidentally add them.

Prepare for branching

Even if you don't branch right now, the day might come when you do want to branch. That day might be put off if the up front work is big. Now, you can kind of prepare for this day by simply moving all your files up one level in the repository tree. Instead of having:

//depot/shared/core.h
//depot/projects/tetris/main.cpp

You can instead move this to be

//depot/main/shared/core.h
//depot/main/projects/tetris/main.cpp

This way you can have several top level directories, each naming a particular branch. It's an easy way to visualize the branches in the perforce viewer as well. All without making complicated client mappings. Yay.

Ooops, I forgot to branch

Ever found yourself in a situation where you started on a minor change and it all snowballed into a bloody mess, source code all over the place died and you went rampart on the optimize delete-key? At those times you wished that you were already on a branch, but it's kind of a pain to create a new branch and start working on it. Well, it turns out that it really isn't that hard, but it's just a lot of tedious work. It would be great if there was a script to do this, right?

You can actually use p4shelf for this exact scenario. The script allows you to archive your work in the current clientspec and move the work to any other clientspec that has a similar mapping.

In closing

That were some of my tips of making your daily perforce life a little bit easier so that you can concentrate on simply writing code or perhaps world domination through the next addictive game. Do you have any must do tips?

Resources

Comments