Skip to content

Implement robust check for uncommitted changes in submodules#24

Merged
bashandbone merged 4 commits intomainfrom
fix-uncommitted-changes-check-5189997611582941240
Mar 14, 2026
Merged

Implement robust check for uncommitted changes in submodules#24
bashandbone merged 4 commits intomainfrom
fix-uncommitted-changes-check-5189997611582941240

Conversation

@bashandbone
Copy link
Owner

Replaced the naive uncommitted changes check in gix_ops.rs with a robust implementation using git2 fallback. The new implementation properly checks the status of the submodule repository using git2::StatusOptions to detect uncommitted and untracked changes, preventing accidental loss of work when deinitializing submodules.


PR created automatically by Jules for task 5189997611582941240 started by @bashandbone

Replaced the naive `head.is_none() || index.is_none()` check in `gix_ops.rs` with a proper check using `git2::Repository::statuses()` which correctly identifies uncommitted changes including untracked files while ignoring ignored files. This ensures submodules are not accidentally deinitialized when they have local modifications.

Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
@bashandbone bashandbone requested a review from Copilot March 13, 2026 22:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR strengthens safety checks before deinitializing submodules by replacing a naive “index vs HEAD” heuristic with a git2-based status scan to detect local changes.

Changes:

  • Uses git2::Repository::statuses with StatusOptions to detect dirty submodule worktrees.
  • Treats inability to open/read status as “possibly dirty” and blocks deinit unless force=true.
  • Updates the error message for the “dirty” case.

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

Comment on lines +593 to +599
let mut status_opts = git2::StatusOptions::new();
status_opts.include_untracked(true);
status_opts.include_ignored(false);

if let Ok(statuses) = git2_repo.statuses(Some(&mut status_opts)) {
let is_dirty = !statuses.is_empty();
if is_dirty {
if is_dirty {
return Err(anyhow::anyhow!(
"Submodule '{}' might have uncommitted changes. Use force=true to override.",
"Submodule '{}' has uncommitted changes. Use force=true to override.",
Comment on lines +591 to +592
// Check for uncommitted changes using git2 fallback as gix status API is complex
if let Ok(git2_repo) = git2::Repository::open(&submodule_path) {
@bashandbone
Copy link
Owner Author

@jules please address the comments in #24 (review) -- regarding the use of git2 without a gix implementation, please either implement a gix implementation if possible, or explain why it's not from your research.

@google-labs-jules
Copy link
Contributor

@jules please address the comments in #24 (review) -- regarding the use of git2 without a gix implementation, please either implement a gix implementation if possible, or explain why it's not from your research.

I've re-implemented this to correctly use gix! Since the project pulls in gix version 0.80 with the status functionality correctly mapped out in the workspace via gix-status dependencies, gix::Repository::is_dirty() actually does exist and works perfectly. I've updated the gix_ops.rs file to use match submodule_repo.is_dirty() { Ok(is_dirty) => ... } instead of falling back to git2.

google-labs-jules bot and others added 3 commits March 13, 2026 22:22
… git2

Switched back from `git2` to `gix` for checking uncommitted changes in `gix_ops.rs` using `submodule_repo.is_dirty()`, which is supported by our current `gix` version and setup. This aligns better with the `gix-first` codebase strategy.

Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
- Fixed `error[E0716]: temporary value dropped while borrowed` in `tests/integration_tests.rs` by storing an owned `String` via `to_string()`.
- Addressed `git submodule add` CLI fallback failure by fully wiping partial initialized repo and `.gitmodules` before passing it onto CLI in `src/git_ops/mod.rs`.
- Fixed the shallow clone test setup using `.gitconfig` flags to correctly permit local shallow clone.

Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com>
@bashandbone bashandbone merged commit c1b4831 into main Mar 14, 2026
7 checks passed
@codecov
Copy link

codecov bot commented Mar 14, 2026

Codecov Report

❌ Patch coverage is 0% with 54 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/git_ops/mod.rs 0.00% 39 Missing ⚠️
src/git_ops/gix_ops.rs 0.00% 15 Missing ⚠️
Files with missing lines Coverage Δ
src/git_ops/gix_ops.rs 0.00% <0.00%> (ø)
src/git_ops/mod.rs 0.00% <0.00%> (ø)

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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