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
11 11
12mod access;12mod access;
13 13
14#[test]
15fn 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
14pub fn check_common(cg: &Graph, expected: &HashMap<String, RefInfo, impl BuildHasher>) {30pub fn check_common(cg: &Graph, expected: &HashMap<String, RefInfo, impl BuildHasher>) {
15 cg.verify_integrity(|_| Ok::<_, gix_error::Message>(()))31 cg.verify_integrity(|_| Ok::<_, gix_error::Message>(()))
16 .expect("graph is valid");32 .expect("graph is valid");