Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git Diff and Merge Tool - IntelliJ IDEA
# Linux
# add the following to "~/.gitconfig" file
[merge]
tool = intellij
[mergetool "intellij"]
cmd = /usr/local/bin/idea merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED")
trustExitCode = true
[diff]
tool = intellij
[difftool "intellij"]
cmd = /usr/local/bin/idea diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE")
# Mac
# add the following to "~/.gitconfig" file
[merge]
tool = intellij
[mergetool "intellij"]
cmd = /Applications/IntelliJ\\ IDEA.app/Contents/MacOS/idea merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED")
trustExitCode = true
[diff]
tool = intellij
[difftool "intellij"]
cmd = /Applications/IntelliJ\\ IDEA.app/Contents/MacOS/idea diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE")
# Windows
# add the following to "C:\Users\<username>\.gitconfig" file
[merge]
tool = intellij
[mergetool "intellij"]
cmd = cmd.exe //c "\"C:/Program Files (x86)/IntelliJ IDEA Community Edition 12.0/bin/idea.bat\" merge \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\""
trustExitCode = true
[diff]
tool = intellij
[difftool "intellij"]
cmd = cmd.exe //c "\"C:/Program Files (x86)/IntelliJ IDEA Community Edition 12.0/bin/idea.bat\" diff \"$LOCAL\" \"$REMOTE\""

Invoking IntelliJ IDEA from the command line

On OS X or UNIX:
  • Make sure IntelliJ IDEA is running.
  • On the main menu, choose Tools > Create Command-line Launcher. The dialog box Create Launcher Script opens, with the suggested path and name of the launcher script. You can accept default, or specify your own path.
  • Make notice of it, as you'll need it later. Outside of IntelliJ IDEA, add the path and name of the launcher script to your path.
On Windows:
  • Specify the location of the IntelliJ IDEA executable in the Path system environment variable. In this case, you will be able to invoke the IntelliJ IDEA executable and other IntelliJ IDEA commands from any directory.

For more information, visit https://www.jetbrains.com/help/idea/2016.2/running-intellij-idea-as-a-diff-or-merge-command-line-tool.html

Issues and Solutions

@cosbor11

This comment has been minimized.

Copy link

@cosbor11 cosbor11 commented Jun 15, 2017

Is this out of date?

fatal: bad config line 7 in file
@yuriteixeira

This comment has been minimized.

Copy link

@yuriteixeira yuriteixeira commented Jun 26, 2017

@cosbor11: for me it was somehow related to the path of the idea executable. Since I symlinked it to /usr/local/bin and this directory is on my $PATH env var, I just changed it to:

[merge]
    tool = intellij
[mergetool "intellij"]
    cmd = idea merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED")
    trustExitCode = true
[diff]
    tool = intellij
[difftool "intellij"]
    cmd = idea diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE")
@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Jul 19, 2017

For those of you using fish as your shell:

[merge]
  tool = /usr/local/bin/idea
[mergetool "idea"]
	cmd = /usr/local/bin/idea merge (cd (dirname "$LOCAL"); and pwd)/(basename "$LOCAL") (cd (dirname "$REMOTE"); and pwd)/(basename "$REMOTE") (cd (dirname "$BASE"); and pwd)/(basename "$BASE") (cd (dirname "$MERGED"); and pwd)/(basename "$MERGED")
	trustExitCode = true
[diff]
	tool = /usr/local/bin/idea
[difftool "idea"]
  cmd = /usr/local/bin/idea diff (cd (dirname "$LOCAL"); and pwd)/(basename "$LOCAL") (cd (dirname "$REMOTE"); and pwd)/(basename "$REMOTE")
@rambabusaravanan

This comment has been minimized.

Copy link
Owner Author

@rambabusaravanan rambabusaravanan commented Aug 24, 2017

@cosbor11 Can you show us the config file and the error message please ..

@rambabusaravanan

