1use std::collections::BTreeSet;
8use std::path::PathBuf;
9
10pub fn git_diffed(in_git_hook: bool) -> anyhow::Result<Vec<PathBuf>> {
13 let sh = xshell::Shell::new()?;
14
15 let files = xshell::cmd!(sh, "git diff --diff-filter MAR --name-only")
16 .output()?
17 .stdout;
18 let files_cached = xshell::cmd!(sh, "git diff --diff-filter MAR --name-only --cached")
19 .output()?
20 .stdout;
21
22 let files = String::from_utf8_lossy(&files);
23 let files_cached = String::from_utf8_lossy(&files_cached);
24
25 let files: Box<dyn Iterator<Item = _>> = if in_git_hook {
27 Box::new(files_cached.lines())
28 } else {
29 Box::new(files_cached.lines().chain(files.lines()))
30 };
31
32 let mut all_files = files.map(PathBuf::from).collect::<Vec<_>>();
33
34 all_files.sort();
35 all_files.dedup();
36 Ok(all_files)
37}
38
39pub fn git_ls_files() -> anyhow::Result<Vec<PathBuf>> {
42 let sh = xshell::Shell::new()?;
43
44 macro_rules! as_set {
45 ($cmd:literal) => {{
46 let output = xshell::cmd!(sh, $cmd).output()?.stdout;
47 let output = String::from_utf8_lossy(&output).to_string();
48 output
49 .split('\n')
50 .map(PathBuf::from)
51 .collect::<BTreeSet<_>>()
52 }};
53 }
54
55 let all = as_set!("git ls-files");
57 let extra = as_set!("git ls-files --others --exclude-standard");
58 let deleted = as_set!("git ls-files --deleted");
59
60 let mut allow_list = all;
61 allow_list.extend(extra);
62 allow_list = allow_list.difference(&deleted).cloned().collect();
63
64 Ok(allow_list.into_iter().collect())
66}