Since we start all external commands by cd'ing to the current file's
directory, we can use the file's name instead of its full path.
The exception is `git show :FILE` where we must use a path relative to
the repo root for maximum git compatibility. It turns out `git
rev-parse` takes a `--show-prefix` argument which makes our relative
path calculation far simpler.
Minimising files paths has these benefits:
- Easier to inspect the generated commands.
- Less opportunity for escaping problems.
- Eliminates possible mismatches betwen absolute paths generated by git
and absolute paths generated by Vim (crops up with msys/msys2 on
Windows).
Thanks to @suxpert for helping with this.
While I can't say I fully understand escaping rules for Windows, I
understand them better now than I did when I copied that code from
another plugin and hoped for the best.
As far as I can tell, this escaping code was written to be used when
manually constructing a system command to execute – which isn't how this
plugin is written. So this code shouldn't be here.
More recent versions of git support paths relative to current directory.
But for maximum compatibility we need to use paths relative to the
file's repo's root.
While it is aesthetically nicer to discard the unused output from `git
ls-files`, it isn't necessary. Discarding requires a shell redirection
which exposes us to vim's shell quirks; it's not worth it.
This bug meant that a realtime diff of a buffer which wasn't the current
one -- which happens during GitGutterAll() -- diffed the staged version
of the buffer against the current buffer's contents instead of the
buffer's contents.
This avoids shelling out twice per buffer: once to check whether git
knows about the file and once to perform the diff. Now we simply do
both in one external call.
Profiling showed external calls to git taking ~20ms. This doesn't seem
too bad but it adds up.