This comment has been minimized.

Copy link
Owner Author

@rambabusaravanan rambabusaravanan commented Aug 24, 2017

@robbie-10e Thanks for your contribution for "Fish" shell also. I just came to know about fish shell and love fishing it ..

@dudego

This comment has been minimized.

Copy link

@dudego dudego commented Sep 5, 2017

I had to double escape the back slashes (for spaces) to make it work on MacOS.

[merge]
	tool = intellij
[mergetool "intellij"]
	cmd = /Applications/IntelliJ\\IDEA\\ CE.app/Contents/MacOS/idea' merge $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE") $(cd $(dirname "$BASE") && pwd)/$(basename "$BASE") $(cd $(dirname "$MERGED") && pwd)/$(basename "$MERGED")
	trustExitCode = true
[diff]
	tool = intellij
[difftool "intellij"]
	cmd = /Applications/IntelliJ\\ IDEA\\ CE.app/Contents/MacOS/idea diff $(cd $(dirname "$LOCAL") && pwd)/$(basename "$LOCAL") $(cd $(dirname "$REMOTE") && pwd)/$(basename "$REMOTE")
@rambabusaravanan

This comment has been minimized.

Copy link
Owner Author

@rambabusaravanan rambabusaravanan commented Sep 19, 2017

Thanks for your contribution @dudego.
I have updated the gist with double backslash from IntelliJ\ IDEA to IntelliJ\\ IDEA.

@CoreyKaylor

This comment has been minimized.

Copy link

@CoreyKaylor CoreyKaylor commented Nov 10, 2017

This setup worked fine for me on a Mac. Assuming you've already run the create command line launcher step. What doesn't make a lot of sense to me though is why IntelliJ has to already be running. Any context for that? I have the same issue. The reason I find it odd is that if you compare two files directly on the filesystem it works fine without IntelliJ already running. idea diff localfile.txt localfile2.txt

[merge]
    tool = intellij
[mergetool "intellij"]
    cmd = idea merge \"$LOCAL\" \"$REMOTE\" \"$BASE\" \"$MERGED\"
    trustExitCode = true
[diff]
    tool = intellij
[difftool "intellij"]
	cmd = idea diff \"$LOCAL\" \"$REMOTE\"
[difftool]
	  prompt = false
@AlexKalinin

This comment has been minimized.

Copy link

@AlexKalinin AlexKalinin commented Dec 26, 2017

Thanks!

@Mincol

This comment has been minimized.

Copy link

@Mincol Mincol commented Jan 11, 2018

On Windows.
If Idea is already running, only first file get opened, for rest I get error that file does not exists.

There are two solutions to the problem.

  1. Close all idea instances. All work as expected.
  2. Set trustExitCode = false Then you need to visit commandline and say that you are finished with merging.
@aaccioly

This comment has been minimized.

Copy link

@aaccioly aaccioly commented Jan 23, 2018

I hit a problem running git difftool HEAD~1 --dir-diff on Windows. The files created by Git on %TEMP% are generally deleted a few seconds after the original diff command has run. Looks like the problem is that CMD /C runs the UI and terminates itself (releasing the files) before we get a chance to finish the merge.

A possible workaround is to call pause after idea.bat, e.g.:

[difftool "intellij"]
    cmd = cmd //c "idea.bat diff \"$LOCAL\" \"$REMOTE\"" & cmd //c pause

This will display the iconic "Press any key to continue . . ." message after each command and make sure that the inner cmd is not released until we are done.

Alternatively we can run idea.bat with cmd //k but I dislike the idea of not terminating the process. Distracted users can potentially open dozens of shells without noticing. Also, it gets really weird if you start the process from a different shell such as bash or PowerShell

@injulkarnilesh

This comment has been minimized.

Copy link

@injulkarnilesh injulkarnilesh commented Apr 3, 2018

append "&& read -n 1 -s" to mergetool "intellij" command for mac.
Then it would ask to merge one file and wait for key press.

