git 5.0.5 → 5.2.0

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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +69 -0
  3. data/CONTRIBUTING.md +209 -164
  4. data/LICENSE +1 -1
  5. data/README.md +205 -138
  6. data/git.gemspec +77 -17
  7. data/lib/git/command_line/base.rb +1 -2
  8. data/lib/git/commands/base.rb +1 -1
  9. data/lib/git/commands/cat_file/raw.rb +8 -7
  10. data/lib/git/configuring.rb +56 -0
  11. data/lib/git/log.rb +19 -0
  12. data/lib/git/repository/branching.rb +79 -5
  13. data/lib/git/repository/logging.rb +35 -11
  14. data/lib/git/repository/object_operations.rb +22 -1
  15. data/lib/git/version.rb +1 -1
  16. metadata +33 -122
  17. data/.claude/commands/address-copilot-reviews.md +0 -14
  18. data/.claude/settings.json +0 -16
  19. data/.claude/skills +0 -1
  20. data/.commitlintrc.yml +0 -38
  21. data/.dockerignore +0 -27
  22. data/.github/copilot-instructions.md +0 -30
  23. data/.github/hooks/bin-setup-on-worktree.json +0 -11
  24. data/.github/hooks/run-bin-setup-once.sh +0 -20
  25. data/.github/issue_template.md +0 -15
  26. data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +0 -188
  27. data/.github/pull_request_template.md +0 -21
  28. data/.github/skills/breaking-change-analysis/SKILL.md +0 -99
  29. data/.github/skills/ci-cd-troubleshooting/SKILL.md +0 -264
  30. data/.github/skills/command-implementation/REFERENCE.md +0 -994
  31. data/.github/skills/command-implementation/SKILL.md +0 -230
  32. data/.github/skills/command-test-conventions/SKILL.md +0 -664
  33. data/.github/skills/command-yard-documentation/SKILL.md +0 -434
  34. data/.github/skills/dependency-management/SKILL.md +0 -72
  35. data/.github/skills/development-workflow/SKILL.md +0 -512
  36. data/.github/skills/facade-implementation/REFERENCE.md +0 -837
  37. data/.github/skills/facade-implementation/SKILL.md +0 -269
  38. data/.github/skills/facade-test-conventions/SKILL.md +0 -391
  39. data/.github/skills/facade-yard-documentation/SKILL.md +0 -435
  40. data/.github/skills/make-skill-template/SKILL.md +0 -226
  41. data/.github/skills/pr-readiness-review/SKILL.md +0 -205
  42. data/.github/skills/project-context/SKILL.md +0 -306
  43. data/.github/skills/pull-request-review/SKILL.md +0 -168
  44. data/.github/skills/rebase/SKILL.md +0 -148
  45. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +0 -131
  46. data/.github/skills/release-management/SKILL.md +0 -125
  47. data/.github/skills/resolve-feedback/SKILL.md +0 -288
  48. data/.github/skills/review-arguments-dsl/CHECKLIST.md +0 -788
  49. data/.github/skills/review-arguments-dsl/SKILL.md +0 -214
  50. data/.github/skills/review-cross-command-consistency/SKILL.md +0 -139
  51. data/.github/skills/reviewing-skills/SKILL.md +0 -214
  52. data/.github/skills/rspec-unit-testing-standards/SKILL.md +0 -685
  53. data/.github/skills/tdd-refactor-step/SKILL.md +0 -236
  54. data/.github/skills/test-debugging/SKILL.md +0 -161
  55. data/.github/skills/yard-documentation/SKILL.md +0 -981
  56. data/.github/skills/yard-documentation/element-rules.md +0 -162
  57. data/.github/skills-deprecated/README.md +0 -21
  58. data/.github/skills-deprecated/extract-command-from-lib/SKILL.md +0 -487
  59. data/.github/skills-deprecated/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -22
  60. data/.github/skills-deprecated/extract-facade-from-base-lib/SKILL.md +0 -600
  61. data/.github/skills-deprecated/review-backward-compatibility/SKILL.md +0 -275
  62. data/.github/workflows/continuous_integration.yml +0 -343
  63. data/.github/workflows/enforce_conventional_commits.yml +0 -35
  64. data/.github/workflows/experimental_continuous_integration.yml +0 -59
  65. data/.github/workflows/release.yml +0 -52
  66. data/.github/workflows/warm_bundler_caches.yml +0 -82
  67. data/.gitignore +0 -30
  68. data/.husky/commit-msg +0 -1
  69. data/.husky/pre-commit +0 -13
  70. data/.release-please-config.json +0 -36
  71. data/.release-please-manifest.json +0 -3
  72. data/.rspec +0 -2
  73. data/.rubocop.yml +0 -37
  74. data/.rubocop_todo.yml +0 -30
  75. data/.yard-lint.yml +0 -75
  76. data/CLAUDE.md +0 -11
  77. data/Gemfile +0 -22
  78. data/Rakefile +0 -41
  79. data/docker/test/Dockerfile +0 -32
  80. data/docker/test/docker-compose.yml +0 -0
  81. data/package.json +0 -10
  82. data/redesign/1_architecture_existing.md +0 -102
  83. data/redesign/2_architecture_redesign.md +0 -449
  84. data/redesign/3_architecture_implementation.md +0 -1623
  85. data/redesign/Phase 4 - Step A.md +0 -366
  86. data/redesign/Phase 4 - Step B.md +0 -921
  87. data/redesign/Phase 4 - Step C.md +0 -833
  88. data/redesign/beta_release.md +0 -107
  89. data/redesign/branch_parse_refactor_plan.md +0 -163
  90. data/redesign/c1a-public-api-scope.tsv +0 -256
  91. data/redesign/c1c2_audit.md +0 -566
  92. data/redesign/c1c2_bucket6_lib_orphans.md +0 -626
  93. data/redesign/config_design.rb +0 -501
  94. data/redesign/index.md +0 -34
  95. data/redesign/info_object_migration_plan.md +0 -126
  96. data/redesign/integration_test_analysis.md +0 -521
  97. data/redesign/phase-4-step-b-test-audit.tsv +0 -485
  98. data/redesign/remote_refactor_plan.md +0 -164
  99. data/redesign/reverse_dependencies.sql +0 -44
  100. data/tasks/gem_tasks.rake +0 -14
  101. data/tasks/npm_tasks.rake +0 -7
  102. data/tasks/rspec.rake +0 -111
  103. data/tasks/rubocop.rake +0 -5
  104. data/tasks/test_gem.rake +0 -12
  105. data/tasks/yard.rake +0 -57
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.5
4
+ version: 5.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon and others
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: '4.0'
46
+ version: '4.1'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '4.0'
53
+ version: '4.1'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rchardet
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -93,6 +93,20 @@ dependencies:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
95
  version: '2.5'
