git 4.3.2 → 5.0.0.beta.2

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 (297) hide show
  1. checksums.yaml +4 -4
  2. data/.github/copilot-instructions.md +73 -2705
  3. data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +188 -0
  4. data/.github/pull_request_template.md +3 -1
  5. data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
  6. data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
  7. data/.github/skills/command-implementation/REFERENCE.md +993 -0
  8. data/.github/skills/command-implementation/SKILL.md +229 -0
  9. data/.github/skills/command-test-conventions/SKILL.md +660 -0
  10. data/.github/skills/command-yard-documentation/SKILL.md +426 -0
  11. data/.github/skills/dependency-management/SKILL.md +72 -0
  12. data/.github/skills/development-workflow/SKILL.md +506 -0
  13. data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
  14. data/.github/skills/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +22 -0
  15. data/.github/skills/extract-facade-from-base-lib/SKILL.md +600 -0
  16. data/.github/skills/facade-implementation/REFERENCE.md +840 -0
  17. data/.github/skills/facade-implementation/SKILL.md +274 -0
  18. data/.github/skills/facade-test-conventions/SKILL.md +394 -0
  19. data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
  20. data/.github/skills/make-skill-template/SKILL.md +176 -0
  21. data/.github/skills/pr-readiness-review/SKILL.md +185 -0
  22. data/.github/skills/project-context/SKILL.md +313 -0
  23. data/.github/skills/pull-request-review/SKILL.md +168 -0
  24. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
  25. data/.github/skills/release-management/SKILL.md +125 -0
  26. data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
  27. data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
  28. data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
  29. data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
  30. data/.github/skills/reviewing-skills/SKILL.md +189 -0
  31. data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
  32. data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
  33. data/.github/skills/test-debugging/SKILL.md +160 -0
  34. data/.github/skills/yard-documentation/SKILL.md +793 -0
  35. data/.github/workflows/continuous_integration.yml +3 -2
  36. data/.github/workflows/enforce_conventional_commits.yml +1 -1
  37. data/.github/workflows/experimental_continuous_integration.yml +2 -2
  38. data/.github/workflows/release.yml +3 -4
  39. data/.gitignore +8 -0
  40. data/.husky/pre-commit +13 -0
  41. data/.release-please-manifest.json +1 -1
  42. data/.rspec +3 -0
  43. data/.rubocop.yml +12 -3
  44. data/.rubocop_todo.yml +23 -5
  45. data/.yardopts +1 -0
  46. data/CHANGELOG.md +0 -40
  47. data/CONTRIBUTING.md +694 -53
  48. data/README.md +67 -15
  49. data/Rakefile +61 -9
  50. data/UPGRADING.md +141 -0
  51. data/commitlint.test +4 -0
  52. data/git.gemspec +18 -7
  53. data/lib/git/args_builder.rb +0 -8
  54. data/lib/git/branch.rb +369 -43
  55. data/lib/git/branch_delete_failure.rb +31 -0
  56. data/lib/git/branch_delete_result.rb +63 -0
  57. data/lib/git/branch_info.rb +178 -0
  58. data/lib/git/branches.rb +122 -24
  59. data/lib/git/command_line/base.rb +255 -0
  60. data/lib/git/command_line/capturing.rb +251 -0
  61. data/lib/git/command_line/result.rb +96 -0
  62. data/lib/git/command_line/streaming.rb +196 -0
  63. data/lib/git/command_line.rb +43 -322
  64. data/lib/git/command_line_result.rb +4 -88
  65. data/lib/git/commands/add.rb +131 -0
  66. data/lib/git/commands/am/abort.rb +43 -0
  67. data/lib/git/commands/am/apply.rb +252 -0
  68. data/lib/git/commands/am/continue.rb +43 -0
  69. data/lib/git/commands/am/quit.rb +43 -0
  70. data/lib/git/commands/am/retry.rb +47 -0
  71. data/lib/git/commands/am/show_current_patch.rb +64 -0
  72. data/lib/git/commands/am/skip.rb +42 -0
  73. data/lib/git/commands/am.rb +33 -0
  74. data/lib/git/commands/apply.rb +237 -0
  75. data/lib/git/commands/archive/list_formats.rb +46 -0
  76. data/lib/git/commands/archive.rb +140 -0
  77. data/lib/git/commands/arguments.rb +3510 -0
  78. data/lib/git/commands/base.rb +404 -0
  79. data/lib/git/commands/branch/copy.rb +94 -0
  80. data/lib/git/commands/branch/create.rb +173 -0
  81. data/lib/git/commands/branch/delete.rb +80 -0
  82. data/lib/git/commands/branch/list.rb +162 -0
  83. data/lib/git/commands/branch/move.rb +94 -0
  84. data/lib/git/commands/branch/set_upstream.rb +86 -0
  85. data/lib/git/commands/branch/show_current.rb +49 -0
  86. data/lib/git/commands/branch/unset_upstream.rb +57 -0
  87. data/lib/git/commands/branch.rb +34 -0
  88. data/lib/git/commands/cat_file/batch.rb +369 -0
  89. data/lib/git/commands/cat_file/filtered.rb +105 -0
  90. data/lib/git/commands/cat_file/raw.rb +216 -0
  91. data/lib/git/commands/cat_file.rb +49 -0
  92. data/lib/git/commands/checkout/branch.rb +151 -0
  93. data/lib/git/commands/checkout/files.rb +115 -0
  94. data/lib/git/commands/checkout.rb +38 -0
  95. data/lib/git/commands/checkout_index.rb +105 -0
  96. data/lib/git/commands/clean.rb +100 -0
  97. data/lib/git/commands/clone.rb +240 -0
  98. data/lib/git/commands/commit.rb +272 -0
  99. data/lib/git/commands/commit_tree.rb +100 -0
  100. data/lib/git/commands/config_option_syntax/add.rb +83 -0
  101. data/lib/git/commands/config_option_syntax/get.rb +117 -0
  102. data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
  103. data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
  104. data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
  105. data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
  106. data/lib/git/commands/config_option_syntax/get_urlmatch.rb +107 -0
  107. data/lib/git/commands/config_option_syntax/list.rb +107 -0
  108. data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
  109. data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
  110. data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
  111. data/lib/git/commands/config_option_syntax/set.rb +114 -0
  112. data/lib/git/commands/config_option_syntax/unset.rb +89 -0
  113. data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
  114. data/lib/git/commands/config_option_syntax.rb +56 -0
  115. data/lib/git/commands/describe.rb +155 -0
  116. data/lib/git/commands/diff.rb +656 -0
  117. data/lib/git/commands/diff_files.rb +518 -0
  118. data/lib/git/commands/diff_index.rb +496 -0
  119. data/lib/git/commands/fetch.rb +352 -0
  120. data/lib/git/commands/fsck.rb +136 -0
  121. data/lib/git/commands/gc.rb +132 -0
  122. data/lib/git/commands/grep.rb +338 -0
  123. data/lib/git/commands/init.rb +99 -0
  124. data/lib/git/commands/log.rb +632 -0
  125. data/lib/git/commands/ls_files.rb +191 -0
  126. data/lib/git/commands/ls_remote.rb +155 -0
  127. data/lib/git/commands/ls_tree.rb +131 -0
  128. data/lib/git/commands/maintenance/register.rb +75 -0
  129. data/lib/git/commands/maintenance/run.rb +104 -0
  130. data/lib/git/commands/maintenance/start.rb +66 -0
  131. data/lib/git/commands/maintenance/stop.rb +55 -0
  132. data/lib/git/commands/maintenance/unregister.rb +79 -0
  133. data/lib/git/commands/maintenance.rb +31 -0
  134. data/lib/git/commands/merge/abort.rb +44 -0
  135. data/lib/git/commands/merge/continue.rb +44 -0
  136. data/lib/git/commands/merge/quit.rb +46 -0
  137. data/lib/git/commands/merge/start.rb +245 -0
  138. data/lib/git/commands/merge.rb +28 -0
  139. data/lib/git/commands/merge_base.rb +86 -0
  140. data/lib/git/commands/mv.rb +77 -0
  141. data/lib/git/commands/name_rev.rb +114 -0
  142. data/lib/git/commands/pull.rb +377 -0
  143. data/lib/git/commands/push.rb +246 -0
  144. data/lib/git/commands/read_tree.rb +149 -0
  145. data/lib/git/commands/remote/add.rb +91 -0
  146. data/lib/git/commands/remote/get_url.rb +66 -0
  147. data/lib/git/commands/remote/list.rb +54 -0
  148. data/lib/git/commands/remote/prune.rb +61 -0
  149. data/lib/git/commands/remote/remove.rb +52 -0
  150. data/lib/git/commands/remote/rename.rb +69 -0
  151. data/lib/git/commands/remote/set_branches.rb +63 -0
  152. data/lib/git/commands/remote/set_head.rb +82 -0
  153. data/lib/git/commands/remote/set_url.rb +71 -0
  154. data/lib/git/commands/remote/set_url_add.rb +61 -0
  155. data/lib/git/commands/remote/set_url_delete.rb +64 -0
  156. data/lib/git/commands/remote/show.rb +71 -0
  157. data/lib/git/commands/remote/update.rb +72 -0
  158. data/lib/git/commands/remote.rb +42 -0
  159. data/lib/git/commands/repack.rb +277 -0
  160. data/lib/git/commands/reset.rb +147 -0
  161. data/lib/git/commands/rev_parse.rb +297 -0
  162. data/lib/git/commands/revert/abort.rb +45 -0
  163. data/lib/git/commands/revert/continue.rb +57 -0
  164. data/lib/git/commands/revert/quit.rb +47 -0
  165. data/lib/git/commands/revert/skip.rb +44 -0
  166. data/lib/git/commands/revert/start.rb +153 -0
  167. data/lib/git/commands/revert.rb +29 -0
  168. data/lib/git/commands/rm.rb +114 -0
  169. data/lib/git/commands/show.rb +632 -0
  170. data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
  171. data/lib/git/commands/show_ref/exists.rb +78 -0
  172. data/lib/git/commands/show_ref/list.rb +145 -0
  173. data/lib/git/commands/show_ref/verify.rb +120 -0
  174. data/lib/git/commands/show_ref.rb +42 -0
  175. data/lib/git/commands/stash/apply.rb +75 -0
  176. data/lib/git/commands/stash/branch.rb +65 -0
  177. data/lib/git/commands/stash/clear.rb +41 -0
  178. data/lib/git/commands/stash/create.rb +58 -0
  179. data/lib/git/commands/stash/drop.rb +67 -0
  180. data/lib/git/commands/stash/list.rb +39 -0
  181. data/lib/git/commands/stash/pop.rb +78 -0
  182. data/lib/git/commands/stash/push.rb +103 -0
  183. data/lib/git/commands/stash/show.rb +149 -0
  184. data/lib/git/commands/stash/store.rb +63 -0
  185. data/lib/git/commands/stash.rb +38 -0
  186. data/lib/git/commands/status.rb +169 -0
  187. data/lib/git/commands/symbolic_ref/delete.rb +68 -0
  188. data/lib/git/commands/symbolic_ref/read.rb +95 -0
  189. data/lib/git/commands/symbolic_ref/update.rb +76 -0
  190. data/lib/git/commands/symbolic_ref.rb +38 -0
  191. data/lib/git/commands/tag/create.rb +139 -0
  192. data/lib/git/commands/tag/delete.rb +55 -0
  193. data/lib/git/commands/tag/list.rb +143 -0
  194. data/lib/git/commands/tag/verify.rb +71 -0
  195. data/lib/git/commands/tag.rb +26 -0
  196. data/lib/git/commands/update_ref/batch.rb +140 -0
  197. data/lib/git/commands/update_ref/delete.rb +92 -0
  198. data/lib/git/commands/update_ref/update.rb +106 -0
  199. data/lib/git/commands/update_ref.rb +42 -0
  200. data/lib/git/commands/version.rb +57 -0
  201. data/lib/git/commands/worktree/add.rb +140 -0
  202. data/lib/git/commands/worktree/list.rb +64 -0
  203. data/lib/git/commands/worktree/lock.rb +58 -0
  204. data/lib/git/commands/worktree/management_base.rb +51 -0
  205. data/lib/git/commands/worktree/move.rb +66 -0
  206. data/lib/git/commands/worktree/prune.rb +67 -0
  207. data/lib/git/commands/worktree/remove.rb +63 -0
  208. data/lib/git/commands/worktree/repair.rb +76 -0
  209. data/lib/git/commands/worktree/unlock.rb +47 -0
  210. data/lib/git/commands/worktree.rb +43 -0
  211. data/lib/git/commands/write_tree.rb +68 -0
  212. data/lib/git/commands.rb +87 -0
  213. data/lib/git/config.rb +17 -0
  214. data/lib/git/config_entry_info.rb +106 -0
  215. data/lib/git/configuring.rb +665 -0
  216. data/lib/git/deprecation.rb +9 -0
  217. data/lib/git/detached_head_info.rb +54 -0
  218. data/lib/git/diff.rb +293 -7
  219. data/lib/git/diff_file_numstat_info.rb +29 -0
  220. data/lib/git/diff_file_patch_info.rb +134 -0
  221. data/lib/git/diff_file_raw_info.rb +127 -0
  222. data/lib/git/diff_info.rb +169 -0
  223. data/lib/git/diff_path_status.rb +67 -19
  224. data/lib/git/diff_result.rb +32 -0
  225. data/lib/git/diff_stats.rb +51 -14
  226. data/lib/git/dirstat_info.rb +86 -0
  227. data/lib/git/errors.rb +65 -2
  228. data/lib/git/execution_context/global.rb +31 -0
  229. data/lib/git/execution_context/repository.rb +136 -0
  230. data/lib/git/execution_context.rb +501 -0
  231. data/lib/git/file_ref.rb +74 -0
  232. data/lib/git/fsck_object.rb +9 -9
  233. data/lib/git/fsck_result.rb +1 -1
  234. data/lib/git/log.rb +9 -2
  235. data/lib/git/object.rb +90 -27
  236. data/lib/git/parsers/branch.rb +224 -0
  237. data/lib/git/parsers/cat_file.rb +111 -0
  238. data/lib/git/parsers/config_entry.rb +110 -0
  239. data/lib/git/parsers/diff.rb +585 -0
  240. data/lib/git/parsers/fsck.rb +133 -0
  241. data/lib/git/parsers/grep.rb +42 -0
  242. data/lib/git/parsers/ls_remote.rb +79 -0
  243. data/lib/git/parsers/ls_tree.rb +58 -0
  244. data/lib/git/parsers/stash.rb +208 -0
  245. data/lib/git/parsers/tag.rb +257 -0
  246. data/lib/git/remote.rb +120 -9
  247. data/lib/git/repository/branching.rb +743 -0
  248. data/lib/git/repository/committing.rb +187 -0
  249. data/lib/git/repository/configuring.rb +351 -0
  250. data/lib/git/repository/context_helpers.rb +264 -0
  251. data/lib/git/repository/diffing.rb +775 -0
  252. data/lib/git/repository/factories.rb +682 -0
  253. data/lib/git/repository/inspecting.rb +252 -0
  254. data/lib/git/repository/logging.rb +247 -0
  255. data/lib/git/repository/maintenance.rb +65 -0
  256. data/lib/git/repository/merging.rb +357 -0
  257. data/lib/git/repository/object_operations.rb +1199 -0
  258. data/lib/git/repository/path_resolver.rb +207 -0
  259. data/lib/git/repository/remote_operations.rb +898 -0
  260. data/lib/git/repository/shared_private.rb +51 -0
  261. data/lib/git/repository/staging.rb +554 -0
  262. data/lib/git/repository/stashing.rb +143 -0
  263. data/lib/git/repository/status_operations.rb +201 -0
  264. data/lib/git/repository/worktree_operations.rb +159 -0
  265. data/lib/git/repository.rb +203 -1
  266. data/lib/git/stash.rb +78 -4
  267. data/lib/git/stash_info.rb +104 -0
  268. data/lib/git/stashes.rb +125 -13
  269. data/lib/git/status.rb +215 -18
  270. data/lib/git/tag_delete_failure.rb +31 -0
  271. data/lib/git/tag_delete_result.rb +63 -0
  272. data/lib/git/tag_info.rb +105 -0
  273. data/lib/git/version.rb +109 -2
  274. data/lib/git/version_constraint.rb +81 -0
  275. data/lib/git/worktree.rb +108 -6
  276. data/lib/git/worktrees.rb +94 -7
  277. data/lib/git.rb +260 -61
  278. data/redesign/1_architecture_existing.md +54 -18
  279. data/redesign/2_architecture_redesign.md +365 -46
  280. data/redesign/3_architecture_implementation.md +1497 -63
  281. data/redesign/Phase 4 - Step A.md +360 -0
  282. data/redesign/beta_release.md +107 -0
  283. data/redesign/c1c2_audit.md +566 -0
  284. data/redesign/c1c2_bucket6_lib_orphans.md +626 -0
  285. data/redesign/config_design.rb +501 -0
  286. data/tasks/gem_tasks.rake +4 -0
  287. data/tasks/npm_tasks.rake +7 -0
  288. data/tasks/rspec.rake +48 -0
  289. data/tasks/test.rake +13 -1
  290. data/tasks/yard.rake +34 -7
  291. metadata +365 -22
  292. data/lib/git/base.rb +0 -1128
  293. data/lib/git/index.rb +0 -6
  294. data/lib/git/lib.rb +0 -2277
  295. data/lib/git/path.rb +0 -38
  296. data/lib/git/working_directory.rb +0 -6
  297. /data/{release-please-config.json → .release-please-config.json} +0 -0
