August 8, 2013

A New Way to Merge Local Edits

Traceability
Version Control

If you're a heavy user of branches to isolate work intended for different product versions or runtime configurations, you've probably run into this situation. You start working on a branch, make a few changes, merge some upstream work, and then find out you need to move your changes to a different branch. What you'd like to do is merge just the files you've actually modified on your branch, and not bother with the changes that originated in the upstream branch. With the 2013.1 release of Perforce, there's a new way to tackle this problem.

Let's look at a diagram that shows a simple example. I'm working on the dev-xray branch and the following sequence of events happens:

  1. I check in an edit to a file called command.c.
  2. Someone checks in an unrelated change on main to command.h.
  3. I merge the latest from main to dev-xray.
  4. I check in an edit to glob.c
  5. Someone checks in a change to scan.c on main.

Now I find out that I need to move my two local changes, commits 250 and 255, from dev-xray to dev-zulu. I want to move the changes in the triangles labeled '1' and '4' to dev-zulu. I can use a new merge flavor:

> p4 integ -Rl -3 dev-xray\... dev-zulu\...
//depot/dev-zulu/src/command.c#1 - integrate from //depot/dev-xray/src/command.c#2
//depot/dev-zulu/src/glob.c#1 - integrate from //depot/dev-xray/src/glob.c#2

Notice the with this new -Rl option, I'm only merging the two files I directly modified on dev-xray, command.c and glob.c. The two files modified as a result of merging from main (command.h and scan.c) are not included. If I had run a regular merge I'd see a different result:

> p4 integ -3 dev-xray\... dev-zulu\...
//depot/dev-zulu/src/command.c#1 - integrate from //depot/dev-xray/src/command.c#2
//depot/dev-zulu/src/command.h#1 - integrate from //depot/dev-xray/src/command.h#2
//depot/dev-zulu/src/glob.c#1 - integrate from //depot/dev-xray/src/glob.c#2
//depot/dev-zulu/src/scan.c#1 - integrate from //depot/dev-xray/src/scan.c#2

That's a very handy little tool. Now, the -Rl flag is undocumented for now. That means that it's still a bit on the experimental side, and you may uncover some edge cases that we haven't tested yet. Use the -n preview flag before you actually run a merge, and make sure that the results are as expected. Also note that a merge that results in a conflict (a resolve action of -ae) will be picked up for merging, since it may have unique changes made while resolving the merge.

The 2013.1 release is out now, so give it a shot!