96
+ - !ruby/object:Gem::Dependency
97
+ name: irb
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.16'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.16'
96
110
  - !ruby/object:Gem::Dependency
97
111
  name: main_branch_shared_rubocop_config
98
112
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +149,20 @@ dependencies:
135
149
  - - "~>"
136
150
  - !ruby/object:Gem::Version
137
151
  version: '13.3'
152
+ - !ruby/object:Gem::Dependency
153
+ name: redcarpet
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '3.6'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '3.6'
138
166
  - !ruby/object:Gem::Dependency
139
167
  name: rspec
140
168
  requirement: !ruby/object:Gem::Requirement
@@ -205,34 +233,6 @@ dependencies:
205
233
  - - "~>"
206
234
  - !ruby/object:Gem::Version
207
235
  version: '1.1'
208
- - !ruby/object:Gem::Dependency
209
- name: irb
210
- requirement: !ruby/object:Gem::Requirement
211
- requirements:
212
- - - "~>"
213
- - !ruby/object:Gem::Version
214
- version: '1.16'
215
- type: :development
216
- prerelease: false
217
- version_requirements: !ruby/object:Gem::Requirement
218
- requirements:
219
- - - "~>"
220
- - !ruby/object:Gem::Version
221
- version: '1.16'
222
- - !ruby/object:Gem::Dependency
223
- name: redcarpet
224
- requirement: !ruby/object:Gem::Requirement
225
- requirements:
226
- - - "~>"
227
- - !ruby/object:Gem::Version
228
- version: '3.6'
229
- type: :development
230
- prerelease: false
231
- version_requirements: !ruby/object:Gem::Requirement
232
- requirements:
233
- - - "~>"
234
- - !ruby/object:Gem::Version
235
- version: '3.6'
236
236
  - !ruby/object:Gem::Dependency
237
237
  name: yard
238
238
  requirement: !ruby/object:Gem::Requirement
@@ -298,80 +298,16 @@ executables: []
298
298
  extensions: []
