24

I'm trying to use vimdiff+dirdiff.vim to diff inside Vim multiple files versionned with Git.

For Mercurial, it is possible with mercurial extdiff extension.

The only way I found on the web to integrate Vim with Git diff is to use vimdiff on a singe file, as describe in this post.

Does any one know how to use vimdiff+dirdiff+git?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user744629
  • 1,961
  • 1
  • 18
  • 27

4 Answers4

19

Before git version 1.7.11

git-diffall is what I need, thanks a lot. With help of this page about git difftool and this one about running vim+dirdiff from command line, I wrote my $HOME/.gitconfig as:

[diff]
  tool = default-difftool

[difftool "default-difftool"]
  cmd = vim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)' $LOCAL $REMOTE

[difftool]
  prompt = false

After putting git-diffall in my PATH, I can diff for example working directory with branch dev with:

git diffall dev

The --copy-back is also what I need if I want to modify the working directory persitantly from Vim:

git diffall --copy-back dev

Since git version 1.7.11

Since version 1.7.11, "git difftool" learned the "--dir-diff" option that simplify things and git-diffall is no longer needed.

.gitconfig contains:

[diff]
  tool = default-difftool
[difftool "default-difftool"]
  cmd = vim -f '+next' '+execute \"DirDiff\" argv(0) argv(1)' $LOCAL $REMOTE '+syntax off'

And diffing for example working directory with branch dev is done with:

git difftool -d dev
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
user744629
  • 1,961
  • 1
  • 18
  • 27
  • 1
    +1 for the `cmd`. Adding this comment instead of a new answer so maybe you could update this answer with the following information and accept it for future reference. As @VonC already noted, you can now use `git difftool -d` to diff the entire directory. Your `cmd` will launch you straight into vim's `DirDiff` where everything will work as expected. You **no longer** need `git-diffall`, and the `prompt=false` config line is not necessary when using `-d` with `git difftool`. – dev May 19 '14 at 19:08
  • Note: `git diffall` is being removed for git 2.0.X/2.1: see http://stackoverflow.com/a/24979228/6309 – VonC Jul 27 '14 at 08:28
6

Tim Pope's fugitive is the quintessential git plug-in for vim. It might not have dirdiff's functionality, but it does integrate git status output beautifully, with key mappings to easily navigate between modified files. Any files listed in your git status output can then easy be diffed with the D mapping, allowing you to customise the exact changes going into your changes.

Walter
  • 7,809
  • 1
  • 30
  • 30
3

It would be interesting to monitor the commits for the Vim module fugitive, because, starting with (git 1.7.11, June 2012), git now can diff directories (ie display all the files to be compared, before opening the difftool)

See "git difftool to give directory compare?"

So adding that feature to fugitive.vim would be an evolution from a file to file diff approach.

However, Zyx points out in the comment the limits of that approach:

All you need to get this working is:

  1. git diff --name-status and
  2. git cat-file,

nothing more (except for some vimscript code).
And, unlike git difftool, this works for any VCS with vcs diff and vcs cat-file support

Zyx mentions as an example of that file-byfile approach his project aurum:

My aurum has dirdiff-like functionality (AuVimDiff full opens a bunch of tabs with vimdiff view of files that have differences) and it never used any sort of difftool support.

(See script aurum / autoload / aurum / vimdiff.vim)

Zyx adds:

it cannot be a good guide for a person that wants to add this functionality to fugitive:
Actual git diff --name-status call is hidden inside the git driver in a function called by s:git.status accessed as repo.functions.status (because mercurial uses hg status -r rev1:rev2, not hg diff --name-status and I find this rather logical).
Thus you have to traverse three levels of abstraction here (repository interface, shell commands wrapper and only then actual git call).
It is faster to write everything from scratch

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • My [aurum](https://bitbucket.org/ZyX_I/aurum) has dirdiff-like functionality (`AuVimDiff full` opens a bunch of tabs with vimdiff view of files that have differences) and it never used any sort of difftool support. All you need to get this working is 1. `git diff --name-status` and 2. `git cat-file`, nothing more (except for some vimscript code). And, unlike `git difftool`, this works for *any* VCS with `vcs diff` and `vcs cat-file` support. – ZyX Jun 18 '12 at 17:27
  • And currently fugitive does not use difftool for anything. – ZyX Jun 18 '12 at 17:36
  • @ZyX: very interesting. I have included the reference to your m`aurum` project in the answer for more visibility. – VonC Jun 18 '12 at 19:47
  • I have to say that though the script you pointed out works, it cannot be a good guide for a person that wants to add this functionality to fugitive: actual `git diff --name-status` call is hidden inside the git driver in a function called by `s:git.status` accessed as `repo.functions.status` (because mercurial uses `hg status -r rev1:rev2`, not `hg diff --name-status` and I find this rather logical). Thus you have to traverse three levels of abstraction here (repository interface, shell commands wrapper and only then actual `git` call). It is faster to write everything from scratch. – ZyX Jun 19 '12 at 18:20
  • @ZyX understood. I have include your last comment in the answer in order to make that more visible. – VonC Jun 19 '12 at 20:42
2

Git does not support directory diffs directly, but it can be done with 3rd party extension.

Check out git diffall (disclosure: I wrote this script). This script works with the tool set by git config diff.tool <TOOL> to perform a true directory diff.

Also, see these related questions:

Community
  • 1
  • 1
Tim Henigan
  • 60,452
  • 11
  • 85
  • 78
  • Note: I see you finally removed that script: http://stackoverflow.com/a/24979228/6309 – VonC Jul 27 '14 at 08:35