@@ -0,0 +1,600 @@
1
+ ---
2
+ name: extract-facade-from-base-lib
3
+ description: "Migrates a public method from Git::Base or Git::Lib to a Git::Repository facade method (under lib/git/repository/) as part of the v5.0.0 architectural redesign. Use when extracting a specific public method during the Strangler Fig migration of Git::Base / Git::Lib into Git::Repository."
4
+ ---
5
+
6
+ # Extract Facade from Base/Lib
7
+
8
+ Migrate an existing public method from `Git::Base` and/or `Git::Lib` to a
9
+ `Git::Repository::*` facade method. This is the second extraction step of the
10
+ v5.0.0 redesign — it follows
11
+ [Extract Command from Lib](../extract-command-from-lib/SKILL.md), which moves
12
+ the underlying CLI invocation into a `Git::Commands::*` class.
13
+
14
+ In Phase 4 of the redesign, **both `Git::Base` and `Git::Lib` will be deleted**.
15
+ This migration moves their public surface to `Git::Repository`. Until Phase 4,
16
+ the original methods remain in place and delegate to the new facade method to
17
+ preserve backward compatibility within the migration window.
18
+
19
+ ## Contents
20
+
21
+ - [How to use this skill](#how-to-use-this-skill)
22
+ - [Prerequisites](#prerequisites)
23
+ - [Related skills](#related-skills)
24
+ - [Input](#input)
25
+ - [Source patterns](#source-patterns)
26
+ - [Pattern A — `Git::Base` wrapper + `Git::Lib` implementation](#pattern-a--gitbase-wrapper--gitlib-implementation)
27
+ - [Pattern B — `Git::Lib`-only (public-by-exposure)](#pattern-b--gitlib-only-public-by-exposure)
28
+ - [Pattern C — `Git::Base`-only (no `Git::Lib` method)](#pattern-c--gitbase-only-no-gitlib-method)
29
+ - [Signature compatibility policy](#signature-compatibility-policy)
30
+ - [Keyword-arg remediation list](#keyword-arg-remediation-list)
31
+ - [Determining the option allowlist](#determining-the-option-allowlist)
32
+ - [Workflow](#workflow)
33
+ - [Branch setup](#branch-setup)
34
+ - [Step 1 — Identify the source pattern](#step-1--identify-the-source-pattern)
35
+ - [Step 2 — Plan the migration and get approval](#step-2--plan-the-migration-and-get-approval)
36
+ - [Step 3 — Ensure adequate legacy tests](#step-3--ensure-adequate-legacy-tests)
37
+ - [Step 4 — Ensure the underlying `Git::Commands::*` class exists](#step-4--ensure-the-underlying-gitcommands-class-exists)
38
+ - [Step 5 — Implement the facade method](#step-5--implement-the-facade-method)
39
+ - [Step 6 — Update `Git::Base` and/or `Git::Lib` to delegate](#step-6--update-gitbase-andor-gitlib-to-delegate)
40
+ - [Commit discipline](#commit-discipline)
41
+ - [Quality gates](#quality-gates)
42
+ - [What stays vs. what moves](#what-stays-vs-what-moves)
43
+ - [Review mode](#review-mode)
44
+ - [Invoke](#invoke)
45
+ - [R1 — Source analysis](#r1--source-analysis)
46
+ - [R2 — Legacy test coverage](#r2--legacy-test-coverage)
47
+ - [R3 — Command class](#r3--command-class)
48
+ - [R4 — Facade implementation](#r4--facade-implementation)
49
+ - [R5 — Delegation](#r5--delegation)
50
+ - [R6 — Quality gates](#r6--quality-gates)
51
+
52
+ ## How to use this skill
53
+
54
+ Attach this file to your Copilot Chat context, then invoke with the public method
55
+ to migrate. Examples:
56
+
57
+ ```text
58
+ Using the Extract Facade from Base/Lib skill, migrate Git::Base#commit to
59
+ Git::Repository#commit.
60
+ ```
61
+
62
+ ```text
63
+ Extract Facade: Git::Lib#branches_all (called publicly via g.lib.branches_all)
64
+ ```
65
+
66
+ ## Prerequisites
67
+
68
+ Before starting, you **MUST** load the following skill(s):
69
+
70
+ - [Facade Implementation](../facade-implementation/SKILL.md) — drives the actual
71
+ scaffolding of the new facade method
72
+ - [YARD Documentation](../yard-documentation/SKILL.md) — baseline YARD rules
73
+
74
+ ## Related skills
75
+
76
+ - [Facade Implementation](../facade-implementation/SKILL.md) — used in Step 5 to
77
+ scaffold the new facade method
78
+ - [Facade Test Conventions](../facade-test-conventions/SKILL.md) — unit and
79
+ integration test conventions for the new facade method
80
+ - [Facade YARD Documentation](../facade-yard-documentation/SKILL.md) — YARD docs
81
+ for the new facade module/method
82
+ - [Extract Command from Lib](../extract-command-from-lib/SKILL.md) — sibling
83
+ extraction skill that moves the underlying CLI call into a
84
+ `Git::Commands::*` class. **Run first** when no command class exists yet.
85
+ - [Command Implementation](../command-implementation/SKILL.md) — used in Step 4
86
+ if a new `Git::Commands::*` class needs to be scaffolded
87
+ - [Project Context](../project-context/SKILL.md) — three-layer architecture and
88
+ Phase 4 deletion plan
89
+
90
+ ## Input
91
+
92
+ Required:
93
+
94
+ 1. The `Git::Base` and/or `Git::Lib` public method to migrate.
95
+ 2. The git operation it performs (subcommand + flags).
96
+
97
+ ## Source patterns
98
+
99
+ Public methods being migrated fall into one of three patterns. Identify which
100
+ pattern applies before planning the migration.
101
+
102
+ ### Pattern A — `Git::Base` wrapper + `Git::Lib` implementation
103
+
104
+ The most common pattern. `Git::Base#foo` is a thin wrapper that forwards to
105
+ `Git::Lib#foo`, which contains the orchestration logic.
106
+
107
+ Examples: `commit`, `diff_full`, `branches`, `worktree_add`.
108
+
109
+ ```ruby
110
+ # lib/git/base.rb
111
+ def commit(message, opts = {})
112
+ self.lib.commit(message, opts)
113
+ end
114
+
115
+ # lib/git/lib.rb
116
+ def commit(message, opts = {})
117
+ opts = opts.merge(message: message) if message
118
+ deprecate_commit_no_gpg_sign_option!(opts)
119
+ Git::Commands::Commit.new(self).call(edit: false, **opts).stdout
120
+ end
121
+ ```
122
+
123
+ **Public contract source:** `Git::Base#commit` signature; `Git::Lib#commit`
124
+ implementation.
125
+
126
+ > When migrating, the facade method **must** preserve this signature exactly
127
+ > (e.g. `commit(message, opts = {})`) — even though greenfield facade methods
128
+ > would prefer `**options` per
129
+ > [facade-implementation REFERENCE.md — Choosing the method signature](../facade-implementation/REFERENCE.md#choosing-the-method-signature).
130
+ > The legacy public contract wins during migration.
131
+
132
+ ### Pattern B — `Git::Lib`-only (public-by-exposure)
133
+
134
+ The public API is `g.lib.foo` — `Git::Base` exposes `Git::Lib` as `#lib` (or
135
+ through a similar accessor), so `Git::Lib` methods are reachable as public API
136
+ even when no `Git::Base` wrapper exists.
137
+
138
+ Examples: `branches_all`, `worktrees_all`, `current_branch_state`.
139
+
140
+ ```ruby
141
+ # lib/git/lib.rb (no Git::Base wrapper exists)
142
+ def branches_all
143
+ result = Git::Commands::Branch::List.new(self).call(all: true, format: ...)
144
+ Git::Parsers::Branch.parse_list(result.stdout)
145
+ end
146
+ ```
147
+
148
+ **Public contract source:** `Git::Lib#foo` signature and implementation.
149
+
150
+ **Migration consequence:** After Phase 4, callers using `g.lib.foo` must migrate
151
+ to `g.foo` (or `g.repository.foo`). Document this in the migration plan.
152
+
153
+ ### Pattern C — `Git::Base`-only (no `Git::Lib` method)
154
+
155
+ The implementation lives entirely in `Git::Base` with no `Git::Lib` counterpart.
156
+ The method may call `command(...)` directly via `lib.send(...)` or implement
157
+ filesystem operations.
158
+
159
+ Examples: `add_remote`, `with_index`, `repo_size`, `archive`.
160
+
161
+ ```ruby
162
+ # lib/git/base.rb
163
+ def repo_size
164
+ all_files_size = 0
165
+ Find.find(repo.path) { |f| all_files_size += File.size(f) if File.file?(f) }
166
+ all_files_size
167
+ end
168
+ ```
169
+
170
+ **Public contract source:** `Git::Base#foo` signature and implementation.
171
+
172
+ ## Signature compatibility policy
173
+
174
+ Use this policy in both extraction mode and review mode:
175
+
176
+ | Classification | When it applies | Signature requirement |
177
+ | --- | --- | --- |
178
+ | `legacy-contract` | Method existed in `Git::Base` and/or `Git::Lib` as public API | Copy the 4.x signature verbatim, including rare `**opts` forms where they already exist |
179
+ | `5.x-native` | Truly new facade API with no legacy public predecessor | Use `opts = {}` style (kwargs migration is deferred to v6.x for consistency) |
180
+
181
+ Rules:
182
+
183
+ 1. `legacy-contract` methods preserve the exact 4.x call shape verbatim,
184
+ including rare `**opts` signatures; never alter the parameter list when a
185
+ legacy predecessor exists.
186
+ 2. `5.x-native` methods use `opts = {}` style for consistency; a broader kwargs
187
+ migration is deferred to v6.x so it can be applied uniformly across the
188
+ entire public API.
189
+ 3. Every extracted method must be explicitly classified as `legacy-contract` or
190
+ `5.x-native` before the PR is opened.
191
+ 4. The classification must appear in the PR description and in the extracted
192
+ method's YARD `@note`. Example:
193
+
194
+ ```ruby
195
+ # @note Signature compatibility: legacy-contract — preserves the exact Git::Base#foo 4.x call shape.
196
+ ```
197
+
198
+ ## Keyword-arg remediation list
199
+
200
+ See [KEYWORD_ARG_REMEDIATION.md](KEYWORD_ARG_REMEDIATION.md) for the initial list
201
+ of facade methods that use `**opts`/`**` keyword-splat where the legacy predecessor
202
+ used `opts = {}`. Each method in this list must be resolved before
203
+ `Git.open`/`.clone`/`.init`/`.bare` are changed to return `Git::Repository`:
204
+ either fix the signature to match the `legacy-contract` classification, or
205
+ record an explicit `5.x-native` justification.
206
+
207
+ ## Determining the option allowlist
208
+
209
+ When the facade method uses `assert_valid_opts!`, the allowlist (`*_ALLOWED_OPTS`) must
210
+ contain **only the options that were accepted in the 4.x branch** of this gem. Do not
211
+ expand the allowlist to match everything the underlying `Git::Commands::*` class
212
+ supports — new options are deferred to a follow-up PR so they can be properly
213
+ documented and tested.
214
+
215
+ **How to find the 4.x allowlist for a method:**
216
+
217
+ 1. Open `https://github.com/ruby-git/ruby-git/blob/4.x/lib/git/lib.rb` and search
218
+ for the method's `*_OPTION_MAP` constant (e.g. `ADD_OPTION_MAP`,
219
+ `RESET_OPTION_MAP`).
220
+ 2. The option keys declared in that map are the only keys that were valid in 4.x.
221
+ Any key not present in the map would have raised `ArgumentError` via
222
+ `ArgsBuilder.validate!` — confirmed by
223
+ `https://github.com/ruby-git/ruby-git/blob/4.x/lib/git/args_builder.rb`.
224
+ 3. Use those keys — and only those keys — in the facade's `*_ALLOWED_OPTS`
225
+ constant, `@option` YARD tags, and integration/unit tests.
226
+ 4. If the underlying `Git::Commands::*` class supports additional options beyond the
227
+ 4.x map, note them in a follow-up issue rather than silently including them.
228
+
229
+ ## Workflow
230
+
231
+ ### Branch setup
232
+
233
+ All work must be done on a feature branch. **Never commit or push directly to
234
+ `main`.**
235
+
236
+ ```bash
237
+ git checkout -b <feature-branch-name>
238
+ ```
239
+
240
+ ### Step 1 — Identify the source pattern
241
+
242
+ 1. Locate the public method in `Git::Base` and/or `Git::Lib`.
243
+ 2. Determine which [Source pattern](#source-patterns) applies (A, B, or C).
244
+ 3. Note:
245
+ - the public signature (positional args, options hash, keyword args)
246
+ - the signature classification (`legacy-contract` or `5.x-native`) and
247
+ justification
248
+ - the **exact return value** of the legacy method — read the source code to
249
+ see whether it ends in `.stdout`, `.stdout.chomp`, a parser call, a domain
250
+ object, `nil`, etc. **Do not assume** from the YARD `@return` tag, which
251
+ may be stale or missing. The facade must reproduce this exact value (e.g.
252
+ if `Git::Lib#add` ends in `.stdout`, the facade returns `String`, not
253
+ `Git::CommandLineResult`).
254
+ - any pre-processing (path expansion, option whitelisting, deprecation
255
+ handling)
256
+ - any post-processing (parsing, result-class assembly)
257
+ - any execution-context arguments (`timeout:`, `chdir:`, `env:`)
258
+ - the **4.x-supported options**: locate the corresponding `*_OPTION_MAP`
259
+ constant in `4.x/lib/git/lib.rb` and record which option keys it declared.
260
+ These become the facade's `*_ALLOWED_OPTS` allowlist — see
261
+ [Determining the option allowlist](#determining-the-option-allowlist).
262
+ 4. Document the method's current **public contract** in writing — it must be
263
+ preserved exactly by the facade method.
264
+ 5. Run linters and rubocop to confirm a clean baseline:
265
+
266
+ ```bash
267
+ bundle exec rubocop
268
+ ```
269
+
270
+ ### Step 2 — Plan the migration and get approval
271
+
272
+ Before writing or changing any code, present a migration plan and **wait for
273
+ explicit confirmation** from the user.
274
+
275
+ The plan must include:
276
+
277
+ | Public method | Source pattern | Underlying command class | Class exists? | Target facade module | Notes |
278
+ | --- | --- | --- | --- | --- | --- |
279
+ | `Git::Base#foo` | A / B / C | `Git::Commands::Foo` | ✅ / 🆕 | `Git::Repository::Topic` (existing or new) | mapping decisions |
280
+
281
+ Also state:
282
+
283
+ - The exact **public contract** to preserve (signature + return type + raised
284
+ errors).
285
+ - The signature classification and why (`legacy-contract` or `5.x-native`).
286
+ - For `legacy-contract` methods, confirm the exact 4.x call shape is preserved
287
+ verbatim (including rare `**opts` signatures).
288
+ - Whether a new topic module is required (justify per
289
+ [facade-implementation REFERENCE.md](../facade-implementation/REFERENCE.md#decision-rules-for-adding-a-new-module)).
290
+ When extracting one method at a time, scan `Git::Base` / `Git::Lib` for
291
+ siblings on the same git topic and check
292
+ `redesign/3_architecture_implementation.md` before deciding — see
293
+ [One-at-a-time extraction](../facade-implementation/REFERENCE.md#one-at-a-time-extraction-from-gitbase--gitlib).
294
+ - The delegation strategy for `Git::Base` and/or `Git::Lib` (Step 6) — both
295
+ remain in place during the migration window and delegate to the new facade.
296
+ - For Pattern B: explicit note that `g.lib.foo` callers will need to migrate
297
+ before Phase 4; capture this as a follow-up issue or CHANGELOG entry.
298
+
299
+ Then ask:
300
+
301
+ > Does this mapping look correct? Any changes before I start implementing?
302
+
303
+ **Do not move to Step 3 until the user confirms the plan.**
304
+
305
+ ### Step 3 — Ensure adequate legacy tests
306
+
307
+ Verify that legacy tests in `tests/units/` and existing specs in `spec/`
308
+ adequately cover the public method. The legacy tests guarantee the migration
309
+ preserves backward compatibility.
310
+
311
+ 1. Search for coverage:
312
+
313
+ ```bash
314
+ grep -rn '<method_name>' tests/units/ spec/
315
+ ```
316
+
317
+ 2. If coverage is insufficient, add **minimal new tests** that exercise the
318
+ current public contract. Use existing legacy test conventions for `Test::Unit`
319
+ tests in `tests/units/`. Do **not** change existing tests.
320
+ 3. Add or update facade tests that prove signature behavior:
321
+ - for `legacy-contract` methods, test the expected legacy call shape(s) (positional hash and/or keyword-arg / `**opts`)
322
+
323
+ 4. Run the new tests and RuboCop:
324
+
325
+ ```bash
326
+ bundle exec bin/test <test-file-basename>
327
+ bundle exec rubocop tests/units/<test-file>
328
+ ```
329
+
330
+ 5. Commit:
331
+
332
+ ```bash
333
+ git commit -m "refactor(test): add legacy tests for <method_name>"
334
+ ```
335
+
336
+ ### Step 4 — Ensure the underlying `Git::Commands::*` class exists
337
+
338
+ The facade method calls one or more `Git::Commands::*` classes. If any required
339
+ command class does not exist yet, scaffold it first using
340
+ [Extract Command from Lib](../extract-command-from-lib/SKILL.md) (which in turn
341
+ uses [Command Implementation](../command-implementation/SKILL.md)).
342
+
343
+ For Pattern C migrations, the source `Git::Base` method may not currently call
344
+ through a `Git::Commands::*` class at all (it uses `command(...)` directly or
345
+ filesystem operations). In that case, you must scaffold the `Git::Commands::*`
346
+ class before this step.
347
+
348
+ Skip this step when every required command class already exists.
349
+
350
+ ### Step 5 — Implement the facade method
351
+
352
+ Delegate to the [Facade Implementation](../facade-implementation/SKILL.md) skill
353
+ in **Scaffold** or **Update** mode. That skill handles:
354
+
355
+ - topic module selection
356
+ - generating or extending `lib/git/repository/<topic>.rb`
357
+ - generating or extending `spec/unit/git/repository/<topic>_spec.rb`
358
+ - generating or extending `spec/integration/git/repository/<topic>_spec.rb`
359
+ - YARD documentation
360
+ - running facade-side quality gates
361
+
362
+ The new facade method **must preserve the source method's public contract
363
+ exactly** — same signature, same return type, same raised errors. Use the
364
+ exact return type the source method documented (String, Array, Hash, domain
365
+ object, `CommandLineResult`).
366
+
367
+ Apply the [Signature compatibility policy](#signature-compatibility-policy):
368
+
369
+ - `legacy-contract`: preserve the 4.x call shape verbatim and add call-shape
370
+ tests.
371
+ - `5.x-native`: use `opts = {}` style; classification must be explicit in
372
+ migration notes.
373
+
374
+ For Pattern A and B migrations, copy any pre-processing logic
375
+ (option whitelisting, deprecation rewrites, key normalization) from `Git::Lib`
376
+ to the facade method. Do **not** leave it behind in `Git::Lib` — the facade is
377
+ now the source of truth.
378
+
379
+ When copying option whitelisting logic, use only the keys from the 4.x
380
+ `*_OPTION_MAP` for the `*_ALLOWED_OPTS` constant — do not expand to match the
381
+ full `Git::Commands::*` argument DSL. See
382
+ [Determining the option allowlist](#determining-the-option-allowlist).
383
+
384
+ For Pattern C migrations, port any pre-processing or filesystem logic from
385
+ `Git::Base` to the facade method.
386
+
387
+ After the facade method is in place and tests pass, commit:
388
+
389
+ ```bash
390
+ git commit -m "feat(repository): add Git::Repository#<method_name> facade method"
391
+ ```
392
+
393
+ ### Step 6 — Update `Git::Base` and/or `Git::Lib` to delegate
394
+
395
+ The original methods stay in place during the migration window and delegate to
396
+ the new facade method. Both `Git::Base` and `Git::Lib` will be deleted in
397
+ Phase 4; until then, delegation preserves backward compatibility.
398
+
399
+ For each source pattern, the delegation looks like:
400
+
401
+ **Pattern A** — both files delegate:
402
+
403
+ ```ruby
404
+ # lib/git/base.rb — already a wrapper; redirect to repository
405
+ def commit(message, opts = {})
406
+ repository.commit(message, opts)
407
+ end
408
+
409
+ # lib/git/lib.rb — keep public-by-exposure callers working
410
+ def commit(message, opts = {})
411
+ @repository.commit(message, opts)
412
+ end
413
+ ```
414
+
415
+ **Pattern B** — `Git::Lib` delegates:
416
+
417
+ ```ruby
418
+ # lib/git/lib.rb
419
+ def branches_all
420
+ @repository.branches_all
421
+ end
422
+ ```
423
+
424
+ **Pattern C** — `Git::Base` delegates:
425
+
426
+ ```ruby
427
+ # lib/git/base.rb
428
+ def remote_add(name, url, opts = {})
429
+ facade_repository.remote_add(name, url, opts)
430
+ end
431
+ ```
432
+
433
+ (Use `facade_repository` to access the `Git::Repository` facade instance — this
434
+ is the accessor used by all migrated methods in `Git::Base`.)
435
+
436
+ After delegation is in place, verify:
437
+
438
+ ```bash
439
+ bundle exec bin/test <legacy-test-file-basename>
440
+ bundle exec rspec
441
+ bundle exec rubocop
442
+ bundle exec rake yard
443
+ ```
444
+
445
+ Commit:
446
+
447
+ ```bash
448
+ git commit -m "refactor(base): delegate <method_name> to Git::Repository"
449
+ ```
450
+
451
+ (Use `refactor(lib):` if only `Git::Lib` was updated. When both files change,
452
+ use two separate commits — one per scope — to keep each commit single-scoped.)
453
+
454
+ ## Commit discipline
455
+
456
+ Keep work organized into **three logical commit categories** (each optional if
457
+ no changes were needed for that step):
458
+
459
+ 1. `refactor(test): add legacy tests for <method_name>` — new tests in
460
+ `tests/units/` (Step 3)
461
+ 2. `feat(repository): add Git::Repository#<method_name> facade method` — new
462
+ facade module/method, unit specs, integration specs (Step 5)
463
+ 3. `refactor(base): delegate <method_name> to Git::Repository` — `Git::Base`
464
+ updated to delegate (Step 6); use `refactor(lib):` if only `Git::Lib`
465
+ changed. When both files change, prefer **two separate commits** — one
466
+ per scope — so each commit has a single conventional-commits scope.
467
+
468
+ If a new `Git::Commands::*` class was scaffolded in Step 4, it gets its own
469
+ commit (`refactor(command): add Git::Commands::<Command> class`) per
470
+ [Extract Command from Lib](../extract-command-from-lib/SKILL.md).
471
+
472
+ **Issue and PR references in commit bodies:** Do not use `#<number>` in the
473
+ commit body — write `issue 1000` not `issue #1000`. To close an issue/PR, use
474
+ `Closes`/`Fixes`/`Resolves #<number>` in the footer.
475
+
476
+ If further changes are needed after task commits are created, amend into the
477
+ appropriate commit and rebase. Always verify quality gates pass after rebasing.
478
+
479
+ ## Quality gates
480
+
481
+ Run the gates discovered from the project's parallel default task at every step:
482
+
483
+ ```bash
484
+ bundle exec ruby -e "require 'rake'; load 'Rakefile'; puts Rake::Task['default:parallel'].prerequisites"
485
+ ```
486
+
487
+ Run each listed task individually via `bundle exec rake <task>` and fix
488
+ failures before advancing. All listed tasks must pass before committing.
489
+
490
+ ## What stays vs. what moves
491
+
492
+ **Stays in `Git::Base` / `Git::Lib` until Phase 4:**
493
+
494
+ - Delegating methods — one-line forwards to the new `Git::Repository` facade
495
+ method, preserving backward compatibility during the migration window.
496
+ - Methods not yet migrated — original implementation remains until extracted.
497
+
498
+ **Moves to `Git::Repository::*`:**
499
+
500
+ - The full public contract (signature, return type, raised errors).
501
+ - All pre-processing logic (option whitelisting, deprecation handling, key
502
+ normalization, defaults).
503
+ - All post-processing logic (parsing, result-class assembly).
504
+ - The YARD docs that document the public API.
505
+
506
+ > **Branch workflow:** Implement migrations on a feature branch. Never commit
507
+ > or push directly to `main` — open a pull request when changes are ready to
508
+ > merge.
509
+
510
+ ## Review mode
511
+
512
+ Use this checklist to audit a completed extraction PR. For each item, read the
513
+ relevant source files, check the box, and note any finding.
514
+
515
+ ### Invoke
516
+
517
+ ```text
518
+ Using the Extract Facade from Base/Lib skill (review mode), audit the extraction
519
+ of Git::Base#<method_name>.
520
+ ```
521
+
522
+ ### R1 — Source analysis
523
+
524
+ - [ ] **Pattern identified.** Confirm which source pattern (A, B, or C) applies
525
+ by reading `Git::Base` and `Git::Lib`.
526
+ - [ ] **Classification recorded.** The method is explicitly classified as
527
+ `legacy-contract` or `5.x-native`, with rationale.
528
+ - [ ] **Signature policy respected.** For `legacy-contract` methods, facade
529
+ signature behavior preserves the legacy call shape contract; for
530
+ `5.x-native`, `opts = {}` style is confirmed (no `**kwargs` in v5).
531
+ - [ ] **Return type correct.** The facade returns the same type as the legacy
532
+ implementation (e.g. `String` from `.stdout`, not `CommandLineResult`). Read
533
+ the source — do not rely on YARD tags alone.
534
+ - [ ] **4.x options only in allowlist.** The `*_ALLOWED_OPTS` constant contains
535
+ only keys declared in the corresponding `*_OPTION_MAP` in
536
+ `4.x/lib/git/lib.rb`. Look up the map at
537
+ `https://github.com/ruby-git/ruby-git/blob/4.x/lib/git/lib.rb`. Any extra
538
+ keys are a finding.
539
+ - [ ] **Pre-processing ported.** All option whitelisting, deprecation handling,
540
+ and key normalization from `Git::Lib` is reproduced in the facade. Nothing
541
+ was left behind in `Git::Lib`.
542
+ - [ ] **Post-processing ported.** Any parsing or result-class assembly that
543
+ lived in `Git::Lib` is reproduced in the facade.
544
+
545
+ ### R2 — Legacy test coverage
546
+
547
+ - [ ] **Legacy tests exist and pass.** `tests/units/` has tests exercising the
548
+ public method. Verify with `bundle exec bin/test <test-file-basename>`.
549
+ - [ ] **All 4.x options exercised.** Every option in `*_ALLOWED_OPTS` has at
550
+ least one legacy or integration test that passes an actual value and asserts
551
+ the outcome.
552
+
553
+ ### R3 — Command class
554
+
555
+ - [ ] **Command class exists.** The `Git::Commands::*` class used by the facade
556
+ exists in `lib/git/commands/`.
557
+ - [ ] **Arguments DSL covers the allowlisted options.** Every key in
558
+ `*_ALLOWED_OPTS` maps to a declared entry in the command's `arguments` block.
559
+
560
+ ### R4 — Facade implementation
561
+
562
+ - [ ] **Topic module correct.** The facade method is placed in the right
563
+ `Git::Repository::*` module per the redesign topic groupings.
564
+ - [ ] **`assert_valid_opts!` used.** The facade calls
565
+ `Git::Repository::Internal.assert_valid_opts!(ALLOWED_OPTS, **)` before
566
+ forwarding to the command.
567
+ - [ ] **`*_ALLOWED_OPTS` placement correct.** Each `<METHOD>_ALLOWED_OPTS`
568
+ constant is declared **immediately before** the public facade method that
569
+ uses it (not grouped at the top of the module, not inside `Private`).
570
+ - [ ] **YARD docs complete.** Each allowed option has an `@option` tag with
571
+ type, name, default, and description. `@param`, `@return`, `@raise` are
572
+ present and accurate.
573
+ - [ ] **Unit specs present.** `spec/unit/git/repository/<topic>_spec.rb`
574
+ covers: default call, explicit path(s), each documented option, unknown
575
+ option raises `ArgumentError`, return value is `.stdout`.
576
+ - [ ] **Call-shape tests present.** For `legacy-contract` methods, tests assert
577
+ the expected legacy call shape(s) as used in 4.x (positional hash and/or keyword-arg / `**opts` where applicable).
578
+ - [ ] **Integration specs present (or explicitly skipped).** Write
579
+ `spec/integration/git/repository/<topic>_spec.rb` **only** when the facade
580
+ adds behavior not exercised by any single command's integration tests —
581
+ specifically multi-command orchestration or facade-owned post-processing of
582
+ real git output. For one-line delegators (e.g. `#add`, `#reset`) the
583
+ command's own integration tests already provide end-to-end coverage; omit
584
+ the facade integration spec and add a comment in the unit spec explaining
585
+ which command integration specs provide coverage.
586
+
587
+ ### R5 — Delegation
588
+
589
+ - [ ] **`Git::Base` delegates.** The original `Git::Base` method is a one-line
590
+ forward to `facade_repository.<method>(...)`.
591
+ - [ ] **`Git::Lib` delegates (Pattern A/B only).** The original `Git::Lib`
592
+ method is a one-line forward to the facade.
593
+ - [ ] **Legacy tests still pass after delegation.** Run
594
+ `bundle exec bin/test <test-file-basename>` against the delegating methods.
595
+
596
+ ### R6 — Quality gates
597
+
598
+ - [ ] `bundle exec rspec` passes
599
+ - [ ] `bundle exec rubocop` passes
600
+ - [ ] `bundle exec rake yard` passes (no undocumented public methods)