Perforce FAQ
Questions
- 1.1 How do I go back on an older change?
- 1.2 Why should I not obliterate?
- 1.3 How can I find out who changed which line of code?
- 1.4 How do I reorganize a source tree?
- 1.5 How do I deal with large files?
Answers
- 1.1 How do I go back on an older change?
Say N is the change you wish to restore.
- cd to the directory containing the files you wish to back out
Sync to the old version:
% p4 sync ...@NCheck out the file you wish to revert:
% p4 edit ...Now sync up to the head:
% p4 syncResolve merge by inoring head version:
% p4 resolve -ayRevert any unchanged files:
% p4 revert -aSubmit your change:
% p4 submit
Note that this method will record a subtractive diff. If done often, it may create some interesting merge problems down the road, especially if people only selectively merge your change and not the changes which lead there.
- 1.2 Why should I not obliterate?
-
The p4 obliterate command is extremely dangerous. It not only destroys the change data, it also has a variety of unexpected consequences:
p4 obliterate will remove the file from the perforce server, but will not yank it from the clients, so other users will still see the file, which may not be what you wish;
p4 obliterate may force the perforce server to make good on the "copy on write" promise. If the file you are obliterating is the base contributor to branches, all the branched files will need to be instantiated. This may paradoxically increase the storage requirements instead of decreasing them.
Nevertheless, the "p4 obliterate" command does have its uses, and the p4 wrapper script available here implements a p4 undo function which uses p4 obliterate to destroy specific versions of a file. This is somewhat safer, but still should only be done rarely.
- 1.3 How can I find out who changed which line of code?
See p4 help annotate. Note that the p4 wrapper here implements a p4 blame function. Combining p4 history, another wrapper function based on the built-in p4 filelog function with the p4 annotate or p4 blame function will ususally allow you to track the origin of any change.
- 1.6 How do I reorganize a source tree?
Perforce does not have directory versioning, so any source tree re-org needs to be implemented via branching:
Locate a new place in the source tree for the newly reorganized tree. If you use the autobuilder, try to move stuff into src/language/module. If you need to move stuff within src/language/module, it may be best to invent a new module name. The goal is to not break existing development while you are working on your re-org.
Define a branch spec (p4 help branch), which will map old location to new location. Note that the mapping must be bijective. You can use perforces "I want this, but not that, but then again this" paradigm of adding and subtracting mappings to simplify the list, but the result must be a 1:1 mapping of source files to destination files. If it becomes too hard or tedious to make 1:1 mappings, you can define multiple branch specs, but then you run the risk of mapping multiple source files onto the same destination.
Run the following commands to generate your new source tree
% p4 integ -b branch-spec % p4 submit
Make whatever changes are needed in the code and build system to support your new structure. This may take a while, so repeat the previous step often, resolving merges of changes from other developers.
Once you got the new source tree to work, you can submit and then proceed to delete the old files. Before deleting the old files, ensure that all developers know what's going on and have all finished making changes to the old files. Keep merging as described above until all developers have converted to the new source tree.
Delete all the old files.
Sometimes, people have gone ahead and started a reorg using simple p4 integ from to commands and not using a branch spec. It is possible, but tedious, to reconstruct a branch spec from those operations.
A good starting point is to run the following command, then edit the result to become a branch spec:
% p4 files ...\ | awk -F# '{print "echo "$1; print "p4 filelog "$1" | grep \"branch from\""}'\ | shThis command will effectively extract the branch from indications from the filelog of every file in the current directory.
The result should be edited into the format suitable for branch specs.
- 1.5 How do I deal with large files?
Large files should not be checked into the branched portion of the source tree. Doing so will really hinder development for people working from home or on slow links. It will also waste a lot of disk space, since every branch on your client will have its own version of the (same) file.
Instead, check the file into a unique permanent location in the depot tree. Note that the location need not match up with the location your build expects. In this example, we will use //depot/large-files.
To ensure reproducability of builds, the following rules must be followed:
The location of the file within //depot/large-files never changes.
The contents of the large file never changes. If you need to check in a new version, you must give the file a new name or version. The only exception to this rule is when you need to re-sign the exact same version for licensing reasons.
The trick now is to use the build system to extract the large files on demand using p4 print.
