prati0100 / git-gui

Tcl/Tk based UI for Git. I am currently acting as the project's maintainer.
161 stars 87 forks source link

Visualization of intraline differences #31

Open annulen opened 4 years ago

annulen commented 4 years ago

Many IDEs and diff tools not only colorize - and + lines, but also highlight parts of respective which were actually changed, so that common parts can be more visible in complex diffs. For example, see https://gist.github.com/annulen/884b116d229f04b4e7db8fa6d018e865, which contains screenshot and textual diff which could be used as a testcase. It would be great if such highlighting was available in git-gui.

I think this feature could be implemented in one of following ways:

cc @ashkulz

prati0100 commented 4 years ago

Hi @annulen,

I think the feature would be a nice addition, though we might want look into making it optional if some people don't like this style of diffs.

  • Parse output of git diff --word-diff=porcelain. However it also needs a different regex to find "word" boundaries to provide more useful output (like tools on screenshots)

  • Parse output of external highlighter which uses ASCII escape codes. There is such highlighter included with git itself - diff-highlight, however it's very basic and cannot handle cases when number of added and removed lines is different (like in my example). Much more robust tool is diffr. In theory it should be to port more advanced highlighting algorithm to perl and replace diff-highlight in mainline git.

I would prefer to not add any dependency that is not in the Git core. So, if diff-highlight ships by default with Git then we can look into using it. Otherwise I'd prefer to use --word-diff.

Either way, I have very limited bandwidth so I don't think I will be able to take this on in the near future. But I am happy to review, so patches are welcome.

annulen commented 4 years ago

I think the feature would be a nice addition, though we might want look into making it optional if some people don't like this style of diffs.

Of course.

I would prefer to not add any dependency that is not in the Git core. So, if diff-highlight ships by default with Git then we can look into using it.

As I pointed out above, diff-highlight currently doesn't produce satisfactory results. Also, I didn't mean that git-gui should rely on external tool - instead, it could be parsing output of "diff filter" command which user can customize, probably defaulting to diff-highlight.

So, how do you think, which way is the most perspective?

Either way, I have very limited bandwidth so I don't think I will be able to take this on in the near future. But I am happy to review, so patches are welcome.

Unfortunately I don't have bandwidth for it either, however I can provide some funding if that can help anything.

j6t commented 4 years ago

Otherwise I'd prefer to use --word-diff.

Please don't. When I operate git-gui, it is of utmost importance for me to see exact results. --word-diff does not provide exact results; it collapses white-space changes and so loses information. I need to know whether a change adds blanks or removes some.

If the feature is implemented, it must be done by post-processing the standard diff in such a way that only color is added to (or removed from) the display, but nothing else is changed.

ashkulz commented 4 years ago

Yeah, I implemented something like that for gitk in ashkulz/git@4ac92e8e82c23c9080a72ae25f1ee4215a57b94e but it's lossy. Either you need parse the ANSI escape sequences (after forcing them to generate) or try to get better output from git diff (via a new format?) -- neither of which was an easy task, so kind of abandoned it for now.

annulen commented 4 years ago

Yeah, collapsing whitespaces is totally unacceptable.

Either you need parse the ANSI escape sequences (after forcing them to generate) or try to get better output from git diff (via a new format?) -- neither of which was an easy task

Well, parsing output of diff-highlight is quite easy - by default it just marks boundaries of changed parts with [7m and [27m. On the other hand, output of diffr is much less parser-friendly, though with color spec [1] it's possible to assume that all changed parts are wrapped between [4m and [0m

[1] diffr --colors added:none --colors removed:none --colors refine-added:underline:nobold:background:none --colors refine-removed:underline:nobold:background:none

asmwarrior commented 3 years ago

I personally think parsing output of diff-highlight result could be easier, and there are many third part of command line tools which can generate ANSI escape sequenced based result, such as dandavison/delta: A viewer for git and diff output.

asmwarrior commented 3 years ago

Can we use some control which supports ANSI escape sequence? For example, Tk::TextANSIColor - Tk::Text widget with support for ANSI color escape codes - metacpan.org.

Thanks.

asmwarrior commented 3 years ago

Some more information:

There is a git gui client project named gitahead, which is QT based and implemented in C++. I just see that it compares some added or remove lines, see the code below:

https://github.com/gitahead/gitahead/blob/bb747caef098140d9674990b1d79d096d1eac8df/src/ui/DiffView.cpp#L1323-L1371

It just split a line to different words(tokens), and then compare token by token, then mark the mismatched tokens in different code styles.

vlsi commented 2 years ago

I think it would be great to decouple coloring from git gui into a separate colorer like https://github.com/dandavison/delta, https://github.com/Wilfred/difftastic, and so on.

It looks like currently "added vs removed" is deeply coded into gui, and implementing syntax highlighting (e.g. C, Java, Kotlin, Dockerfile, JavaScript, ... in TCL would not scale well)

The diff with syntax highlighting is often much easier to understand.