Skip to content

Commit

Permalink
Handle quoted file paths in hunk headers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
th1000s committed Sep 2, 2024
1 parent 218af16 commit 2d1cb20
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/handlers/diff_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,23 +374,25 @@ 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
// diff·--git·a/a·b·b/c·d␊
// 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(
Expand Down Expand Up @@ -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 = "\
Expand Down

0 comments on commit 2d1cb20

Please sign in to comment.