How to use Visual Studio Code as the default editor for Git MergeTool including for 3-way merge
Asked Answered
I

5

188

Today I was trying to use the git mergetool on the Windows command prompt and realized that it was defaulting to use Vim, which is cool, but I'd prefer VS Code.

How can I have Visual Studio Code function as my GUI for handling merge conflicts (or even as a diffing tool) for Git?

Is it possible to setup VS Code to get visuals for a three-way merge?

International answered 14/6, 2017 at 16:7 Comment(0)
I
361

Update: As of Visual Studio Code 1.70 Three-way merge with improvements were added. Visuals and further explanations are available if that's of interest to you πŸ˜‰.

As of Visual Studio Code 1.13 Better Merge was integrated into the core of Visual Studio Code.

The way to wire them together is to modify your .gitconfig and you have two options.

  1. To do this with command line entries, enter each of these: (Note: if on Windows Command Prompt replace ' with ". Thanks to Iztok Delfin and e4rache for helping clarify this.)

    1. git config --global merge.tool vscode
    2. git config --global mergetool.vscode.cmd 'code --wait --merge $REMOTE $LOCAL $BASE $MERGED'
    3. git config --global diff.tool vscode
    4. git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
  2. To do this by pasting some line in the .gitconfig with Visual Studio Code.

    • Run git config --global core.editor 'code --wait' from the command line.

    • From here you can enter the command git config --global -e. You will want to paste in the code in the "Extra Block" below.

        [user]
            name = EricDJohnson
            email = [email protected]
        [gui]
            recentrepo = E:/src/gitlab/App-Custom/Some-App
        # Comment: You just added this via 'git config --global core.editor "code --wait"'
        [core]
            editor = code --wait
        # Comment: Start of "Extra Block"
        # Comment: This is to unlock Visual Studio Code as your Git diff and Git merge tool
        [merge]
            tool = vscode
        [mergetool "vscode"]
        # Comment: Original way before three-way merge shown commented out
        #    cmd = code --wait $MERGED
        # Comment: For "Three-way merge"
            cmd = code --wait --merge $REMOTE $LOCAL $BASE $MERGED
        [diff]
            tool = vscode
        [difftool "vscode"]
            cmd = code --wait --diff $LOCAL $REMOTE
        # Comment: End of "Extra Block"
      

Now from within your Git directory with a conflict run git mergetool and, tada, you have Visual Studio Code helping you handle the merge conflict! (Just make sure to save your file before closing Visual Studio Code.)

Accept Incoming Change anyone?

For further reading on launching code from the command line, look in this documentation.

For more information in git mergetool check out this documentation.

International answered 14/6, 2017 at 16:7 Comment(28)
Does this integration of Better Merge allow you to accept and choose which portion to merge? Or do you still have to remove by hand the extra comments of the conflict like <<<< HEAD and >>>> develop? – Tantalous
There is a line above <<<< Head, that gets inserted that lists the options: "Accept Current Change | Accept Incoming Change | Accept Both Changes | Compare Changes" and I believe it inserts this on each section of detected changes in the file. But within a section if you want to custom merge a bit of this and a bit of that by hand, I believe you would make that change in your local and then go with the "Accept Current Change" option. So the work flow does kind of have you take a step back in order to take a step forward. If others resolve this in a different way please post here to educate us – International
Oh I see it in your print screen now, very neat. Thanks a lot for the explanation and the how to do it. Will happily use it on the next time conflicts gets in the way :) – Tantalous
@FiruzzZ , good question, vscode is just a variable name you pick, on the lines like tool = vscode and then reference again in quotes below that in [mergetool "vscode"] . So you could use tool = vs-code-beats-chuck-norris and then [mergetool "vs-code-beats-chuck-norris"] and it should still work. – International
I get the error unknown tool: vscode... I'm pretty sure to call VsCode from command line you have to use code instead of vscode – Proteose
@KolobCanyon just for clarity for you and others who might hit the same wall, in cmd = code --wait $MERGED , you are correct, you need to use "code", but in the reference lines above (tool = vscode and [mergetool "vscode"]) you can pick the variable name, like was mentioned above in the reply to @FiruzzZ . – International
@EricD.Johnson I re-read your answer and there is no reference to setting the alias code => vscode. You should probably just use code as it would make things easier. – Proteose
Also, this is not working for me. It just pops open VsCode and no files are ever brought up – Proteose
@KolobCanyon if you open a new question ( and link it in a comment here) with what's in your .gitconfig we can try to do a little collaborative debugging and see if we can figure it out. Far warning I don't currently have hardware running macOS, but since you're a PowerShell nerd I'm guessing you're rocking Windows as well. – International
Is there a way to let git open all the diffs at once instead of waiting for you to close the current tab to open another? – Minervamines
@Minervamines I assume you mean when there are multiple rounds of resolving the merge across lots of commits? I don't think there is a way to do this at the moment. – International
What I would like to do is "giff difftool mybranch master" and have VS code open with the diff of all the files that changed. Right now, it would open only one and wait for you to close it. – Minervamines
@Minervamines if you open the folder your git project is in with VS Code and then the little branching git icon, it will show you all the changes list file by file in SOURCE CONTROL: GIT side panel (as well as STAGED changes). See code.visualstudio.com/Docs/editor/versioncontrol#_git-support for screenshots and more explanation. – International
Oh ya, I know that, but it does not have the flexibility I'm looking for like getting a diff between two commits or two branches. And if it does, navigating git in vs code is quite horrible in my opinion. I just like their diff and merge UI. I was going and saw the git difftool -d for a directory diff. I'll check how that works tomorrow. – Minervamines
Although git difftool -d is pretty cool, VS code doesn't have a good way to diff two folders. The result is a VS code instance with a left and right folder but you need to manually select the matching left and right files, right click, compare. Not very practical. – Minervamines
@Minervamines sounds like you should try out extension marketplace.visualstudio.com/items?itemName=huizhou.githd . I tried it and it lets you do stuff like diff a folder in one branch against a different branch, etc. and move ahead one commit at a time to see how it morphs over time. Let us know if it gets you further down the path after you play around with it a bit. – International
there's @typo in code example on line 7 … it should be [core] instead of [code] (can't edit it so I writeing it as a comment) – Calomel
Using Sublime Text in macos this worked for me. Just replaced vscode and code for subl. – Tommi
Note that you should also use single quotes when running the git config commands in PowerShell, otherwise the $MERGED and the other variables get replaced with empty strings before the command is executed. Single quotes tells PowerShell to treat it as a literal string and not to perform interpolation. – Levo
if it opens in a new window everytime, just remove the "-n" option from the config file – Chandelier
And is there a way to use Visual Studio 2019 as difftool when using VS 2019 only? For example, I click on compare on History window in VS2019 and it opens up VS Code since that's the default difftool now. I only want to use VS Code as a difftool when I'm on command prompt... – Acropetal
@sotn I believe you can pick which difftool you want if you have multiple defined with git difftool --tool={someNonDefault}. See this multiple-diff-tools answer – International
See also: roboleary.net/vscode/2020/09/15/vscode-git.html – Macdermot
@GabrielStaples that link does give good visuals to compare VS Code with VIM and Nano – International
Going down the first path, running the commands with " on mac didn't work. VSCode would open when typing git difftool but with no files to compare. I had to make sure the config file is composed properly using path 2: git config --edit and changing cmd line to cmd = code --wait --diff $LOCAL $REMOTE manually. It wasn't formed well using the command line entries in path 1. In my case, I didn't want --global. – Menendez
@RTD Can you try it again with single quotes and tell me what you get for path 1? An editor to the answer but I think the wording threw you off. Basically double quote is just for Windows Command Prompt, and everybody else uses single-quote. – International
@EricD.Johnson true, the wording confused me. With ", the variables are stored as blanks. With ', things are better. Thank you. – Menendez
@RTD I simplified the wording to be less confusing now. Thanks for commenting so we could know to clean that up ;) – International
Z
34

