fix: pass -E to git so the multi-identity author filter matches

OwnEmailMatcher::author_regex() emits an extended-regex alternation
(<email>|<noreply-address>), but scan_repo_own_commits ran `git log
--author=` without -E. git defaults --author to *basic* regex, where |
is a literal, so the pattern matched nothing for anyone with two or more
identities — silently zeroing streak, heatmap, digest and the hour/day
patterns (measured 0 -> 141 own commits across the workspace after the
fix). Add -E here and in the new has_own_commit helper.
This commit is contained in:
dualfroz committed 2026-07-08 16:14:43 +02:00
1 parent 6adc22d665
commit 2ccf69f64c
1 file changed
+26 -1
+26 -1
View File
@@ -99,7 +99,10 @@ pub fn scan_repo_own_commits(path: &std::path::Path, matcher: &OwnEmailMatcher)
let Some(regex) = matcher.author_regex() else { return vec![] };
let out = std::process::Command::new("git")
.arg("-C").arg(path)
.args(["log", "--branches", "-i", &format!("--author={regex}")])
// `-E`: `author_regex()` emits an extended-regex alternation (`a|b`);
// git's `--author` defaults to *basic* regex, where `|` is a literal
// and the pattern silently matches nothing — so this must be explicit.
.args(["log", "--branches", "-E", "-i", &format!("--author={regex}")])
.args(["--date=format-local:%Y-%m-%dT%H", "--pretty=format:%ae\x1f%ad"])
.output();
let Ok(out) = out else { return vec![] };
@@ -113,6 +116,28 @@ pub fn scan_repo_own_commits(path: &std::path::Path, matcher: &OwnEmailMatcher)
}).collect()
}
/// Whether you've ever committed to the repo at `path`. A workspace clone
/// you've never touched — a vendored/reference fork like an upstream
/// `pterodactyl` — returns `Some(false)`; that's the signal used to mark and
/// optionally hide such repos. Uses the same git-side `--author` filter as
/// the stats scan with `--max-count=1`, so repos where you *do* have commits
/// short-circuit on the first match and only a true zero-match clone walks
/// its full history. `None` when no identity is configured (can't tell — the
/// caller then treats the repo as yours).
pub fn has_own_commit(path: &std::path::Path, matcher: &OwnEmailMatcher) -> Option<bool> {
let regex = matcher.author_regex()?;
let out = std::process::Command::new("git")
.arg("-C").arg(path)
// `-E` for the same reason as `scan_repo_own_commits`: the regex is an
// extended-regex alternation that git's default basic-regex `--author`
// would treat as a literal `|` and never match.
.args(["log", "--branches", "-E", "-i", &format!("--author={regex}"), "--max-count=1", "--format=%H"])
.output()
.ok()?;
// `--format=%H` prints "<sha>\n" on a match, nothing at all on none.
Some(out.stdout.iter().any(|b| !b.is_ascii_whitespace()))
}
/// Scans every repo and merges the result into one date-sorted list.
pub fn scan_workspace_own_commits(
repos: &[crate::status::RepoSummary], matcher: &OwnEmailMatcher,