p5: a set of tools for use with Perforce.

p5 is a drop-in replacement for p4 (the Perforce CLI). It provides some new commands, and enhances the behavior of some existing commands.

Enhanced commands

p5 provides enhanced versions of a few Perforce commands:

Enhanced changeset syntax

If you hate remembering and typing changeset numbers, p5 can take care of that for you. All of the p5 commands that take -c changeset on the command line will accept an enhanced changeset specification. The format can be summarized as
    -c (p|su|sh)[:userid][:nth]

For example, you can type -cp and p5 will replace that "p" with the most recent pending changeset number in the current workspace. That way, you never have to look up the number for the changeset you're working on. Examples:

-c sh and -c su do the same for the most recently shelved and submitted changesets.

If you specify an optional userid, p5 will show the most recent changeset for that user, instead of for the current workspace. So, for example, p5 describe -csu:suzanne will show Suzanne's most recently submitted changeset. The me shortcut works here, too. So p5 describe -S -c sh:me will show your most recently shelved changeset in any workspace.

Finally, an optional nth specifier allows you to select the nth most recent changeset. For example, p5 describe -c su:2 will show the penultimate submission from the current workspace. p5 describe -c su:me:2 will show your penultimate submission across all workspaces.

Enhanced changeset specifications also work with p5 unshelve -s. For example, if you just shelved something in one workspace, you can unshelve it in another by saying p5 unshelve -s sh:me.

Workspace Backups

When writing code that will eventually be submitted to the Perforce depot, it is often helpful to checkpoint the work as it progresses, so you can revert the workspace back to that point, or even just grep through it months or years later.

Creating a backup

p5 backup [-ef] [-b backup-name] [-c changeset] [-C client] [-d description] [file...]

p5 backup creates a tarball of all currently open files, and stores it in ~/p5.backup/workspace/backup, where workspace is the name of the current Perforce client, and backup is an automatically incrementing number. A diff file—suitable for feeding to patch(1)—is also saved in that same directory. It also prompts for a short description of the backup, which is stored in a comment.txt file.

Here are the command line options in decreasing order of usefulness:

If you want your backups somewhere other than ~/p5.backup/, set the environment variable P5_BACKUP_DIR to point to that directory.

Restoring from backup

    p5 restore [-b backup-name] [-B src-client] [-c changeset] [-C client] [-n] [-p | file...]
p5 restore will return the files to the state they were in at the time the backup was created. On Unix, the most recent backup is used by default. So, e.g., if all your open files are in the default changeset, this sequence will leave your workspace unchanged:
    $ p5 backup -f
    $ p5 revert ...
    $ p5 restore
The command line options are the same as for p5 backup, with the following additions: Note: On Windows machines, -b backup-name is must be specified. On other systems, it defaults to the most recently created one.

Examining a backup

    p5 bdiff  [-b backup-name] [-B src-client] [-d] file...
    p5 bprint [-b backup-name] [-B src-client] [-q] [-r] file...
These two commands examine the contents of one or more files in a backup. p5 bdiff compares the file to the version in the current workspace. Normally, files refer to files in the current workspace relative to the current directory. This is usually the right thing, but may lead to surprising behavior for p5 bprint -B src-client if the current workspace has a different directory layout than the backup did.

To address this, the -r flag says to treat the files as paths relative to the root of the backed up workspace, without considering the current workspace at all. Note: On Windows machines, -b backup-name is must be specified. On other systems, it defaults to the most recently created one.

Listing all backups

p5 backups [-l] [-b backup-glob | -m max] [-B src-client]

p5 backups lists the backups for the current workspace, along with their descriptions.

Code review

Sending code out for review

p5 share [-o] [-c changeset] [-d flag] [-s] [-t] [file...]

This command prepares a diff of the specified files, suitable for code review. Files associated with a changeset are also shelved in that changeset. By default, the diff file is saved in your home-directory in a file named changeset.share. If you want to save it somewhere else, put the pathname in the environment variable P5_SHARE_FILE, putting "%s" where you want the changeset number to go. For example, you might add this to your ~/.kshrc file:

    export P5_SHARE_FILE=$HOME/review/%s.desc 
If p5 share can't find a single changeset number--either because there are multiple changesets pending, or because all the opened files are in the default changeset--it will use the filename p5.share.

Viewing changesets

p5 desc [-d flag] [[-c] changeset] [-s]

This is a DWIM command. It runs one of p5 share, p5 describe or p5 describe -S depending on whether the changeset is in the local workspace, submitted or shelved (respectively). And for changesets that get renamed at submit-time, you can specify either the old or the new changeset number.

Use with other Perforce utilities

Home-grown Perforce tools can also be wrapped by p5, so that they can take advantage of the enhanced changeset syntax. Simply set the environment variable P5_WRAPPED. For example, if your workgroup has scripts named p4validate and p4nits, you might set this in your environment:
  export P5_WRAPPED=grab=get_changeset:nits=p4nits
Then:
p5 command Might expand to
p5 nits -c su:me p4nits -c 12345
p5 grab -c sh:suzanne get_changeset -c 12399

Example

Putting it all together, your workflow might look like this:
    $ p5 change
    Waiting for Emacs...
    Change 445685 created with 1 open file(s).
    $ p5 backup
    Enter a description for this backup ('.' or EOF when done):
      Everything seems to be working. About to send it out for code review.
    Created backup at /home/adent/p5.backup/bypass-3/243 ]
    $ p5 share
    Change 445685 files shelved.
    Wrote /home/adent/445685.share
    
Code reviewer points out that I forgot a change to the Makefile, but otherwise everything is okay...
    $ p5 open -cp Makefile
    $ emacs Makefile
    $ p5 submit -cp
    Submitting change 445685.
    Locking 2 files ...
    edit //depot/bypass/src/Makefile#314159
    edit //depot/bypass/src/one/hoopy/frood.cpp#8
    Change 445685 submitted.