Skip to content

Commit

Permalink
Support .jj as well as .git
Browse files Browse the repository at this point in the history
- Allow `.jj` dirs to count as vcs directories.
- Simplify the control flow around resolving info/exclude
  • Loading branch information
fowles committed Jun 22, 2024
1 parent c9ebcbd commit 879eb17
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions crates/ignore/src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -290,10 +281,17 @@ impl Ignore {
errs.maybe_push(err);
m
};

let gi_exclude_matcher = if !self.0.opts.git_exclude {
Gitignore::empty()
} else {
match resolve_git_commondir(dir, git_type) {
let git_dir = dir.join(".git");
let git_type = if self.0.opts.require_git {
git_dir.metadata().ok().map(|md| md.file_type())
} else {
None
};
match resolve_git_commondir(git_dir, git_type) {
Ok(git_dir) => {
let (m, err) = create_gitignore(
&dir,
Expand Down Expand Up @@ -325,7 +323,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: dir.join(".git").exists() || dir.join(".jj").exists(),
opts: self.0.opts,
};
(ig, errs.into_error_option())
Expand Down Expand Up @@ -829,24 +827,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),
};
Expand Down Expand Up @@ -943,6 +939,19 @@ mod tests {
assert!(ig.matched("baz", false).is_none());
}

#[test]
fn gitignore_with_jj() {
let td = tmpdir();
mkdirp(td.path().join(".jj"));
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();
Expand Down

0 comments on commit 879eb17

Please sign in to comment.