git 5.0.0.beta.2 → 5.0.0.beta.4

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 (270) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +27 -0
  3. data/.github/copilot-instructions.md +3 -8
  4. data/.github/hooks/bin-setup-on-worktree.json +11 -0
  5. data/.github/hooks/run-bin-setup-once.sh +14 -0
  6. data/.github/skills/breaking-change-analysis/SKILL.md +6 -9
  7. data/.github/skills/ci-cd-troubleshooting/SKILL.md +2 -2
  8. data/.github/skills/command-implementation/REFERENCE.md +34 -33
  9. data/.github/skills/command-implementation/SKILL.md +5 -4
  10. data/.github/skills/command-test-conventions/SKILL.md +13 -9
  11. data/.github/skills/command-yard-documentation/SKILL.md +14 -6
  12. data/.github/skills/development-workflow/SKILL.md +20 -14
  13. data/.github/skills/facade-implementation/REFERENCE.md +19 -22
  14. data/.github/skills/facade-implementation/SKILL.md +0 -5
  15. data/.github/skills/facade-test-conventions/SKILL.md +4 -7
  16. data/.github/skills/facade-yard-documentation/SKILL.md +8 -2
  17. data/.github/skills/make-skill-template/SKILL.md +53 -3
  18. data/.github/skills/pr-readiness-review/SKILL.md +22 -2
  19. data/.github/skills/project-context/SKILL.md +16 -23
  20. data/.github/skills/pull-request-review/SKILL.md +2 -2
  21. data/.github/skills/rebase/SKILL.md +148 -0
  22. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +1 -1
  23. data/.github/skills/resolve-feedback/SKILL.md +288 -0
  24. data/.github/skills/review-arguments-dsl/CHECKLIST.md +3 -3
  25. data/.github/skills/reviewing-skills/SKILL.md +28 -3
  26. data/.github/skills/test-debugging/SKILL.md +20 -19
  27. data/.github/skills/yard-documentation/SKILL.md +671 -483
  28. data/.github/skills/yard-documentation/element-rules.md +162 -0
  29. data/.github/skills-deprecated/README.md +21 -0
  30. data/.github/{skills → skills-deprecated}/extract-command-from-lib/SKILL.md +9 -9
  31. data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/SKILL.md +12 -12
  32. data/.github/workflows/continuous_integration.yml +3 -2
  33. data/.rubocop.yml +7 -39
  34. data/.yard-lint.yml +75 -0
  35. data/CONTRIBUTING.md +186 -174
  36. data/Gemfile +17 -0
  37. data/README.md +86 -23
  38. data/Rakefile +3 -21
  39. data/UPGRADING.md +219 -70
  40. data/docker/test/Dockerfile +32 -0
  41. data/docker/test/docker-compose.yml +0 -0
  42. data/git.gemspec +3 -4
  43. data/lib/git/author.rb +20 -1
  44. data/lib/git/branch.rb +26 -6
  45. data/lib/git/branch_delete_failure.rb +3 -0
  46. data/lib/git/branch_delete_result.rb +6 -3
  47. data/lib/git/branch_info.rb +6 -6
  48. data/lib/git/command_line/base.rb +6 -13
  49. data/lib/git/command_line/capturing.rb +67 -10
  50. data/lib/git/command_line/result.rb +0 -8
  51. data/lib/git/command_line/streaming.rb +45 -5
  52. data/lib/git/command_line.rb +4 -3
  53. data/lib/git/commands/add.rb +61 -53
  54. data/lib/git/commands/am/abort.rb +2 -2
  55. data/lib/git/commands/am/apply.rb +109 -98
  56. data/lib/git/commands/am/continue.rb +2 -2
  57. data/lib/git/commands/am/quit.rb +2 -2
  58. data/lib/git/commands/am/retry.rb +4 -2
  59. data/lib/git/commands/am/show_current_patch.rb +1 -1
  60. data/lib/git/commands/am/skip.rb +2 -2
  61. data/lib/git/commands/am.rb +2 -2
  62. data/lib/git/commands/apply.rb +7 -2
  63. data/lib/git/commands/archive/list_formats.rb +3 -3
  64. data/lib/git/commands/archive.rb +7 -2
  65. data/lib/git/commands/arguments.rb +1370 -359
  66. data/lib/git/commands/base.rb +111 -13
  67. data/lib/git/commands/branch/copy.rb +29 -21
  68. data/lib/git/commands/branch/create.rb +72 -68
  69. data/lib/git/commands/branch/delete.rb +25 -17
  70. data/lib/git/commands/branch/list.rb +76 -60
  71. data/lib/git/commands/branch/move.rb +29 -21
  72. data/lib/git/commands/branch/set_upstream.rb +8 -8
  73. data/lib/git/commands/branch/show_current.rb +3 -3
  74. data/lib/git/commands/branch/unset_upstream.rb +4 -8
  75. data/lib/git/commands/branch.rb +2 -2
  76. data/lib/git/commands/cat_file/batch.rb +36 -20
  77. data/lib/git/commands/cat_file/filtered.rb +12 -12
  78. data/lib/git/commands/cat_file/raw.rb +13 -13
  79. data/lib/git/commands/cat_file.rb +4 -4
  80. data/lib/git/commands/checkout/branch.rb +7 -5
  81. data/lib/git/commands/checkout/files.rb +5 -4
  82. data/lib/git/commands/checkout.rb +4 -4
  83. data/lib/git/commands/checkout_index.rb +5 -4
  84. data/lib/git/commands/clean.rb +6 -4
  85. data/lib/git/commands/clone.rb +5 -4
  86. data/lib/git/commands/commit.rb +5 -4
  87. data/lib/git/commands/commit_tree.rb +5 -4
  88. data/lib/git/commands/config_option_syntax/add.rb +7 -4
  89. data/lib/git/commands/config_option_syntax/get.rb +9 -5
  90. data/lib/git/commands/config_option_syntax/get_all.rb +7 -4
  91. data/lib/git/commands/config_option_syntax/get_color.rb +8 -4
  92. data/lib/git/commands/config_option_syntax/get_color_bool.rb +7 -4
  93. data/lib/git/commands/config_option_syntax/get_regexp.rb +8 -4
  94. data/lib/git/commands/config_option_syntax/get_urlmatch.rb +8 -4
  95. data/lib/git/commands/config_option_syntax/list.rb +8 -4
  96. data/lib/git/commands/config_option_syntax/remove_section.rb +7 -2
  97. data/lib/git/commands/config_option_syntax/rename_section.rb +7 -2
  98. data/lib/git/commands/config_option_syntax/replace_all.rb +7 -2
  99. data/lib/git/commands/config_option_syntax/set.rb +7 -2
  100. data/lib/git/commands/config_option_syntax/unset.rb +7 -4
  101. data/lib/git/commands/config_option_syntax/unset_all.rb +7 -2
  102. data/lib/git/commands/describe.rb +5 -4
  103. data/lib/git/commands/diff.rb +13 -12
  104. data/lib/git/commands/diff_files.rb +7 -6
  105. data/lib/git/commands/diff_index.rb +10 -7
  106. data/lib/git/commands/fetch.rb +6 -4
  107. data/lib/git/commands/fsck.rb +6 -4
  108. data/lib/git/commands/gc.rb +6 -4
  109. data/lib/git/commands/grep.rb +6 -5
  110. data/lib/git/commands/init.rb +6 -4
  111. data/lib/git/commands/log.rb +287 -285
  112. data/lib/git/commands/ls_files.rb +69 -65
  113. data/lib/git/commands/ls_remote.rb +62 -56
  114. data/lib/git/commands/ls_tree.rb +50 -46
  115. data/lib/git/commands/maintenance/register.rb +25 -23
  116. data/lib/git/commands/maintenance/run.rb +7 -2
  117. data/lib/git/commands/maintenance/start.rb +7 -2
  118. data/lib/git/commands/maintenance/stop.rb +7 -2
  119. data/lib/git/commands/maintenance/unregister.rb +7 -2
  120. data/lib/git/commands/merge/abort.rb +2 -2
  121. data/lib/git/commands/merge/continue.rb +2 -2
  122. data/lib/git/commands/merge/quit.rb +2 -2
  123. data/lib/git/commands/merge/start.rb +7 -2
  124. data/lib/git/commands/merge.rb +2 -2
  125. data/lib/git/commands/merge_base.rb +7 -2
  126. data/lib/git/commands/mv.rb +7 -2
  127. data/lib/git/commands/name_rev.rb +7 -2
  128. data/lib/git/commands/pull.rb +7 -2
  129. data/lib/git/commands/push.rb +7 -2
  130. data/lib/git/commands/read_tree.rb +7 -2
  131. data/lib/git/commands/remote/add.rb +7 -2
  132. data/lib/git/commands/remote/get_url.rb +4 -2
  133. data/lib/git/commands/remote/list.rb +4 -2
  134. data/lib/git/commands/remote/prune.rb +4 -2
  135. data/lib/git/commands/remote/remove.rb +4 -2
  136. data/lib/git/commands/remote/rename.rb +4 -2
  137. data/lib/git/commands/remote/set_branches.rb +9 -2
  138. data/lib/git/commands/remote/set_head.rb +12 -5
  139. data/lib/git/commands/remote/set_url.rb +9 -2
  140. data/lib/git/commands/remote/set_url_add.rb +11 -2
  141. data/lib/git/commands/remote/set_url_delete.rb +9 -2
  142. data/lib/git/commands/remote/show.rb +18 -12
  143. data/lib/git/commands/remote/update.rb +19 -12
  144. data/lib/git/commands/remote.rb +2 -2
  145. data/lib/git/commands/repack.rb +67 -63
  146. data/lib/git/commands/reset.rb +51 -44
  147. data/lib/git/commands/rev_parse.rb +135 -128
  148. data/lib/git/commands/revert/abort.rb +2 -2
  149. data/lib/git/commands/revert/continue.rb +7 -2
  150. data/lib/git/commands/revert/quit.rb +2 -2
  151. data/lib/git/commands/revert/skip.rb +2 -2
  152. data/lib/git/commands/revert/start.rb +7 -2
  153. data/lib/git/commands/revert.rb +2 -2
  154. data/lib/git/commands/rm.rb +35 -36
  155. data/lib/git/commands/show.rb +1 -1
  156. data/lib/git/commands/show_ref/exclude_existing.rb +3 -4
  157. data/lib/git/commands/show_ref/exists.rb +15 -13
  158. data/lib/git/commands/show_ref/list.rb +39 -35
  159. data/lib/git/commands/show_ref/verify.rb +29 -27
  160. data/lib/git/commands/show_ref.rb +4 -4
  161. data/lib/git/commands/stash/apply.rb +31 -25
  162. data/lib/git/commands/stash/branch.rb +10 -8
  163. data/lib/git/commands/stash/clear.rb +7 -5
  164. data/lib/git/commands/stash/create.rb +10 -8
  165. data/lib/git/commands/stash/drop.rb +15 -9
  166. data/lib/git/commands/stash/list.rb +9 -5
  167. data/lib/git/commands/stash/pop.rb +21 -12
  168. data/lib/git/commands/stash/push.rb +20 -11
  169. data/lib/git/commands/stash/show.rb +21 -12
  170. data/lib/git/commands/stash/store.rb +19 -10
  171. data/lib/git/commands/stash.rb +2 -2
  172. data/lib/git/commands/status.rb +7 -2
  173. data/lib/git/commands/symbolic_ref/delete.rb +18 -14
  174. data/lib/git/commands/symbolic_ref/read.rb +24 -20
  175. data/lib/git/commands/symbolic_ref/update.rb +20 -17
  176. data/lib/git/commands/symbolic_ref.rb +4 -4
  177. data/lib/git/commands/tag/create.rb +45 -42
  178. data/lib/git/commands/tag/delete.rb +5 -3
  179. data/lib/git/commands/tag/list.rb +47 -44
  180. data/lib/git/commands/tag/verify.rb +12 -12
  181. data/lib/git/commands/tag.rb +2 -2
  182. data/lib/git/commands/update_ref/batch.rb +6 -1
  183. data/lib/git/commands/update_ref/delete.rb +19 -21
  184. data/lib/git/commands/update_ref/update.rb +22 -25
  185. data/lib/git/commands/update_ref.rb +4 -4
  186. data/lib/git/commands/version.rb +14 -11
  187. data/lib/git/commands/worktree/add.rb +50 -51
  188. data/lib/git/commands/worktree/list.rb +17 -17
  189. data/lib/git/commands/worktree/lock.rb +12 -12
  190. data/lib/git/commands/worktree/move.rb +16 -16
  191. data/lib/git/commands/worktree/prune.rb +2 -2
  192. data/lib/git/commands/worktree/remove.rb +2 -2
  193. data/lib/git/commands/worktree/repair.rb +2 -2
  194. data/lib/git/commands/worktree/unlock.rb +2 -2
  195. data/lib/git/commands/write_tree.rb +2 -2
  196. data/lib/git/commands.rb +4 -3
  197. data/lib/git/config.rb +47 -1
  198. data/lib/git/configuring.rb +89 -15
  199. data/lib/git/detached_head_info.rb +4 -1
  200. data/lib/git/diff.rb +2 -5
  201. data/lib/git/diff_file_numstat_info.rb +3 -1
  202. data/lib/git/diff_file_patch_info.rb +3 -1
  203. data/lib/git/diff_file_raw_info.rb +3 -1
  204. data/lib/git/diff_info.rb +8 -15
  205. data/lib/git/diff_path_status.rb +16 -3
  206. data/lib/git/diff_result.rb +3 -1
  207. data/lib/git/diff_stats.rb +15 -0
  208. data/lib/git/dirstat_info.rb +24 -8
  209. data/lib/git/encoding_utils.rb +32 -1
  210. data/lib/git/errors.rb +19 -9
  211. data/lib/git/escaped_path.rb +55 -3
  212. data/lib/git/execution_context/repository.rb +15 -0
  213. data/lib/git/execution_context.rb +76 -74
  214. data/lib/git/file_ref.rb +6 -3
  215. data/lib/git/fsck_object.rb +8 -0
  216. data/lib/git/fsck_result.rb +26 -15
  217. data/lib/git/log.rb +152 -5
  218. data/lib/git/object.rb +284 -8
  219. data/lib/git/parsers/branch.rb +18 -0
  220. data/lib/git/parsers/cat_file.rb +2 -2
  221. data/lib/git/parsers/diff.rb +213 -5
  222. data/lib/git/parsers/fsck.rb +11 -0
  223. data/lib/git/parsers/ls_remote.rb +1 -1
  224. data/lib/git/parsers/stash.rb +51 -0
  225. data/lib/git/parsers/tag.rb +38 -0
  226. data/lib/git/remote.rb +34 -2
  227. data/lib/git/repository/branching.rb +23 -21
  228. data/lib/git/repository/committing.rb +46 -6
  229. data/lib/git/repository/context_helpers.rb +45 -16
  230. data/lib/git/repository/diffing.rb +32 -23
  231. data/lib/git/repository/factories.rb +153 -28
  232. data/lib/git/repository/inspecting.rb +1 -1
  233. data/lib/git/repository/logging.rb +169 -30
  234. data/lib/git/repository/maintenance.rb +1 -1
  235. data/lib/git/repository/merging.rb +3 -3
  236. data/lib/git/repository/object_operations.rb +108 -14
  237. data/lib/git/repository/remote_operations.rb +150 -171
  238. data/lib/git/repository/shared_private.rb +7 -5
  239. data/lib/git/repository/staging.rb +36 -12
  240. data/lib/git/repository/stashing.rb +16 -16
  241. data/lib/git/repository/status_operations.rb +1 -1
  242. data/lib/git/repository/worktree_operations.rb +1 -1
  243. data/lib/git/repository.rb +287 -6
  244. data/lib/git/stash.rb +16 -21
  245. data/lib/git/stash_info.rb +4 -4
  246. data/lib/git/stashes.rb +20 -26
  247. data/lib/git/status.rb +25 -13
  248. data/lib/git/tag_delete_failure.rb +3 -0
  249. data/lib/git/tag_delete_result.rb +6 -3
  250. data/lib/git/tag_info.rb +1 -0
  251. data/lib/git/url.rb +12 -5
  252. data/lib/git/version.rb +6 -4
  253. data/lib/git/version_constraint.rb +4 -0
  254. data/lib/git.rb +400 -314
  255. data/redesign/3_architecture_implementation.md +81 -30
  256. data/redesign/Phase 4 - Step A.md +6 -0
  257. data/redesign/Phase 4 - Step B.md +921 -0
  258. data/redesign/Phase 4 - Step C.md +833 -0
  259. data/redesign/c1a-public-api-scope.tsv +256 -0
  260. data/redesign/phase-4-step-b-test-audit.tsv +485 -0
  261. data/tasks/yard.rake +24 -17
  262. metadata +24 -58
  263. data/commitlint.test +0 -4
  264. data/lib/git/args_builder.rb +0 -103
  265. data/lib/git/command_line_result.rb +0 -8
  266. data/lib/git/deprecation.rb +0 -9
  267. data/lib/git/repository/configuring.rb +0 -351
  268. data/tasks/test.rake +0 -25
  269. /data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -0
  270. /data/.github/{skills → skills-deprecated}/review-backward-compatibility/SKILL.md +0 -0