After merging one file go back to terminal press any key to continue merging next files.

@mariohuq

This comment has been minimized.

Copy link

@mariohuq mariohuq commented May 20, 2018

On windows version there is some issue:

▒▒▒ 21, 2018 1:11:55 AM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. 
Windows RegCreateKeyEx(...) returned error code 5.

I am using Windows 10.0.17133 Build 17133
jdk's release file contents

JAVA_VERSION="1.8.0_152"
OS_NAME="Windows"
OS_VERSION="5.2"
OS_ARCH="amd64"
SOURCE=""

IntelliJ IDEA Community Edition 2018.1
MINGW64 from Git for Widows.

What's the reason?

@contentfree

This comment has been minimized.

Copy link

@contentfree contentfree commented Apr 4, 2019

Doesn't seem to work on macOS if Intellij is installed from the JetBrains Toolbox app. (Haven't found the workaround yet, either)

@dror-weiss

This comment has been minimized.

Copy link

@dror-weiss dror-weiss commented May 3, 2019

@contentfree, did you manage to find a solution?

@Yamp

This comment has been minimized.

Copy link

@Yamp Yamp commented Sep 19, 2019

@dror-weiss @contentfree have you found a solution?

@ImanMahmoudinasab

This comment has been minimized.

Copy link

@ImanMahmoudinasab ImanMahmoudinasab commented May 14, 2020

@Yamp @dror-weiss @contentfree
Follow steps of the following instruction and you will end up with having a global command idea in your terminal:
https://www.jetbrains.com/help/idea/working-with-the-ide-features-from-command-line.html

@rwe

This comment has been minimized.

Copy link

@rwe rwe commented Nov 30, 2020

The problem on macOS is that the shell script generated by JetBrains Toolbox looks like this:

open -na "/Users/…/202.7660.26/IntelliJ IDEA.app/Contents/MacOS/idea" --args "$@"

However, if you man open, you'll see that the additional flag -W is required:

-W Causes open to wait until the applications it opens (or that were already open) have exited. Use with the -n flag to allow open to function as an appropriate app for the $EDITOR environment variable.

Solution

Caveat: The JetBrains toolbox will likely clobber changes to the generated script, so perhaps instead make a new one named like idea-wait/intellij-wait and replace the name after cmd = in the config below. Alternatively again, you could inline entire open -Wna … command. This would make your .gitconfig non-portable, but would remove the need to muck around with the script files.

Add the additional -W flag to the script. It's also not a bad idea to use exec so that sh doesn't sit in the way of signals:

exec open -Wna "/Users/…/MacOS/idea" --args "$@"

Which allows the following portable and correctly-quoted .gitconfig to work:

[difftool "idea"]
	cmd = idea diff \
		\"$(cd \"$(dirname \"$LOCAL\")\" && pwd)/$(basename \"$LOCAL\")\" \
		\"$(cd \"$(dirname \"$REMOTE\")\" && pwd)/$(basename \"$REMOTE\")\" \

[diff]
	tool = idea
	guitool = idea

[mergetool "idea"]
	cmd = idea merge \
		\"$(cd \"$(dirname \"$LOCAL\")\" && pwd)/$(basename \"$LOCAL\")\" \
		\"$(cd \"$(dirname \"$REMOTE\")\" && pwd)/$(basename \"$REMOTE\")\" \
		\"$(cd \"$(dirname \"$BASE\")\" && pwd)/$(basename \"$BASE\")\" \
		\"$(cd \"$(dirname \"$MERGED\")\" && pwd)/$(basename \"$MERGED\")\" \

[merge]
	tool = idea
	guitool = idea

Note also that if you have realpath available (via brew install coreutils), those awkward \"$(cd \"$(dirname…)\"…)/$(basename …)\" lines can just be replaced by e.g. \"$(realpath \"${LOCAL}\")\".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.