Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into feat-git-path-env-var
Browse files Browse the repository at this point in the history
  • Loading branch information
gthb committed Jul 21, 2024
2 parents 46e835b + 78650c3 commit 973cc5f
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 46 deletions.
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
## 0.59 (unreleased)
## 0.60 (unreleased)

### Display

Fixed an issue where files with no common content would show duplicate
hunks.

Fixed a performance issue when files had extremely long lines
(e.g. 100,000+ characters).

## 0.59 (released 20th July 2024)

### Diffing

Fixed crash on some textual files where a single change contained more than
1,000 words.

### Parsing

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description = "A structural diff that understands syntax."
repository = "https://github.com/wilfred/difftastic"
homepage = "http://difftastic.wilfred.me.uk/"
license = "MIT"
version = "0.59.0"
version = "0.60.0"
authors = ["Wilfred Hughes <[email protected]>"]
keywords = ["diff", "syntax"]
categories = ["development-tools", "command-line-utilities", "parser-implementations"]
Expand Down Expand Up @@ -94,7 +94,7 @@ pretty_assertions = "1.3.0"
[build-dependencies]
# TODO: enable parallel mode once MSRV hits 1.61, see discussion in
# https://github.com/rust-lang/cc-rs/pull/849
cc = "1.0.83"
cc = "1.1.5"
rayon = "1.7.0"
version_check = "0.9.4"

Expand Down
2 changes: 1 addition & 1 deletion manual/src/profiling.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ If you have a file that's particularly slow, you can use
which functions are slow.

```
$ CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph --bin difft sample_files/slow_1.rs sample_files/slow_2.rs
$ CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph --bin difft -- sample_files/slow_1.rs sample_files/slow_2.rs
```

It's also worth looking at memory usage, as graph traversal bugs can
Expand Down
1 change: 1 addition & 0 deletions sample_files/all_changed_1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a
1 change: 1 addition & 0 deletions sample_files/all_changed_2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
b
7 changes: 7 additions & 0 deletions sample_files/big_text_hunk_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/streadway/amqp v0.0.0-20160311215503-2e25825abdbd h1:625/bJvSNfQrzzK5ttnUqMqnVe8M5MILmf5ZRGgeeDY=
github.com/streadway/amqp v0.0.0-20160311215503-2e25825abdbd/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
49 changes: 49 additions & 0 deletions sample_files/big_text_hunk_2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/streadway/amqp v0.0.0-20160311215503-2e25825abdbd h1:625/bJvSNfQrzzK5ttnUqMqnVe8M5MILmf5ZRGgeeDY=
github.com/streadway/amqp v0.0.0-20160311215503-2e25825abdbd/go.mod h1:1WNBiOZtZQLpVAyu0iTduoJL9hEsMloAK5XWrtW0xdY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
14 changes: 10 additions & 4 deletions sample_files/compare.expected
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ sample_files/added_line_1.txt sample_files/added_line_2.txt
sample_files/align_footer_1.txt sample_files/align_footer_2.txt
d640bd2de31e56a39f0efb92aff0f379 -

sample_files/all_changed_1.js sample_files/all_changed_2.js
40eb536d8b626e27ae227a090fb05f25 -

sample_files/apex_1.cls sample_files/apex_2.cls
8e477350907734ac4d5201752523dff3 -

Expand All @@ -19,6 +22,9 @@ sample_files/b2_math_1.h sample_files/b2_math_2.h
sample_files/bad_combine_1.rs sample_files/bad_combine_2.rs
f5051bf7d2b8afa3a677388cbd458891 -

sample_files/big_text_hunk_1.txt sample_files/big_text_hunk_2.txt
fd0c8912c094097f82c6b29ae66fb912 -

sample_files/change_outer_1.el sample_files/change_outer_2.el
2b9334a4cc72da63bba28eff958f0038 -

Expand Down Expand Up @@ -131,7 +137,7 @@ sample_files/load_1.js sample_files/load_2.js
22365043359164f717d495336d86b996 -

sample_files/long_line_1.txt sample_files/long_line_2.txt
40e22d364bb714421eec24b8ef808f01 -
7fc50bd547f0c20fda89a1931e5eb61e -

sample_files/lua_1.lua sample_files/lua_2.lua
8318115b642361955346cc620bc3ad86 -
Expand All @@ -140,7 +146,7 @@ sample_files/makefile_1.mk sample_files/makefile_2.mk
d0572210b5121ce68ac0ce45e43b922b -

sample_files/many_newlines_1.txt sample_files/many_newlines_2.txt
615de4b145b7b161e4fb285728280ed1 -
52ca05855e520876479e6f608c5e7831 -

sample_files/metadata_1.clj sample_files/metadata_2.clj
4b58ce366467c8cca46db53508e81323 -
Expand Down Expand Up @@ -224,7 +230,7 @@ sample_files/simple_1.scss sample_files/simple_2.scss
265261e79df78abfc09392d72a0273d8 -

sample_files/simple_1.txt sample_files/simple_2.txt
416d05b8a02e41cb70b78d28cd3153d9 -
6fd97a544afd0a3be7eebba75f82f696 -

sample_files/slider_1.rs sample_files/slider_2.rs
d10128f3d9ffc4a8670f417a9371bacc -
Expand Down Expand Up @@ -293,5 +299,5 @@ sample_files/yaml_1.yaml sample_files/yaml_2.yaml
f068239fc7bade0e6de96d81136c1ac5 -

sample_files/zig_1.zig sample_files/zig_2.zig
4516796003b81f35bfa57d84bb7c0cbe -
e36d1ea126b8b68e3344434bb63f205e -

