mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2024-12-12 19:18:24 +02:00
Support .jj as well as .git
- Allow `.jj` dirs to count as vcs directories. - Simplify the control flow around resolving info/exclude
This commit is contained in:
parent
c9ebcbd8ab
commit
bb1f30f88e
@ -212,7 +212,7 @@ impl Ignore {
|
||||
igtmp.absolute_base = Some(absolute_base.clone());
|
||||
igtmp.has_git =
|
||||
if self.0.opts.require_git && self.0.opts.git_ignore {
|
||||
parent.join(".git").exists()
|
||||
parent.join(".git").exists() || parent.join(".jj").exists()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
@ -244,15 +244,6 @@ impl Ignore {
|
||||
|
||||
/// Like add_child, but takes a full path and returns an IgnoreInner.
|
||||
fn add_child_path(&self, dir: &Path) -> (IgnoreInner, Option<Error>) {
|
||||
let git_type = if self.0.opts.require_git
|
||||
&& (self.0.opts.git_ignore || self.0.opts.git_exclude)
|
||||
{
|
||||
dir.join(".git").metadata().ok().map(|md| md.file_type())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let has_git = git_type.map(|_| true).unwrap_or(false);
|
||||
|
||||
let mut errs = PartialErrorBuilder::default();
|
||||
let custom_ig_matcher = if self.0.custom_ignore_filenames.is_empty() {
|
||||
Gitignore::empty()
|
||||
@ -290,10 +281,28 @@ impl Ignore {
|
||||
errs.maybe_push(err);
|
||||
m
|
||||
};
|
||||
|
||||
let mut git_dir = dir.join(".git");
|
||||
let mut git_type: Option<FileType> = None;
|
||||
if self.0.opts.require_git {
|
||||
git_type = git_dir.metadata().ok().map(|md| md.file_type());
|
||||
if git_type.is_none() {
|
||||
let jj_internal_git_dir = dir.join(".jj/repo/store/git");
|
||||
let jj_type = jj_internal_git_dir
|
||||
.metadata()
|
||||
.ok()
|
||||
.map(|md| md.file_type());
|
||||
if jj_type.is_some() {
|
||||
git_dir = jj_internal_git_dir;
|
||||
git_type = jj_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let gi_exclude_matcher = if !self.0.opts.git_exclude {
|
||||
Gitignore::empty()
|
||||
} else {
|
||||
match resolve_git_commondir(dir, git_type) {
|
||||
match resolve_git_commondir(git_dir, git_type) {
|
||||
Ok(git_dir) => {
|
||||
let (m, err) = create_gitignore(
|
||||
&dir,
|
||||
@ -325,7 +334,7 @@ impl Ignore {
|
||||
git_global_matcher: self.0.git_global_matcher.clone(),
|
||||
git_ignore_matcher: gi_matcher,
|
||||
git_exclude_matcher: gi_exclude_matcher,
|
||||
has_git,
|
||||
has_git: git_type.is_some(),
|
||||
opts: self.0.opts,
|
||||
};
|
||||
(ig, errs.into_error_option())
|
||||
@ -829,24 +838,22 @@ pub(crate) fn create_gitignore<T: AsRef<OsStr>>(
|
||||
///
|
||||
/// Some I/O errors are ignored.
|
||||
fn resolve_git_commondir(
|
||||
dir: &Path,
|
||||
git_dir: PathBuf,
|
||||
git_type: Option<FileType>,
|
||||
) -> Result<PathBuf, Option<Error>> {
|
||||
let git_dir_path = || dir.join(".git");
|
||||
let git_dir = git_dir_path();
|
||||
if !git_type.map_or(false, |ft| ft.is_file()) {
|
||||
return Ok(git_dir);
|
||||
}
|
||||
let file = match File::open(git_dir) {
|
||||
let file = match File::open(&git_dir) {
|
||||
Ok(file) => io::BufReader::new(file),
|
||||
Err(err) => {
|
||||
return Err(Some(Error::Io(err).with_path(git_dir_path())));
|
||||
return Err(Some(Error::Io(err).with_path(git_dir)));
|
||||
}
|
||||
};
|
||||
let dot_git_line = match file.lines().next() {
|
||||
Some(Ok(line)) => line,
|
||||
Some(Err(err)) => {
|
||||
return Err(Some(Error::Io(err).with_path(git_dir_path())));
|
||||
return Err(Some(Error::Io(err).with_path(git_dir)));
|
||||
}
|
||||
None => return Err(None),
|
||||
};
|
||||
@ -943,6 +950,19 @@ mod tests {
|
||||
assert!(ig.matched("baz", false).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitignore_with_jj() {
|
||||
let td = tmpdir();
|
||||
mkdirp(td.path().join(".jj/repo/store/git"));
|
||||
wfile(td.path().join(".gitignore"), "foo\n!bar");
|
||||
|
||||
let (ig, err) = IgnoreBuilder::new().build().add_child(td.path());
|
||||
assert!(err.is_none());
|
||||
assert!(ig.matched("foo", false).is_ignore());
|
||||
assert!(ig.matched("bar", false).is_whitelist());
|
||||
assert!(ig.matched("baz", false).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gitignore_no_git() {
|
||||
let td = tmpdir();
|
||||
|
Loading…
Reference in New Issue
Block a user