When I type git diff
, I'd like to see a side-by-side diff, like with diff -y
, or like to display the diff in an interactive diff tool like kdiff3
. How can this be done?

- 20,112
- 21
- 72
- 113
-
possible duplicate of [How do I view 'git diff' output with visual diff program?](http://stackoverflow.com/questions/255202/how-do-i-view-git-diff-output-with-visual-diff-program) – Greg Hewgill Oct 06 '11 at 03:12
-
Note: you have a [side-by-side diff on GitHub](http://stackoverflow.com/a/25657797/6309). – VonC Sep 04 '14 at 05:22
-
Duplicate of [How do I view 'git diff' output with my preferred diff tool/ viewer?](https://stackoverflow.com/questions/255202/how-do-i-view-git-diff-output-with-my-preferred-diff-tool-viewer) – smci Feb 13 '18 at 23:25
-
Damn, this is annoying that you can't do it like with `diff`. I better get used to reading the non-side-by-side format, which is hard for a visual person. – Sridhar Sarnobat Dec 14 '21 at 22:38
19 Answers
Try git difftool
Use git difftool
instead of git diff
. You'll never go back.
UPDATE to add an example usage:
Here is a link to another stackoverflow that talks about git difftool
: How do I view 'git diff' output with my preferred diff tool/ viewer?
For newer versions of git
, the difftool
command supports many external diff tools out-of-the-box. For example vimdiff
is auto supported and can be opened from the command line by:
cd /path/to/git/repo
git difftool --tool=vimdiff
Other supported external diff tools are listed via git difftool --tool-help
here is an example output:
'git difftool --tool=<tool>' may be set to one of the following:
araxis
kompare
vimdiff
vimdiff2
The following tools are valid, but not currently available:
bc3
codecompare
deltawalker
diffuse
ecmerge
emerge
gvimdiff
gvimdiff2
kdiff3
meld
opendiff
tkdiff
xxdiff
-
50Or maybe you will go back if you get `This message is displayed because 'diff.tool' is not configured.`. Perhaps update answer with minimal how-to configure this thing, so that it display side-by-side diffs in terminal, which is what OP asked for? GUI tools are quite useless on remote server where you connect using ssh. – Petr May 22 '16 at 12:04
-
1Interesting point, though I don't think I've personally ever needed to use git while SSH'd. Once of the nice things about DVCS is the Distributed part: at least in my environments it's never a hassle to locally clone whatever repo I want to poke around. – Matt Ball May 22 '16 at 14:39
-
1At least in my config, `git difftool` with `vimdiff` doesn't always line up the two files/buffers correctly. – tim-phillips Apr 23 '17 at 00:46
-
1Thats nice, and so down below in the answer list :O I use `git difftool -y` to prevent tkdiff prompt – gawkface Jun 13 '17 at 03:06
-
Related: make meld your `git difftool` in Windows & Linux: https://stackoverflow.com/a/48979939/4561887 – Gabriel Staples Sep 20 '19 at 18:41
-
We need command line diffing for other reasons, like over plaintext chat when collaborating (e.g. a code review) or when doing something over ssh. – Sridhar Sarnobat Jun 10 '21 at 00:09
-
Related: open all differences at once instead of serially by using `dir-diff` option: https://stackoverflow.com/a/2746292/1518546 – John Cummings Apr 14 '23 at 18:39
-
Just a heads-up that the list of Available tools seems to be based on certain app names being in `$PATH`. "Araxis" is a tool for Windows and Mac whose name in the shell is `compare`. `compare` also happens to be a program included with ImageMagick on Linux, so if you've never heard of Araxis and see it on your machine you probably don't actually have it and passing it to `--tool=` will do nothing. – pyansharp Jul 07 '23 at 21:00
Although Git has an internal implementation of diff, you can set up an external tool instead.
There are two different ways to specify an external diff tool:
- setting the
GIT_EXTERNAL_DIFF
and theGIT_DIFF_OPTS
environment variables. - configuring the external diff tool via
git config
ymattw
's answer is also pretty neat, using ydiff
See also:
- https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration
git diff --help
- http://www.pixelbeat.org/programming/diffs/
When doing a git diff
, Git checks both the settings of above environment variables and its .gitconfig
file.
By default, Git passes the following seven arguments to the diff program:
path old-file old-hex old-mode new-file new-hex new-mode
You typically only need the old-file and new-file parameters. Of course most diff tools only take two file names as an argument. This means that you need to write a small wrapper-script, which takes the arguments which Git provides to the script, and hands them on to the external git program of your choice.
Let's say you put your wrapper-script under ~/scripts/my_diff.sh
:
#!/bin/bash
# un-comment one diff tool you'd like to use
# side-by-side diff with custom options:
# /usr/bin/sdiff -w200 -l "$2" "$5"
# using kdiff3 as the side-by-side diff:
# /usr/bin/kdiff3 "$2" "$5"
# using Meld
/usr/bin/meld "$2" "$5"
# using VIM
# /usr/bin/vim -d "$2" "$5"
you then need to make that script executable:
chmod a+x ~/scripts/my_diff.sh
you then need to tell Git how and where to find your custom diff wrapper script. You have three choices how to do that: (I prefer editing the .gitconfig file)
Using
GIT_EXTERNAL_DIFF
,GIT_DIFF_OPTS
e.g. in your .bashrc or .bash_profile file you can set:
GIT_EXTERNAL_DIFF=$HOME/scripts/my_diff.sh export GIT_EXTERNAL_DIFF
Using
git config
use "git config" to define where your wrapper script can be found:
git config --global diff.external ~/scripts/my_diff.sh
Editing your
~/.gitconfig
fileyou can edit your
~/.gitconfig
file to add these lines:[diff] external = ~/scripts/my_diff.sh
Note:
Similarly to installing your custom diff tool, you can also install a custom merge-tool, which could be a visual merging tool to better help visualizing the merge. (see the progit.org page)
See: http://fredpalma.com/518/visual-diff-and-merge-tool/ and https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration

- 33,354
- 5
- 79
- 106
-
1
-
4This is great, but it launches a new viewer for every file. Any way to create a consolidated diff in, say, `meld`? – HRJ Nov 12 '13 at 18:11
-
2@Tilo I am getting error for vim as im: Warning: Output is not to a terminal – dead programmer May 25 '17 at 10:31
-
Can the `meld` version be configured to do a directory diff, where I can choose which file(s) I want to see the diff for? Currently it runs a separate `meld` command for each file, and I have to quit `meld` in order to see the next file. I'd rather have `meld` show me a directory listing of changed files like it behaves when `meld` is used from Mercurial. – kasperd Jan 14 '19 at 12:54
-
I don't want to vote this answer down. But the answer from ymattw was very easy to implement. – Aug 07 '20 at 19:20
You can also try git diff --word-diff
.
It's not exactly side-by-side, but somehow better, so you might prefer it to your actual side-by-side need.
-
21This is the easiest way. What's even better is `git diff --word-diff=color` – Rolf Aug 14 '14 at 10:42
-
@Rolf `--word-diff=color` gives me an invalid option error. Which version was it introduced in? – Holloway Oct 14 '14 at 16:03
-
-
6@Rolf default installed version here is 1.7.1. Could explain the difference. `git diff --color-words` does work. – Holloway Oct 15 '14 at 10:05
-
8Yes, `git diff --color-words` is the way to go on modern git versions. – VasiliNovikov Jan 13 '17 at 13:22
-
ydiff
Formerly called cdiff
, this tool can display side by side, incremental, and colorful diff.
Instead of doing git diff
, do:
ydiff -s -w0
This will launch ydiff
in side-by-side display mode for each of the files with differences.
Install with:
python3 -m pip install --user ydiff
-or-
brew install ydiff
For git log
, you can use:
ydiff -ls -w0
-w0
auto-detects your terminal width. See the ydiff
GitHub repository page for detail and demo.
Tested in Git 2.18.0, ydiff 1.1.

- 25,981
- 23
- 80
- 125

- 1,129
- 10
- 7
-
@RyneEverett: Can you explain how to do the equivalent of `git diff | cdiff -s` with icdiff? – einpoklum Jan 07 '19 at 09:51
-
1Just run `ydiff -s` from a git/svn/hg workspace, you don't have to pipe in. – ymattw Jan 08 '19 at 14:13
-
1if you want to limit the diff to a specific file through Git's history, `cd
` and then run `ydiff -ls – slm Jan 16 '20 at 17:47` -
I installed it with pip, but still I the the command ydiff on the console not found, because it is intalled as `~/.local/bin/ydiff` – rubo77 May 19 '23 at 09:47
You can do a side-by-side diff
using sdiff
as follows:
$ git difftool -y -x sdiff HEAD^ | less
where HEAD^
is an example that you should replace with whatever you want to diff against.
I found this solution here where there are a couple of other suggestions also. However, this one answer's the OP's question succinctly and clearly.
See the man git-difftool for an explanation of the arguments.
Taking the comments on board, you can create a handy git sdiff
command by writing the following executable script:
#!/bin/sh
git difftool -y -x "sdiff -w $(tput cols)" "${@}" | less
Save it as /usr/bin/git-sdiff
and chmod +x
it. Then you'll be able to do this:
$ git sdiff HEAD^
Extra Tip
As suggested in comments you can use icdiff
to do what sdiff
does with colored output:
$ more /usr/bin/git-sdiff
#!/bin/sh
git difftool -y -x "icdiff --cols $(tput cols)" "${@}" | less --raw-control-chars

- 9,273
- 7
- 66
- 96
For unix, combining just git
and the built-in diff
:
git show HEAD:path/to/file | diff -y - path/to/file
Of course, you can replace HEAD with any other git reference, and you probably want to add something like -W 170
to the diff command.
This assumes that you are just comparing your directory contents with a past commit. Comparing between two commits is more complex. If your shell is bash
you can use "process substitution":
diff -y -W 170 <(git show REF1:path/to/file) <(git show REF2:path/to/file)
where REF1
and REF2
are git references – tags, branches or hashes.

- 3,252
- 2
- 21
- 11
-
Thanks -- your command 'git show HEAD:path/to/file' was what I needed to come up with my own solution, 'vimdfiff <(git show HEAD:path/to/file) path/to/file'. The bits still aren't lined up correctly, but that's the best solution I've got right now. – talexb Apr 30 '19 at 17:28
I recently implemented a tool that does exactly this: https://github.com/banga/git-split-diffs
Here's how to use it:
npm install -g git-split-diffs
git config --global core.pager "git-split-diffs --color | less -RFX"
And this is how it looks in your terminal (with the default theme):
As you can see, it also supports syntax highlighting and highlighting changed words within lines

- 812
- 7
- 16
-
-
-
There are some notes on performance at https://github.com/banga/git-split-diffs#performance, but if this seems different, it would be great if you could file an issue. Thanks! – Shrey Sep 11 '21 at 03:17
-
1This was perfect! Thank you! Works great when I run `git diff --staged` – 1Mojojojo1 May 17 '23 at 17:36
export GIT_EXTERNAL_DIFF='meld $2 $5; echo >/dev/null'
then simply:
git diff

- 39,603
- 20
- 94
- 123

- 99
- 1
- 2
-
1`meld .' works too! And it shows all of the changes in a consolidated window. – HRJ Nov 12 '13 at 18:19
-
-
```meld``` works also quite good with XQartz-X-Display-Redirect. (Debian to macOS) – Fusca Software Feb 15 '23 at 10:18
If you'd like to see side-by-side diffs in a browser without involving GitHub, you might enjoy git webdiff, a drop-in replacement for git diff
:
$ pip install webdiff
$ git webdiff
This offers a number of advantages over traditional GUI difftools like tkdiff
in that it can give you syntax highlighting and show image diffs.
Read more about it here.

- 15,863
- 5
- 72
- 116
I use colordiff.
On Mac OS X, install it with
$ sudo port install colordiff
On Linux is possibly apt get install colordiff
or something like that, depending on your distro.
Then:
$ git difftool --extcmd="colordiff -ydw" HEAD^ HEAD
Or create an alias
$ git alias diffy "difftool --extcmd=\"colordiff -ydw\""
Then you can use it
$ git diffy HEAD^ HEAD
I called it "diffy" because diff -y
is the side-by-side diff in unix. Colordiff also adds colors, that are nicer.
In the option -ydw
, the y
is for the side-by-side, the w
is to ignore whitespaces, and the d
is to produce the minimal diff (usually you get a better result as diff)

- 8,659
- 7
- 53
- 66
-
add `-y` to skip the `Launch 'colordiff' [Y/n]:` prompt. – Beni Cherniavsky-Paskin Aug 10 '14 at 07:17
-
are you sure it is `git alias diffy "difftool --extcmd=\"colordiff -ydw\""`? Shouldn't it be `git config --global alias.diffy "difftool --extcmd=\"colordiff -ydw\""` ? – nonopolarity Apr 07 '20 at 06:15
-
Please correct to ```apt install colordiff``` or ```apt-get install colordiff```, ```apt get install colordiff``` is not working. – Fusca Software Feb 15 '23 at 10:02
I personally really like icdiff !
If you're on Mac OS X
with HomeBrew
, just do brew install icdiff
.
To get the file labels correctly, plus other cool features, I have in my ~/.gitconfig
:
[pager]
difftool = true
[diff]
tool = icdiff
[difftool "icdiff"]
cmd = icdiff --head=5000 --highlight --line-numbers -L \"$BASE\" -L \"$REMOTE\" \"$LOCAL\" \"$REMOTE\"
And I use it like: git difftool

- 7,286
- 2
- 34
- 19
This question showed up when I was searching for a fast way to use git builtin way to locate differences. My solution criteria:
- Fast startup, needed builtin options
- Can handle many formats easily, xml, different programming languages
- Quickly identify small code changes in big textfiles
I found this answer to get color in git.
To get side by side diff instead of line diff I tweaked mb14's excellent answer on this question with the following parameters:
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]"
If you do not like the extra [- or {+ the option --word-diff=color
can be used.
$ git diff --word-diff-regex="[A-Za-z0-9. ]|[^[:space:]]" --word-diff=color
That helped to get proper comparison with both json and xml text and java code.
In summary the --word-diff-regex
options has a helpful visibility together with color settings to get a colorized side by side source code experience compared to the standard line diff, when browsing through big files with small line changes.

- 397
- 2
- 16
Open Intellij IDEA, select a single or multiple commits in the "Version Control" tool window, browse changed files, and double click them to inspect changes side by side for each file.
With the bundled command-line launcher you can bring IDEA up anywhere with a simple idea some/path

- 10,634
- 3
- 64
- 63
Here's an approach. If you pipe through less, the xterm width is set to 80, which ain't so hot. But if you proceed the command with, e.g. COLS=210, you can utilize your expanded xterm.
gitdiff()
{
local width=${COLS:-$(tput cols)}
GIT_EXTERNAL_DIFF="diff -yW$width \$2 \$5; echo >/dev/null" git diff "$@"
}

- 21
- 1
-
1Funny. I signed by name with a pseudonym but that was ignored... Thanks for outing me, Stack Overflow. :( – Thomas Mellman Jun 27 '16 at 09:15
Several others already mentioned cdiff for git side-by-side diffing but no one gave a full implementation of it.
Setup cdiff:
git clone https://github.com/ymattw/cdiff.git
cd cdiff
ln -s `pwd`/cdiff ~/bin/cdiff
hash -r # refresh your PATH executable in bash (or 'rehash' if you use tcsh)
# or just create a new terminal
Edit ~/.gitconfig inserting these lines:
[pager]
diff = false
show = false
[diff]
tool = cdiff
external = "cdiff -s $2 $5 #"
[difftool "cdiff"]
cmd = cdiff -s \"$LOCAL\" \"$REMOTE\"
[alias]
showw = show --ext-dif
The pager off is needed for cdiff to work with Diff, it is essentially a pager anyway so this is fine. Difftool will work regardless of these settings.
The show alias is needed because git show only supports external diff tools via argument.
The '#' at the end of the diff external command is important. Git's diff command appends a $@ (all available diff variables) to the diff command, but we only want the two filenames. So we call out those two explicitly with $2 and $5, and then hide the $@ behind a comment which would otherwise confuse sdiff. Resulting in an error that looks like:
fatal: <FILENAME>: no such path in the working tree
Use 'git <command> -- <path>...' to specify paths that do not exist locally.
Git commands that now produce side-by-side diffing:
git diff <SHA1> <SHA2>
git difftool <SHA1> <SHA2>
git showw <SHA>
Cdiff usage:
'SPACEBAR' - Advances the page of the current file.
'Q' - Quits current file, thus advancing you to the next file.
You now have side-by-side diff via git diff and difftool. And you have the cdiff python source code for power user customization should you need it.

- 29
- 3
This may be a somewhat limited solution, but does the job using the system's diff
command without external tools:
diff -y <(git show from-rev:the/file/path) <(git show to-rev:the/file/path)
- filter just the change lines use
--suppress-common-lines
(if yourdiff
supports the option). - no colors in this case, just the usual
diff
markers - can tweak the column width
--width=term-width
; in Bash can get the width as$COLUMNS
ortput cols
.
This can be wrapped into a helper git-script too for more convenience, for example, usage like this:
git diffy the/file/path --from rev1 --to rev2

- 21
- 2
Use delta
.
In your gitconfig file (usually ~/.gitconfig
or ~/.config/git/config
),
add:
[core]
pager = delta --light --side-by-side

- 2,639
- 2
- 18
- 30
There are a lot of good answers on this thread. My solution for this issue was to write a script.
Name this 'git-scriptname' (and make it executable and put it in your PATH, like any script), and you can invoke it like a normal git command by running
$ git scriptname
The actual functionality is just the last line. Here's the source:
#!/usr/bin/env zsh
#
# Show a side-by-side diff of a particular file how it currently exists between:
# * the file system
# * in HEAD (latest committed changes)
function usage() {
cat <<-HERE
USAGE
$(basename $1) <file>
Show a side-by-side diff of a particular file between the current versions:
* on the file system (latest edited changes)
* in HEAD (latest committed changes)
HERE
}
if [[ $# = 0 ]]; then
usage $0
exit
fi
file=$1
diff -y =(git show HEAD:$file) $file | pygmentize -g | less -R

- 2,836
- 1
- 20
- 26
There are multiple solutions:
Solution 1 : Meld :
Install meld (in ubuntu I used sudo apt install meld
). Then configure it like bellow.
git config --global diff.tool meld
git config --global difftool.meld.path "$(which meld)"
git config --global difftool.prompt false
git config --global merge.tool meld
git config --global mergetool.meld.path "$(which meld)"
Solution 2 : Delta :
If you decide to use cli, then install delta. The config I use is:
git config --global core.pager 'delta'
git config --global interactive.diffFilter 'delta --color-only'
git config --global delta.side-by-side true
git config --global delta.line-numbers true
git config --global delta.syntax-theme 'Solarized (dark)'
Solution 3 : Melt :
You can also use Melt. It's syntax highlighting is done with bat. This is also a cli tool.

- 11,636
- 6
- 52
- 87