Skip to content

Commit 1f9aca5

Browse files
committed
Merge branch 'feat_basic_connectivity_check'
2 parents 7227410 + 7ab5c76 commit 1f9aca5

File tree

19 files changed

+347
-2
lines changed

19 files changed

+347
-2
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ members = [
281281
"gix-archive",
282282
"gix-worktree-stream",
283283
"gix-revwalk",
284+
"gix-fsck",
284285

285286
"tests/tools",
286287

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ is usable to some extent.
140140
* [gix-tui](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-tui)
141141
* [gix-tix](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-tix)
142142
* [gix-bundle](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-bundle)
143+
* [gix-fsck](https://github.com/Byron/gitoxide/blob/main/crate-status.md#gix-fsck)
143144

144145
### Stress Testing
145146
* [x] Verify huge packs

crate-status.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,23 @@ See its [README.md](https://github.com/Byron/gitoxide/blob/main/gix-lock/README.
775775
* [x] validate submodule names
776776
* [x] [validate][tagname-validation] tag names
777777

778+
### gix-fsck
779+
* [x] validate connectivity and find missing objects starting from…
780+
- [x] commits
781+
- [ ] tags
782+
- [ ] tree-cache in the `index` or any entry within
783+
* [ ] validate object hashes during connectivity traversal
784+
* [ ] progress reporting and interruptability
785+
* [ ] skipList to exclude objects which are known to be broken
786+
* [ ] validate blob hashes (connectivity check
787+
* [ ] identify objects that exist but are not reachable (i.e. what remains after a full graph traversal from all valid starting points)
788+
* [ ] write dangling objects to the `.git/log-found` directory structure
789+
* [ ] `strict` mode, to check for tree objects with `g+w` permissions
790+
* [ ] consider reflog entries from `ref` starting points
791+
* [ ] when reporting reachable objects, provide the path through which they are reachable, i.e. ref-log@{3} -> commit -> tree -> path-in-tree
792+
* [ ] limit search to ODB without alternates (default is equivalent to `git fsck --full` due to ODB implementation)
793+
* [ ] all individual [checks available in `git fsck`](https://git-scm.com/docs/git-fsck#_fsck_messages) (*too many to print here*)
794+
778795
### gix-ref
779796
* [ ] Prepare code for arrival of longer hashes like Sha256. It's part of the [V2 proposal][reftable-v2] but should work for loose refs as well.
780797
* **Stores**

etc/check-package-size.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function indent () {
1515
}
1616

1717
echo "in root: gitoxide CLI"
18+
(enter gix-fsck && indent cargo diet -n --package-size-limit 10KB)
1819
(enter gix-actor && indent cargo diet -n --package-size-limit 10KB)
1920
(enter gix-archive && indent cargo diet -n --package-size-limit 10KB)
2021
(enter gix-worktree-stream && indent cargo diet -n --package-size-limit 40KB)

gitoxide-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ gix-pack-for-configuration-only = { package = "gix-pack", version = "^0.44.0", p
4949
gix-transport-configuration-only = { package = "gix-transport", version = "^0.38.0", path = "../gix-transport", default-features = false }
5050
gix-archive-for-configuration-only = { package = "gix-archive", version = "^0.6.0", path = "../gix-archive", optional = true, features = ["tar", "tar_gz"] }
5151
gix-status = { version = "^0.2.0", path = "../gix-status" }
52+
gix-fsck = { version = "^0.1.0", path = "../gix-fsck" }
5253
serde = { version = "1.0.114", optional = true, default-features = false, features = ["derive"] }
5354
anyhow = "1.0.42"
5455
thiserror = "1.0.34"

gitoxide-core/src/repository/fsck.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use anyhow::Context;
2+
use gix::{objs::Kind, ObjectId};
3+
4+
pub fn function(mut repo: gix::Repository, spec: Option<String>, mut out: impl std::io::Write) -> anyhow::Result<()> {
5+
let spec = spec.unwrap_or("HEAD".into());
6+
7+
repo.object_cache_size_if_unset(4 * 1024 * 1024);
8+
// We expect to be finding a bunch of non-existent objects here - never refresh the ODB
9+
repo.objects.refresh_never();
10+
11+
let id = repo
12+
.rev_parse_single(spec.as_str())
13+
.context("Only single revisions are supported")?;
14+
let commits: gix::revision::Walk<'_> = id
15+
.object()?
16+
.peel_to_kind(gix::object::Kind::Commit)
17+
.context("Need commitish as starting point")?
18+
.id()
19+
.ancestors()
20+
.all()?;
21+
22+
let on_missing = |oid: &ObjectId, kind: Kind| {
23+
writeln!(out, "{oid}: {kind}").expect("failed to write output");
24+
};
25+
26+
let mut check = gix_fsck::Connectivity::new(&repo.objects, on_missing);
27+
// Walk all commits, checking each one for connectivity
28+
for commit in commits {
29+
let commit = commit?;
30+
check.check_commit(&commit.id)?;
31+
// Note that we leave parent-iteration to the commits iterator, as it will
32+
// correctly handle shallow repositories which are expected to have the commits
33+
// along the shallow boundary missing.
34+
}
35+
Ok(())
36+
}

gitoxide-core/src/repository/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ pub use clone::function::clone;
3535
pub use fetch::function::fetch;
3636

3737
pub mod commitgraph;
38+
mod fsck;
39+
pub use fsck::function as fsck;
3840
pub mod index;
3941
pub mod mailmap;
4042
pub mod odb;

gix-fsck/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

gix-fsck/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "gix-fsck"
3+
version = "0.1.0"
4+
repository = "https://github.com/Byron/gitoxide"
5+
authors = ["Cameron Esfahani <[email protected]>", "Sebastian Thiel <[email protected]>"]
6+
license = "MIT OR Apache-2.0"
7+
description = "Verifies the connectivity and validity of objects in the database"
8+
edition = "2021"
9+
include = ["src/**/*", "LICENSE-*"]
10+
rust-version = "1.65"
11+
12+
[lib]
13+
doctest = false
14+
15+
[dependencies]
16+
gix-hash = { version = "^0.13.1", path = "../gix-hash" }
17+
gix-hashtable = { version = "^0.4.0", path = "../gix-hashtable" }
18+
gix-object = { version = "^0.38.0", path = "../gix-object" }
19+
20+
[dev-dependencies]
21+
gix-odb = { path = "../gix-odb" }
22+
gix-testtools = { path = "../tests/tools"}

0 commit comments

Comments
 (0)