crates/mimir-ingest/tests/lfs_skip.rs
//! The consumer's clones never run a content filter (git-lfs and its kind).
//!
//! Loki, 2026-10-17: git-lfs was installed, an LFS object was not in the
//! source, the smudge failed — and the clone's checkout stopped halfway, most
//! of the tree missing; every repo reaching into it failed as "sibling
//! missing". Mimir reads code, never LFS binaries: a clone and a checkout
//! keep the pointer files as stored, whatever filter the box configures.
//!
//! Its own test binary: it points HOME at a box whose git configures a
//! smudge filter that always fails (what a missing LFS object does).
use std::path::Path;
use std::process::Command;
fn git(dir: &Path, args: &[&str]) {
let st = Command::new("git").args(args).current_dir(dir).env("GIT_CONFIG_NOSYSTEM", "1").status().unwrap();
assert!(st.success(), "git {args:?}");
}
#[test]
fn a_clone_and_its_checkout_skip_a_failing_smudge_filter() {
let tmp = tempfile::tempdir().unwrap();
// the box: a global git config whose lfs smudge fails, required
let home = tmp.path().join("home");
std::fs::create_dir_all(&home).unwrap();
std::fs::write(home.join(".gitconfig"), "[user]\n\tname = t\n\temail = t@localhost\n").unwrap();
// SAFETY: this test binary has one test; nothing else reads the env concurrently
unsafe {
std::env::set_var("HOME", &home);
std::env::set_var("GIT_CONFIG_NOSYSTEM", "1");
}
// the source: a pointer file under an lfs attribute, and code beside it
let src = tmp.path().join("src");
std::fs::create_dir_all(src.join("assets")).unwrap();
git(&src, &["init", "-q", "-b", "main"]);
std::fs::write(src.join(".gitattributes"), "*.jpeg filter=lfs diff=lfs merge=lfs -text\n").unwrap();
std::fs::write(src.join("assets/pic.jpeg"), "version https://git-lfs.github.com/spec/v1\noid sha256:5d9ba0106f23f2f247bbf3b2bb3bf308a7702b3171149876bca83dcedf380d4e\nsize 117000\n").unwrap();
std::fs::create_dir_all(src.join("gatling/src")).unwrap();
std::fs::write(src.join("gatling/src/lib.rs"), "pub fn f() {}\n").unwrap();
// committed before the box has its filter: the blob IS the pointer
git(&src, &["add", "-A"]);
git(&src, &["commit", "-q", "-m", "c"]);
let head = String::from_utf8(Command::new("git").args(["rev-parse", "HEAD"]).current_dir(&src).output().unwrap().stdout).unwrap().trim().to_string();
// … and only now the box's failing filter
std::fs::write(home.join(".gitconfig"), "[filter \"lfs\"]\n\tsmudge = false\n\tprocess = false\n\trequired = true\n[user]\n\tname = t\n\temail = t@localhost\n").unwrap();
let clone = tmp.path().join("clones/zz");
std::fs::create_dir_all(clone.parent().unwrap()).unwrap();
mimir_ingest::git::sync_clone(&src.to_string_lossy(), &clone).expect("the clone is made, its filter skipped");
mimir_ingest::checkout::checkout_changed(&clone, &head).expect("the checkout runs no filter");
assert!(clone.join("gatling/src/lib.rs").is_file(), "the tree beside the LFS file is all there");
let pic = std::fs::read_to_string(clone.join("assets/pic.jpeg")).unwrap();
assert!(pic.starts_with("version https://git-lfs"), "the pointer, as stored: {pic}");
// the next commit adds another LFS file: fetched, and checked out by the
// consumer's own checkout (the files that changed only)
std::fs::write(home.join(".gitconfig"), "[user]\n\tname = t\n\temail = t@localhost\n").unwrap();
std::fs::write(src.join("assets/two.jpeg"), "version https://git-lfs.github.com/spec/v1\noid sha256:6d9ba0106f23f2f247bbf3b2bb3bf308a7702b3171149876bca83dcedf380d4e\nsize 9\n").unwrap();
std::fs::write(src.join("gatling/src/two.rs"), "pub fn g() {}\n").unwrap();
git(&src, &["add", "-A"]);
git(&src, &["commit", "-q", "-m", "c2"]);
let head2 = String::from_utf8(Command::new("git").args(["rev-parse", "HEAD"]).current_dir(&src).output().unwrap().stdout).unwrap().trim().to_string();
std::fs::write(home.join(".gitconfig"), "[filter \"lfs\"]\n\tsmudge = false\n\tprocess = false\n\trequired = true\n[user]\n\tname = t\n\temail = t@localhost\n").unwrap();
mimir_ingest::git::sync_clone(&src.to_string_lossy(), &clone).expect("fetched");
mimir_ingest::checkout::checkout_changed(&clone, &head2).expect("the changed files are written, no filter run");
assert!(clone.join("gatling/src/two.rs").is_file() && std::fs::read_to_string(clone.join("assets/two.jpeg")).unwrap().starts_with("version https://git-lfs"));
}