Git Difftool And Mergetool With Visual Studio Code Git VSCode

Dec 25th, 2020 - written by Kimserey with .

Visual Code ships with powerful Git support. In this post we will look at how we can use Visual Code as default diff and merge tool for Git.

Using VSCode command line

In this post we assume that we have installed VSCode and have access to code command line. If you don’t have access run CMD SHIFT P > shell command and install code in command path. Then we should be able to do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
❯ code -h
Visual Studio Code 1.51.1

Usage: code [options][paths...]

To read from stdin, append '-' (e.g. 'ps aux | grep code | code -')

Options
  -d --diff <file> <file>           Compare two files with each other.
  -a --add <folder>                 Add folder(s) to the last active window.
  -g --goto <file:line[:character]> Open a file at the path on the specified line and character position.
  -n --new-window                   Force to open a new window.
  -r --reuse-window                 Force to open a file or folder in an already opened window.
  --folder-uri <uri>                Opens a window with given folder uri(s)
  --file-uri <uri>                  Opens a window with given file uri(s)
  -w --wait                         Wait for the files to be closed before returning.
  --locale <locale>                 The locale to use (e.g. en-US or zh-TW).
  --user-data-dir <dir>             Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.
  -h --help                         Print usage.

This verifies that code is accessible from path. The important commands here are:

  • --diff: open VSCode with the difftool feature,
  • --new-window: forces VSCode to open in a new window (useful when we already have VSCode open and don’t want to open into the same window),
  • --wait: waits for the file to be closed prior returning (we will see next why this is important).

Just from here we can already see that we can take advantage of the difftool directly from command line:

1
❯ code -d  <file> <file>

This will open VSCode on the diff window between the two files.

Setting up VSCode as mergetool and difftool

Now that we can use VSCode command line, we can then directly use it as command for mergetool and difftool in Git. We can do that by editing the global configuration:

1
❯ vim ~/.gitconfig

And we add or replace if those were already added:

1
2
3
4
5
6
7
8
9
10
11
[merge]
        tool = vscode
[mergetool]
        keepBackup = false
[mergetool "vscode"]
        cmd = code --wait --new-window $MERGED

[diff]
        tool = vscode
[difftool "vscode"]
        cmd = code --wait --diff --new-window $LOCAL $REMOTE

We set VSCode as mergetool and difftool, here I’ve also disabled the backup orig files with keepBackup = false. And then we’ve specified the commands to execute when we want to open the tools.

1
❯ code --wait --new-window $MERGED

$MERGED will open the file that contains the merge conflict.

1
❯ code --wait --diff --new-window $LOCAL $REMOTE

This will open VSCode on a diff with $LOCAL and $REMOTE pointing to temporary checkout file versions having diffs.

Now that we have setup VSCode as mergetool and difftool we can now use them. For example let’s say we have a feature-a branch which has conflicts, and we try to merge it into our current branch:

1
2
3
4
❯ git merge feature-a
Auto-merging c.md
CONFLICT (content): Merge conflict in c.md
Automatic merge failed; fix conflicts and then commit the result.

Git detected a conflict that couldn’t be resolved and paused the merge for a manual resolution. We can then run git mergetool:

1
2
3
4
5
6
7
❯ git mergetool
Merging:
c.md

Normal merge conflict for 'c.md':
  {local}: modified file
  {remote}: modified file

This will open VSCode on the file having a merge conflict allowing us to resolve the conflict:

mergetool

We can then resolve the conflict, save and close the file. Once we exit the file, Git knows to continue to the next file or to complete merge by staging all changes. We can then simply commit the merge changes to complete the merge:

1
❯ git commit

Similarly to the mergetool, we can check the diff which we could do with git diff:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
❯ git diff develop feature-a

diff --git a/c.md b/c.md
index 8156f33..7fdb9e2 100644
--- a/c.md
+++ b/c.md
@@ -4,6 +4,6 @@ Proin sit amet consectetur lorem, aliquet tempus sem.

 Nulla ipsum tellus, scelerisque non lacinia vel, rhoncus gravida nisl. Vestibulum nec cursus dui. In consectetur purus pellentesque, venenatis lacus vitae, vulputate dolor. Curabitur erat enim, hendrerit eget vehicula id, sitametcursus in dui.

-Test
+Replacing everything test

 Nulla et dignissim elit. Maecenas eleifend pharetra metus. Nullam dictum neque at urna blandit, convallis pellentesque urna tincidunt. Nulla facilisi. Etiam id neque vitae massa molestie varius. Nulla eu pretium sem. Phasellus dolor nisl, tempor ut facilisis vel, interdum vel nulla.
\ No newline at end of file
(END)

This will show the difference between develop and feature-a, we can see that feature-a would remove Test and replace it with Replacing everything test. To display the diff in Vscode we can use difftool instead:

1
2
3
4
❯ git difftool develop feature-a

Viewing (1/1): 'c.md'
Launch 'vscode' [Y/n]? y

The diff will then be opened in VSCode:

difftool

And that concludes this week’s post! See you on the next one!

External Source

Designed, built and maintained by Kimserey Lam.