I had to replace the double quotes with simple quotes:

  git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'

for it to work properly (with double quotes, $LOCAL and $REMOTE are replaced by their values).

This is needed if you are using Git Bash for Windows instead of Windows Command Prompt.

Zemstvo answered 19/8, 2018 at 10:9 Comment(6)
Not for me. I just did this on Windows using the Command Prompt. Perhaps you're using something different? If so, I suggest adding which environment you're using so others with the same environment will know that they'll need to make this change. – W
@Zemstvo and @Iztok-Delfin what you have listed here is helpful content but you've accidentally made it an answer, when it's really a comment. I'm sure you ran into trouble because you didn't have the 50 point on SO to allow you to comment, which is kind of a site work flow problem that should maybe be looked into. Anyway, thanks for contributing, and I added your tip in my answer above. Thanks for helping those who come later and are using Git Bash :^) – International
@eric-d-johnson I totally meant to make a comment instead of a reply. ( sorry, I'm new to this site ) and btw I was using bash on linux. Is there a way to transorm this reply into a comment ? – Zemstvo
@Zemstvo I don't know a way to make it a comment, but perhaps a moderator will see this and give us some tips (hint, hint). If you had the 50 points, you could make a comment on the accepted answer, and delete this one, so once you become an SO rock-star with tons of points you can come back here and do whatever housekeeping makes you happy and brings back good memories of how it all started. – International
The original solution didn't work fully on Mac OS, but this one worked fine – Synovitis
@mohamedghonemi Good feedback. I updated the explanation at the top for macOS and Linux now to remember to use single quotes ('s). – International
O
27

On top of the excellent existing answer, you should open VS Code in a new window by adding -n to the command line.

So your git config --global --edit looks something like this.

[merge]
        tool = vscode
[mergetool "vscode"]
        cmd = code --new-window --wait $MERGED
[diff]
        tool = vscode
[difftool "vscode"]
        cmd = code --new-window --wait --diff $LOCAL $REMOTE                                                    
Oat answered 28/1, 2020 at 22:27 Comment(3)
I used these settings, but when I do git diff commit_id1 commit_id2, it doesn't bring up a VS code editor window. It still defaults to the terminal. Am I using the wrong command? – Azerbaijani
@Azerbaijani have you tried git diftool instead of git diff? – Oat
Note: use cmd = code --wait --merge $REMOTE $LOCAL $BASE $MERGED if you have VSCode 1.7+ and want three-way merge UI. – Menendez
B
11

Using the manual you can find an interesting argument:

git difftool --help 
-x <command>, --extcmd=<command>
       Specify a custom command for viewing diffs.  git-difftool ignores the configured defaults and runs $command $LOCAL $REMOTE when this option is specified.
       Additionally, $BASE is set in the environment.

With this information you can easily use the following command without touching the git configuration:

git difftool -x "code --wait --diff" 

Similar question here

Backcross answered 21/11, 2019 at 20:53 Comment(0)
G
4

In case if someone want to resolve it in Visual Studio, another option would be doing it through Visual Studio: Team Explorer -> click on Home icon => Settings button => expand Git section => click on Global Settings

enter image description here enter image description here enter image description here

Gathers answered 16/1, 2020 at 16:12 Comment(3)
Visual Studio is not equivalent to Visual Studio Code. The way settings like this are done are quite different. See stackoverflow.com/a/33798601 for the differences – Kelleekelleher
@Kelleekelleher I know VS code is different than VS. I had this issue in VS but couldn't find a solution for that so I though it would be better to post it in case someone is experincing this problem. No need to down-vote. – Gathers
This is an answer to a completely different question for a different product. – Rivero

© 2022 - 2024 β€” McMap. All rights reserved.