Ideally branching is a clear, orderly process. In reality, branches are often created as needed; this kind of a behaviour results in integrations that jump through several hedges before reaching their destination.
A file integration jumping through hedges
Let us look at the example of a file which was branched in the 'stable' branch. Later, it was decided to use a new intermediate branch when integrating files to 'stable'. What happens when a file is deleted in the source codeline before this new, unplanned ("ad-hoc") branch is created?
The non-existent file issue
Because the file was deleted in the development branch before the ad-hoc branch was even created, the latter has no record such a file ever existed. If Perforce preserved this information soon the overhead of branching would be in copying the 'dead' file records more than copying the 'live' file records.
When a branch has no record of a deleted file, integrating that branch into a pre-existing branch - where the file still exists - does not cause the file to be deleted in the target. In fact, there is no option you can give to the 'integrate' operation (like -Ds) which will cause the file deletion to be propagated in the target branch.
This is because the deletion of the file did not happen in the ad-hoc branch.
The copy solution
Starting with Perforce 2010.2, a new command was introduced: 'p4 copy'. This command is available in the command-line client, the Perforce client API as well as in the 2011.1 Perforce Visual Client (P4V)
The copy command makes the target exactly identical to the source. In particular, the help for the 'p4 copy' command says:
Files that exist in the source and target but are different are opened
for 'integrate', automatically resolved as 'copies', and synced to the
workspace as if a 'p4 resolve -at' had been performed. Files that do
not exist (or are deleted) in the source but do exist in the target
are opened for 'delete' and removed from the workspace. Files that
exist in the source but not the target are opened for 'branch' and
synced to the workspace.
What is new in 2011.1
Perforce 2011.1 introduces Streams, which encourages best practices by making it easier to manage branches and the flow of changes between them.
The rules of change propagation with Streams dictate that changes are copied from development branches into more stable branches, and merged from stable branches into branches with more fluid contents.
Since a copy operation is used to propagate changes up the stability scale, non-existent files in the ad-hoc branch will be deleted in the pre-existing branch if it is re-parented such that the ad-hoc branch is below it.
A stream graph which propagates deletes
Going down: the backdated ad-hoc branch solution
So far, we only saw cases where the pre-existing branch is more stable, than the ad-hoc branch which is created. If the flow of change is going the other way, changes in the ad-hoc branch need to be merged - not copied - in the pre-existing branch. Then a record of the deletion needs to be created in the ad-hoc branch, so that it can be propagated.
This is done by backdating the ad-hoc branch to the time the development branch was last integrated into the pre-existing branch. To find the changelist number for this integration use:
p4 changes -m 1 //depot/pre-existing/...
Once you have this changelist number, you can create the ad-hoc branch with the same files as the pre-existing branch:
p4 integ //depot/development/...@1234 //depot/adhoc/...
Then update the ad-hoc branch with the latest changes:
p4 integ //depot/development/... //depot/adhoc/...
p4 resolve -at
This way the ad-hoc branch will hold records for deleted files. File deletions will be propagated into the preexisting branch.
The 2012.1 solution
Perforce 2012.1 introduced a new command to branch a set of files as a one-step operation: 'p4 populate
'. This command has an option to include deleted files in the operation, removing the requirement to backdate the branch in order to propagate deleted files. Use it this way:
p4 populate -f //depot/development/... //depot/adhoc/...