299
299
  extra_rdoc_files: []
300
300
  files:
301
- - ".claude/commands/address-copilot-reviews.md"
302
- - ".claude/settings.json"
303
- - ".claude/skills"
304
- - ".commitlintrc.yml"
305
- - ".dockerignore"
306
- - ".github/copilot-instructions.md"
307
- - ".github/hooks/bin-setup-on-worktree.json"
308
- - ".github/hooks/run-bin-setup-once.sh"
309
- - ".github/issue_template.md"
310
- - ".github/prompts/iteratively-address-copilot-reviews.prompt.md"
311
- - ".github/pull_request_template.md"
312
- - ".github/skills-deprecated/README.md"
313
- - ".github/skills-deprecated/extract-command-from-lib/SKILL.md"
314
- - ".github/skills-deprecated/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md"
315
- - ".github/skills-deprecated/extract-facade-from-base-lib/SKILL.md"
316
- - ".github/skills-deprecated/review-backward-compatibility/SKILL.md"
317
- - ".github/skills/breaking-change-analysis/SKILL.md"
318
- - ".github/skills/ci-cd-troubleshooting/SKILL.md"
319
- - ".github/skills/command-implementation/REFERENCE.md"
320
- - ".github/skills/command-implementation/SKILL.md"
321
- - ".github/skills/command-test-conventions/SKILL.md"
322
- - ".github/skills/command-yard-documentation/SKILL.md"
323
- - ".github/skills/dependency-management/SKILL.md"
324
- - ".github/skills/development-workflow/SKILL.md"
325
- - ".github/skills/facade-implementation/REFERENCE.md"
326
- - ".github/skills/facade-implementation/SKILL.md"
327
- - ".github/skills/facade-test-conventions/SKILL.md"
328
- - ".github/skills/facade-yard-documentation/SKILL.md"
329
- - ".github/skills/make-skill-template/SKILL.md"
330
- - ".github/skills/pr-readiness-review/SKILL.md"
331
- - ".github/skills/project-context/SKILL.md"
332
- - ".github/skills/pull-request-review/SKILL.md"
333
- - ".github/skills/rebase/SKILL.md"
334
- - ".github/skills/refactor-command-to-commandlineresult/SKILL.md"
335
- - ".github/skills/release-management/SKILL.md"
336
- - ".github/skills/resolve-feedback/SKILL.md"
337
- - ".github/skills/review-arguments-dsl/CHECKLIST.md"
338
- - ".github/skills/review-arguments-dsl/SKILL.md"
339
- - ".github/skills/review-cross-command-consistency/SKILL.md"
340
- - ".github/skills/reviewing-skills/SKILL.md"
341
- - ".github/skills/rspec-unit-testing-standards/SKILL.md"
342
- - ".github/skills/tdd-refactor-step/SKILL.md"
343
- - ".github/skills/test-debugging/SKILL.md"
344
- - ".github/skills/yard-documentation/SKILL.md"
345
- - ".github/skills/yard-documentation/element-rules.md"
346
- - ".github/workflows/continuous_integration.yml"
347
- - ".github/workflows/enforce_conventional_commits.yml"
348
- - ".github/workflows/experimental_continuous_integration.yml"
349
- - ".github/workflows/release.yml"
350
- - ".github/workflows/warm_bundler_caches.yml"
351
- - ".gitignore"
352
- - ".husky/commit-msg"
353
- - ".husky/pre-commit"
354
- - ".release-please-config.json"
355
- - ".release-please-manifest.json"
356
- - ".rspec"
357
- - ".rubocop.yml"
358
- - ".rubocop_todo.yml"
359
- - ".yard-lint.yml"
360
301
  - ".yardopts"
361
302
  - AI_POLICY.md
362
303
  - CHANGELOG.md
363
- - CLAUDE.md
364
304
  - CODE_OF_CONDUCT.md
365
305
  - CONTRIBUTING.md
366
306
  - GOVERNANCE.md
367
- - Gemfile
368
307
  - LICENSE
369
308
  - MAINTAINERS.md
370
309
  - README.md
371
- - Rakefile
372
310
  - UPGRADING.md
373
- - docker/test/Dockerfile
374
- - docker/test/docker-compose.yml
375
311
  - git.gemspec
376
312
  - lib/git.rb
377
313
  - lib/git/author.rb
@@ -600,39 +536,14 @@ files:
600
536
  - lib/git/version_constraint.rb
