Skip to content

feat(vcs): add gix-based VCS module with status support - #6

Merged
kerryhatcher merged 4 commits into
mainfrom
feat/git-status-gix
Jul 26, 2026
Merged

feat(vcs): add gix-based VCS module with status support#6
kerryhatcher merged 4 commits into
mainfrom
feat/git-status-gix

Conversation

@kerryhatcher

@kerryhatcher kerryhatcher commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Implements Phase 0 of the gor status feature.

Changes

  • src/vcs/types.rs — Data types: WorkingTreeStatus, FileStatus, ChangeType, VcsError (all serde::Serialize)
  • src/vcs/repo.rsGitRepo wrapper over gix: open() and status() methods
  • src/vcs/mod.rs — Module declaration with re-exports
  • src/lib.rs — Registered pub mod vcs
  • _typos.toml — Added rela to the allow list (false positive)

Key design decisions

  • Zero new dependencies — gix was already in Cargo.toml with status feature
  • Single gix::status iterator pass for staged + unstaged + untracked
  • Index-based with lstat caching (no full tree walk)
  • Ahead/behind stubbed to (0, 0) — requires commit walking API not trivial in gix 0.85

Validation

  • cargo build — clean
  • cargo clippy — no warnings
  • cargo test --lib — 155/155 pass

Next steps

Phase 1: CLI arg definition + dispatch for gor status
Phase 2: Output formatting in output.rs
Phase 3: Integration tests

Summary by CodeRabbit

  • Documentation

    • Added specifications and implementation guidance for a planned gor status command.
    • Documented Git engine research, supported status formats, options, and testing expectations.
    • Added a project handoff outlining phased implementation steps and design considerations.
  • New Features

    • Added foundational Git repository status support, including staged, unstaged, untracked, and conflicted file information.
    • Added structured status data suitable for future command output and JSON responses.
  • Chores

    • Updated typo detection exceptions for valid Git terminology.

Add handoff document, status story, and research doc for implementing
gor status using gix (gitoxide) instead of jj-lib.

Key advantages of gix over jj-lib:
- Already a dependency (no new transitives)
- Fully synchronous (no tokio runtime)
- No .jj/ directory side effects
- Index-based status with lstat caching (fast)
Introduce a new `gor::vcs` module backed by `gix` (gitoxide) for local git
operations, beginning with working tree status.

- GitRepo::open() discovers repos via gix::discover() (walks up dirs)
- GitRepo::status() returns staged, unstaged, untracked, and conflicted
  files in a single index-based pass
- Branch name and upstream tracking ref are extracted from HEAD config
- All types derive serde::Serialize for --json output
- Zero new dependencies — gix was already in Cargo.toml with "status" feature

Phase 0 of the gor status implementation.
Copilot AI review requested due to automatic review settings July 26, 2026 21:35
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kerryhatcher, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 17d62e22-5405-4aa2-b521-23e68c30ba66

📥 Commits

Reviewing files that changed from the base of the PR and between 599b2b5 and 3ace4a3.

📒 Files selected for processing (3)
  • HANDOFF.md
  • docs/research/research-gix-for-gor.md
  • src/vcs/repo.rs
📝 Walkthrough

Walkthrough

Adds a gix-backed VCS module with serializable status types, repository discovery, branch metadata, staged/unstaged/untracked classification, and conflict extraction. Supporting documents define the planned gor status interface, implementation phases, and gix integration approach.

Changes

Status VCS foundation

Layer / File(s) Summary
Status specification and gix integration plan
HANDOFF.md, docs/issues/status.md, docs/research/research-gix-for-gor.md, _typos.toml
Documents the planned gor status behavior, CLI flags, output formats, testing strategy, gix capability mapping, implementation phases, and accepted VCS terminology.
Status data and error contracts
src/vcs/types.rs
Defines serializable working-tree status structures, file-change variants, and VCS error variants.
Git repository discovery and status collection
src/vcs/repo.rs, src/vcs/mod.rs, src/lib.rs
Adds GitRepo discovery and status APIs, branch and upstream lookup, change classification, conflict extraction, and public module exports.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: a new gix-based VCS module with status support.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/git-status-gix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI 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.

Pull request overview

Adds a new gor::vcs module that wraps gix to provide a foundation for implementing gor status (Phase 0), along with supporting documentation and typos configuration updates.

Changes:

  • Introduced src/vcs/ with status data types and a GitRepo wrapper that discovers a repo and computes working tree status via gix.
  • Exposed the new VCS module from the library (pub mod vcs) and re-exported key types.
  • Added design/research docs and updated _typos.toml to accommodate new terminology.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/vcs/types.rs Adds VCS status data structures and error type used by the VCS layer.
src/vcs/repo.rs Implements GitRepo::open() and GitRepo::status() using gix status/index APIs.
src/vcs/mod.rs Declares the vcs module and re-exports public surface area.
src/lib.rs Exposes the new vcs module from the crate.
HANDOFF.md Adds a handoff/design note for implementing gor status.
docs/research/research-gix-for-gor.md Adds research documentation mapping gix capabilities to planned commands.
docs/issues/status.md Adds the gor status story/spec and acceptance criteria.
_typos.toml Extends typos allow-list for new tokens encountered in docs/code.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/vcs/repo.rs
Comment on lines +36 to +43
/// # Errors
///
/// Returns [`VcsError::NotARepository`] if no git repository is found.
/// Returns [`VcsError::Io`] if an I/O error occurs during discovery.
pub fn open(path: &Path) -> Result<Self, VcsError> {
let repo = gix::discover(path).map_err(|e| VcsError::NotARepository(format!("{e}")))?;
Ok(Self { repo })
}
Comment thread src/vcs/repo.rs
Comment on lines +76 to +84
/// Get the current branch name, or an empty string if detached HEAD.
fn get_branch_name(&self) -> String {
self.repo
.head()
.ok()
.map(|head| head.name().as_bstr().to_string())
.filter(|s| !s.is_empty())
.unwrap_or_default()
}
Comment thread src/vcs/repo.rs Outdated
Comment on lines +183 to +187
});
}
EntryStatus::Conflict { .. } => {
untracked.push(path);
}
Comment thread src/vcs/repo.rs
Comment thread src/vcs/repo.rs
Comment on lines +109 to +114

