diff options
| author | Thomas Otto <th1000s@posteo.net> | 2024-09-02 23:12:19 +0200 |
|---|---|---|
| committer | Thomas Otto <th1000s@posteo.net> | 2024-09-02 23:26:56 +0200 |
| commit | 2d1cb201ab1e3c6ebd8f5a6e9209ec5bdcb4d39a (patch) | |
| tree | 9c56b73a76572f210fe3858673e04c5cafe44d13 /src | |
| parent | 218af1617f512b06bb1a7f52a15510fe56c5de80 (diff) | |
Handle quoted file paths in hunk headers
When core.quotepath is true (the default) then non-ASCII chars
in a file name are quoted. These quotes hide the DIFF_PREFIXES and
"a/1" "b/1" remains as such, instead of becoming "1" "1".
This was interpreted by delta as renamed file. Now these quotes are
removed before the DIFF_PREFIXES are searched.
Diffstat (limited to 'src')
| -rw-r--r-- | src/handlers/diff_header.rs | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/handlers/diff_header.rs b/src/handlers/diff_header.rs index fed5152..99da998 100644 --- a/src/handlers/diff_header.rs +++ b/src/handlers/diff_header.rs @@ -374,7 +374,11 @@ fn remove_surrounding_quotes(path: &str) -> &str { } } -fn _parse_file_path(s: &str, git_diff_name: bool) -> String { +fn _parse_file_path(path: &str, git_diff_name: bool) -> String { + // When git config 'core.quotepath = true' (the default), and `path` contains + // non-ASCII characters, a backslash, or a quote; then it is quoted, so remove + // these quotes. Characters may also be escaped, but these are left as-is. + let path = remove_surrounding_quotes(path); // It appears that, if the file name contains a space, git appends a tab // character in the diff metadata lines, e.g. // $ git diff --no-index "a b" "c d" | cat -A @@ -382,15 +386,13 @@ fn _parse_file_path(s: &str, git_diff_name: bool) -> String { // index·d00491f..0cfbf08·100644␊ // ---·a/a·b├──┤␊ // +++·b/c·d├──┤␊ - let path = match s.strip_suffix('\t').unwrap_or(s) { + match path.strip_suffix('\t').unwrap_or(path) { "/dev/null" => "/dev/null", path if git_diff_name && DIFF_PREFIXES.iter().any(|s| path.starts_with(s)) => &path[2..], path if git_diff_name => path, path => path.split('\t').next().unwrap_or(""), - }; - // When a path contains non-ASCII characters, a backslash, or a quote then it is quoted, - // so remove these quotes. Characters may also be escaped, but these are left as-is. - remove_surrounding_quotes(path).to_string() + } + .to_string() } pub fn get_file_change_description_from_file_paths( @@ -638,6 +640,10 @@ mod tests { "diff --git a/.config/Code - Insiders/User/settings.json b/.config/Code - Insiders/User/settings.json"), Some(".config/Code - Insiders/User/settings.json".to_string()) ); + assert_eq!( + get_repeated_file_path_from_diff_line(r#"diff --git "a/quoted" "b/quoted""#), + Some("quoted".to_string()) + ); } pub const BIN_AND_TXT_FILE_ADDED: &str = "\ |
