[PR #530] Add dual-mode git-ai operation via global hooks and wrapper #544

Closed
opened 2026-03-02 04:13:55 +03:00 by kerem · 0 comments
Owner

Original Pull Request: https://github.com/git-ai-project/git-ai/pull/530

State: closed
Merged: Yes


Summary

  • rewrote hook management to repo-local only (.git/ai/hooks) with persisted repo state in .git/ai/git_hooks_state.json
  • removed git-ai global hook management paths and now rely on safe forwarding to prior repo hooks or global fallback hooks when applicable
  • implemented both-mode child hook virtualization (-c core.hooksPath=<forward-or-null>) so child git does not execute git-ai managed hooks
  • replaced rebase hooksPath mutation with in-place managed-hook masking/restoration (terminal hooks retained, stale-state self-heal)
  • added sequencer-aware fast paths and cherry-pick terminal batching to reduce managed hook churn
  • hardened forwarding recursion guards to reject forwarding into .git/ai and .git-ai paths
  • hardened benchmark harness setup by re-running git-ai git-hooks ensure per copied run repo and asserting local hooksPath/hook surface

Performance Results

Heavy Matrix (baseline = current_wrapper, margin target = <=25%)

Run: benchmark_modes_vs_main.py --iterations-basic 5 --iterations-complex 4 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin

Scenario Wrapper (ms) Hooks (ms) Hooks vs Wrapper Both (ms) Both vs Wrapper Status
commit_human 149.062 182.896 +22.698% 142.994 -4.071% pass
checkpoint_commit_ai 307.771 344.476 +11.926% 305.943 -0.594% pass
reset_mixed_head6 262.999 269.920 +2.632% 258.096 -1.864% pass
stash_roundtrip 174.314 210.041 +20.496% 174.443 +0.074% pass
cherry_pick_three 187.428 272.665 +45.477% 197.004 +5.109% hooks fail
rebase_linear 176.566 173.724 -1.610% 190.119 +7.676% pass
rebase_rebase_merges 434.018 453.332 +4.450% 437.533 +0.810% pass
squash_merge_commit 764.811 817.109 +6.838% 784.600 +2.587% pass

Result: 15/16 checks passing (only cherry_pick_three in hooks mode misses).

10x Nasty Rebase Matrix (cpPython workload)

Run: benchmark_nasty_modes_vs_main.py --feature-commits 900 --main-commits 350 --side-commits 250 --files 6 --lines-per-file 1500 --burst-every 15 --repetitions 1 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin

Scenario Main Wrapper (s) Current Wrapper (s) Hooks (s) Hooks vs Wrapper Both (s) Both vs Wrapper Status
linear 8.423 8.845 8.743 -1.153% 9.270 +4.805% pass
onto 7.465 7.538 7.824 +3.794% 7.681 +1.897% pass
rebase_merges 11.644 11.993 12.183 +1.584% 11.852 -1.176% pass

Result: 6/6 checks passing.

10x Cherry-Pick Stress (targeted)

Workload: 30 sequential cherry-picks (3 reps/mode), with upstream divergence.

Variant Median Time (s) vs Current Wrapper
current_wrapper 0.296 baseline
current_hooks 2.235 +654.986%
current_both 0.287 -3.078%
main_wrapper 1.395 +371.237%

Validation

  • cargo check -q
  • python3 scripts/benchmarks/git/benchmark_modes_vs_main.py --iterations-basic 5 --iterations-complex 4 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin
  • python3 scripts/benchmarks/git/benchmark_nasty_modes_vs_main.py --feature-commits 900 --main-commits 350 --side-commits 250 --files 6 --lines-per-file 1500 --burst-every 15 --repetitions 1 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin
  • targeted 30-commit cherry-pick stress script (3 reps/mode), summary at:
    • /var/folders/6w/760cbpln2cs16fxprwshynb80000gn/T/git-ai-cherrypick-scale-ayt78i0x/summary_cherrypick30.json

Also fixes #215


Open with Devin
**Original Pull Request:** https://github.com/git-ai-project/git-ai/pull/530 **State:** closed **Merged:** Yes --- ## Summary - rewrote hook management to repo-local only (`.git/ai/hooks`) with persisted repo state in `.git/ai/git_hooks_state.json` - removed git-ai global hook management paths and now rely on safe forwarding to prior repo hooks or global fallback hooks when applicable - implemented both-mode child hook virtualization (`-c core.hooksPath=<forward-or-null>`) so child git does not execute git-ai managed hooks - replaced rebase hooksPath mutation with in-place managed-hook masking/restoration (terminal hooks retained, stale-state self-heal) - added sequencer-aware fast paths and cherry-pick terminal batching to reduce managed hook churn - hardened forwarding recursion guards to reject forwarding into `.git/ai` and `.git-ai` paths - hardened benchmark harness setup by re-running `git-ai git-hooks ensure` per copied run repo and asserting local hooksPath/hook surface ## Performance Results ### Heavy Matrix (baseline = `current_wrapper`, margin target = <=25%) Run: `benchmark_modes_vs_main.py --iterations-basic 5 --iterations-complex 4 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin` | Scenario | Wrapper (ms) | Hooks (ms) | Hooks vs Wrapper | Both (ms) | Both vs Wrapper | Status | |---|---:|---:|---:|---:|---:|---| | commit_human | 149.062 | 182.896 | +22.698% | 142.994 | -4.071% | pass | | checkpoint_commit_ai | 307.771 | 344.476 | +11.926% | 305.943 | -0.594% | pass | | reset_mixed_head6 | 262.999 | 269.920 | +2.632% | 258.096 | -1.864% | pass | | stash_roundtrip | 174.314 | 210.041 | +20.496% | 174.443 | +0.074% | pass | | cherry_pick_three | 187.428 | 272.665 | +45.477% | 197.004 | +5.109% | hooks fail | | rebase_linear | 176.566 | 173.724 | -1.610% | 190.119 | +7.676% | pass | | rebase_rebase_merges | 434.018 | 453.332 | +4.450% | 437.533 | +0.810% | pass | | squash_merge_commit | 764.811 | 817.109 | +6.838% | 784.600 | +2.587% | pass | Result: **15/16 checks passing** (only `cherry_pick_three` in hooks mode misses). ### 10x Nasty Rebase Matrix (cpPython workload) Run: `benchmark_nasty_modes_vs_main.py --feature-commits 900 --main-commits 350 --side-commits 250 --files 6 --lines-per-file 1500 --burst-every 15 --repetitions 1 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin` | Scenario | Main Wrapper (s) | Current Wrapper (s) | Hooks (s) | Hooks vs Wrapper | Both (s) | Both vs Wrapper | Status | |---|---:|---:|---:|---:|---:|---:|---| | linear | 8.423 | 8.845 | 8.743 | -1.153% | 9.270 | +4.805% | pass | | onto | 7.465 | 7.538 | 7.824 | +3.794% | 7.681 | +1.897% | pass | | rebase_merges | 11.644 | 11.993 | 12.183 | +1.584% | 11.852 | -1.176% | pass | Result: **6/6 checks passing**. ### 10x Cherry-Pick Stress (targeted) Workload: 30 sequential cherry-picks (`3` reps/mode), with upstream divergence. | Variant | Median Time (s) | vs Current Wrapper | |---|---:|---:| | current_wrapper | 0.296 | baseline | | current_hooks | 2.235 | +654.986% | | current_both | 0.287 | -3.078% | | main_wrapper | 1.395 | +371.237% | ## Validation - `cargo check -q` - `python3 scripts/benchmarks/git/benchmark_modes_vs_main.py --iterations-basic 5 --iterations-complex 4 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin` - `python3 scripts/benchmarks/git/benchmark_nasty_modes_vs_main.py --feature-commits 900 --main-commits 350 --side-commits 250 --files 6 --lines-per-file 1500 --burst-every 15 --repetitions 1 --margin-pct 25 --margin-baseline current_wrapper --enforce-margin` - targeted 30-commit cherry-pick stress script (3 reps/mode), summary at: - `/var/folders/6w/760cbpln2cs16fxprwshynb80000gn/T/git-ai-cherrypick-scale-ayt78i0x/summary_cherrypick30.json` Also fixes #215 <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/git-ai-project/git-ai/pull/530" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
kerem 2026-03-02 04:13:55 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/git-ai#544
No description provided.