From 4ab99abb97a36c5155768185384f28eb87c64a3b Mon Sep 17 00:00:00 2001 From: Stephen Albert-Moore Date: Wed, 17 Apr 2024 16:58:23 -0400 Subject: [PATCH] ignore/gitignore: Skip BOM at start of ignore file Match Git's behavior. Fixes #2177. --- crates/ignore/src/gitignore.rs | 6 ++++++ crates/ignore/tests/gitignore_skip_bom.gitignore | 2 ++ crates/ignore/tests/gitignore_skip_bom.rs | 14 ++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 crates/ignore/tests/gitignore_skip_bom.gitignore create mode 100644 crates/ignore/tests/gitignore_skip_bom.rs diff --git a/crates/ignore/src/gitignore.rs b/crates/ignore/src/gitignore.rs index 0b667f26..d065705a 100644 --- a/crates/ignore/src/gitignore.rs +++ b/crates/ignore/src/gitignore.rs @@ -401,6 +401,12 @@ impl GitignoreBuilder { break; } }; + + // Match Git's handling of .gitignore files that begin with the Unicode BOM + const UTF8_BOM: &str = "\u{feff}"; + let line = + if i == 0 { line.trim_start_matches(UTF8_BOM) } else { &line }; + if let Err(err) = self.add_line(Some(path.to_path_buf()), &line) { errs.push(err.tagged(path, lineno)); } diff --git a/crates/ignore/tests/gitignore_skip_bom.gitignore b/crates/ignore/tests/gitignore_skip_bom.gitignore new file mode 100644 index 00000000..a78c13a9 --- /dev/null +++ b/crates/ignore/tests/gitignore_skip_bom.gitignore @@ -0,0 +1,2 @@ +ignore/this/path +# This file begins with a BOM (U+FEFF) diff --git a/crates/ignore/tests/gitignore_skip_bom.rs b/crates/ignore/tests/gitignore_skip_bom.rs new file mode 100644 index 00000000..0e8cdefa --- /dev/null +++ b/crates/ignore/tests/gitignore_skip_bom.rs @@ -0,0 +1,14 @@ +use ignore::gitignore::GitignoreBuilder; + +const IGNORE_FILE: &'static str = "tests/gitignore_skip_bom.gitignore"; + +/// Skip a Byte-Order Mark (BOM) at the beginning of the file, matching Git's behavior. +#[test] +fn gitignore_skip_bom() { + let mut builder = GitignoreBuilder::new("ROOT"); + let error = builder.add(IGNORE_FILE); + assert!(error.is_none(), "failed to open gitignore file"); + let g = builder.build().unwrap(); + + assert!(g.matched("ignore/this/path", false).is_ignore()); +}