Skip to content

Cover workspace and index mutation attribution - #2139

Open
svarlamov wants to merge 9 commits into
codex/git-ops-02-semantic-eventsfrom
codex/git-ops-03-workspace-index-e2e
Open

Cover workspace and index mutation attribution#2139
svarlamov wants to merge 9 commits into
codex/git-ops-02-semantic-eventsfrom
codex/git-ops-03-workspace-index-e2e

Conversation

@svarlamov

@svarlamov svarlamov commented Aug 12, 2026

Copy link
Copy Markdown
Member
  • Adds end-to-end attribution coverage for add, rm, restore, branch, checkout, and switch modes.
  • Extends the integration repository helper with stdin, shell-wrapper, target-repository, and deterministic daemon synchronization support.

devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-03-workspace-index-e2e branch 2 times, most recently from 54de872 to 8560683 Compare August 12, 2026 19:47
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-03-workspace-index-e2e branch 4 times, most recently from 48c825c to 4f4aa0a Compare August 12, 2026 22:31
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-03-workspace-index-e2e branch 2 times, most recently from f6e5004 to ff01c3a Compare August 12, 2026 23:25
devin-ai-integration[bot]

This comment was marked as resolved.

@svarlamov
svarlamov force-pushed the codex/git-ops-03-workspace-index-e2e branch 4 times, most recently from 64478fc to d691996 Compare August 13, 2026 21:47

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

Copy link
Copy Markdown
Contributor

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 5 additional findings in Devin Review.

Open in Devin Review

Comment thread src/daemon.rs
Comment on lines +1596 to +1599
let head = restore_head
.filter(|head| !head.is_empty())
.map(ToOwned::to_owned)
.unwrap_or(repo.head()?.target()?);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Cleanup of discarded AI edits after a file restore still aborts when the repository's current position cannot be read

The repository's current position is looked up unconditionally (repo.head()?.target()? at src/daemon.rs:1599) even when the position captured at command time is already known, so a restore whose position is known is still abandoned with an error whenever the current position cannot be resolved.

Impact: Discarded AI edits can stay attached to restored files (and the operation reports an error) even though all the information needed to clean them up was already available.

Eager evaluation of the `unwrap_or` fallback defeats the new event-derived head

The PR threads the head captured by the RestorePaths semantic event (src/daemon.rs:8019-8023, produced in src/daemon/analyzers/workspace.rs:30-32) into apply_checkout_switch_working_log_side_effect so the async side effect no longer depends on live repository state. However Option::unwrap_or evaluates its argument eagerly, so repo.head()?.target()? runs on every restore with pathspecs, even when restore_head is Some:

  • Any error from repo.head() / Reference::target() (src/git/repository.rs:832-854, which falls back to spawning git rev-parse) propagates out of the function with ?, so the pruning is skipped and a side-effect error is recorded even though the known head made the lookup unnecessary. This is reachable in the intended async scenario: HEAD may have become unborn (e.g. a later checkout --orphan) by the time the restore side effect runs.
  • It also performs an avoidable ref read / git rev-parse spawn per restore command.

The pre-existing analogue at src/daemon.rs:7422-7425 has the same shape, but there the value is genuinely needed as a fallback.

Suggested change
let head = restore_head
.filter(|head| !head.is_empty())
.map(ToOwned::to_owned)
.unwrap_or(repo.head()?.target()?);
let head = match restore_head.filter(|head| !head.is_empty()) {
Some(head) => head.to_string(),
None => repo.head()?.target()?,
};
Open in Devin Review

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

@svarlamov
svarlamov force-pushed the codex/git-ops-03-workspace-index-e2e branch from d691996 to 33bbf33 Compare August 13, 2026 22:22
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