fix: preserve AI attribution through git revert and revert-of-revert (ISSUE-004, 015)#967
Open
fix: preserve AI attribution through git revert and revert-of-revert (ISSUE-004, 015)#967
Conversation
… ISSUE-015) When a revert commit is itself reverted, the restored content now correctly inherits the original AI attribution by traversing one level of the revert chain. Simple reverts of AI commits remain attribution-neutral (ai=0) since they only delete lines. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add RevertComplete semantic event and wire up revert attribution in the daemon pipeline so revert-of-revert note copying works in daemon and wrapper-daemon modes, not just wrapper mode. Changes: - Add "revert" to trace_command_may_mutate_refs and ORIG_HEAD tracking - Add RevertComplete variant to SemanticEvent enum - Emit RevertComplete from the history analyzer for "revert" commands - Convert RevertComplete to RevertMixed rewrite log events - Apply revert attribution side effect (note copying) in daemon mode - Add RevertComplete to reducer event filter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Skip flag value arguments (-m, --strategy, etc.) in find_reverted_commit to avoid misinterpreting "1" as a commit ref in `git revert -m 1 abc123` - Replace ? operator with match/continue in find_reverted_commit to avoid premature function return on UTF-8 parse failure - Guard parent chain traversal with is_revert_commit check (commit message starts with "Revert ") to prevent false attribution when reverting a normal human commit whose parent happens to be an AI commit - Apply the same is_revert_commit guard in daemon-mode side effect Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Apply rustfmt to daemon.rs and fix Devin review feedback: -s is --signoff (boolean) not --strategy (value-taking) in git revert, so remove it from the skip-next-arg list in find_reverted_commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The trace normalizer's command_may_mutate_refs list was missing "revert", causing the daemon to skip mutation state capture (pre/post repo context, ref changes) for revert commands. Without this data, head_change() cannot detect the HEAD change and no RevertComplete event is emitted, so the revert-of-revert attribution side effect never fires in daemon mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4466c72 to
6d22a78
Compare
…g log Addresses Devin review finding: byte-level slice on commit summary could panic on multi-byte UTF-8 characters (CJK, emoji, etc.). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ent fires Without 'revert' in the HistoryAnalyzer registry, git revert in daemon mode was routed to the GenericAnalyzer which emits no semantic events. RevertComplete was never fired, so apply_revert_attribution_side_effect was never called, and revert-of-revert attribution was silently dropped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…ntax error from --gpg-sign removal) Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
|
|
…rted_commit - HistoryAnalyzer now checks for --abort before emitting RevertComplete, matching cherry-pick pattern. Emits RevertAbort instead. - Added RevertAbort variant to SemanticEvent and wired it through reducer and daemon event handler (no-op, abort needs no attribution). - find_reverted_commit: changed bare keyword check (continue/abort/quit/skip) to use --prefix and return None, matching how git actually accepts these and consistent with daemon-side revert_source_ref_from_command. Co-Authored-By: Sasha Varlamov <sasha@sashavarlamov.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pre_revert_hookandpost_revert_hookto interceptgit revertoperations in wrapper modeRevertMixedevent to the rewrite log (was previously defined but never emitted)SemanticEvent::RevertCompleteandRevertAbort, registers"revert"inAnalyzerRegistry, implementsapply_revert_attribution_side_effectandrevert_source_ref_from_commandfor full daemon-mode parityUpdates since last revision
find_reverted_commitbare keyword check: changedcontinue/abort/quit/skipto--continue/--abort/--quit/--skipand returnsNone(control mode, no commit to find), matching how git actually accepts these and consistent with daemon-siderevert_source_ref_from_commandRevertAborthandling in daemon mode:HistoryAnalyzernow checks for--abortbefore emittingRevertComplete(previously agit revert --abortthat changed HEAD would emit a spuriousRevertComplete). AddedSemanticEvent::RevertAbortvariant, wired through reducer and daemon event handler (no-op — abort needs no attribution or rewrite log entry)Test plan
test_revert_of_revert_restores_ai_attributionpassestest_revert_of_ai_commit_is_attribution_neutralpassestest_revert_preserves_original_commit_notepassescargo clippywith-D warningscleanReview & Testing Checklist for Human
TestRepo(wrapper mode). Manually verifyapply_revert_attribution_side_effectworks by running a revert with daemon mode enabled and checkinggit notes --ref=ai show HEADis_revert_commitheuristic: relies on commit message starting with"Revert ". Will fail if user passes--editto customize the message or uses a non-English git locale — verify this is acceptablerevert_source_ref_from_commandarg parsing: verify edge cases likegit revert -m 1 --gpg-sign abc123andgit revert --strategy=recursive abc123(equals-sign form) — the daemon-side parser does not handle--flag=valuesyntax for-m/--strategy/-X, which could cause the flag value to be mistaken for the commit refRevertMixedEventfallback: in the daemon event handler, ifrevert_source_ref_from_commandreturnsNone, the event is emitted with an emptyreverted_commitstring — verify downstream consumers handle this gracefullyNotes
utf8_filenames::test_arabic_filename(ubuntu daemon) — daemon completion log timeoutdaemon_restart_brings_up_new_process(windows wrapper) — PID file race conditionlicense/clacheck is pending for the bot commit; expected and not blockingLink to Devin session: https://app.devin.ai/sessions/64198314ca39403db3aa3ac6f342e34f
Requested by: @svarlamov