altsem / gitu

A TUI Git client inspired by Magit
MIT License
1.65k stars 86 forks source link

[Bug] incorrect diff if file uses CRLF line endings #162

Closed rzikm closed 1 month ago

rzikm commented 2 months ago

On Windows

gitu - shows changes on every single line: image

git: image

altsem commented 2 months ago

From what I could conclude occurs when the line-ending was changed from/to crlf/lf. I suppose here the \r is highlighted as removed/added (though it's invisible).

#[test]
fn crlf_diff() {
    let ctx = TestContext::setup_init();
    commit(ctx.dir.path(), "clrf.txt", "unchanged\r\nunchanged\r\n");
    fs::write(ctx.dir.child("clrf.txt"), "unchanged\nunchanged\n").unwrap();

    snapshot!(ctx, "jj<tab>");
}
          0 │+ On branch main                                                                 |
          1 │+                                                                                |
          2 │+ Unstaged changes (1)                                                           |
          3 │+▌modified   clrf.txt                                                            |
          4 │+▌@@ -1,2 +1,2 @@                                                                |
          5 │+▌-unchanged                                                                     |
          6 │+▌-unchanged                                                                     |
          7 │+▌+unchanged                                                                     |
          8 │+▌+unchanged                                                                     |
          9 │+                                                                                |

Not sure if this is the scenario you had @rzikm. I was not able to reproduce the behaviour. Either:

I ran this on latest master: gitu v0.19.2-10-g7662832-modified

bshashank commented 2 months ago

I too tried gitu recently and hit this bug. One thing to mention is that you can only reproduce the issue when autocrlf is turned on:

$ git config --local core.autocrlf
true

Or you have setup .gitattributes to do the equivalent. (more context)

That's when the git diff is much smaller than gitu. Since git will convert all the \r\n to \n when writing back to object directory.

I think the only way to solve for this to read these configs from git (via local/global configs and the .gitattributes file) and ignore \r differences if autoclrf is true or input.

I saw elsewhere that we want to use gitoxide as the git layer, which provides this conversion. But that change would also probably require changing from the similar diff library to using imara-diff

altsem commented 2 months ago

That's great input @bshashank, ty!

I've been thinking of pulling in Imara-diff instead and/or using Gitoxide. It should be easier now ever since a large chunk of the inline diffing was re-written to no rely so much on Similar. However, there might be an easy fix before moving there.