Skip to content

Comments

fix: handle cross-repo checkpoints when CWD is a different git repo#569

Open
svarlamov wants to merge 4 commits intomainfrom
devin/1771641689-fix-cross-repo-checkpoint
Open

fix: handle cross-repo checkpoints when CWD is a different git repo#569
svarlamov wants to merge 4 commits intomainfrom
devin/1771641689-fix-cross-repo-checkpoint

Conversation

@svarlamov
Copy link
Member

@svarlamov svarlamov commented Feb 21, 2026

fix: handle cross-repo checkpoints when CWD is a different git repo

Summary

When an AI agent working from repos/repo-1 edits files in repos/repo-2, the checkpoint was only written to repo-1's working log. Files in repo-2 were silently filtered out by path_is_in_workdir in checkpoint.rs, so all changes showed as "human" when later committing in repo-2.

Root cause: In handle_checkpoint(), when the CWD is itself a git repo, needs_file_based_repo_detection is false and the code falls to the single-repo path. The single-repo checkpoint naturally ignores files outside its workdir — but nothing ever processes those external files.

Fix: After running the local repo checkpoint, detect any edited files outside the current repo's workdir, group them by their containing repository via group_files_by_repository, and run separate checkpoints for each external repo. Passes None as workspace boundary since external files are by definition outside the local workspace.

Updates since initial revision

  • Applied Devin Review suggestion: use repo workdir (not CWD repository_working_dir) when resolving relative external paths to absolute, fixing an inconsistency where the containment check and absolute path generation used different base directories.
  • Fixed Rust 1.93.0 rustfmt formatting differences.
  • Collapsed nested if to satisfy clippy::collapsible_if lint.

Review & Testing Checklist for Human

  • Manually verify with a real agent in a multi-repo workspace. Tests use mock_ai which doesn't exercise the full agent preset pipeline. From repos/repo-1, have an AI (Claude Code, Cursor, etc.) edit a file in repos/repo-2, then commit in repo-2 and run git-ai blame to confirm AI attribution.
  • Check AgentRunResult clone cost. agent_run_result.as_ref().cloned() copies the full struct including transcript. For agents with large transcripts, this could be non-trivial memory. Consider whether only the needed fields should be extracted.
  • Verify spawn_background_flush() placement. It was moved from inside the Ok arm to after external processing. The Err arm calls process::exit(0) so it should be equivalent, but worth a glance.
  • Confirm group_files_by_repository(&external_files, None) with no workspace boundary is acceptable. This walks up the filesystem unbounded looking for .git dirs. It only runs for files already identified as external, but verify no edge cases with symlinks or deeply nested paths cause issues.

Notes

  • The three new tests were confirmed to fail before the fix and pass after.
  • CI passes on Ubuntu and macOS (all modes). Windows test jobs were still in progress at time of last check.
  • Link to Devin run
  • Requested by @svarlamov

When an AI agent working from repo-1 edits files in repo-2, the
checkpoint was only written to repo-1's working log. Files in repo-2
were silently filtered out by path_is_in_workdir, causing all changes
to show as 'human' when committing in repo-2.

After running the local repo checkpoint, detect any edited files
outside the current repo's workdir, group them by their containing
repository, and run separate checkpoints for each external repo.

Adds three E2E tests covering:
- Working log creation in the target repo
- AI attribution on commit in the target repo
- Preservation of local repo checkpoint alongside cross-repo

Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@CLAassistant
Copy link

CLAassistant commented Feb 21, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ svarlamov
❌ devin-ai-integration[bot]
You have signed the CLA already but the status is still pending? Let us recheck it.

@git-ai-cloud-dev
Copy link

No AI authorship found for these commits. Please install git-ai to start tracking AI generated code in your commits.

devin-ai-integration[bot]

This comment was marked as resolved.

Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@svarlamov
Copy link
Member Author

devin fix the lints

devin-ai-integration bot and others added 2 commits February 21, 2026 05:10
Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 13 additional findings in Devin Review.

Open in Devin Review

Comment on lines 853 to 854
std::process::exit(0);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🔴 process::exit(0) on local checkpoint failure silently skips all cross-repo checkpoints

When the local repository's checkpoint fails, std::process::exit(0) at line 853 terminates the process immediately, preventing any of the newly-added cross-repo checkpoints (lines 856–921) from running. This means if an AI agent edits files in both repo1 (local) and repo2 (external), and the repo1 checkpoint fails for any reason (e.g., a git error, permission issue, or bare repo), repo2's AI-edited files will never get a working-log entry — silently losing AI attribution for those files.

Root Cause and Impact

The Err arm of the local checkpoint result match (line 843–854) calls std::process::exit(0), which was a pre-existing pattern for the single-repo case. However, the new cross-repo processing code at lines 856–921 is placed after this match block, so it becomes unreachable on error:

// line 843-854
Err(e) => {
    // ...
    std::process::exit(0);  // kills the process
}
// line 856-921: cross-repo checkpoints — never reached on Err

This is inconsistent with the multi-repo workspace path (lines 692–701), which explicitly continues processing other repos on failure:

Err(e) => {
    // Continue processing other repos instead of exiting
}

Impact: Cross-repo AI attribution is lost whenever the local checkpoint encounters an error. The external repos' changes will appear as "human" when committed, which is the exact problem this PR aims to fix.

(Refers to lines 843-854)

Prompt for agents
In src/commands/git_ai_handlers.rs, the Err arm of the checkpoint_result match (lines 843-854) calls std::process::exit(0), which prevents the cross-repo checkpoint processing on lines 856-921 from ever executing when the local checkpoint fails. To fix this, remove the std::process::exit(0) call and instead let execution fall through to the cross-repo processing block. You may want to track whether the local checkpoint succeeded/failed and still report the error, but the key change is to NOT exit the process so that cross-repo checkpoints can still run. This would be consistent with the multi-repo workspace path at lines 692-701 which continues processing other repos on failure. After the cross-repo processing, you can exit with code 0 if the local checkpoint failed (to preserve the existing behavior of not propagating checkpoint errors to callers).
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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