Previously gitgutter could only diff the buffer against the index. This
change enables diffing against the working tree, which will be useful
for stashing.
This provides `g:gitgutter_hook_context` during the hook's execution and
removes the `:silent`, but uses `exists()` instead.
The bufnr might be necessary to know in the User autocommand, e.g. to
clear some cache.
Not using`:silent` is good practice in general to not hide (wanted)
output and errors etc.
This is to avoid side effects caused by switching to the buffer to be
written and back again.
It also means that the plugin can process any buffer without having to
make it the current buffer.
Using the lower level writefile() function means we have to deal with
line endings. It might also mean we have to deal with (file) encodings
but I hope not...
See #463, #466.
- Hunk stage/undo/preview no longer saves the buffer.
- Hunk undo no longer makes locations go out of sync.
- Grep can be opted out of (grep output with ansi escapes is number one cause
of issues).
- Replaced g:gitgutter_grep_command with g:gitgutter_grep.
- Always runs git-diff the same way instead of in two possible ways.
- Separated detection of git tracking from diffing.
- Simplified path handling.
- Removed support for xolox shell: Windows taskbar does not flash with async
jobs.
- Removed g:gitgutter_{eager,realtime}.
- Simplified implementation generally.
Before the plugin tries to diff a file, it checks whether git is
tracking the file. If git isn't tracking the file, it stops there and
doesn't display any signs. If git is tracking the file, the plugin
remembers so next time it can skip the check.
When I introduced asynchronous diffing for NeoVim (18b78361), I made a
refactoring mistake which caused the plugin on second and subsequent
runs [to always think git is tracking a file][1].
The non-realtime diffs – the ones you get when you save a buffer –
basically run `git diff FILE`. With an untracked file git returns
nothing and exits successfully. So although the plugin erroneously
thinks git is tracking the file, it gets an error-free, empty diff back
and so removes any and all signs. Which means that the bug doesn't make
any difference.
However the realtime diffs write the buffer's contents to a temporary
file, and write the file as staged in the index to a temporary file,
then run `git diff FILE1 FILE2`. To write the staged version of the
file we use `git show :FILE > TMPFILE`.
When `FILE` isn't known to git, `git show :FILE` exits with an error.
Unless, that is, [the filename contains square brackets and you're using
git v2.5.0+][2], in which case git exits successfully with empty output.
So if you're using git v2.5.0+, and you're editing an untracked file in
a repository, and the filename contains square brackets, the plugin will
think: git is tracking the file; the realtime diff is successful; the
file in the index is empty; so every line in the the working copy must
be an addition; hence a `+` sign on every line.
[1]: 18b7836168/autoload/gitgutter/diff.vim (L119-L121)
[2]: http://comments.gmane.org/gmane.comp.version-control.git/285686Closes#325.
"Undo" is a better name than "revert" because:
- "revert" sounds like it has something to do with `git-revert` but they
are entirely different;
- "undo" is consistent with vim's "undo": discarding changes and going
back to the original.
Maintain backwards compatibility and add deprecation warnings.
Closes#306.
Pass the git command to `jobstart()` as a string, not a list.
`jobstart()` does some kind of internal black magic to parse strings
like `'"/usr/bin/env bash" -l'`, whereas it would be impossible to pass
in an equivalent argument using a list.
Before, the value of `&shell` was being passed verbatim to `jobstart`
because no word splitting is done when the argument to `jobstart` is a
list. This would cause errors if the user's `&shell` were set to
something like `'/usr/local/bin/zsh -l'`.
This does not, however, fix another potential edge case, when the shell
command itself requires quoting (as per the example in the Neovim docs,
option E91). After doing some testing, it appears that `jobstart()` cannot
handle a quoted command, despite the recommendation in the manual (and
despite the fact that commands like `:terminal` work just fine with
double-quoted values for `&shell`). Whether this inconsistency is due to
a bug or something else, additional defensive action is probably needed.
For demonstration, try symlinking `/bin/bash` to `"./bad shell"`, and
inside Neovim setting `let &shell='"./bad shell"'. Everything works
fine, except `:call jobstart([&shell])` fails. Try various combinations
of quoting and calls to `jobstart()`, `split()`, and such: there seems
to be no way to get `jobstart()` to handle the quotes and spaces
properly without additional manipulation up-front.