airblade/vim-gitgutter

`let g:gitgutter_diff_args='--cached'` Isn't Working

compese opened this issue · 4 comments

What is the latest commit SHA in your installed vim-gitgutter?
$ pacman -Q vim-gitgutter
vim-gitgutter 768.256702d-1

What vim/nvim version are you on?
NVIM v0.9.1

Doing let g:gitgutter_diff_args='--cached' never shows any changes for me.
I tested with stashed changes i.e. git add -u and confirmed with git diff --cached
Also confirmed that let g:gitgutter_diff_args=-w worked as expected

Related: #252

...great plugin, thanks!

The plugin shows the difference between what's in your buffer and the index or a specific commit.

git diff --cached shows the difference between the index and a specific commit (defaulting to the latest).

So whatever the output of git diff --cached, it's not clear to me how to show its signs in the buffer because the buffer generally doesn't match the index.

As an aside, there have been 52 commits since your installed version.

Thanks, that makes sense. For now I'm using a mapping to toggle let g:gitgutter_diff_base='HEAD' which is useful in its own right.

However it would be nice to get some sort of (optional) visualization for staged changes. As you pointed out to me above, this is non-trivial so I'm just starting to think out loud about it now.

The main difficulty is that we're dealing with a 3 states: the working file (what is seen in the editor), and the index and HEAD which are not seen in the editor. (Note that if you use the technique shown here to view the 3 possible types of changes when you have differing HEAD/index/work, fugitive will open temp files for index and head--which isn't an option for gitgutter)

My initial thought would be to have 2 new modes:

  1. Extra symbol categories when diffing against HEAD i.e. something like adding g:gitgutter_sign_added_index, g:gitgutter_sign_removed_index, and g:gitgutter_sign_modified_index. Policy would be to use an *_index sign any time there are modifications to a line in both working file and the index. To make things simple(-ish), gitgutter_sign_modified_index would be used any time the type of change between work and index is different than the type of change between index and head for a given line (or hunk) (e.g. changed in one but just added in another).
  2. A mode that just ignores any work/index changes and only shows head/index changes in the working file somehow.

I realize this could be pretty tricky and my ideas here are only half-baked. They could prove to be logically inconsistent when actually implementing or thinking more deeply about this feature. Some type of 3-way diff logic would probably need to be implemented (again, not trivial). Obviously it's up to you if you want to leave this open as a starting point for a new feature (stretch-goal) or to close it as a non-goal.

...any time there are modifications to a line in both working file and the index.

This would require running git diff twice (with different arguments, obviously), which means a longer delay until the signs can be updated. Typically calling out to an external command is the slowest part of the whole process. Also with two diffs to consider at the same time, the code would have to diff the diffs to figure out the signs. This complicates the code and also makes the signs harder for the user to understand.

...only shows head/index changes in the working file somehow.

This can't be done in the general case. You can diff two things but how can you project the result on to a third thing? I know that most of the time the third thing will be very similar to one of those two things, but that's not really enough.

Instead I think it would require opening the staged version of the file in a new buffer. Then you can have signs showing its difference from HEAD. Again, though, it makes both the code and the UI more complicated.

All in all, I don't think the benefit justifies the complexity so I'm not going to pursue it.