/// Collect staged, unstaged, and untracked changes from the status iterator.
#[allow(clippy::type_complexity)]
fn collect_status_changes(
&self,
) -> Result<(Vec<FileStatus>, Vec<FileStatus>, Vec<String>), VcsError> {
Comment thread src/vcs/types.rs
Comment on lines +5 to +20
/// Errors from VCS operations.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum VcsError {
/// Error when the directory is not a git repository.
#[error("not a git repository: {0}")]
NotARepository(String),

/// A git operation failed with an unexpected error.
#[error("git operation failed: {0}")]
Other(String),

/// IO error during file or network access.
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
}
Comment thread HANDOFF.md
Comment on lines +206 to +213
## First Steps for the Agent

1. `cd /home/kwhatcher/projects/gor-jj-integration`
2. Read the two reference docs above
3. Start with Phase 0: create the `vcs` module (`mod.rs`, `types.rs`, `repo.rs`)
4. Run `cargo build` to validate compilation
5. Move to Phase 1: add the CLI arg + dispatch
6. Iterate
Add parentheses to resolve ambiguous link in doc comment — gix::discover
is both a function and a module, causing a rustdoc warning error.

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
HANDOFF.md (1)

88-120: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update both status examples to the gix 0.85 platform API.

Repository::status() accepts a progress implementation and returns a configurable status::Platform, which is consumed via into_iter(); it does not take gix::worktree::Status or expose staged()/unstaged()/untracked() accessors. (docs.rs)

  • HANDOFF.md#L88-L120: replace the pseudo-code status construction and collection calls with the Platform + iterator flow used by src/vcs/repo.rs.
  • docs/research/research-gix-for-gor.md#L155-L193: correct the quick-reference snippet to use gix::progress::Discard and Platform::into_iter().
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@HANDOFF.md` around lines 88 - 120, The status examples in HANDOFF.md (lines
88-120) and docs/research/research-gix-for-gor.md (lines 155-193) use the
obsolete gix status API. Update both snippets to match src/vcs/repo.rs: pass
gix::progress::Discard to Repository::status, configure and consume the returned
status::Platform via into_iter(), and derive staged, unstaged, and untracked
entries from the iterator instead of calling accessor methods; leave the
surrounding GitRepo/status guidance unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/vcs/repo.rs`:
- Around line 185-187: Update the EntryStatus::Conflict branch in the status
classification logic so conflicted paths are not added to untracked. Remove the
untracked.push(path) behavior while preserving conflict reporting through
get_conflicted_files() and the existing handling of other entry statuses.
- Around line 221-225: Update get_conflicted_files() to sort the collected
conflicted paths and remove duplicates before returning the public list.
Preserve filtering on non-Unconflicted stages and path conversion, ensuring
multiple index stages for the same path produce only one result.
- Around line 76-104: Update get_branch_name and the upstream flow to read the
branch referent via referent_name() instead of Head::name(), returning an empty
string for detached HEAD. Preserve the resolved local branch reference when
calling get_upstream_info, and shorten the full result from
branch_remote_tracking_ref_name() before exposing it as the upstream name.

---

Nitpick comments:
In `@HANDOFF.md`:
- Around line 88-120: The status examples in HANDOFF.md (lines 88-120) and
docs/research/research-gix-for-gor.md (lines 155-193) use the obsolete gix
status API. Update both snippets to match src/vcs/repo.rs: pass
gix::progress::Discard to Repository::status, configure and consume the returned
status::Platform via into_iter(), and derive staged, unstaged, and untracked
entries from the iterator instead of calling accessor methods; leave the
surrounding GitRepo/status guidance unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b689ada0-0cd8-4b2b-9e62-77e5ceba0585

📥 Commits

Reviewing files that changed from the base of the PR and between d359c0e and 599b2b5.

📒 Files selected for processing (8)
  • HANDOFF.md
  • _typos.toml
  • docs/issues/status.md
  • docs/research/research-gix-for-gor.md
  • src/lib.rs
  • src/vcs/mod.rs
  • src/vcs/repo.rs
  • src/vcs/types.rs

Comment thread src/vcs/repo.rs Outdated
Comment thread src/vcs/repo.rs Outdated
Comment thread src/vcs/repo.rs Outdated
…docs

- Fix get_branch_name() to use Head::referent_name() instead of
  Head::name() (the latter always returns "HEAD", not the branch)
- Shorten upstream tracking ref names via FullNameRef::shorten()
- Remove conflicted files from the untracked set (already reported
  separately via get_conflicted_files())
- Sort and deduplicate conflicted file paths (multiple index stages
  per path)
- Update HANDOFF.md and research-gix-for-gor.md code examples to
  match the gix 0.85 platform iterator API
@kerryhatcher
kerryhatcher merged commit c7db96b into main Jul 26, 2026
19 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