18 changes: 12 additions & 6 deletions src/display/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
use crate::{
constants::Side,
display::context::{calculate_after_context, calculate_before_context, opposite_positions},
display::hunks::Hunk,
display::style::{self, apply_colors, apply_line_number_color},
lines::{format_line_num, MaxLine},
display::{
context::{calculate_after_context, calculate_before_context, opposite_positions},
hunks::Hunk,
style::{self, apply_colors, apply_line_number_color},
},
lines::{format_line_num, split_on_newlines, MaxLine},
options::DisplayOptions,
parse::syntax::MatchedPos,
summary::FileFormat,
Expand Down Expand Up @@ -43,8 +45,12 @@ pub(crate) fn print(
)
} else {
(
lhs_src.lines().map(|s| format!("{}\n", s)).collect(),
rhs_src.lines().map(|s| format!("{}\n", s)).collect(),
split_on_newlines(lhs_src)
.map(|s| format!("{}\n", s))
.collect(),
split_on_newlines(rhs_src)
.map(|s| format!("{}\n", s))
.collect(),
)
};

Expand Down
39 changes: 29 additions & 10 deletions src/display/side_by_side.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ use owo_colors::{OwoColorize, Style};

use crate::{
constants::Side,
display::context::all_matched_lines_filled,
display::hunks::{matched_lines_indexes_for_hunk, Hunk},
display::style::{
self, apply_colors, apply_line_number_color, color_positions, novel_style, replace_tabs,
split_and_apply, BackgroundColor,
display::{
context::all_matched_lines_filled,
hunks::{matched_lines_indexes_for_hunk, Hunk},
style::{
self, apply_colors, apply_line_number_color, color_positions, novel_style,
replace_tabs, split_and_apply, BackgroundColor,
},
},
hash::DftHashMap,
lines::format_line_num,
lines::{format_line_num, split_on_newlines},
options::{DisplayMode, DisplayOptions},
parse::syntax::{zip_pad_shorter, MatchedPos},
summary::FileFormat,
Expand Down Expand Up @@ -338,8 +340,12 @@ pub(crate) fn print(
)
} else {
(
lhs_src.lines().map(|s| format!("{}\n", s)).collect(),
rhs_src.lines().map(|s| format!("{}\n", s)).collect(),
split_on_newlines(lhs_src)
.map(|s| format!("{}\n", s))
.collect(),
split_on_newlines(rhs_src)
.map(|s| format!("{}\n", s))
.collect(),
)
};

Expand Down Expand Up @@ -401,8 +407,21 @@ pub(crate) fn print(
let mut prev_lhs_line_num = None;
let mut prev_rhs_line_num = None;

let lhs_lines = lhs_src.lines().collect::<Vec<_>>();
let rhs_lines = rhs_src.lines().collect::<Vec<_>>();
let mut lhs_lines = split_on_newlines(lhs_src).collect::<Vec<_>>();
let mut rhs_lines = split_on_newlines(rhs_src).collect::<Vec<_>>();

// If "foo" is one line, is "foo\n" two lines? Generally we want
// to care about newlines when deciding whether content differs.
//
// Ending a file with a trailing newline is extremely common
// though. If both files have a trailing newline, consider "foo\n"
// to be "foo" so we don't end up displaying a blank line on both
// sides.
if lhs_lines.last() == Some(&"") && rhs_lines.last() == Some(&"") {
lhs_lines.pop();
rhs_lines.pop();
}

let matched_lines = all_matched_lines_filled(lhs_mps, rhs_mps, &lhs_lines, &rhs_lines);
let mut matched_lines_to_print = &matched_lines[..];

Expand Down
17 changes: 15 additions & 2 deletions src/display/style.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use line_numbers::SingleLineSpan;
use owo_colors::{OwoColorize, Style};
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};

use crate::lines::split_on_newlines;
use crate::parse::syntax::StringKind;
use crate::{
constants::Side,
Expand Down Expand Up @@ -91,7 +92,19 @@ fn split_string_by_width(s: &str, max_width: usize, tab_width: usize) -> Vec<(&s
let mut parts: Vec<(&str, usize)> = vec![];
let mut s = s;

while width_respecting_tabs(s, tab_width) > max_width {
// Optimisation: width_respecting_tabs() walks the whole string,
// which is slow when we have files with massive lines.
//
// A single character (grapheme) in UTF-8 can be 1, 2, 3 or 4
// bytes. A character's display width can be 0 (control
// characters), 1 (the typical case), 2 (e.g. fullwidth characters
// in Chinese, Japanese and Korean) or 4 (the default width for
// tabs in difftastic).
//
// Ignoring control characters, this means an n-byte UTF-8 string
// has a display width of at least n/4 characters. Check that case
// first, because it's a cheap conservative calculation.
while s.len() / 4 > max_width || width_respecting_tabs(s, tab_width) > max_width {
let offset = byte_offset_for_width(s, max_width, tab_width);

let part = substring_by_byte(s, 0, offset);
Expand Down Expand Up @@ -401,7 +414,7 @@ pub(crate) fn apply_colors(
positions: &[MatchedPos],
) -> Vec<String> {
let styles = color_positions(side, background, syntax_highlight, file_format, positions);
let lines = s.lines().collect::<Vec<_>>();
let lines = split_on_newlines(s).collect::<Vec<_>>();
style_lines(&lines, &styles)
}

Expand Down
Loading

0 comments on commit 973cc5f

Please sign in to comment.