I have a file I renamed in one branch. When I try to integrate changes from that branch to another, Perforce insists on renaming the same file in the target branch. How do I prevent that?

I think part of the problem is that people assume p4 integrate is doing something other than what they've told it to do. Perforce has no alternative but to obey the commands you give it. The key is to use branch views with correct file patterns for integration.

I'll try to explain how it works, starting with some background first -- I never really know how much people understand about this stuff, so forgive me if I start at too remedial a level. Please bear with me while I try to explain without being able to wave my arms around or scribble on a cocktail napkin.

For example, take the codeline //depot/A. You know you can branch that into //depot/B using:

	p4 integ //depot/A/... //depot/B/...
	p4 submit
This takes every single file in the //depot/A path and makes a copy of it in the //depot/B path. Furthermore, given a file like:
Perforce stores the fact that revisions #1 thru #14 of //depot/A/foo.c have been integrated into //depot/B/foo.c. So if you try the same integrate on that file again:
	p4 integ //depot/A/foo.c //depot/B/foo.c
Perforce will tell you "all revisions already integrated" (unless of course there's a newer version of foo.c in //depot/A.) That's because it looked at all the files in the "//depot/A/foo.c" pattern and checked each one's integration records relative to its counterpart in the files listed in the "//depot/B/foo.c" pattern. In this case, there is only one file listed by each pattern. But the same thing happens if you try to integrate the whole codeline:
	p4 integ //depot/A/... //depot/B/...
Perforce takes every file in the "//depot/A/..." pattern and checks its integration records relative to the file that matches it in the "//depot/B/..." pattern.

SO...all that was just the opening act. Here comes the plot.

You know you can rename //depot/A/foo.c thus:

	p4 integ //depot/A/foo.c //depot/A/bar.c
	p4 delete //depot/A/foo.c
	p4 submit
Perforce has done the whole whole ball of wax for the foo.c->bar.c integration: it's made a copy of foo.c in bar.c, and it's recorded the fact that all revisions of foo.c have been integrated into bar.c.

But none of that matters, because no one is going to be doing any more integrations from foo.c into bar.c. From now on, users who sync to //depot/A will get bar.c, not foo.c. The don't care (and may not even know) that foo.c ever existed. If they do care, they can always use commands like "p4 filelog bar.c" and "p4 changes -i bar.c" to see the origin and evolution of bar.c.

Okay, so say later you want to propagate the latest batch of changes from //depot/A to //depot/B. You use the commands:

	p4 integrate //depot/A/... //depot/B/...
	p4 resolve
	p4 submit
The intent of this p4 integrate command is correct, but because of the rename that occured in //depot/A, the effect may not be. The effect, of course, is that when Perforce concocts the list of files in the "//depot/A/..." pattern, it comes up with foo.c#15 and bar.c#1. When it checks foo.c's integration records, it finds that only revs #1 thru #14 have been integrated into the file that matches it in the target pattern. So it does the action to integrate foo.c#15, which is to delete //depot/B/foo.c. Likewise, for //depot/A/bar.c#1, it finds there is no matching file in "//depot/B/..." pattern, so it adds it.

Whoa --- you've just propagated a rename from one branch to another! Was that what you wanted? No? Well, the integrate command was only doing what you told it to do. The command shown above is the "integrate everything including renames" command.

If you want to rename files in one branch, but not in another branch, and if you want to be able to propagate changes between files whose names are not the same, the key is to give integrate the correct file patterns to look at when it compares integration records.

When you're doing integrations across codelines whose filenames match exactly, it's easy to put the branch view right on the integrate command lines, as shown above. But once filenames no longer match, you can't tell integrate to use patterns that do expect them to match. Here's where stored branch specs are indispensible.

The command

	p4 integrate //depot/A/... //depot/B/...
is exactly the same as:
	p4 integrate -b AtoB
where "AtoB" is a stored branch spec whose view is defined thus:
		//depot/A/...    //depot/B/...
However, now that you've got filenames that don't match between those patterns, you need to modify the branch view to accomodate the mismatches:
		//depot/A/...      //depot/B/...
		//depot/A/bar.c    //depot/B/foo.c
A stored branch view can have any number of mapping lines. Each line overrides any before it. So the spec above now defines how the matching will be done: all the files in //depot/A will be matched with files of the same name in //depot/B, except for //depot/A/foo.c, which will be matched with //depot/B/bar.c. Now, to propagate changes from //depot/A to //depot/B, while preserving the original filenames in //depot/B, you'd use:
	p4 integ -b AtoB
	p4 resolve 
	p4 submit

As of Rel 99.1, branch specs can be used for diffing as well as integrating. So you could use:

	p4 diff2 -b AtoB
and one of the outputs would be the diffs between //depot/A/bar.c and //depot/B/foo.c.

(February 1999)


This is file $Id: //guest/laura_wingerd/perforce/faq/br03.html#1 $ in the Perforce Public Depot