Skip to content

Fix git commit replay: divergence guard, file permissions, ResolveHEAD#70

Merged
JAORMX merged 2 commits intomainfrom
fix-git
Mar 19, 2026
Merged

Fix git commit replay: divergence guard, file permissions, ResolveHEAD#70
JAORMX merged 2 commits intomainfrom
fix-git

Conversation

@JAORMX
Copy link
Copy Markdown
Contributor

@JAORMX JAORMX commented Mar 19, 2026

Summary

  • Add git commit replay feature that replays agent commits from the snapshot back onto the original workspace after flush, preserving author metadata and commit history
  • Add HEAD divergence guard — if the original repo's HEAD moves while the VM runs, replay is skipped to avoid misleading ancestry
  • Preserve executable file permissions (0o755) in replayed commits instead of hardcoding 0o644
  • Fix ResolveHEAD to return ("", nil) for repos with no commits, matching its interface contract
  • Wire CommitReplayer and ReplayCommits() into the CLI composition root

Test plan

  • TestResolveHEAD_NoCommits — empty repo returns ("", nil) not an error
  • TestReplay_HeadDiverged — diverged original returns Diverged=true, Replayed=0
  • TestReplay_PreservesExecutableBit — executable files keep 0o755 after replay
  • TestGetFileModeAtCommit — table-driven: regular=0o644, executable=0o755, missing=0o644 fallback
  • All existing replay tests continue to pass
  • Manual E2E: bbox claude-code -- -p "..." successfully replayed 1 commit onto original repo

🤖 Generated with Claude Code

JAORMX and others added 2 commits March 19, 2026 11:44
After a sandbox session, git commits made by the agent inside the VM
are now preserved in the original workspace's git history. A new
post-flush pipeline step extracts commits from the snapshot repo and
recreates them in the original using the same author metadata.

Key design decisions:
- Replay runs after flush to preserve the interactive review security model
- Best-effort: replay errors are warnings, file changes are already safe
- Partial acceptance: rejected files are filtered from replayed commits
- Merge commits are skipped; worktree snapshots skip replay entirely

Security: ValidateInBounds symlink checks, .git path blocking, no
shell invocation (exec.Command argv only), no --allow-empty commits.

Signed-off-by: Juan Antonio Osorio <ozz@stacklok.com>
…ntract

Add HEAD divergence detection to skip replay when the original repo's
HEAD moves during a VM session, preventing misleading commit ancestry.
Preserve executable file permissions by querying git ls-tree for the
tree mode instead of hardcoding 0o644. Fix ResolveHEAD to return
("", nil) for repos with no commits, matching its interface contract.
Wire ReplayCommits into the CLI composition root.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JAORMX JAORMX merged commit 944bf78 into main Mar 19, 2026
8 checks passed
@JAORMX JAORMX deleted the fix-git branch March 19, 2026 11:21
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.

1 participant