Sep 18, 2009

Using P4Merge with Visual Studio 2008 and TFS

The merge and diff utility included with Visual Studio 2008 is, let’s face it, not the best tool on the market.  Sure, it does the job, but it could be so much better.  Thankfully, Visual Studio gives you a way to customise the tool that is used for merging.

Now, in the past, I’ve usually gone for WinMerge as my tool of choice to replace the out of the box offering, but WinMerge is starting to show it’s age and whilst it does a great job at comapres it doesn’t do 3-way merges, so I’d rather use something else.  By the way, I keep WinMerge installed because of it’s great directory comparison feature.  Oh, for those who don’t know, a 3-way merge is a merge that shows both your current version of the file, the file you’re merging with, and the root file from which the two other files are derived (i.e. the original).

Many people talk about how great the BeyondCompare product is, but for the sake of my wallet I’d rather use a tool that was free.  Enter Perforce’s P4Merge.

The only hassle with using this tool is that it doesn’t integrate that easily into Visual Studio as a merrge tool – you can’t just call the executable and supply arguments, you have to work around it a little.  Here’s how:

As a Comparison Tool

Setting P4Merge up as your comparison tool is simple enough.  Go to Tools->Options and navigate to Source Control and Visual Studio Team Foundation Server.  Select the Configure User Tools… option.

image

Then choose Add and set the options as shown:

image

Hit OK, and that one’s done.  Note you may have to supply a different path to the P4Merge program if you installed it in a different location.

Merge Tool

For merging things get a little tricker because P4Merge wants the output file for the merge operation to exist before you actually do the merge.  This is where the VS integration presents a small problem, since VS doesn’t create the result file before calling the tool.  It expects the tool to create it instead.

To work around this we need to create a simple batch file that we will get Visual Studio to call.  For the sake of sharing across multiple users on my machine, I’m placing the file in C:\Users\Public\Documents\p4merge.bat.

The contents of the file should be:

@ECHO OFF
COPY /Y NUL %4
START /WAIT /D "C:\Program Files\Perforce" p4merge.exe %1 %2 %3 %4

Once you’ve created that file, go through the same steps as above for Compare, but this time select the Merge operation and point to the batch file instead of the P4Merge program.  The end result should be something like this:

image

Note that the arguments are passed in a non-standard order. It’s %3 %1 %2 %4

Once this is done, get out of the options and try it out.  Here’s the tool in action

Comparison:

image

Merging:

image

Enjoy!

10 comments:

  1. This is great I could never figure out how to get the merge working. Granted I only spent about 5 minutes trying but this is great.

    ReplyDelete
  2. Yup, I'm a big fan of p4merge. The only thing I do differently is I swap the parameter positions in the batch file so that when I help a coworker set it up, they can just put in %1 %2 %3 %4 and the batch file handles the rest.

    ReplyDelete
  3. Just stumbled on your post and got excited because I could finally replace the diffmerge.exe tool of Visual Studio.
    After using p4merge for several merges I have uninstalled it. I have been merging SQL files and p4merge fails to recognize when you have blocks of sql with the same end line (for example:
    ');
    ).
    When you try to merge two sql blocks, one written localy and on received from server it only offers to merge the same lines, it does not offer to leave them as is. So if I have on server the following:

    29: execute immediate '
    30: blah blah
    31: ');


    and I write:

    29: execute immediate '
    30: some other blah
    31: ');

    It always merges the last line, it does not offer to leave two copies of them. Very frustrating.

    ReplyDelete
  4. @Dalibor I'd actually expect the merge tool to act that way. Maybe have a look at using BeyondCompare or another 3-way merge tool as an alternative as see if they do what you want them to.

    By the way, in case you hadn't noticed, you can always directly edit the merged results at the bottom of the screen to get the merge just as you want it.

    ReplyDelete
  5. I've also found in the past that most merge tools can't handle XML files properly. P4Merge included, which is why I wrote Project: Merge. A comparison and merge tool specifically for XML files. (I originally wrote it because I had a VS project file with almost 10,000 conflicts.)

    Anyway, more information can be found on the website at: http://www.projectmerge.com

    Hope you like it.
    James

    ReplyDelete
  6. Awesome. Thanks!

    ReplyDelete
  7. I modified the script this way, so it shows the correct pannel titles:
    START /WAIT /D "C:\Program Files\Perforce" p4merge.exe -dw -nl %6 -nr %7 -nm %9 -nb %8 %3 %1 %2 %4

    These are the arguments I set in Visual Studio for the Merge command:
    %1 %2 %3 %4 "m" %6 %7 %8 %9

    ---
    Link to stack overflow post that opened my eyes on undocumented command line switches :)
    http://stackoverflow.com/questions/4034462/how-to-set-file-labels-in-p4merge/4037887
    ---

    Hope this helps,
    Marco

    ReplyDelete
  8. Funny I came across this blog post hoping to see if other people have experienced the same frustrations that I've had with P4Merge and therefore moved to BeyondCompare instead.

    Personally, I find p4merge an extremely lame tool compared to BeyondCompare. For example, when i work in VB, I want to ignore case differences, and p4merge doesnt provide a way to do that, this alone costs me at least 5mins per diff session.

    And navigating between each diff section is another pain in p4merge.

    ReplyDelete
  9. This is the greatest post on the whole internets!

    ReplyDelete
  10. Late to the party.. but... a follow up to the May 18, 2012 post. If you want the panels named for comparison in addition to merge, change the parameters to:

    -nl %6 -nr %7 %1 %2

    ReplyDelete