History

fix(gix-commitgraph): preserve I/O errors for missing graph paths (#2978)

<!-- agent --> An absent `.git/objects/info` directory made `Graph::at()` return an error without its filesystem cause. The optional-cache fallback in `Repository::commit_graph_if_enabled()` could not recognize `NotFound`, so operations such as `merge_base(HEAD, HEAD)` failed despite having all required commit objects. Inspect the path with one fallible metadata read and preserve its I/O error in the chain. Missing paths now reach the existing fallback, while other metadata failures remain distinguishable. Cover the error source and merge-base behavior with an empty and then absent `objects/info`. Both regression tests failed before the fix. Git reference: `commit-graph.c` at `1630431f326e15fcde608827b5ff38422528eb59` uses `open_commit_graph()`, `load_commit_graph_one()`, and `prepare_commit_graph()` to fall back when no graph can be opened. With Git 2.50.1 (Apple Git-155), `git -c core.commitGraph=true merge-base` returns the expected commits for `HEAD HEAD` and `HEAD HEAD^` with either an empty or an absent `objects/info` directory.

Byron committed 2 months ago

Commit 72f3e8f1 parent e7317903 files · +53 −2Browse files

Showing the changes to gix-commitgraph/tests/commitgraph.rs (1 of 3 files). Show all

Unified · Split

gix-commitgraph/tests/commitgraph.rs+16−0
@@ -11,6 +11,22 @@ use gix_testtools::scripted_fixture_read_only; · 10 unmodified lines
1111
1212 mod access;
1313
14+#[test]
15+fn missing_path_keeps_io_error() -> gix_testtools::Result {
16+ let dir = gix_testtools::tempfile::tempdir()?;
17+ let err = gix_commitgraph::at(dir.path().join("missing"))
18+ .err()
19+ .expect("a missing path cannot contain a commit-graph");
20+ assert_eq!(
21+ err.downcast_any_ref::<std::io::Error>()
22+ .expect("the filesystem error is preserved")
23+ .kind(),
24+ std::io::ErrorKind::NotFound,
25+ "callers can distinguish a missing optional cache from other failures"
26+ );
27+ Ok(())
28+}
29+
1430 pub fn check_common(cg: &Graph, expected: &HashMap<String, RefInfo, impl BuildHasher>) {
1531 cg.verify_integrity(|_| Ok::<_, gix_error::Message>(()))
1632 .expect("graph is valid");