T14: paths stay git's bytes until shown, so a name not in UTF-8 names its own file in status, stage, unstage and diff, and Files keys and opens each name by its bytes too; a copy is a new file whose source no unstage or diff touches; diffs run no text converter; an untracked diff git prints despite a warning stands, the warning logged, while a missing file still fails; a conflict diffs against HEAD, so a file we deleted reads as new; AGENTS.md says Files reads porcelain v2
CI / platforms (windows-latest) (push) Failing after 10s
CI / macos (push) Failing after 7m48s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-14 20:03:12 -04:00
1 parent e2966686bd
commit 911500c64e
6 files changed
+486 -237

No files matched your search

+30 -1
View File
@@ -49,7 +49,7 @@ fn folders_come_first_then_files_by_name_ignoring_case() {
let listed: Vec<_> = list(&root).expect("a listing");
let listed: Vec<_> = listed
.iter()
.map(|entry| (entry.name.as_str(), entry.folder))
.map(|entry| (entry.name.to_str().expect("a UTF-8 name"), entry.folder))
.collect();
assert_eq!(listed, expected);
assert!(list(&root.join("missing")).is_err());
@@ -161,6 +161,35 @@ fn names_with_newlines_label_on_one_line_and_keep_their_paths() {
assert_eq!(files.folder(&root, "r".into(), false), expected);
}
#[cfg(unix)]
#[test]
fn names_that_show_alike_keep_their_own_keys_and_paths() {
use std::{ffi::OsStr, os::unix::ffi::OsStrExt};
let root = PathBuf::from("/r");
let raw = OsStr::from_bytes(b"bad\xff.txt");
let (text, bytes) = (root.join("bad\u{FFFD}.txt"), root.join(raw));
let mut files = Files::new(root.clone());
let entry = |name: &OsStr| Entry {
name: name.into(),
folder: false,
};
let entries = vec![entry(OsStr::new("bad\u{FFFD}.txt")), entry(raw)];
files.listings.insert(root.clone(), Ok(entries));
assert_ne!(key(&text), key(&bytes), "two paths, two keys");
let expected = TreeNode::new(key(&root), "r")
.icon(IconName::Folder)
.children([
TreeNode::new(key(&text), "bad\u{FFFD}.txt").icon(IconName::File),
TreeNode::new(key(&bytes), "bad\u{FFFD}.txt").icon(IconName::File),
]);
assert_eq!(files.folder(&root, "r".into(), false), expected);
for path in [&root, &text, &bytes] {
let found = files.path(&key(path));
assert_eq!(found.as_ref(), Some(path), "{}", path.display());
}
assert_eq!(files.path("/r/gone"), None);
}
/// Runs git in `root` as a fixed author, unsigned.
#[cfg(target_os = "macos")]
fn run(root: &Path, args: &[&str]) {