Using p4merge as a git mergetool

So, don’t get me wrong, I hate Perforce. It actually makes my head hurt a little remembering my experience with it. The only saving grace was the Perforce merge tool, p4merge. There are number of different diff/merge tools that will work with git on OS X, but I’m not all that impressed with them — even the rather expensive Changes left me feeling underwhelmed.

Perforce Visual Merge Tool

Perforce Visual Merge Tool (shown on Windows)

After figuring out how to configure git to use Changes as its merging and diff tool, I set out on a mission (read: Google search) to figure out how to use p4merge instead. It turns out it’s pretty simple, but that all the pages with instructions on how to do it no longer exist.

Here are the steps to get it working:

Download and Install P4V

Download the free Perforce Visual Client dmg from here. Once it’s downloaded, copy p4merge from the disk image to your /Applications directory.

Write some simple shell scripts


Create a new text file in /usr/local/bin called p4merge and add the following lines:

/Applications/ $*

Make the script executable by entering this command:

chmod +x p4merge


Create a new text file in /usr/local/bin called p4diff and add the following lines:

[ $# -eq 7 ] && /usr/local/bin/p4merge "$2" "$5"

Make the script executable by entering this command:

chmod +x p4diff

Configure Git to use the scripts

Open your git configuration file (probably ~/.gitconig) and add these lines:

	keepBackup = false;
	tool = p4merge
[mergetool "p4merge"]
	cmd = p4merge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
	keepTemporaries = false
	trustExitCode = false
	keepBackup = false
	external = p4diff

Use it!

That’s it. Now when you run git-mergetool or git-diff the visual Perforce merge tool will launch with the files you want to merge or diff. Hope this helps!

This entry was posted in git. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.


  1. Posted April 5, 2009 at 8:40 am | Permalink

    I am definitely going to use this. Thanks for the steps!

  2. Posted April 5, 2009 at 8:54 am | Permalink

    You’re my hero, Mr. McIntosh

  3. Posted April 12, 2009 at 9:56 am | Permalink

    make sure that you change the && to an actual &&

  4. Posted April 12, 2009 at 9:57 am | Permalink

    and by && I mean & &

  5. Posted May 5, 2009 at 10:30 pm | Permalink

    This doesn’t seem to work when there is only a LOCAL and REMOTE, but no BASE… p4merge gets hung up looking for the BASE, which does not exist.

  6. Senthil A Kumar
    Posted May 12, 2009 at 11:31 pm | Permalink

    Thanks a lot for the post, but

    [ $# -eq 7 ] && /usr/local/bin/p4merge “$2″ “$5″

    cmd = p4merge “$BASE” “$LOCAL” “$REMOTE” “$MERGED”

    But what does the above line do? Can i use the same thing for GIT on UNIX?
    Someone please help

  7. Posted July 2, 2009 at 2:18 pm | Permalink

    You can save yourself from having to create the script if you use the launchp4merge that comes bundled:

    [mergetool "p4merge"]
    cmd = /Applications/ “$PWD/$BASE” “$PWD/$REMOTE” “$PWD/$LOCAL” “$PWD/$MERGED”
    keepTemporaries = false
    trustExitCode = false
    keepBackup = false

    With this, all you have to do is install the app.

  8. Ben
    Posted August 25, 2009 at 11:39 am | Permalink

    when I use this, it will open a different window for each file in to diff. how do I open it all in 1 p4merge process? I figured this out for merging by googling around, but i’m not sure how to do this for diffing.

  9. Luís Miranda
    Posted September 23, 2009 at 8:52 am | Permalink

    Short and sweet, thanks!

  10. SooTyLaD
    Posted January 8, 2010 at 8:59 am | Permalink

    I have 3 questions regarding this if you don’t mind?

    1) After I “Hit return to start merge resolution tool (p4merge)” it pops straight up with this:

    2010-01-08 15:50:36.269 p4merge.real[58490:80b] Can’t open input server /Library/InputManagers/Inquisitor

    Any idea what this is and whats wrong? the editor still starts and all seems well but things like this bug me :p

    2) despite having trustExitCode set to false, it doesn’t ask me if the merge is complete like it would with say vimdiff?

    3) i have used both sets of keepBackup settings (both set to false, in fact, everything is as above) but if still leaves pesky .orig files in my working directory… any ideas?

    I have a feeling these are linked, could anyone shed some light? Also quite interested to see the authors answer to W. Andrew Loe III’s post?

  11. Max
    Posted November 16, 2010 at 9:04 am | Permalink

    Awesome! Worked first time with those instructions. What a joy after using the default diff tool!

    Thanks! My life will be easier from today on…

  12. Gregory
    Posted November 30, 2010 at 12:47 pm | Permalink

    Hello Andy,

    Please allow me to post here as a follow up to the first result when googling for Git + p4merge. I also thought my observations would spare hairy moments to people landing n your page.

    Time has passed since you wrote your blog post. Now Git recognizes p4merge and will no more use the value of mergetool.p4merge.cmd.

    The only configuration option Git is going to use is mergetool.p4merge.path eventually.

    Also since you posted, Git has gained git-difftool and will do the right thing ™ when the diff tool (or the mergetool) is p4merge. As a consequence, you don’t need your p4diff script anymore. Just remove the external = p4diff configuration section and delete your existing p4diff script.

    Finally, here is my p4merge script that takes care of converting relative paths to absolute paths in order to benefit from the launchp4merge shim.

    for arg; do [[ $arg = /* ]] || arg=$PWD/$arg; absargs+=("$arg"); done;
    /Applications/ "${absargs[@]}"

    Put it in /usr/local/bin in place of the previous one.

    For Windows users who landed here, you’ll notice p4merge.exe doesn’t handle NUL device properly. Here is a p4merge script you have to put in your C:\Program Files(x86)\Git\bin folder (MSYS Git).

    for arg; do [[ $arg = /dev/null ]] && arg=$NULL && echo "" >"$arg"; args+=("$arg"); done;
    /c/Program\ Files/Perforce/p4merge "${args[@]}"
    [[ -f $NULL ]] && rm $NULL

    Hope that helps.

  13. Gregory
    Posted November 30, 2010 at 12:51 pm | Permalink

    Hum looks like the formatting broke the script display, anyway here are two links to those files:

    p4merge script for mac:
    p4merge script for windows:

  14. Posted April 17, 2011 at 9:41 pm | Permalink

    Great article! And even better comments. Just a quick typo fix:

    keepBackup = false;

    Should probably instead be:

    keepBackup = false

    The semi-colon seems to be invalid.

  15. Gal
    Posted May 23, 2011 at 5:27 pm | Permalink

    Thanks for this – I keep referring back to this post.

    As of 5/23/11 newest version of p4merge for OSX is 10.2, available here:

  16. Dave Bayer
    Posted August 31, 2011 at 7:14 am | Permalink

    As of August 2011, Gregory’s p4merge script works perfectly for me. The only entries in my .gitconfig file that have anything to do with diff or merge are

    tool = p4merge
    prompt = false

    and so far, p4merge works vastly better for me than opendiff. The command ‘git diff’ uses the terminal window, but ‘git difftool’ uses P4Merge. A nice choice to have, both have their uses.

    In particular, Unicode characters display without the hack required for opendiff. The files open one at a time without the prompt, and close with command-W, leaving P4Merge running. No temporary files are left behind.

    I repeat, if you are tempted to use any diff or merge related lines in .gitconfig not shown here, prove to yourself that you need them, then please post a comment for all of us explaining why they were necessary.

    Don’t play Simon Says with anything else found on the web, as Gregory notes it is probably out of date.

    (Like most code-related apps, P4Merge looks much better using the Lucida Console font, at a larger font size.)

  17. Posted October 28, 2011 at 3:02 am | Permalink

    This was very helpful, cheers.

    One trick that I do in my version of your diff script is to copy the files into /tmp and append the revision hash to their filenames, then call p4merge to diff the copies. It makes it slightly easier to work out which revision is which if you’re diffing between two arbitrary points in the history.

  18. Posted April 19, 2014 at 1:24 am | Permalink

    I updated the scripts I provided here on the following post:

One Trackback

  1. By Sönke Rohde » GIT Tips and Tools on November 5, 2009 at 8:27 am

    [...] for merging. I am not a big Perforce fan but the free p4merge tool is really great. Check out the blog post by Andy McIntosh for a detailed explanation how to set it [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>