601
537
  - lib/git/worktree.rb
602
538
  - lib/git/worktrees.rb
603
- - package.json
604
- - redesign/1_architecture_existing.md
605
- - redesign/2_architecture_redesign.md
606
- - redesign/3_architecture_implementation.md
607
- - redesign/Phase 4 - Step A.md
608
- - redesign/Phase 4 - Step B.md
609
- - redesign/Phase 4 - Step C.md
610
- - redesign/beta_release.md
611
- - redesign/branch_parse_refactor_plan.md
612
- - redesign/c1a-public-api-scope.tsv
613
- - redesign/c1c2_audit.md
614
- - redesign/c1c2_bucket6_lib_orphans.md
615
- - redesign/config_design.rb
616
- - redesign/index.md
617
- - redesign/info_object_migration_plan.md
618
- - redesign/integration_test_analysis.md
619
- - redesign/phase-4-step-b-test-audit.tsv
620
- - redesign/remote_refactor_plan.md
621
- - redesign/reverse_dependencies.sql
622
- - tasks/gem_tasks.rake
623
- - tasks/npm_tasks.rake
624
- - tasks/rspec.rake
625
- - tasks/rubocop.rake
626
- - tasks/test_gem.rake
627
- - tasks/yard.rake
628
539
  homepage: http://github.com/ruby-git/ruby-git
629
540
  licenses:
630
541
  - MIT
631
542
  metadata:
632
543
  homepage_uri: http://github.com/ruby-git/ruby-git
633
544
  source_code_uri: http://github.com/ruby-git/ruby-git
634
- changelog_uri: https://rubydoc.info/gems/git/5.0.5/file/CHANGELOG.md
635
- documentation_uri: https://rubydoc.info/gems/git/5.0.5
545
+ changelog_uri: https://rubydoc.info/gems/git/5.2.0/file/CHANGELOG.md
546
+ documentation_uri: https://rubydoc.info/gems/git/5.2.0
636
547
  rubygems_mfa_required: 'true'
637
548
  rdoc_options: []
638
549
  require_paths:
