tig
tig copied to clipboard
vimdiff-like Diff View
It would be cool to have a vimdiff-like diff view.
it would be nice to enable plugins like git itself. http://jeetworks.org/node/90
I do something similar to this already with this tig binding in my git config:
[tig "bind"]
generic = D !git difftool --tool=vimdiff --no-prompt %(commit)^ %(commit)
It just compares to previous commit but works for me most of the time.
Great idea. A slight improvement is:
[tig "bind"]
generic = D !git difftool --tool=vimdiff --no-prompt --trust-exit-code %(commit)^!
The --trust-exit-code option is useful when you are viewing a diff with lots of files and you want to quit part of the way through: just exit vim with :cq (instead of the normal :qa), and it will return an error code, triggering git difftool to exit without showing any more files.
Note the commit^! is explained in gitrevisions(1) as basically a range containing the single commit.
This seems like just about the only thing missing from tig
. Specifically, Vim's side-by-side diff functionality is very helpful.
Here's a sketch I threw together to show how a vim undo tree plugin could make use of a vertical diff compare, and I imagine it's pretty similar to how tig
could use it as well. The main difference is that you wouldn't have the right half that shows the current commit's file, you'd only show the history tree and a side by side diff of the currently selected commit under it.

@dustymabe @GarySmith but this bind can only work for committed changes, how can I compare unstaged changes?
@dustymabe @GarySmith but this bind can only work for committed changes, how can I compare unstaged changes?
for that I just run git difftool
instead of tig
@dustymabe make sense then :)
I have the following bindings in my .tigrc which cover commited, staged and unstaged changes:
bind diff D >git difftool --tool=vimdiff --trust-exit-code --no-prompt %(commit)^! -- %(file)
bind stage D >sh -c "git difftool --tool=vimdiff --trust-exit-code --no-prompt `expr '%(status)' : 'Staged changes' >/dev/null && echo --cached` -- '%(file)'"
If the diff is simple enough, I view it from tig, if it requires more attention, I just press D from the diff view or the stage view to open vimdiff on the particular file.
I use delta to view diffs outside of tig
.
I have these bindings to view unified or split diff:
# View diffs using `delta`
bind diff D >sh -c "git show %(commit) | delta --paging always"
bind diff S >sh -c "git show %(commit) | delta --paging always --side-by-side"
bind stage D >sh -c "git diff HEAD -- %(file) | delta --paging always"
bind stage S >sh -c "git diff HEAD -- %(file) | delta --paging always --side-by-side"
bind status D >sh -c "git diff HEAD -- %(file) | delta --paging always"
bind status S >sh -c "git diff HEAD -- %(file) | delta --paging always --side-by-side"
(I've set delta
as the git
pager, but the "alway use paging" flag is not propagated correctly in my setup, so I have to pipe it explicitly to delta
to not have less
exit if the output is less than a screen in height. 🤷 )