Skip to content

feat(pack): add PackStats and stats_pack for pack file object statistics#138

Merged
genedna merged 3 commits into
libra-tools:mainfrom
sunruizhesrz:main
Jun 30, 2026
Merged

feat(pack): add PackStats and stats_pack for pack file object statistics#138
genedna merged 3 commits into
libra-tools:mainfrom
sunruizhesrz:main

Conversation

@sunruizhesrz

Copy link
Copy Markdown
Contributor

📝 Background

git-internal can fully decode pack files (Pack::decode), but lacks a lightweight way to get object type counts (commits, trees, blobs, tags, deltas) without full decompression and delta resolution.

This PR adds a read‑only statistics interface that reuses existing parsing logic.


✨ Changes

📦 New PackStats struct (in decode.rs)

pub struct PackStats {
    pub total:   usize,
    pub commits: usize,
    pub trees:   usize,
    pub blobs:   usize,
    pub tags:    usize,
    pub deltas:  usize,
}

⚙️ New Pack::stats_pack method

pub fn stats_pack(path: PathBuf) -> Result<PackStats, GitError>
Step Description
1️⃣ Validate pack header, read total object count
2️⃣ Stream objects via decode_pack_object
3️⃣ Classify by type (deltas normalized → deltas)
4️⃣ Return PackStats or propagate GitError

🧪 Tests (4)

Test Scenario
test_stats_pack_small_sha1 19 objects, basic counting ✅
test_stats_pack_medium_sha1_has_deltas 35k objects with deltas ✅
test_stats_pack_file_not_found Missing file error ❌
test_stats_pack_invalid_pack_magic Corrupt header error ❌

✅ All tests pass · cargo fmt · clippy clean


✅ Verification

cargo test --lib internal::pack::decode::
let stats = Pack::stats_pack("tests/data/packs/small-sha1.pack".into())?;
// Output: PackStats { total: 19, commits: 1, trees: 4, blobs: 14, tags: 0, deltas: 0 }

🧠 Design

Principle Implementation
Reuse Uses decode_pack_object → consistency, minimal duplication
Lightweight No delta reconstruction, no decompression, no cache writes
Error handling All errors via ? → no panics
Invariant commits + trees + blobs + tags + deltas == total (tested)

📂 Files changed

  • src/internal/pack/decode.rs (only)

📎 Compatibility

  • ✅ Fully backward compatible – adds new API only
  • ✅ No new dependencies

Thanks for reviewing! 🙏

Implements experiment 3, task 3 from the course assignment:

- Add PackStats struct with fields: total, commits, trees, blobs, tags, deltas
- Add Pack::stats_pack(path) -> Result<PackStats, GitError> that:
  - Opens and validates the pack file header via check_header
  - Iterates all objects using decode_pack_object
  - Counts each object by type (BaseObject vs delta variants)
  - Returns Err on missing file or invalid pack magic
- Add 4 tests:
  - test_stats_pack_small_sha1: normal-path on small-sha1.pack (total=19)
  - test_stats_pack_medium_sha1_has_deltas: normal-path on medium-sha1.pack (35031 objects, 22339 deltas)
  - test_stats_pack_file_not_found: error-path for nonexistent file
  - test_stats_pack_invalid_pack_magic: error-path for corrupted pack header

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64aecdc06e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/internal/pack/decode.rs Outdated
Comment thread src/internal/pack/decode.rs Outdated
Use the existing lightweight PackStats analyzer for Pack::stats_pack.
@genedna genedna merged commit 9b1ed71 into libra-tools:main Jun 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants