ace-git-copilot 0.3.4__tar.gz → 0.3.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/PKG-INFO +8 -1
  2. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/README.md +7 -0
  3. ace_git_copilot-0.3.6/ace/__init__.py +1 -0
  4. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/intent.py +3 -0
  5. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/cli.py +16 -4
  6. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/context.py +25 -4
  7. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/pyproject.toml +1 -1
  8. ace_git_copilot-0.3.6/tests/test_merge_state.py +84 -0
  9. ace_git_copilot-0.3.4/ace/__init__.py +0 -1
  10. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/AGENTS.md +0 -0
  11. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/BRIEFING.md +0 -0
  12. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/ORIGINAL_REQUEST.md +0 -0
  13. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/e2e_testing_track/BRIEFING.md +0 -0
  14. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/e2e_testing_track/ORIGINAL_REQUEST.md +0 -0
  15. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/e2e_testing_track/SCOPE.md +0 -0
  16. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/e2e_testing_track/progress.md +0 -0
  17. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/BRIEFING.md +0 -0
  18. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/ORIGINAL_REQUEST.md +0 -0
  19. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/emojis_list.txt +0 -0
  20. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/find_unused_modules.py +0 -0
  21. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/handoff.md +0 -0
  22. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/measure_lazy_startup.py +0 -0
  23. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/measure_startup.py +0 -0
  24. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/profile_imports.py +0 -0
  25. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/progress.md +0 -0
  26. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/run_importtime.py +0 -0
  27. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/search_banner.py +0 -0
  28. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/search_emojis.py +0 -0
  29. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/search_git_usages.py +0 -0
  30. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/search_usages.py +0 -0
  31. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/test_import_profiler.py +0 -0
  32. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/explorer_init/test_mocked_sys.py +0 -0
  33. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/handoff.md +0 -0
  34. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/implementation_track/BRIEFING.md +0 -0
  35. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/implementation_track/ORIGINAL_REQUEST.md +0 -0
  36. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/implementation_track/explorer_initial_report.md +0 -0
  37. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/implementation_track/progress.md +0 -0
  38. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/orchestrator/.gitkeep +0 -0
  39. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/orchestrator/BRIEFING.md +0 -0
  40. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/orchestrator/ORIGINAL_REQUEST.md +0 -0
  41. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/orchestrator/PROJECT.md +0 -0
  42. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/orchestrator/progress.md +0 -0
  43. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/teamwork_preview_explorer_e2e_explore/BRIEFING.md +0 -0
  44. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/teamwork_preview_explorer_e2e_explore/ORIGINAL_REQUEST.md +0 -0
  45. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/teamwork_preview_explorer_e2e_explore/handoff.md +0 -0
  46. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/teamwork_preview_explorer_e2e_explore/progress.md +0 -0
  47. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_e2e_testing/BRIEFING.md +0 -0
  48. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_e2e_testing/ORIGINAL_REQUEST.md +0 -0
  49. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_e2e_testing/progress.md +0 -0
  50. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_m1_startup/BRIEFING.md +0 -0
  51. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_m1_startup/ORIGINAL_REQUEST.md +0 -0
  52. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.agents/worker_m1_startup/progress.md +0 -0
  53. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.env.example +0 -0
  54. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.github/workflows/tests.yml +0 -0
  55. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/.gitignore +0 -0
  56. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/CODE_OF_CONDUCT.md +0 -0
  57. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/CONTRIBUTING.md +0 -0
  58. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/LICENSE +0 -0
  59. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/PROJECT.md +0 -0
  60. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/SECURITY.md +0 -0
  61. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/SUPPORT.md +0 -0
  62. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/TEST_INFRA.md +0 -0
  63. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/TEST_READY.md +0 -0
  64. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/__main__.py +0 -0
  65. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/changelog_generator.py +0 -0
  66. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/code_reviewer.py +0 -0
  67. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/commit_generator.py +0 -0
  68. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/conflict_resolver.py +0 -0
  69. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/gitignore_generator.py +0 -0
  70. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/history_analyzer.py +0 -0
  71. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/intent_parser.py +0 -0
  72. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/llm_factory.py +0 -0
  73. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/pr_drafter.py +0 -0
  74. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/changelog.py +0 -0
  75. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/commit.py +0 -0
  76. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/conflict.py +0 -0
  77. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/doctor.py +0 -0
  78. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/explain.py +0 -0
  79. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/ignore.py +0 -0
  80. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/pr.py +0 -0
  81. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/rebase.py +0 -0
  82. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/review.py +0 -0
  83. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/search.py +0 -0
  84. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/prompts/undo.py +0 -0
  85. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ai/rebase_helper.py +0 -0
  86. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/config.py +0 -0
  87. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/diagnostics.py +0 -0
  88. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/git_ops.py +0 -0
  89. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/hooks.py +0 -0
  90. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/core/safety.py +0 -0
  91. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ui/banner.py +0 -0
  92. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ui/dashboard.py +0 -0
  93. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ui/display.py +0 -0
  94. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ui/prompts.py +0 -0
  95. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/ui/themes.py +0 -0
  96. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/utils/conflict_parser.py +0 -0
  97. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/utils/diff_parser.py +0 -0
  98. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/ace/utils/json_utils.py +0 -0
  99. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/conftest.py +0 -0
  100. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/e2e/conftest.py +0 -0
  101. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/e2e/test_tier1_features.py +0 -0
  102. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/e2e/test_tier2_boundaries.py +0 -0
  103. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/e2e/test_tier3_combinations.py +0 -0
  104. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/e2e/test_tier4_workloads.py +0 -0
  105. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_changelog_generator.py +0 -0
  106. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_code_reviewer.py +0 -0
  107. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_config_atomic_write.py +0 -0
  108. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_conflict_resolver.py +0 -0
  109. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_conflict_resolver_backup.py +0 -0
  110. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_context_gitdir_detection.py +0 -0
  111. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_diagnostics.py +0 -0
  112. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_diff_trimmer.py +0 -0
  113. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_git_ops.py +0 -0
  114. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_git_ops_execute.py +0 -0
  115. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_help.py +0 -0
  116. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_history_analyzer.py +0 -0
  117. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_hooks.py +0 -0
  118. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_ignore.py +0 -0
  119. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_intent_parser.py +0 -0
  120. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_llm_factory.py +0 -0
  121. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_llm_factory_ollama.py +0 -0
  122. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_pr_drafter.py +0 -0
  123. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_rebase_helper.py +0 -0
  124. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_safety.py +0 -0
  125. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_search.py +0 -0
  126. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_undo.py +0 -0
  127. {ace_git_copilot-0.3.4 → ace_git_copilot-0.3.6}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ace-git-copilot
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: AI-powered Git copilot — talk to Git in plain English
5
5
  Project-URL: Homepage, https://github.com/jachinsamuel/Ace
6
6
  Project-URL: Documentation, https://github.com/jachinsamuel/Ace#readme
@@ -199,6 +199,13 @@ Distributed under the MIT License. See [LICENSE](LICENSE) for more details.
199
199
 
200
200
  ## Changelog
201
201
 
202
+ ### v0.3.6 — Merge/Rebase Conflict Planning Fix (2026-07-12)
203
+ * Enhanced repository context builder to check for active unmerged files in the index, distinguishing between resolved and unresolved conflict states.
204
+ * Updated AI intent guidelines to prevent the planner from incorrectly suggesting `git merge --abort` when conflicts are already resolved and ready to be finalized.
205
+
206
+ ### v0.3.5 — Empty Diff Handling (2026-07-11)
207
+ * Improved warning panel message and title when committing empty files or mode changes to prevent confusing users when files are already staged.
208
+
202
209
  ### v0.3.4 — Workspace Management (2026-07-11)
203
210
  * Added new `workspace` command (alias `ws`) to scan, monitor, and navigate multiple repositories.
204
211
  * Shows active branch, staged/unstaged/untracked file counts, and local upstream sync offsets in a Rich Table.
@@ -166,6 +166,13 @@ Distributed under the MIT License. See [LICENSE](LICENSE) for more details.
166
166
 
167
167
  ## Changelog
168
168
 
169
+ ### v0.3.6 — Merge/Rebase Conflict Planning Fix (2026-07-12)
170
+ * Enhanced repository context builder to check for active unmerged files in the index, distinguishing between resolved and unresolved conflict states.
171
+ * Updated AI intent guidelines to prevent the planner from incorrectly suggesting `git merge --abort` when conflicts are already resolved and ready to be finalized.
172
+
173
+ ### v0.3.5 — Empty Diff Handling (2026-07-11)
174
+ * Improved warning panel message and title when committing empty files or mode changes to prevent confusing users when files are already staged.
175
+
169
176
  ### v0.3.4 — Workspace Management (2026-07-11)
