fix: handle cross-repo checkpoints when CWD is a different git repo#569
fix: handle cross-repo checkpoints when CWD is a different git repo#569
Conversation
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 EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
|
|
No AI authorship found for these commits. Please install git-ai to start tracking AI generated code in your commits. |
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
|
devin fix the lints |
Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
| std::process::exit(0); | ||
| } |
There was a problem hiding this comment.
🔴 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 ErrThis 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).
Was this helpful? React with 👍 or 👎 to provide feedback.
fix: handle cross-repo checkpoints when CWD is a different git repo
Summary
When an AI agent working from
repos/repo-1edits files inrepos/repo-2, the checkpoint was only written to repo-1's working log. Files in repo-2 were silently filtered out bypath_is_in_workdirincheckpoint.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_detectionisfalseand 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. PassesNoneas workspace boundary since external files are by definition outside the local workspace.Updates since initial revision
workdir(not CWDrepository_working_dir) when resolving relative external paths to absolute, fixing an inconsistency where the containment check and absolute path generation used different base directories.rustfmtformatting differences.ifto satisfyclippy::collapsible_iflint.Review & Testing Checklist for Human
mock_aiwhich doesn't exercise the full agent preset pipeline. Fromrepos/repo-1, have an AI (Claude Code, Cursor, etc.) edit a file inrepos/repo-2, then commit in repo-2 and rungit-ai blameto confirm AI attribution.AgentRunResultclone 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.spawn_background_flush()placement. It was moved from inside theOkarm to after external processing. TheErrarm callsprocess::exit(0)so it should be equivalent, but worth a glance.group_files_by_repository(&external_files, None)with no workspace boundary is acceptable. This walks up the filesystem unbounded looking for.gitdirs. It only runs for files already identified as external, but verify no edge cases with symlinks or deeply nested paths cause issues.Notes