@@ -1,14 +0,0 @@
1
- ---
2
- description: Address all unresolved Copilot review threads on the active pull request
3
- argument-hint: "[PR number — defaults to the PR for the current branch]"
4
- ---
5
-
6
- Follow the shared agent prompt in
7
- `.github/prompts/iteratively-address-copilot-reviews.prompt.md` exactly. That file
8
- is the canonical instructions for this task and is shared with other AI agents; read
9
- it before doing anything else.
10
-
11
- @.github/prompts/iteratively-address-copilot-reviews.prompt.md
12
-
13
- If `$ARGUMENTS` is non-empty, treat it as the pull request number to operate on
14
- instead of detecting the PR from the current branch.
@@ -1,16 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/claude-code-settings.json",
3
- "hooks": {
4
- "SessionStart": [
5
- {
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "\"$CLAUDE_PROJECT_DIR/.github/hooks/run-bin-setup-once.sh\"",
10
- "timeout": 900
11
- }
12
- ]
13
- }
14
- ]
15
- }
16
- }
data/.claude/skills DELETED
@@ -1 +0,0 @@
1
- ../.github/skills
data/.commitlintrc.yml DELETED
@@ -1,38 +0,0 @@
1
- ---
2
- extends: '@commitlint/config-conventional'
3
-
4
- rules:
5
- # See: https://commitlint.js.org/reference/rules.html
6
- #
7
- # Rules are made up by a name and a configuration array. The configuration
8
- # array contains:
9
- #
10
- # * Severity [0..2]: 0 disable rule, 1 warning if violated, or 2 error if
11
- # violated
12
- # * Applicability [always|never]: never inverts the rule
13
- # * Value: value to use for this rule (if applicable)
14
- #
15
- # Run `npx commitlint --print-config` to see the current setting for all
16
- # rules.
17
- #
18
- header-max-length: [2, always, 100] # Header can not exceed 100 chars
19
-
20
- type-case: [2, always, lower-case] # Type must be lower case
21
- type-empty: [2, never] # Type must not be empty
22
-
23
- # Supported conventional commit types
24
- type-enum: [2, always, [build, ci, chore, docs, feat, fix, perf, refactor, revert, style, test]]
25
-
26
- scope-case: [2, always, lower-case] # Scope must be lower case
27
-
28
- # Error if subject is one of these cases (encourages lower-case)
29
- subject-case: [2, never, [sentence-case, start-case, pascal-case, upper-case]]
30
- subject-empty: [2, never] # Subject must not be empty
31
- subject-full-stop: [2, never, "."] # Subject must not end with a period
32
-
33
- body-leading-blank: [2, always] # Body must have a blank line before it
34
- body-max-line-length: [2, always, 100] # Body lines can not exceed 100 chars
35
-
36
- footer-leading-blank: [2, always] # Footer must have a blank line before it
37
- footer-max-line-length: [2, always, 100] # Footer lines can not exceed 100 chars
38
-
data/.dockerignore DELETED
@@ -1,27 +0,0 @@
1
- # Keep the Docker build context free of host-generated artifacts so the
2
- # image always builds gems fresh instead of picking up stale or
3
- # host-specific state (see .gitignore for the equivalent git-tracked list).
4
- #
5
- # .git is also excluded: the Dockerfile initializes its own throwaway git
6
- # repo instead of relying on the host's, since the host's `.git` may be a
7
- # linked-worktree pointer file referencing a path that doesn't exist in the
8
- # image (see docker/test/Dockerfile for details).
9
- .git
10
- *.gem
11
- *.kpf
12
- *.sw?
13
- .DS_Store
14
- .bundle/
15
- vendor/bundle/
16
- coverage
17
- doc
18
- .yardoc
19
- pkg
20
- rdoc
21
- Gemfile.lock
22
- node_modules
23
- package-lock.json
24
- ai-prompt.erb
25
- rubocop-report.json
26
- .rspec_status
27
- git-reference/
@@ -1,30 +0,0 @@
1
- # GitHub Copilot Instructions for ruby-git
2
-
3
- ## Project Overview
4
-
5
- A Ruby gem providing an interface to Git repositories by wrapping system calls to the
6
- `git` CLI.
7
-
8
- Read the "Project Context" skill (`.github/skills/project-context/SKILL.md`) for
9
- design philosophy, technical details, and compatibility requirements.
10
-
11
- This project enforces Conventional Commits. See `.commitlintrc.yml` for allowed types
12
- and scopes. Never use `#` in the commit message body. Doing so will cause
13
- commitlint to incorrectly parse the commit message body as a footer. If you need to
14
- refer to an issue in the body, use `issue 999` instead of `issue #999`. It is still
15
- fine to use `#` in footer values such as `Closes: #999` or `Refs: #999`.
16
-
17
- ## Terminology & Writing Style
18
-
19
- - Use American English.
20
- - **Version strings:** Use `vN.x` for major series compatibility (e.g., `v4.x`) and
21
- `vN.0.0` for specific releases (e.g., `v5.0.0`). Never use the ambiguous `vN.0`.
22
- - **RuboCop:** Use `RuboCop` for prose and `rubocop` for CLI or gem names. Never use
23
- `Rubocop`.
24
-
25
- ## Branch & PR Strategy
26
-
27
- | Target | When |
28
- | --- | --- |
29
- | `main` | New features, breaking changes, all active development |
30
- | `4.x` | Security fixes and backward-compatible bug fixes for the v4.x series |
@@ -1,11 +0,0 @@
1
- {
2
- "hooks": {
3
- "SessionStart": [
4
- {
5
- "type": "command",
6
- "command": ".github/hooks/run-bin-setup-once.sh",
7
- "timeout": 900
8
- }
9
- ]
10
- }
11
- }
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- # This hook is shared by every agent configured for this repo (GitHub Copilot via
5
- # .github/hooks/, Claude Code via .claude/settings.json), so do not assume the
6
- # caller's working directory.
7
- command -v git >/dev/null 2>&1 || exit 0
8
- cd "$(dirname "${BASH_SOURCE[0]}")/../.." || exit 0
9
-
10
- # Skip if this repo does not use bin/setup.
11
- [[ -x "./bin/setup" ]] || exit 0
12
-
13
- # Keep setup idempotent per-worktree. The marker is shared across agents so that
14
- # cloning and opening the repo in two different tools does not run setup twice.
15
- marker="$(git rev-parse --git-path agent-bin-setup.done 2>/dev/null)" || exit 0
16
- [[ -f "$marker" ]] && exit 0
17
-
18
- ./bin/setup
19
- mkdir -p "$(dirname "$marker")"
20
- touch "$marker"
@@ -1,15 +0,0 @@
1
- ### Subject of the issue
2
- Describe your issue here.
3
-
4
- ### Your environment
5
- * version of git and ruby-git
6
- * version of ruby
7
-
8
- ### Steps to reproduce
9
- Tell us how to reproduce this issue.
10
-
11
- ### Expected behaviour
12
- What did you expect to happen?
13
-
14
- ### Actual behaviour
15
- What actually happened?
@@ -1,188 +0,0 @@
1
- ---
2
- agent: agent
3
- model: claude-sonnet-4.6
4
- description: Address all unresolved Copilot review threads on the active pull request until there are no remaining unresolved review threads
5
- ---
6
-
7
- Address unresolved **Copilot** review threads on the active pull request. Ignore threads opened by human reviewers. Ask me for clarification or decisions as needed.
8
-
9
- If any terminal script command fails, stop immediately. Do not continue the loop, do not resolve additional threads, and do not request a new review. Report: the failed command, exit code, and the most relevant stderr output. **Exception**: the reply POST in Step 3 is intentionally non-fatal — a 404 after a force-push is expected and the resolve step must still run.
10
-
11
- ## Terminology
12
-
13
- - **Review** — a top-level review submission by `copilot-pull-request-reviewer`, with a `submittedAt` timestamp and an optional summary body. A single review may contain zero or more Review Threads.
14
- - **Review Thread** — an inline comment thread attached to a specific code location. Key fields: `id` (GraphQL node ID, e.g. `PRRT_…`), `isResolved` (manually resolved by a maintainer), `isOutdated` (the underlying code changed since the thread was created). Each thread has one or more comments; the first comment is Copilot's suggestion.
15
- - **Check Run** — a standard CI status object on the HEAD commit. Note: Copilot Reviews do **not** create a Check Run; use the Reviews API to detect completion instead.
16
-
17
- ## Before the Loop
18
-
19
- Run in terminal to establish `OWNER`, `REPO`, and `PR_NUMBER` for use throughout:
20
-
21
- ```bash
22
- set -euo pipefail
23
- OWNER=$(gh repo view --json owner --jq '.owner.login')
24
- REPO=$(gh repo view --json name --jq '.name')
25
- PR_NUMBER=$(gh pr view --json number --jq '.number')
26
- : "${OWNER:?failed to resolve OWNER}"
27
- : "${REPO:?failed to resolve REPO}"
28
- : "${PR_NUMBER:?failed to resolve PR_NUMBER}"
29
- ```
30
-
31
- Fetch unresolved, non-outdated Copilot Review Threads:
32
-
33
- ```bash
34
- set -euo pipefail
35
- : "${OWNER:?missing OWNER}"
36
- : "${REPO:?missing REPO}"
37
- : "${PR_NUMBER:?missing PR_NUMBER}"
38
- threads_json=$(gh api graphql -f query='
39
- query($owner:String!,$repo:String!,$pr:Int!){
40
- repository(owner:$owner,name:$repo){
41
- pullRequest(number:$pr){
42
- reviewThreads(first:100){nodes{id isResolved isOutdated path
43
- comments(first:1){nodes{databaseId author{login} createdAt body}}}}}}
44
- }' -f owner="$OWNER" -f repo="$REPO" -F pr="$PR_NUMBER" \
45
- --jq '.data.repository.pullRequest.reviewThreads.nodes')
46
- if [[ $(echo "$threads_json" | jq 'length') -ge 100 ]]; then
47
- echo "Error: the PR already has 100 threads or more. Aborting."
48
- exit 1
49
- fi
50
- echo "$threads_json" | jq '[.[] |
51
- select(.isResolved==false) |
52
- select(.isOutdated==false) |
53
- select(.comments.nodes[0].author.login=="copilot-pull-request-reviewer")]'
54
- ```
55
-
56
- - **Results non-empty** → proceed directly to the iteration loop.
57
- - **Results empty** → record `REVIEW_REQUESTED_AT` (current UTC, `YYYY-MM-DDTHH:MM:SSZ`, e.g. `2026-06-16T12:00:00Z`), request a new Copilot Review using the `mcp_github_mcp_se_request_copilot_review` tool (owner, repo, pullNumber), then jump to the **Wait for Review** section below.
58
-
59
- ## Iteration Loop
60
-
61
- Repeat up to **${input:maxIterations:5}** iterations:
62
-
63
- ### 1. Address threads
64
-
65
- Re-fetch unresolved, non-outdated Copilot Review Threads using the same `gh api graphql` query from Before the Loop. Group by file. For each file, read it once and address all its threads in that single pass:
66
- - Validate each suggestion before accepting it.
67
- - If a suggestion is invalid or out of scope: reply explaining why, then resolve the thread without changing code.
68
- - Otherwise: implement the change using TDD where possible; ensure test coverage.
69
-
70
- Skip any thread where `isOutdated` is true — the code it references has already changed; Copilot will re-evaluate it in the next Review.
71
-
72
- After all threads are addressed, run `rake`. If it fails, capture `rake 2>&1 | tail -n 50` and fix the failure before continuing.
73
-
74
- ### 2. Commit and push
75
-
76
- Amend each change into the most relevant existing commit on the branch based on file name. If a change spans multiple commits or doesn't map clearly to one, ask me which commit to amend into (or whether to create a new commit). Confirm the working tree is clean and `rake` passes, then force push.
77
-
78
- ### 3. Reply and resolve
79
-
80
- For each addressed thread object from the unresolved-threads query, in the same `run_in_terminal` script block that performs reply/resolve, export:
81
-
82
- - `COMMENT_DBID=.comments.nodes[0].databaseId`
83
- - `THREAD_ID=.id`
84
- - `EXPLANATION` to your plain-language fix summary for that thread
85
-
86
- Set the per-thread variables (`COMMENT_DBID`, `THREAD_ID`, `EXPLANATION`) immediately before running the commands below — do not rely on them surviving from a prior terminal invocation.
87
-
88
- Then post a reply and resolve it:
89
-
90
- ```bash
91
- set -euo pipefail
92
- : "${OWNER:?missing OWNER}"
93
- : "${REPO:?missing REPO}"
94
- : "${COMMENT_DBID:?missing COMMENT_DBID}"
95
- : "${EXPLANATION:?missing EXPLANATION}"
96
-
97
- # Reply (COMMENT_DBID = databaseId of the thread's first comment)
98
- # Build JSON via jq to safely handle quotes/newlines/special chars in EXPLANATION.
99
- # EXPLANATION should contain the full reply text (e.g. "Fixed: ..." or "Not addressing this because...").
100
- BODY_JSON=$(jq -n --arg body "$EXPLANATION" '{body:$body}')
101
- # Non-fatal: a force-push can mark threads as outdated, causing the REST reply to return 404.
102
- # Always continue to the GraphQL resolve step regardless.
103
- gh api "repos/$OWNER/$REPO/pulls/comments/$COMMENT_DBID/replies" \
104
- -X POST --input - <<<"$BODY_JSON" \
105
- || echo "Warning: reply POST failed (thread may be outdated after force-push) — skipping reply, will still resolve"
106
-
107
- : "${THREAD_ID:?missing THREAD_ID}"
108
-
109
- # Resolve (THREAD_ID = GraphQL node id, e.g. PRRT_...)
110
- gh api graphql \
111
- -f query='mutation($id:ID!){resolveReviewThread(input:{threadId:$id}){thread{isResolved}}}' \
112
- -f id="$THREAD_ID"
113
- ```
114
-
115
- ### 4. Request review
116
-
117
- **If this was the ${input:maxIterations:5}th iteration**, skip steps 4 and 6 entirely — go directly to step 5 (Report) and then produce the Final Report.
118
-
119
- Otherwise, capture `REVIEW_REQUESTED_AT` by running `date -u +%Y-%m-%dT%H:%M:%SZ` in the terminal immediately before requesting the review. Then request a new Copilot Review using the `mcp_github_mcp_se_request_copilot_review` tool (owner, repo, pullNumber).
120
-
121
- ### 5. Report
122
-
123
- List what was addressed and how each issue was resolved.
124
-
125
- ### 6. Wait
126
-
127
- Jump to the **Wait for Review** section below. Return here to begin the next iteration once the new Copilot Review has been submitted.
128
-
129
- ## Wait for Review
130
-
131
- **[BLOCKING — do not proceed until complete]** Poll for a new Copilot Review submission using the Reviews API. A Review with `submittedAt >= REVIEW_REQUESTED_AT` is the authoritative completion signal — it fires even when Copilot produces zero Review Threads.
132
-
133
- Run the following script via `run_in_terminal` (sync mode, timeout 750000 ms). Set the four variables on the first line to their actual values. On success, capture the script's last output line; on failure, follow the global failure-reporting rule (failed command, exit code, relevant stderr):
134
-
135
- ```bash
136
- set -euo pipefail
137
- # Replace with actual values. REVIEW_REQUESTED_AT = output of `date -u +%Y-%m-%dT%H:%M:%SZ` captured just before requesting the review.
138
- OWNER="ruby-git"; REPO="ruby-git"; PR_NUMBER="1439"; REVIEW_REQUESTED_AT="2026-06-16T12:00:00Z"
139
- : "${OWNER:?missing OWNER}"
140
- : "${REPO:?missing REPO}"
141
- : "${PR_NUMBER:?missing PR_NUMBER}"
142
- : "${REVIEW_REQUESTED_AT:?missing REVIEW_REQUESTED_AT}"
143
- START=$(date +%s)
144
- for i in $(seq 1 60); do
145
- new_review=$(gh pr view "$PR_NUMBER" --repo "$OWNER/$REPO" --json reviews \
146
- --jq "[.reviews[] | select(.author.login==\"copilot-pull-request-reviewer\") | select(.submittedAt != null) | select(.submittedAt | fromdateiso8601 >= (\"$REVIEW_REQUESTED_AT\" | fromdateiso8601))] | length") \
147
- || { rc=$?; echo "Error: gh pr view failed (exit $rc)"; exit $rc; }
148
- if [[ -n "$new_review" && "$new_review" -gt 0 ]]; then
149
- raw_nodes=$(gh api graphql -f query='
150
- query($owner:String!,$repo:String!,$pr:Int!){
151
- repository(owner:$owner,name:$repo){
152
- pullRequest(number:$pr){
153
- reviewThreads(first:100){nodes{isResolved isOutdated comments(first:1){nodes{author{login}}}}}
154
- }
155
- }
156
- }' -f owner="$OWNER" -f repo="$REPO" -F pr="$PR_NUMBER" \
157
- --jq '.data.repository.pullRequest.reviewThreads.nodes') \
158
- || { rc=$?; echo "Error: gh api graphql failed (exit $rc)"; exit $rc; }
159
- if [[ $(echo "$raw_nodes" | jq 'length') -ge 100 ]]; then
160
- echo "Error: the PR already has 100 threads or more. Aborting."
161
- exit 1
162
- fi
163
- count=$(echo "$raw_nodes" | jq "[.[] |
164
- select(.isResolved==false) |
165
- select(.isOutdated==false) |
166
- select(.comments.nodes[0].author.login==\"copilot-pull-request-reviewer\")] | length")
167
- echo "done: $count threads" # count of all unresolved non-outdated Copilot Review Threads
168
- exit 0
169
- fi
170
- elapsed=$(( $(date +%s) - START ))
171
- echo "Waiting for Copilot Review to complete... (${elapsed}s elapsed)"
172
- sleep 10
173
- done
174
- echo "timed out after 60 polls"
175
- exit 1
176
- ```
177
-
178
- **If `timed out after 60 polls`**: stop immediately and ask me whether to re-request the review and retry, or abort.
179
-
180
- **If `done: 0 threads`**: the loop is complete — exit.
181
-
182
- **If `done: N threads`** (N > 0): begin the next iteration.
183
-
184
- ## Final Report
185
-
186
- - Total iterations completed
187
- - Total threads addressed
188
- - Unresolved threads in the final Copilot review (should be 0 if the loop exited cleanly)
@@ -1,21 +0,0 @@
1
- Review our [guidelines for contributing](https://github.com/ruby-git/ruby-git/blob/main/CONTRIBUTING.md) to this repository. A good start is to:
2
-
3
- - Write tests for your changes
4
- - Run `rake` before pushing
5
- - Include / update docs in the README.md and in YARD documentation
6
-
7
- # Description
8
-
9
- \<your description here\>
10
-
11
- ## Checklist
12
-
13
- - [ ] I reviewed and applied the project's [AI Policy](../AI_POLICY.md). I understand
14
- and verify any AI-assisted changes included in this PR and ensured they meet
15
- quality, security, and licensing standards.
16
- - [ ] I ran `bundle exec rake` locally on this branch and it passed (see
17
- [Local development setup](../CONTRIBUTING.md#local-development-setup)).
18
- - [ ] Tests added/updated as needed.
19
- - [ ] `bundle exec rake spec:unit` reports 100% line and branch coverage (see
20
- [Test coverage policy](../CONTRIBUTING.md#test-coverage-policy)).
21
- - [ ] Documentation updated where applicable (README and/or YARD).