diff --git a/crates/bashkit/src/builtins/rg/mod.rs b/crates/bashkit/src/builtins/rg/mod.rs index fa47b0ab7..29629b48c 100644 --- a/crates/bashkit/src/builtins/rg/mod.rs +++ b/crates/bashkit/src/builtins/rg/mod.rs @@ -1705,6 +1705,10 @@ fn glob_to_regex(pattern: &str) -> String { let mut i = 0; while i < chars.len() { match chars[i] { + '*' if i + 2 < chars.len() && chars[i + 1] == '*' && chars[i + 2] == '/' => { + out.push_str("(?:.*/)?"); + i += 3; + } '*' if i + 1 < chars.len() && chars[i + 1] == '*' => { out.push_str(".*"); i += 2; @@ -4950,6 +4954,12 @@ mod tests { ("/proj/x.txt", b"needle\n"), ]; + const DIFF_GLOB_GLOBSTAR_FILES: &[(&str, &[u8])] = &[ + ("/proj/foo.txt", b"needle\n"), + ("/proj/dir/foo.txt", b"needle\n"), + ("/proj/dir/bar.txt", b"needle\n"), + ]; + const DIFF_COMMON_TYPE_FILES: &[(&str, &[u8])] = &[ ("/proj/data.csv", b"needle\n"), ("/proj/Dockerfile", b"needle\n"), @@ -5371,6 +5381,14 @@ mod tests { cwd: "/", output: RgDiffOutput::UnorderedLines, }, + RgDiffCase { + name: "globstar slash matches zero or more directories", + args: &["--files", "-g", "**/foo.txt", "."], + stdin: None, + files: DIFF_GLOB_GLOBSTAR_FILES, + cwd: "/proj", + output: RgDiffOutput::UnorderedLines, + }, RgDiffCase { name: "context combined", args: &["-nC1", "needle", "proj/context.txt"],