@@ -0,0 +1,288 @@
1
+ ---
2
+ name: resolve-feedback
3
+ description: 'Resolves unresolved pull request review threads on the current branch, folds each fix into the existing commit that last touched the same file, force-pushes with lease, and requests a fresh Copilot review. Use when addressing PR feedback, resolving review comments or threads, amending fixes into prior commits, or asking Copilot to re-review after changes.'
4
+ ---
5
+
6
+ # Resolve Feedback
7
+
8
+ Address the unresolved review threads on the pull request for the current
9
+ branch, folding each fix into the existing commit that last touched the affected
10
+ file, then force-push and request another Copilot review.
11
+
12
+ ## Contents
13
+
14
+ - [Contents](#contents)
15
+ - [How to use this skill](#how-to-use-this-skill)
16
+ - [Related skills](#related-skills)
17
+ - [Prerequisites](#prerequisites)
18
+ - [Terms](#terms)
19
+ - [Safety and stop points](#safety-and-stop-points)
20
+ - [Workflow](#workflow)
21
+ - [Step 1: Identify the PR and branch](#step-1-identify-the-pr-and-branch)
22
+ - [Step 2: Fetch unresolved review threads](#step-2-fetch-unresolved-review-threads)
23
+ - [Step 3: Triage each thread](#step-3-triage-each-thread)
24
+ - [Step 4: Implement the changes](#step-4-implement-the-changes)
25
+ - [Step 5: Fold each change into the matching commit](#step-5-fold-each-change-into-the-matching-commit)
26
+ - [Step 6: Force-push the branch](#step-6-force-push-the-branch)
27
+ - [Step 7: Reply to and resolve threads](#step-7-reply-to-and-resolve-threads)
28
+ - [Step 8: Request another Copilot review](#step-8-request-another-copilot-review)
29
+ - [Troubleshooting](#troubleshooting)
30
+
31
+ ## How to use this skill
32
+
33
+ Attach this file to your Copilot Chat context and invoke it when a PR has review
34
+ feedback to address on the current branch. Work top to bottom. Stop and ask the
35
+ user whenever a thread needs a clarification or decision (Step 3) and before the
36
+ history-rewriting force-push (Step 6).
37
+
38
+ ## Related skills
39
+
40
+ - [Pull Request Review](../pull-request-review/SKILL.md) — the review workflow
41
+ that produces the threads this skill resolves
42
+ - [PR Readiness Review](../pr-readiness-review/SKILL.md) — pre-PR quality gate to
43
+ run before pushing follow-up changes
44
+ - [Development Workflow](../development-workflow/SKILL.md) — TDD process and
45
+ branch rules that govern the fixes made here
46
+
47
+ ## Prerequisites
48
+
49
+ - The `gh` CLI is installed and authenticated (`gh auth status`).
50
+ - The current branch has an open PR and is a topic branch (not `main` or `4.x`).
51
+ - The working tree has no unrelated uncommitted changes before starting.
52
+
53
+ ## Terms
54
+
55
+ - **Unresolved review thread** — a PR review thread whose `isResolved` is
56
+ `false` in the GitHub GraphQL API.
57
+ - **Base** — the merge-base between the PR base branch and `HEAD`, computed with
58
+ `git merge-base origin/<base-branch> HEAD`. All commit lookups are scoped to
59
+ `<base>..HEAD` so only this branch's commits are considered.
60
+ - **Target commit** — the newest commit in `<base>..HEAD` that last touched the
61
+ file a fix applies to. Each fix is folded into its target commit.
62
+
63
+ ## Safety and stop points
64
+
65
+ These rules are mandatory:
66
+
67
+ - Never rewrite history on `main` or `4.x`. Confirm the branch first with
68
+ `git branch --show-current`.
69
+ - Stop and ask the user whenever a thread requests a clarification or decision
70
+ (Step 3). Do not guess on ambiguous feedback.
71
+ - Force-push only with `--force-with-lease`, and only after the user confirms
72
+ (Step 6).
73
+ - Do not resolve a thread until its fix is committed and pushed (Step 7).
74
+
75
+ ## Workflow
76
+
77
+ 1. [Identify the PR and branch](#step-1-identify-the-pr-and-branch)
78
+ 2. [Fetch unresolved review threads](#step-2-fetch-unresolved-review-threads)
79
+ 3. [Triage each thread](#step-3-triage-each-thread) — ask for clarifications or
80
+ decisions as needed
81
+ 4. [Implement the changes](#step-4-implement-the-changes)
82
+ 5. [Fold each change into the matching commit](#step-5-fold-each-change-into-the-matching-commit)
83
+ 6. [Force-push the branch](#step-6-force-push-the-branch)
84
+ 7. [Reply to and resolve threads](#step-7-reply-to-and-resolve-threads)
85
+ 8. [Request another Copilot review](#step-8-request-another-copilot-review)
86
+
87
+ ## Step 1: Identify the PR and branch
88
+
89
+ Confirm the branch and locate the PR for it:
90
+
91
+ ```bash
92
+ git branch --show-current
93
+ gh pr view --json number,title,headRefName,baseRefName,url,state
94
+ ```
95
+
96
+ Record the PR number, `baseRefName` (the base branch), and URL. If no PR is
97
+ associated with the branch, stop and tell the user.
98
+
99
+ ## Step 2: Fetch unresolved review threads
100
+
101
+ List the first 100 review threads and keep the ones where `isResolved` is
102
+ `false`. For unusually active PRs with more than 100 review threads, paginate
103
+ before assuming no unresolved threads remain.
104
+
105
+ ```bash
106
+ OWNER=$(gh repo view --json owner --jq '.owner.login')
107
+ REPO=$(gh repo view --json name --jq '.name')
108
+ PR_NUMBER=$(gh pr view --json number --jq '.number')
109
+
110
+ gh api graphql -f query='
111
+ query($owner:String!, $repo:String!, $pr:Int!) {
112
+ repository(owner:$owner, name:$repo) {
113
+ pullRequest(number:$pr) {
114
+ reviewThreads(first:100) {
115
+ nodes {
116
+ id
117
+ isResolved
118
+ isOutdated
119
+ path
120
+ line
121
+ comments(first:30) {
122
+ nodes { databaseId author { login } body }
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }' -F owner="$OWNER" -F repo="$REPO" -F pr="$PR_NUMBER" \
129
+ --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'
130
+ ```
131
+
132
+ For each unresolved thread, note its `id` (thread ID, needed to resolve it), the
133
+ first comment `databaseId` (needed to reply), the `path`, and the `line`.
134
+
135
+ ## Step 3: Triage each thread
136
+
137
+ For each unresolved thread, classify it and act:
138
+
139
+ - **Actionable and unambiguous** → plan the concrete code or doc change.
140
+ - **Needs a clarification or decision** → stop and ask the user. Present the
141
+ thread's file, line, and comment text, and the specific question or the
142
+ options you see. Wait for the answer before implementing.
143
+ - **Not applicable / disagree** → do not change code; draft a short, respectful
144
+ reply explaining why (used in Step 7). Ask the user if you are unsure whether
145
+ to push back.
146
+
147
+ Do not proceed to Step 4 for a thread until its resolution is clear.
148
+
149
+ ## Step 4: Implement the changes
150
+
151
+ Apply the agreed changes in the workspace. Keep edits for each thread minimal and
152
+ scoped to what the feedback asks. If the project has tests or linters, run the
153
+ relevant checks before folding changes into commits:
154
+
155
+ ```bash
156
+ bundle exec rake default
157
+ ```
158
+
159
+ Fix any failures before continuing.
160
+
161
+ ## Step 5: Fold each change into the matching commit
162
+
163
+ Amend each change into its target commit — the existing commit on this branch
164
+ that last touched the file — instead of adding new follow-up commits.
165
+
166
+ 1. Compute the base once:
167
+
168
+ ```bash
169
+ BASE=$(git merge-base origin/<base-branch> HEAD)
170
+ ```
171
+
172
+ 2. For each changed file, find its target commit (the topmost line is newest):
173
+
174
+ ```bash
175
+ git log --oneline "$BASE"..HEAD -- <path>
176
+ ```
177
+
178
+ 3. Stage that file and create a fixup commit aimed at its target SHA:
179
+
180
+ ```bash
181
+ git add <path>
182
+ git commit --fixup=<target-sha>
183
+ ```
184
+
185
+ Repeat for each changed file. When several files share the same target
186
+ commit, stage them together for one fixup.
187
+
188
+ 4. Autosquash the fixups into their targets non-interactively:
189
+
190
+ ```bash
191
+ GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash "$BASE"
192
+ ```
193
+
194
+ 5. Verify the result — the fixup commits should be gone and history should be
195
+ clean:
196
+
197
+ ```bash
198
+ git --no-pager log --oneline "$BASE"..HEAD
199
+ git status --short --branch
200
+ ```
201
+
202
+ If a change does not correspond to any existing commit (e.g. a brand-new file
203
+ requested in review), ask the user whether to fold it into a related commit or
204
+ add a new, conventionally formatted commit.
205
+
206
+ ## Step 6: Force-push the branch
207
+
208
+ History was rewritten, so the branch must be force-pushed. This is a
209
+ history-rewriting operation — confirm with the user first, then use a lease to
210
+ avoid clobbering unseen remote commits:
211
+
212
+ ```bash
213
+ git push --force-with-lease
214
+ ```
215
+
216
+ If the push is rejected, someone updated the remote branch. Fetch and reconcile
217
+ before retrying; do not use `--force` to override the lease.
218
+
219
+ ## Step 7: Reply to and resolve threads
220
+
221
+ For each thread that is now addressed:
222
+
223
+ 1. Reply to the thread, referencing what changed. Keep reply bodies shell-safe:
224
+ use single quotes for simple one-line replies, or assign a quoted heredoc to a
225
+ variable for arbitrary text. Do not put human-written reply text directly in a
226
+ double-quoted shell argument; review comments can contain characters such as
227
+ `!`, `$`, backticks, or quotes that the shell may expand before `gh` runs.
228
+
229
+ ```bash
230
+ COMMENT_DATABASE_ID=COMMENT_DATABASE_ID_FROM_THREAD
231
+ reply_body='Addressed in the latest push: <short summary>.'
232
+
233
+ gh api \
234
+ "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments/$COMMENT_DATABASE_ID/replies" \
235
+ -f body="$reply_body"
236
+ ```
237
+
238
+ For multi-line replies or text that may contain shell metacharacters, use a
239
+ single-quoted heredoc delimiter:
240
+
241
+ ```bash
242
+ COMMENT_DATABASE_ID=COMMENT_DATABASE_ID_FROM_THREAD
243
+ reply_body=$(cat <<'EOF'
244
+ Addressed in the latest push: the guidance now covers `@!method` declarations.
245
+ EOF
246
+ )
247
+
248
+ gh api \
249
+ "repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments/$COMMENT_DATABASE_ID/replies" \
250
+ -f body="$reply_body"
251
+ ```
252
+
253
+ 2. Resolve the thread:
254
+
255
+ ```bash
256
+ gh api graphql -f query='
257
+ mutation($threadId:ID!) {
258
+ resolveReviewThread(input:{threadId:$threadId}) {
259
+ thread { id isResolved }
260
+ }
261
+ }' -F threadId=THREAD_ID
262
+ ```
263
+
264
+ Only resolve threads whose feedback was actually addressed (or that the user
265
+ agreed to close after a reply). Leave threads open when the user still owes a
266
+ decision.
267
+
268
+ ## Step 8: Request another Copilot review
269
+
270
+ Request a fresh Copilot review on the PR so it re-reviews the amended commits.
271
+
272
+ - Preferred: activate the pull request management tools, then request a Copilot
273
+ review via the GitHub pull request tooling (`request_copilot_review`).
274
+ - Do **not** create a new Copilot PR task for a re-review; that opens separate
275
+ work instead of re-reviewing this PR.
276
+
277
+ Finish by reporting to the user: the threads resolved, any threads left open and
278
+ why, the new commit list, and the PR URL.
279
+
280
+ ## Troubleshooting
281
+
282
+ | Issue | Solution |
283
+ | ----- | -------- |
284
+ | `git log "$BASE"..HEAD -- <path>` is empty | The file is new on this branch; ask the user whether to fold into a related commit or add a new commit. |
285
+ | Rebase stops with conflicts | Resolve the conflict, `git add` the files, then `git rebase --continue`. |
286
+ | Force-push rejected despite `--force-with-lease` | The remote branch moved; run `git fetch`, review the remote changes, reconcile, and retry. |
287
+ | A thread has no obvious file/line (`path` is null) | It is a PR-level comment; reply at the PR level and resolve only if addressed. |
288
+ | Unsure whether to push back on feedback | Stop and ask the user before replying or resolving. |
@@ -101,14 +101,14 @@ output-control, editor-suppression, or progress flags. Declare these as
101
101
  > `no_edit: true` passed from the facade call site.
102
102
 
103
103
  **The `--edit` / `--no-edit` pair:** Model as `flag_option :edit, negatable: true`.
104
- The facade (`Git::Lib`) passes `no_edit: true` at each call site. Do **not** hardcode
104
+ The `Git::Repository::*` facade passes `no_edit: true` at each call site. Do **not** hardcode
105
105
  `literal '--no-edit'` — that prevents the facade from controlling the option — and do
106
106
  **not** exclude `--edit` from the DSL.
107
107
 
108
108
  **Output-format options belong at the facade call site, not as `literal` entries:**
109
109
  When a parser requires specific output flags (e.g. `--pretty=raw`, `--numstat`),
110
110
  declare those flags in the DSL with `flag_option` or `value_option`, and pass them
111
- explicitly from `Git::Lib`. Never hardcode them as `literal` entries inside the
111
+ explicitly from the `Git::Repository::*` facade. Never hardcode them as `literal` entries inside the
112
112
  command class — that hides the parser contract and prevents the facade from choosing
113
113
  the format. See Insight 16 in `redesign/3_architecture_implementation.md`.
114
114
 
@@ -571,7 +571,7 @@ Values are forwarded as Ruby kwargs to the underlying command runner (e.g.,
571
571
 
572
572
  The authoritative set of accepted execution option names is defined by
573
573
  `COMMAND_CAPTURING_ARG_DEFAULTS` and `COMMAND_STREAMING_ARG_DEFAULTS` in
574
- `lib/git/lib.rb`. The complete set of accepted names is:
574
+ `lib/git/execution_context.rb`. The complete set of accepted names is:
575
575
 
576
576
  | Name | Purpose | Capturing | Streaming | Notes |
577
577
  | --- | --- | --- | --- | --- |
@@ -10,6 +10,7 @@ adherence to the Anthropic skill-authoring best practices.
10
10
 
11
11
  ## Contents
12
12
 
13
+ - [Contents](#contents)
13
14
  - [How to use this skill](#how-to-use-this-skill)
14
15
  - [Related skills](#related-skills)
15
16
  - [Input](#input)
@@ -76,11 +77,16 @@ skill is selected from potentially hundreds of available skills.
76
77
 
77
78
  ### 3. Body structure and size
78
79
 
79
- - [ ] SKILL.md body is **under 600 lines** (optimal performance threshold)
80
- - [ ] If approaching the limit, content is split into separate reference files
80
+ - [ ] SKILL.md body targets **under 500 lines** and is reviewed carefully above
81
+ 600 lines
82
+ - [ ] Exceeding the target is justified when splitting always-needed workflow or
83
+ review rules would make the skill less effective
84
+ - [ ] If approaching the limit, situational content is split into separate
85
+ reference files before core workflows or checklists are split
81
86
  - [ ] Reference files are at most **one level deep** from SKILL.md (no
82
87
  deeply-nested chains like SKILL → A.md → B.md → actual content)
83
88
  - [ ] Reference files longer than 100 lines include a table of contents
89
+ - [ ] Reference files state their purpose and when the agent should load them
84
90
 
85
91
  ### 4. Conciseness
86
92
 
@@ -108,6 +114,10 @@ Match instruction specificity to task fragility:
108
114
 
109
115
  - [ ] SKILL.md serves as an overview / table of contents
110
116
  - [ ] Detailed materials are in separate files loaded only when needed
117
+ - [ ] Mandatory workflow steps, validation loops, and review checklist items stay
118
+ in SKILL.md even when detailed examples move to references
119
+ - [ ] Situational, element-specific, type-specific, or platform-specific rules
120
+ are good candidates for reference files
111
121
  - [ ] File names are descriptive (not `doc1.md`, `file2.md`)
112
122
  - [ ] Directory structure is organized by domain or feature
113
123
 
@@ -119,15 +129,26 @@ Match instruction specificity to task fragility:
119
129
  (run validator → fix errors → repeat until clean)
120
130
  - [ ] Decision points use conditional workflow patterns (if X → workflow A,
121
131
  if Y → workflow B)
132
+ - [ ] For standards and review skills, rules are mandatory unless explicitly
133
+ marked `Optional`; advisory skills consistently distinguish requirements,
134
+ recommendations, and examples
122
135
 
123
136
  ### 8. Content quality
124
137
 
125
138
  - [ ] No time-sensitive information (dates that will become stale); if legacy
126
139
  context is needed, it is in a collapsible "old patterns" section
127
140
  - [ ] Consistent terminology throughout (one term per concept, not synonyms)
141
+ - [ ] Named thresholds, modes, phases, or terms are defined before first use and
142
+ have one authoritative definition
128
143
  - [ ] Examples are concrete, not abstract
144
+ - [ ] Examples and domain facts are technically accurate; repo-specific skills
145
+ use real project patterns where practical
129
146
  - [ ] All file paths use forward slashes (no Windows-style backslashes)
130
147
  - [ ] No "voodoo constants" — every magic number or config value is justified
148
+ - [ ] Important rule sections use real markdown headings, not bold paragraphs as
149
+ pseudo-headings
150
+ - [ ] Duplicate rationale and repeated examples are removed, while short
151
+ normative checklist rules remain self-contained
131
152
 
132
153
  ### 9. Cross-skill consistency
133
154
 
@@ -138,8 +159,12 @@ When reviewing multiple skills in the same repository:
138
159
  - [ ] Shared policies (branch rules, commit conventions, quality gates,
139
160
  changelog policy) do not contradict each other
140
161
  - [ ] Cross-skill links in `## Related skills` resolve to existing files
162
+ - [ ] Intra-skill links, cross-skill deep links, table-of-contents anchors, and
163
+ referenced files resolve after heading or file moves
141
164
  - [ ] Every skill referenced in `.github/copilot-instructions.md`'s routing
142
165
  table resolves to an existing `.github/skills/*/SKILL.md` file
166
+ - [ ] Skills that extend other skills clearly state what they inherit, override,
167
+ or add
143
168
  - [ ] Stop/ask checkpoints are used consistently for comparable risk levels
144
169
 
145
170
  ### 10. Discoverability sections
@@ -182,7 +207,7 @@ Key principles distilled:
182
207
  | No time-sensitive info | Avoid dates that will become stale |
183
208
  | Consistent terminology | One term per concept throughout |
184
209
  | One-level references | No deeply nested file chains |
185
- | Under 600 lines | Split if approaching the limit |
210
+ | Size targets | Target under 500 lines; review carefully above 600 lines |
186
211
  | Test with real usage | Iterate based on observed agent behavior |
187
212
 
188
213
  > **Branch workflow:** Implement any fixes on a feature branch. Never commit or
@@ -40,17 +40,14 @@ requests unless the user asks for implementation.
40
40
  1. **Run the failing test:**
41
41
 
42
42
  ```bash
43
- # TestUnit (legacy tests in tests/units/)
44
- bundle exec bin/test <test_file_name>
45
-
46
43
  # RSpec unit test
47
44
  bundle exec rspec spec/unit/git/commands/<command>_spec.rb
48
45
 
49
46
  # RSpec integration test
50
47
  bundle exec rspec spec/integration/git/commands/<command>_spec.rb
51
48
 
52
- # Specific test method (TestUnit)
53
- bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_method_name
49
+ # Specific example, by line number
50
+ bundle exec rspec spec/unit/git/commands/<command>_spec.rb:42
54
51
  ```
55
52
 
56
53
  2. **For suspected flaky tests, run multiple times:**
@@ -58,15 +55,15 @@ requests unless the user asks for implementation.
58
55
  ```bash
59
56
  for i in {1..20}; do
60
57
  echo "Run $i"
61
- bundle exec bin/test <test_file> || break
58
+ bundle exec rspec <spec_file> || break
62
59
  done
63
60
  ```
64
61
 
65
62
  3. **Check test isolation** — run the test alone vs. within the full suite:
66
63
 
67
64
  ```bash
68
- bundle exec bin/test <test_file> # alone
69
- bundle exec rake default # full suite
65
+ bundle exec rspec <spec_file> # alone
66
+ bundle exec rake default # full suite
70
67
  ```
71
68
 
72
69
  ## Step 2: Investigate Root Cause
@@ -129,13 +126,12 @@ Present diagnostic findings to the user:
129
126
 
130
127
  ```bash
131
128
  # Run the specific test
132
- bundle exec bin/test <test_file> # TestUnit
133
- bundle exec rspec <spec_file> # RSpec
129
+ bundle exec rspec <spec_file>
134
130
 
135
131
  # For flaky test fixes, run many times
136
132
  for i in {1..50}; do
137
133
  echo "Run $i"
138
- bundle exec bin/test <test_file> || break
134
+ bundle exec rspec <spec_file> || break
139
135
  done
140
136
 
141
137
  # Run full suite
@@ -144,17 +140,22 @@ bundle exec rake default
144
140
 
145
141
  ## Project-Specific Considerations
146
142
 
147
- **Test frameworks:** This project uses both TestUnit (legacy tests in `tests/units/`)
148
- and RSpec (new tests in `spec/`). Run both when verifying changes.
143
+ **Test framework:** This project uses RSpec exclusively (`spec/unit/` and
144
+ `spec/integration/`).
149
145
 
150
- **Test helpers:** Use `clone_working_repo`, `create_temp_repo`, `in_temp_dir` from
151
- test helpers for TestUnit. Use `include_context` shared contexts for RSpec.
146
+ **Test helpers:** Use the `'in an empty repository'` shared context (and other
147
+ `spec/support/contexts/` shared contexts) plus `Git::IntegrationTestHelpers` methods
148
+ (e.g. `write_file`) for integration specs. Use `let`/`let!` and verifying doubles for
149
+ unit specs — see [RSpec Unit Testing Standards](../rspec-unit-testing-standards/SKILL.md).
152
150
 
153
- **Mocking:** The project uses Mocha for TestUnit mocking and RSpec doubles for RSpec.
154
- Be careful with stubs — they can mask real issues.
151
+ **Mocking:** The project uses RSpec doubles (`instance_double`, `class_double`) for
152
+ unit specs. Be careful with stubs — they can mask real issues.
155
153
 
156
- **Test data:** Fixtures are in `tests/files/`. Use test helpers to create temporary
157
- repos. Clean up in teardown.
154
+ **Test data:** Integration specs create temporary repos on the fly (e.g. via
155
+ `Dir.mktmpdir` and the shared contexts above). Static fixture files in
156
+ `spec/support/fixtures/` exist for a small number of specs that need pre-built
157
+ content (e.g. `spec/integration/git/command_line_spec.rb`); prefer dynamic helpers
158
+ for new specs. Clean up any state created outside those helpers.
158
159
 
159
160
  **CI vs. local differences:** If tests pass locally but fail in CI, use the
160
161
  ci-cd-troubleshooting skill.