170
177
  * Added new `workspace` command (alias `ws`) to scan, monitor, and navigate multiple repositories.
171
178
  * Shows active branch, staged/unstaged/untracked file counts, and local upstream sync offsets in a Rich Table.
@@ -0,0 +1 @@
1
+ __version__ = "0.3.6"
@@ -26,6 +26,9 @@ You MUST return a JSON response containing exactly the following keys, and nothi
26
26
  - **moderate**: Standard modifications (commit, standard push, branch creation, switching branches, merge, rebase, stashing, soft/mixed reset).
27
27
  - **destructive**: Irreversible changes (hard reset, force push, git clean, force branch deletion).
28
28
  6. Always provide a safer alternative in `alternatives` if `risk_level` is moderate or destructive.
29
+ 7. If a merge, rebase, cherry-pick, or revert is in progress and the context indicates that conflicts are resolved (e.g., "Merge conflicts resolved. Ready to finalize merge."), do NOT abort the operation unless the user explicitly requests to abort. Instead, finalize/continue the operation:
30
+ - For a resolved merge, cherry-pick, or revert, use `git commit` or `ace commit` to finalize.
31
+ - For a resolved rebase, use `git rebase --continue` to continue.
29
32
 
30
33
  ### Examples:
31
34
 
@@ -299,10 +299,22 @@ def commit_cmd(
299
299
  with spinner("Analyzing changes and generating commit message..."):
300
300
  msg = generator.generate_message(format_type=format_type, offline=offline)
301
301
  except NoStagedChangesError as e:
302
- show_warning_panel(
303
- f"{str(e)}\n\n[bold]Tip:[/bold] Stage your files first: [command]git add <files>[/command]",
304
- "No Staged Changes"
305
- )
302
+ staged_files = []
303
+ try:
304
+ staged_files = git_ops.get_status().get("staged", [])
305
+ except Exception:
306
+ pass
307
+
308
+ if staged_files:
309
+ show_warning_panel(
310
+ f"{str(e)}\n\n[bold]Tip:[/bold] Use [command]git commit -m \"message\"[/command] to commit these changes manually, or add content to the files.",
311
+ "Empty Staged Diff"
312
+ )
313
+ else:
314
+ show_warning_panel(
315
+ f"{str(e)}\n\n[bold]Tip:[/bold] Stage your files first: [command]git add <files>[/command]",
316
+ "No Staged Changes"
317
+ )
306
318
  raise typer.Exit(code=0)
307
319
  except LLMConfigurationError as e:
308
320
  show_error_panel(f"{str(e)}\n\nRun [bold]ace setup[/bold] to configure your AI credentials.", "Configuration Error")
@@ -75,22 +75,43 @@ class RepoContext:
75
75
  if not git_dir.exists():
76
76
  return state
77
77
 
78
+ # Check if index has unmerged (conflicted) files
79
+ has_conflicts = False
80
+ try:
81
+ unmerged = self.git_ops.repo.index.unmerged_files()
82
+ if unmerged:
83
+ has_conflicts = True
84
+ except Exception:
85
+ pass
86
+
78
87
  if (git_dir / "MERGE_HEAD").exists():
79
88
  state["in_progress"] = True
80
89
  state["type"] = "merge"
81
- state["detail"] = "Merge conflict/resolution in progress."
90
+ if has_conflicts:
91
+ state["detail"] = "Merge conflicts exist. Need resolution."
92
+ else:
93
+ state["detail"] = "Merge conflicts resolved. Ready to finalize merge."
82
94
  elif (git_dir / "rebase-merge").exists() or (git_dir / "rebase-apply").exists():
83
95
  state["in_progress"] = True
84
96
  state["type"] = "rebase"
85
- state["detail"] = "Rebase operation in progress."
97
+ if has_conflicts:
98
+ state["detail"] = "Rebase conflicts exist. Need resolution."
99
+ else:
100
+ state["detail"] = "Rebase conflicts resolved. Ready to continue rebase."
86
101
  elif (git_dir / "CHERRY_PICK_HEAD").exists():
87
102
  state["in_progress"] = True
88
103
  state["type"] = "cherry-pick"
89
- state["detail"] = "Cherry-pick operation in progress."
104
+ if has_conflicts:
105
+ state["detail"] = "Cherry-pick conflicts exist. Need resolution."
106
+ else:
107
+ state["detail"] = "Cherry-pick conflicts resolved. Ready to finalize cherry-pick."
90
108
  elif (git_dir / "REVERT_HEAD").exists():
91
109
  state["in_progress"] = True
92
110
  state["type"] = "revert"
93
- state["detail"] = "Revert operation in progress."
111
+ if has_conflicts:
112
+ state["detail"] = "Revert conflicts exist. Need resolution."
113
+ else:
114
+ state["detail"] = "Revert conflicts resolved. Ready to finalize revert."
94
115
 
95
116
  return state
96
117
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ace-git-copilot"
3
- version = "0.3.4"
3
+ version = "0.3.6"
4
4
  description = "AI-powered Git copilot — talk to Git in plain English"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,84 @@
1
+ import pytest
2
+ from unittest.mock import patch, MagicMock
3
+ from pathlib import Path
4
+ from ace.core.context import RepoContext
5
+ from ace.core.git_ops import GitOps
6
+
7
+ @pytest.fixture
8
+ def mock_git_ops():
9
+ git_ops = MagicMock(spec=GitOps)
10
+ git_ops.working_dir = "/mock/repo"
11
+ mock_repo = MagicMock()
12
+ mock_repo.git_dir = "/mock/repo/.git"
13
+ git_ops.repo = mock_repo
14
+ return git_ops
15
+
16
+ @patch("pathlib.Path.exists", autospec=True)
17
+ def test_no_active_operation(mock_exists, mock_git_ops):
18
+ mock_exists.return_value = False
19
+ context = RepoContext(mock_git_ops)
20
+ state = context.check_merge_rebase_state()
21
+
22
+ assert state["in_progress"] is False
23
+ assert state["type"] is None
24
+ assert state["detail"] == ""
25
+
26
+ @patch("pathlib.Path.exists", autospec=True)
27
+ def test_merge_active_unresolved(mock_exists, mock_git_ops):
28
+ mock_exists.return_value = True
29
+ mock_git_ops.repo.index.unmerged_files.return_value = {"file1.txt": [None]}
30
+
31
+ context = RepoContext(mock_git_ops)
32
+ state = context.check_merge_rebase_state()
33
+
34
+ assert state["in_progress"] is True
35
+ assert state["type"] == "merge"
36
+ assert "Need resolution" in state["detail"]
37
+
38
+ @patch("pathlib.Path.exists", autospec=True)
39
+ def test_merge_active_resolved(mock_exists, mock_git_ops):
40
+ mock_exists.return_value = True
41
+ mock_git_ops.repo.index.unmerged_files.return_value = {}
42
+
43
+ context = RepoContext(mock_git_ops)
44
+ state = context.check_merge_rebase_state()
45
+
46
+ assert state["in_progress"] is True
47
+ assert state["type"] == "merge"
48
+ assert "resolved" in state["detail"]
49
+ assert "finalize merge" in state["detail"]
50
+
51
+ @patch("pathlib.Path.exists", autospec=True)
52
+ def test_rebase_active_unresolved(mock_exists, mock_git_ops):
53
+ def exists_check(path_obj):
54
+ if path_obj.name == "MERGE_HEAD":
55
+ return False
56
+ return True
57
+
58
+ mock_exists.side_effect = exists_check
59
+ mock_git_ops.repo.index.unmerged_files.return_value = {"file2.txt": [None]}
60
+
61
+ context = RepoContext(mock_git_ops)
62
+ state = context.check_merge_rebase_state()
63
+
64
+ assert state["in_progress"] is True
65
+ assert state["type"] == "rebase"
66
+ assert "Need resolution" in state["detail"]
67
+
68
+ @patch("pathlib.Path.exists", autospec=True)
69
+ def test_rebase_active_resolved(mock_exists, mock_git_ops):
70
+ def exists_check(path_obj):
71
+ if path_obj.name == "MERGE_HEAD":
72
+ return False
73
+ return True
74
+
75
+ mock_exists.side_effect = exists_check
76
+ mock_git_ops.repo.index.unmerged_files.return_value = {}
77
+
78
+ context = RepoContext(mock_git_ops)
79
+ state = context.check_merge_rebase_state()
80
+
81
+ assert state["in_progress"] is True
82
+ assert state["type"] == "rebase"
83
+ assert "resolved" in state["detail"]
84
+ assert "continue rebase" in state["detail"]
@@ -1 +0,0 @@
1
- __version__ = "0.3.4"
File without changes