-
-
Notifications
You must be signed in to change notification settings - Fork 344
/
Copy pathexclude.rs
69 lines (60 loc) · 2.14 KB
/
exclude.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use std::io;
use anyhow::{bail, Context};
use git_repository as git;
use git_repository::prelude::FindExt;
use crate::OutputFormat;
pub mod query {
use std::ffi::OsString;
use crate::OutputFormat;
pub struct Options {
pub format: OutputFormat,
pub overrides: Vec<OsString>,
pub show_ignore_patterns: bool,
}
}
pub fn query(
repo: git::Repository,
pathspecs: impl Iterator<Item = git::path::Spec>,
mut out: impl io::Write,
query::Options {
overrides,
format,
show_ignore_patterns,
}: query::Options,
) -> anyhow::Result<()> {
if format != OutputFormat::Human {
bail!("JSON output isn't implemented yet");
}
let worktree = repo
.worktree()
.with_context(|| "Cannot check excludes without a current worktree")?;
let index = worktree.index()?;
let mut cache = worktree.excludes(
&index,
Some(git::attrs::MatchGroup::<git::attrs::Ignore>::from_overrides(overrides)),
)?;
let prefix = repo.prefix().expect("worktree - we have an index by now")?;
for mut spec in pathspecs {
for path in spec.apply_prefix(&prefix).items() {
// TODO: what about paths that end in /? Pathspec might handle it, it's definitely something git considers
// even if the directory doesn't exist. Seems to work as long as these are kept in the spec.
let is_dir = git::path::from_bstr(path).metadata().ok().map(|m| m.is_dir());
let entry = cache.at_entry(path, is_dir, |oid, buf| repo.objects.find_blob(oid, buf))?;
let match_ = entry
.matching_exclude_pattern()
.and_then(|m| (show_ignore_patterns || !m.pattern.is_negative()).then(|| m));
match match_ {
Some(m) => writeln!(
out,
"{}:{}:{}\t{}",
m.source.map(|p| p.to_string_lossy()).unwrap_or_default(),
m.sequence_number,
m.pattern,
path
)?,
None => writeln!(out, "::\t{}", path)?,
}
}
}
Ok(())
}