git 5.0.0.beta.3 → 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.
- checksums.yaml +4 -4
- data/.dockerignore +27 -0
- data/.github/copilot-instructions.md +3 -8
- data/.github/hooks/bin-setup-on-worktree.json +11 -0
- data/.github/hooks/run-bin-setup-once.sh +14 -0
- data/.github/skills/breaking-change-analysis/SKILL.md +6 -9
- data/.github/skills/ci-cd-troubleshooting/SKILL.md +2 -2
- data/.github/skills/command-implementation/REFERENCE.md +34 -33
- data/.github/skills/command-implementation/SKILL.md +5 -4
- data/.github/skills/command-test-conventions/SKILL.md +13 -9
- data/.github/skills/command-yard-documentation/SKILL.md +14 -6
- data/.github/skills/development-workflow/SKILL.md +20 -14
- data/.github/skills/facade-implementation/REFERENCE.md +19 -22
- data/.github/skills/facade-implementation/SKILL.md +0 -5
- data/.github/skills/facade-test-conventions/SKILL.md +4 -7
- data/.github/skills/facade-yard-documentation/SKILL.md +8 -2
- data/.github/skills/make-skill-template/SKILL.md +53 -3
- data/.github/skills/pr-readiness-review/SKILL.md +22 -2
- data/.github/skills/project-context/SKILL.md +16 -23
- data/.github/skills/pull-request-review/SKILL.md +2 -2
- data/.github/skills/rebase/SKILL.md +148 -0
- data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +1 -1
- data/.github/skills/resolve-feedback/SKILL.md +288 -0
- data/.github/skills/review-arguments-dsl/CHECKLIST.md +3 -3
- data/.github/skills/reviewing-skills/SKILL.md +28 -3
- data/.github/skills/test-debugging/SKILL.md +20 -19
- data/.github/skills/yard-documentation/SKILL.md +671 -483
- data/.github/skills/yard-documentation/element-rules.md +162 -0
- data/.github/skills-deprecated/README.md +21 -0
- data/.github/{skills → skills-deprecated}/extract-command-from-lib/SKILL.md +9 -9
- data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/SKILL.md +12 -12
- data/.github/workflows/continuous_integration.yml +3 -2
- data/.rubocop.yml +7 -39
- data/.yard-lint.yml +75 -0
- data/CONTRIBUTING.md +186 -174
- data/Gemfile +17 -0
- data/README.md +47 -12
- data/Rakefile +3 -21
- data/UPGRADING.md +219 -70
- data/docker/test/Dockerfile +32 -0
- data/docker/test/docker-compose.yml +0 -0
- data/git.gemspec +3 -4
- data/lib/git/author.rb +20 -1
- data/lib/git/branch.rb +26 -6
- data/lib/git/branch_delete_failure.rb +3 -0
- data/lib/git/branch_delete_result.rb +6 -3
- data/lib/git/branch_info.rb +6 -6
- data/lib/git/command_line/base.rb +6 -13
- data/lib/git/command_line/capturing.rb +67 -10
- data/lib/git/command_line/result.rb +0 -8
- data/lib/git/command_line/streaming.rb +45 -5
- data/lib/git/command_line.rb +4 -3
- data/lib/git/commands/add.rb +61 -53
- data/lib/git/commands/am/abort.rb +2 -2
- data/lib/git/commands/am/apply.rb +109 -98
- data/lib/git/commands/am/continue.rb +2 -2
- data/lib/git/commands/am/quit.rb +2 -2
- data/lib/git/commands/am/retry.rb +4 -2
- data/lib/git/commands/am/show_current_patch.rb +1 -1
- data/lib/git/commands/am/skip.rb +2 -2
- data/lib/git/commands/am.rb +2 -2
- data/lib/git/commands/apply.rb +7 -2
- data/lib/git/commands/archive/list_formats.rb +3 -3
- data/lib/git/commands/archive.rb +7 -2
- data/lib/git/commands/arguments.rb +1370 -359
- data/lib/git/commands/base.rb +111 -13
- data/lib/git/commands/branch/copy.rb +29 -21
- data/lib/git/commands/branch/create.rb +72 -68
- data/lib/git/commands/branch/delete.rb +25 -17
- data/lib/git/commands/branch/list.rb +76 -60
- data/lib/git/commands/branch/move.rb +29 -21
- data/lib/git/commands/branch/set_upstream.rb +8 -8
- data/lib/git/commands/branch/show_current.rb +3 -3
- data/lib/git/commands/branch/unset_upstream.rb +4 -8
- data/lib/git/commands/branch.rb +2 -2
- data/lib/git/commands/cat_file/batch.rb +36 -20
- data/lib/git/commands/cat_file/filtered.rb +12 -12
- data/lib/git/commands/cat_file/raw.rb +13 -13
- data/lib/git/commands/cat_file.rb +4 -4
- data/lib/git/commands/checkout/branch.rb +7 -5
- data/lib/git/commands/checkout/files.rb +5 -4
- data/lib/git/commands/checkout.rb +4 -4
- data/lib/git/commands/checkout_index.rb +5 -4
- data/lib/git/commands/clean.rb +6 -4
- data/lib/git/commands/clone.rb +5 -4
- data/lib/git/commands/commit.rb +5 -4
- data/lib/git/commands/commit_tree.rb +5 -4
- data/lib/git/commands/config_option_syntax/add.rb +7 -4
- data/lib/git/commands/config_option_syntax/get.rb +9 -5
- data/lib/git/commands/config_option_syntax/get_all.rb +7 -4
- data/lib/git/commands/config_option_syntax/get_color.rb +8 -4
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +7 -4
- data/lib/git/commands/config_option_syntax/get_regexp.rb +8 -4
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +8 -4
- data/lib/git/commands/config_option_syntax/list.rb +8 -4
- data/lib/git/commands/config_option_syntax/remove_section.rb +7 -2
- data/lib/git/commands/config_option_syntax/rename_section.rb +7 -2
- data/lib/git/commands/config_option_syntax/replace_all.rb +7 -2
- data/lib/git/commands/config_option_syntax/set.rb +7 -2
- data/lib/git/commands/config_option_syntax/unset.rb +7 -4
- data/lib/git/commands/config_option_syntax/unset_all.rb +7 -2
- data/lib/git/commands/describe.rb +5 -4
- data/lib/git/commands/diff.rb +13 -12
- data/lib/git/commands/diff_files.rb +7 -6
- data/lib/git/commands/diff_index.rb +10 -7
- data/lib/git/commands/fetch.rb +6 -4
- data/lib/git/commands/fsck.rb +6 -4
- data/lib/git/commands/gc.rb +6 -4
- data/lib/git/commands/grep.rb +6 -5
- data/lib/git/commands/init.rb +6 -4
- data/lib/git/commands/log.rb +287 -285
- data/lib/git/commands/ls_files.rb +69 -65
- data/lib/git/commands/ls_remote.rb +62 -56
- data/lib/git/commands/ls_tree.rb +50 -46
- data/lib/git/commands/maintenance/register.rb +25 -23
- data/lib/git/commands/maintenance/run.rb +7 -2
- data/lib/git/commands/maintenance/start.rb +7 -2
- data/lib/git/commands/maintenance/stop.rb +7 -2
- data/lib/git/commands/maintenance/unregister.rb +7 -2
- data/lib/git/commands/merge/abort.rb +2 -2
- data/lib/git/commands/merge/continue.rb +2 -2
- data/lib/git/commands/merge/quit.rb +2 -2
- data/lib/git/commands/merge/start.rb +7 -2
- data/lib/git/commands/merge.rb +2 -2
- data/lib/git/commands/merge_base.rb +7 -2
- data/lib/git/commands/mv.rb +7 -2
- data/lib/git/commands/name_rev.rb +7 -2
- data/lib/git/commands/pull.rb +7 -2
- data/lib/git/commands/push.rb +7 -2
- data/lib/git/commands/read_tree.rb +7 -2
- data/lib/git/commands/remote/add.rb +7 -2
- data/lib/git/commands/remote/get_url.rb +4 -2
- data/lib/git/commands/remote/list.rb +4 -2
- data/lib/git/commands/remote/prune.rb +4 -2
- data/lib/git/commands/remote/remove.rb +4 -2
- data/lib/git/commands/remote/rename.rb +4 -2
- data/lib/git/commands/remote/set_branches.rb +9 -2
- data/lib/git/commands/remote/set_head.rb +12 -5
- data/lib/git/commands/remote/set_url.rb +9 -2
- data/lib/git/commands/remote/set_url_add.rb +11 -2
- data/lib/git/commands/remote/set_url_delete.rb +9 -2
- data/lib/git/commands/remote/show.rb +18 -12
- data/lib/git/commands/remote/update.rb +19 -12
- data/lib/git/commands/remote.rb +2 -2
- data/lib/git/commands/repack.rb +67 -63
- data/lib/git/commands/reset.rb +51 -44
- data/lib/git/commands/rev_parse.rb +135 -128
- data/lib/git/commands/revert/abort.rb +2 -2
- data/lib/git/commands/revert/continue.rb +7 -2
- data/lib/git/commands/revert/quit.rb +2 -2
- data/lib/git/commands/revert/skip.rb +2 -2
- data/lib/git/commands/revert/start.rb +7 -2
- data/lib/git/commands/revert.rb +2 -2
- data/lib/git/commands/rm.rb +35 -36
- data/lib/git/commands/show.rb +1 -1
- data/lib/git/commands/show_ref/exclude_existing.rb +3 -4
- data/lib/git/commands/show_ref/exists.rb +15 -13
- data/lib/git/commands/show_ref/list.rb +39 -35
- data/lib/git/commands/show_ref/verify.rb +29 -27
- data/lib/git/commands/show_ref.rb +4 -4
- data/lib/git/commands/stash/apply.rb +31 -25
- data/lib/git/commands/stash/branch.rb +10 -8
- data/lib/git/commands/stash/clear.rb +7 -5
- data/lib/git/commands/stash/create.rb +10 -8
- data/lib/git/commands/stash/drop.rb +15 -9
- data/lib/git/commands/stash/list.rb +9 -5
- data/lib/git/commands/stash/pop.rb +21 -12
- data/lib/git/commands/stash/push.rb +20 -11
- data/lib/git/commands/stash/show.rb +21 -12
- data/lib/git/commands/stash/store.rb +19 -10
- data/lib/git/commands/stash.rb +2 -2
- data/lib/git/commands/status.rb +7 -2
- data/lib/git/commands/symbolic_ref/delete.rb +18 -14
- data/lib/git/commands/symbolic_ref/read.rb +24 -20
- data/lib/git/commands/symbolic_ref/update.rb +20 -17
- data/lib/git/commands/symbolic_ref.rb +4 -4
- data/lib/git/commands/tag/create.rb +45 -42
- data/lib/git/commands/tag/delete.rb +5 -3
- data/lib/git/commands/tag/list.rb +47 -44
- data/lib/git/commands/tag/verify.rb +12 -12
- data/lib/git/commands/tag.rb +2 -2
- data/lib/git/commands/update_ref/batch.rb +6 -1
- data/lib/git/commands/update_ref/delete.rb +19 -21
- data/lib/git/commands/update_ref/update.rb +22 -25
- data/lib/git/commands/update_ref.rb +4 -4
- data/lib/git/commands/version.rb +14 -11
- data/lib/git/commands/worktree/add.rb +50 -51
- data/lib/git/commands/worktree/list.rb +17 -17
- data/lib/git/commands/worktree/lock.rb +12 -12
- data/lib/git/commands/worktree/move.rb +16 -16
- data/lib/git/commands/worktree/prune.rb +2 -2
- data/lib/git/commands/worktree/remove.rb +2 -2
- data/lib/git/commands/worktree/repair.rb +2 -2
- data/lib/git/commands/worktree/unlock.rb +2 -2
- data/lib/git/commands/write_tree.rb +2 -2
- data/lib/git/commands.rb +4 -3
- data/lib/git/config.rb +47 -1
- data/lib/git/configuring.rb +89 -15
- data/lib/git/detached_head_info.rb +4 -1
- data/lib/git/diff.rb +2 -5
- data/lib/git/diff_file_numstat_info.rb +3 -1
- data/lib/git/diff_file_patch_info.rb +3 -1
- data/lib/git/diff_file_raw_info.rb +3 -1
- data/lib/git/diff_info.rb +8 -15
- data/lib/git/diff_path_status.rb +16 -3
- data/lib/git/diff_result.rb +3 -1
- data/lib/git/diff_stats.rb +15 -0
- data/lib/git/dirstat_info.rb +24 -8
- data/lib/git/encoding_utils.rb +32 -1
- data/lib/git/errors.rb +19 -9
- data/lib/git/escaped_path.rb +55 -3
- data/lib/git/execution_context/repository.rb +15 -0
- data/lib/git/execution_context.rb +76 -74
- data/lib/git/file_ref.rb +6 -3
- data/lib/git/fsck_object.rb +8 -0
- data/lib/git/fsck_result.rb +26 -15
- data/lib/git/log.rb +152 -5
- data/lib/git/object.rb +284 -8
- data/lib/git/parsers/branch.rb +18 -0
- data/lib/git/parsers/cat_file.rb +2 -2
- data/lib/git/parsers/diff.rb +213 -5
- data/lib/git/parsers/fsck.rb +11 -0
- data/lib/git/parsers/ls_remote.rb +1 -1
- data/lib/git/parsers/stash.rb +51 -0
- data/lib/git/parsers/tag.rb +38 -0
- data/lib/git/remote.rb +34 -2
- data/lib/git/repository/branching.rb +23 -21
- data/lib/git/repository/committing.rb +46 -6
- data/lib/git/repository/context_helpers.rb +45 -16
- data/lib/git/repository/diffing.rb +32 -23
- data/lib/git/repository/factories.rb +153 -28
- data/lib/git/repository/inspecting.rb +1 -1
- data/lib/git/repository/logging.rb +169 -30
- data/lib/git/repository/maintenance.rb +1 -1
- data/lib/git/repository/merging.rb +3 -3
- data/lib/git/repository/object_operations.rb +108 -14
- data/lib/git/repository/remote_operations.rb +150 -171
- data/lib/git/repository/shared_private.rb +7 -5
- data/lib/git/repository/staging.rb +36 -12
- data/lib/git/repository/stashing.rb +16 -16
- data/lib/git/repository/status_operations.rb +1 -1
- data/lib/git/repository/worktree_operations.rb +1 -1
- data/lib/git/repository.rb +123 -63
- data/lib/git/stash.rb +16 -21
- data/lib/git/stash_info.rb +4 -4
- data/lib/git/stashes.rb +20 -26
- data/lib/git/status.rb +21 -7
- data/lib/git/tag_delete_failure.rb +3 -0
- data/lib/git/tag_delete_result.rb +6 -3
- data/lib/git/tag_info.rb +1 -0
- data/lib/git/url.rb +12 -5
- data/lib/git/version.rb +6 -4
- data/lib/git/version_constraint.rb +4 -0
- data/lib/git.rb +398 -314
- data/redesign/3_architecture_implementation.md +59 -29
- data/redesign/Phase 4 - Step B.md +921 -0
- data/redesign/Phase 4 - Step C.md +833 -0
- data/redesign/c1a-public-api-scope.tsv +256 -0
- data/redesign/phase-4-step-b-test-audit.tsv +485 -0
- data/tasks/yard.rake +24 -17
- metadata +24 -57
- data/commitlint.test +0 -4
- data/lib/git/args_builder.rb +0 -103
- data/lib/git/command_line_result.rb +0 -8
- data/lib/git/deprecation.rb +0 -9
- data/tasks/test.rake +0 -25
- /data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -0
- /data/.github/{skills → skills-deprecated}/review-backward-compatibility/SKILL.md +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 24512a581eb9da75ed5026f0579869d4ae549a3c028d94a4d97edb5b5b063ac5
|
|
4
|
+
data.tar.gz: 86ce5ddca8a1bb92802afbb61e84e7b186a782222f8ff8fa7e6ee14d57020779
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fff5622c9a132467a43459c4ea2c5ad059d8e50a18ac7d45b2a7af37abfd37c0ed2e8cc834b654f2cabd99e6a53330a47f0b8e626cbf0e67433ff42f376bf8e0
|
|
7
|
+
data.tar.gz: 927adb62c1023e826cf76da5522fc7b5fb5c182bfec637e0c3d191967ad148b1b134403f7151a2f66460536bcf0ba4383c9daf40d2cc3a730e4aecb2fa97555a
|
data/.dockerignore
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
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/
|
|
@@ -40,20 +40,15 @@ or explanation does not require a skill.
|
|
|
40
40
|
| Purpose | Command |
|
|
41
41
|
| --- | --- |
|
|
42
42
|
| First-time setup | `bin/setup` |
|
|
43
|
-
| Run all tests and linters(CI-equivalent) | `bundle exec rake default
|
|
44
|
-
| Run all tests (
|
|
45
|
-
| Run Test::Unit tests | `bundle exec rake test:parallel` |
|
|
43
|
+
| Run all tests and linters (CI-equivalent) | `bundle exec rake default` |
|
|
44
|
+
| Run all tests and linters (force parallel) | `bundle exec rake default:parallel` |
|
|
46
45
|
| Run all RSpec tests | `bundle exec rake spec:parallel` |
|
|
47
46
|
| Run RSpec unit tests | `bundle exec rake spec:unit:parallel` |
|
|
48
47
|
| Run RSpec integration tests | `bundle exec rake spec:integration:parallel` |
|
|
49
|
-
| Run a specific Test::Unit test | `bundle exec bin/test <test-base-name>` |
|
|
50
48
|
| Run a specific RSpec spec | `bundle exec rspec <path>` |
|
|
51
49
|
| Run linters | `bundle exec rake rubocop yard build` |
|
|
52
50
|
|
|
53
|
-
**Test
|
|
54
|
-
`tests/` (Test::Unit) is legacy; only touch it when modifying existing tests there
|
|
55
|
-
or adding pre-migration coverage to verify that a `Git::Lib` → `Git::Commands`
|
|
56
|
-
migration doesn't break existing behavior.
|
|
51
|
+
**Test suite:** `spec/` (RSpec) is the sole test suite — all new tests go here.
|
|
57
52
|
|
|
58
53
|
## Commit Conventions
|
|
59
54
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Skip if this repo does not use bin/setup.
|
|
5
|
+
[[ -x "./bin/setup" ]] || exit 0
|
|
6
|
+
|
|
7
|
+
# Keep setup idempotent per-worktree.
|
|
8
|
+
command -v git >/dev/null 2>&1 || exit 0
|
|
9
|
+
marker="$(git rev-parse --git-path copilot-bin-setup.done 2>/dev/null)" || exit 0
|
|
10
|
+
[[ -f "$marker" ]] && exit 0
|
|
11
|
+
|
|
12
|
+
./bin/setup
|
|
13
|
+
mkdir -p "$(dirname "$marker")"
|
|
14
|
+
touch "$marker"
|
|
@@ -26,8 +26,6 @@ impact and plan migration.
|
|
|
26
26
|
|
|
27
27
|
## Related skills
|
|
28
28
|
|
|
29
|
-
- [Review Backward Compatibility](../review-backward-compatibility/SKILL.md) —
|
|
30
|
-
verify backward compatibility after command migrations
|
|
31
29
|
- [Development Workflow](../development-workflow/SKILL.md) — implement required
|
|
32
30
|
changes using strict TDD
|
|
33
31
|
|
|
@@ -35,20 +33,20 @@ impact and plan migration.
|
|
|
35
33
|
|
|
36
34
|
1. Determine which classes and methods are affected.
|
|
37
35
|
2. Check API visibility (`@api public` vs `@api private` in YARD docs).
|
|
38
|
-
3. Check if the change affects `Git::
|
|
36
|
+
3. Check if the change affects `Git::Repository` (the current facade layer, modules under `lib/git/repository/`).
|
|
39
37
|
|
|
40
38
|
## Step 2: Find All Usages
|
|
41
39
|
|
|
42
40
|
1. **Internal usages:**
|
|
43
41
|
|
|
44
42
|
```bash
|
|
45
|
-
grep -rn "method_name" lib/
|
|
43
|
+
grep -rn "method_name" lib/ spec/
|
|
46
44
|
```
|
|
47
45
|
|
|
48
46
|
2. **External usage (if applicable):**
|
|
49
47
|
|
|
50
48
|
```bash
|
|
51
|
-
gh search code "Git::
|
|
49
|
+
gh search code "Git::Repository#method_name language:ruby"
|
|
52
50
|
```
|
|
53
51
|
|
|
54
52
|
## Step 3: Assess and Document Impact
|
|
@@ -82,14 +80,13 @@ Produce an impact assessment:
|
|
|
82
80
|
## Step 4: Plan Migration Path
|
|
83
81
|
|
|
84
82
|
**Project versioning policy:**
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
- Use deprecation warnings in the current release line before removal in the next major
|
|
83
|
+
- Breaking changes are batched for major releases
|
|
84
|
+
- Use deprecation warnings in the current major series before removal in the next major release
|
|
88
85
|
|
|
89
86
|
**Deprecation approach:**
|
|
90
87
|
|
|
91
88
|
```ruby
|
|
92
|
-
# @deprecated Use {#new_method} instead. Will be removed in
|
|
89
|
+
# @deprecated Use {#new_method} instead. Will be removed in the next major release.
|
|
93
90
|
def old_method(*args)
|
|
94
91
|
warn "[DEPRECATION] `old_method` is deprecated. Use `new_method` instead."
|
|
95
92
|
new_method(*args)
|
|
@@ -132,7 +132,7 @@ Based on the failure type, investigate:
|
|
|
132
132
|
2. Run the failing tests locally:
|
|
133
133
|
|
|
134
134
|
```bash
|
|
135
|
-
bundle exec
|
|
135
|
+
bundle exec rspec <path/to/spec.rb>
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
3. Run linters:
|
|
@@ -211,7 +211,7 @@ After implementing fixes:
|
|
|
211
211
|
1. **Run Affected Tests Locally:**
|
|
212
212
|
|
|
213
213
|
```bash
|
|
214
|
-
bundle exec
|
|
214
|
+
bundle exec rspec <path/to/spec.rb>
|
|
215
215
|
```
|
|
216
216
|
|
|
217
217
|
2. **Run Full CI Suite:**
|
|
@@ -98,8 +98,8 @@ class Diff < Git::Commands::Base
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
# lib/git/
|
|
102
|
-
Git::Commands::Diff.new(
|
|
101
|
+
# lib/git/repository/diffing.rb — parser contract is visible and auditable:
|
|
102
|
+
Git::Commands::Diff.new(@execution_context).call(patch: true, numstat: true, ...)
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
The same applies for `--format=<string>`, `--pretty=<fmt>`, `--no-color`, and all
|
|
@@ -156,11 +156,11 @@ the pattern of `cat_file.rb`. The file has three required sections in this order
|
|
|
156
156
|
4. A "This module contains command classes split by…" paragraph with a bullet for
|
|
157
157
|
every sub-command class using `{Foo::Bar}` YARD links followed by ` — ` and a
|
|
158
158
|
short description
|
|
159
|
-
5. `@
|
|
160
|
-
6. `@see https://git-scm.com/docs/git-foo git-foo documentation`
|
|
161
|
-
7. At least two `@example` blocks — one per sub-command class; each example should
|
|
159
|
+
5. At least two `@example` blocks — one per sub-command class; each example should
|
|
162
160
|
demonstrate the most common (non-error-path) call using a local variable named
|
|
163
161
|
`cmd` and `lib` as the constructor argument
|
|
162
|
+
6. `@see https://git-scm.com/docs/git-foo git-foo documentation`
|
|
163
|
+
7. `@api private`
|
|
164
164
|
8. Empty `module Foo` + `end` block (no methods, no constants)
|
|
165
165
|
|
|
166
166
|
**Tag ordering inside the YARD comment block:**
|
|
@@ -173,10 +173,6 @@ the pattern of `cat_file.rb`. The file has three required sections in this order
|
|
|
173
173
|
# - {Foo::Bar} — short description
|
|
174
174
|
# - {Foo::Baz} — short description
|
|
175
175
|
#
|
|
176
|
-
# @api private
|
|
177
|
-
#
|
|
178
|
-
# @see https://git-scm.com/docs/git-foo git-foo documentation
|
|
179
|
-
#
|
|
180
176
|
# @example <Short description of the Bar use case>
|
|
181
177
|
# cmd = Git::Commands::Foo::Bar.new(lib)
|
|
182
178
|
# cmd.call(...)
|
|
@@ -184,6 +180,10 @@ the pattern of `cat_file.rb`. The file has three required sections in this order
|
|
|
184
180
|
# @example <Short description of the Baz use case>
|
|
185
181
|
# cmd = Git::Commands::Foo::Baz.new(lib)
|
|
186
182
|
# cmd.call(...)
|
|
183
|
+
#
|
|
184
|
+
# @see https://git-scm.com/docs/git-foo git-foo documentation
|
|
185
|
+
#
|
|
186
|
+
# @api private
|
|
187
187
|
```
|
|
188
188
|
|
|
189
189
|
**Full template:**
|
|
@@ -203,10 +203,6 @@ module Git
|
|
|
203
203
|
# - {Foo::Bar} — what Bar does
|
|
204
204
|
# - {Foo::Baz} — what Baz does
|
|
205
205
|
#
|
|
206
|
-
# @api private
|
|
207
|
-
#
|
|
208
|
-
# @see https://git-scm.com/docs/git-foo git-foo documentation
|
|
209
|
-
#
|
|
210
206
|
# @example <Short description for bar>
|
|
211
207
|
# cmd = Git::Commands::Foo::Bar.new(lib)
|
|
212
208
|
# cmd.call(...)
|
|
@@ -215,6 +211,10 @@ module Git
|
|
|
215
211
|
# cmd = Git::Commands::Foo::Baz.new(lib)
|
|
216
212
|
# cmd.call(...)
|
|
217
213
|
#
|
|
214
|
+
# @see https://git-scm.com/docs/git-foo git-foo documentation
|
|
215
|
+
#
|
|
216
|
+
# @api private
|
|
217
|
+
#
|
|
218
218
|
module Foo
|
|
219
219
|
end
|
|
220
220
|
end
|
|
@@ -233,7 +233,7 @@ module's overview.
|
|
|
233
233
|
- [ ] `@see` link points to `git-scm.com/docs/git-foo` documentation
|
|
234
234
|
- [ ] At least one `@example` block per sub-command class
|
|
235
235
|
- [ ] Each example uses `cmd = Git::Commands::Foo::Bar.new(lib)` form (variable `cmd`, arg `lib`)
|
|
236
|
-
- [ ] Tag order: summary → bullet list → `@
|
|
236
|
+
- [ ] Tag order: summary → bullet list → `@example` blocks → `@see` → `@api private`
|
|
237
237
|
- [ ] No class is defined inside the module file; the `module Foo` block is empty
|
|
238
238
|
|
|
239
239
|
## Architecture contract
|
|
@@ -285,7 +285,7 @@ Structural requirements:
|
|
|
285
285
|
`@execution_context`
|
|
286
286
|
- `require` statements are limited to files actually used within the command
|
|
287
287
|
class file itself — do not carry over `require` entries that belong only to
|
|
288
|
-
the
|
|
288
|
+
the `Git::Repository::*` facade or parser layer
|
|
289
289
|
|
|
290
290
|
## Command template (Base pattern)
|
|
291
291
|
|
|
@@ -326,9 +326,14 @@ module Git
|
|
|
326
326
|
class Bar < Git::Commands::Base # never name the class Object
|
|
327
327
|
arguments do
|
|
328
328
|
# Group related options with section comments (e.g. # Output, # Safety)
|
|
329
|
-
# NEVER add trailing inline comments (e.g. `# --verbose`) to DSL entries
|
|
330
|
-
#
|
|
331
|
-
#
|
|
329
|
+
# NEVER add trailing inline comments (e.g. `# --verbose`) to DSL entries;
|
|
330
|
+
# the DSL is self-documenting and inline comments duplicate the YARD docs.
|
|
331
|
+
# NEVER put YARD tags (@see, @param, @return, etc.) in comments inside this
|
|
332
|
+
# block. A DSL call such as `flag_option :x` is not a documentable construct,
|
|
333
|
+
# so YARD silently drops the whole comment (an orphaned doc comment that
|
|
334
|
+
# Documentation/OrphanedDocComment flags). Put per-option references in the
|
|
335
|
+
# matching @option tag (use continuation text for URLs) and command-wide
|
|
336
|
+
# references in a class-level @see.
|
|
332
337
|
end
|
|
333
338
|
|
|
334
339
|
# Optional: for commands where non-zero exits are valid
|
|
@@ -683,7 +688,7 @@ single source of truth for its own option semantics. There are two narrow except
|
|
|
683
688
|
See `redesign/3_architecture_implementation.md` Insight 6 for the full policy.
|
|
684
689
|
|
|
685
690
|
This step is required. A command class that only exposes the options that happen to
|
|
686
|
-
be used today in `Git::
|
|
691
|
+
be used today in the `Git::Repository::*` facade is incomplete — callers of the future API should not need
|
|
687
692
|
to re-open the docs just because the scaffold only covered current usage.
|
|
688
693
|
|
|
689
694
|
### Scoping options to sub-command classes
|
|
@@ -728,7 +733,7 @@ single-class commands, include all options as described in the decision table ab
|
|
|
728
733
|
### Execution-model conflicts
|
|
729
734
|
|
|
730
735
|
Command classes are neutral — they never hardcode policy choices. Policy defaults
|
|
731
|
-
(`no_edit: true`, `no_progress: true`, etc.) belong to the
|
|
736
|
+
(`no_edit: true`, `no_progress: true`, etc.) belong to the `Git::Repository::*` facade.
|
|
732
737
|
|
|
733
738
|
> **Anti-pattern:** `literal '--no-edit'` inside a command class.
|
|
734
739
|
>
|
|
@@ -833,7 +838,7 @@ allow_exit_status 0..7
|
|
|
833
838
|
## Facade delegation and policy options
|
|
834
839
|
|
|
835
840
|
The command class is only half the story. After scaffolding the command, you must
|
|
836
|
-
also write (or update) the `Git::
|
|
841
|
+
also write (or update) the `Git::Repository::*` facade method that **delegates** to it. The facade
|
|
837
842
|
sets safe policy defaults at each call site — `no_edit: true`, `no_progress: true`,
|
|
838
843
|
etc. — not as `literal` entries inside the command class. See "Command-layer
|
|
839
844
|
neutrality" in CONTRIBUTING.md.
|
|
@@ -850,7 +855,7 @@ Policy defaults fall into two categories (see also
|
|
|
850
855
|
that goes through `**opts`.
|
|
851
856
|
|
|
852
857
|
```ruby
|
|
853
|
-
# lib/git/
|
|
858
|
+
# lib/git/repository/remote_operations.rb — facade method for `git pull`
|
|
854
859
|
|
|
855
860
|
PULL_ALLOWED_OPTS = %i[allow_unrelated_histories].freeze
|
|
856
861
|
|
|
@@ -861,7 +866,7 @@ def pull(remote = nil, branch = nil, opts = {})
|
|
|
861
866
|
allowed_opts = opts.slice(*PULL_ALLOWED_OPTS)
|
|
862
867
|
positional_args = [remote, branch].compact
|
|
863
868
|
# no_edit: true is the non-interactive default (see CONTRIBUTING.md)
|
|
864
|
-
Git::Commands::Pull.new(
|
|
869
|
+
Git::Commands::Pull.new(@execution_context).call(*positional_args, no_edit: true, **allowed_opts).stdout
|
|
865
870
|
end
|
|
866
871
|
```
|
|
867
872
|
|
|
@@ -878,10 +883,6 @@ Key points for the facade method:
|
|
|
878
883
|
- **Return the legacy type** — typically `.stdout` or a parsed struct, not
|
|
879
884
|
`CommandLineResult`.
|
|
880
885
|
|
|
881
|
-
See [Extract Command from Lib](../extract-command-from-lib/SKILL.md) for the complete
|
|
882
|
-
delegation workflow and additional patterns (stdout passthrough, parsed return
|
|
883
|
-
values, opts-hash normalization).
|
|
884
|
-
|
|
885
886
|
## Internal compatibility contract
|
|
886
887
|
|
|
887
888
|
This is the canonical location for the internal compatibility contract. Other
|
|
@@ -940,10 +941,10 @@ flag_option :progress, negatable: true
|
|
|
940
941
|
flag_option :verbose
|
|
941
942
|
value_option :format
|
|
942
943
|
|
|
943
|
-
# ✅ In Git::
|
|
944
|
-
Git::Commands::Pull.new(
|
|
945
|
-
Git::Commands::Mv.new(
|
|
946
|
-
Git::Commands::Fsck.new(
|
|
944
|
+
# ✅ In Git::Repository::* — facade passes the policy value explicitly
|
|
945
|
+
Git::Commands::Pull.new(@execution_context).call(no_edit: true, no_progress: true)
|
|
946
|
+
Git::Commands::Mv.new(@execution_context).call(*args, verbose: true)
|
|
947
|
+
Git::Commands::Fsck.new(@execution_context).call(no_progress: true)
|
|
947
948
|
```
|
|
948
949
|
|
|
949
950
|
See "Command-layer neutrality" in CONTRIBUTING.md for the full policy.
|
|
@@ -965,8 +966,8 @@ newlines are data), hardcode it in a `def call` override instead — exposing it
|
|
|
965
966
|
### Unnecessary `require` statements
|
|
966
967
|
|
|
967
968
|
A command class file should only `require` what it actually uses. The canonical
|
|
968
|
-
example is parser requires: `require 'git/parsers/foo'` is needed by the
|
|
969
|
-
|
|
969
|
+
example is parser requires: `require 'git/parsers/foo'` is needed by the
|
|
970
|
+
`Git::Repository::*` facade but not by the command class itself — the command class just runs git
|
|
970
971
|
and returns `CommandLineResult`.
|
|
971
972
|
|
|
972
973
|
```ruby
|
|
@@ -36,7 +36,8 @@ Additional related skills:
|
|
|
36
36
|
sibling consistency within a command family
|
|
37
37
|
- [Facade Implementation](../facade-implementation/SKILL.md) — the v5.0.0 facade
|
|
38
38
|
layer (`Git::Repository::*`) that calls these command classes; new facade
|
|
39
|
-
wiring goes
|
|
39
|
+
wiring goes into a `Git::Repository::*` facade module rather than directly into
|
|
40
|
+
the command class
|
|
40
41
|
|
|
41
42
|
## Input
|
|
42
43
|
|
|
@@ -181,7 +182,7 @@ This skill supports three modes. Determine which mode applies before starting:
|
|
|
181
182
|
failures](REFERENCE.md#common-failures). Additionally:
|
|
182
183
|
|
|
183
184
|
- For **scaffold** and **update** modes: write or update the
|
|
184
|
-
`Git::
|
|
185
|
+
`Git::Repository::*` facade method per [Facade delegation and policy
|
|
185
186
|
options](REFERENCE.md#facade-delegation-and-policy-options).
|
|
186
187
|
- For **migration PRs**: verify [Phased rollout
|
|
187
188
|
requirements](REFERENCE.md#phased-rollout-requirements).
|
|
@@ -210,8 +211,8 @@ For **scaffold** and **update** modes, produce:
|
|
|
210
211
|
module file for the first command in a namespace)
|
|
211
212
|
2. **Unit tests** — `spec/unit/git/commands/{command}_spec.rb`
|
|
212
213
|
3. **Integration tests** — `spec/integration/git/commands/{command}_spec.rb`
|
|
213
|
-
4. **Facade delegation** — updated `Git::
|
|
214
|
-
5. **All quality gates pass** —
|
|
214
|
+
4. **Facade delegation** — updated `Git::Repository::*` facade method in `lib/git/repository/<topic>.rb`
|
|
215
|
+
5. **All quality gates pass** — RSpec, RuboCop, YARD, and build all green
|
|
215
216
|
|
|
216
217
|
For **review** mode, produce:
|
|
217
218
|
|
|
@@ -241,20 +241,24 @@ expect `--no-edit` unless the test is specifically exercising that option.
|
|
|
241
241
|
> **Correct pattern:** test each option independently (`it 'passes --no-edit
|
|
242
242
|
> when no_edit is true'`); test the default (no option passed) separately. Policy
|
|
243
243
|
> enforcement (which options the facade passes and why) is tested at the facade
|
|
244
|
-
> layer (`
|
|
244
|
+
> layer (for example, `spec/unit/git/repository/remote_operations_spec.rb`).
|
|
245
245
|
|
|
246
246
|
**Where to test policy enforcement:** Policy tests belong in the facade layer,
|
|
247
|
-
not in command specs. When a `Git::
|
|
248
|
-
`no_edit: true` or `no_progress: true`, the corresponding
|
|
249
|
-
(
|
|
247
|
+
not in command specs. When a `Git::Repository::*` facade method sets policy defaults like
|
|
248
|
+
`no_edit: true` or `no_progress: true`, the corresponding facade unit spec
|
|
249
|
+
(e.g. `spec/unit/git/repository/remote_operations_spec.rb`) should verify those defaults reach the command:
|
|
250
250
|
|
|
251
251
|
```ruby
|
|
252
|
-
# spec/unit/git/
|
|
252
|
+
# spec/unit/git/repository/remote_operations_spec.rb — facade policy-default test
|
|
253
253
|
describe '#pull' do
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
254
|
+
let(:pull_command) { instance_double(Git::Commands::Pull) }
|
|
255
|
+
let(:pull_result) { command_result('') }
|
|
256
|
+
|
|
257
|
+
it 'adds no_edit: true and no_progress: true for non-interactive execution' do
|
|
258
|
+
expect(Git::Commands::Pull).to receive(:new).with(execution_context).and_return(pull_command)
|
|
259
|
+
expect(pull_command)
|
|
260
|
+
.to receive(:call).with('origin', 'main', no_edit: true, no_progress: true).and_return(pull_result)
|
|
261
|
+
described_instance.pull('origin', 'main')
|
|
258
262
|
end
|
|
259
263
|
end
|
|
260
264
|
```
|
|
@@ -177,12 +177,20 @@ conflicting documentation for the method.
|
|
|
177
177
|
- Missing `# @!method call(*, **)` directive when there is no `def call` override
|
|
178
178
|
(loses child-specific docs in generated YARD)
|
|
179
179
|
- `@option` docs out of sync with `arguments do`
|
|
180
|
+
- **YARD tags inside the `arguments do` block** — placing a tag (`@see`, `@param`,
|
|
181
|
+
`@return`, etc.) in a comment above a DSL entry such as `flag_option :x` produces an
|
|
182
|
+
orphaned doc comment. The DSL call is not a documentable construct, so YARD silently
|
|
183
|
+
drops the comment and `Documentation/OrphanedDocComment` flags it. Document each
|
|
184
|
+
option in its `@option` tag (put URLs in continuation text) and use a class-level
|
|
185
|
+
`@see` for command-wide references. A plain-prose comment (no leading `@tag`) inside
|
|
186
|
+
the block is fine.
|
|
180
187
|
- **Missing `@raise [ArgumentError]` when `**options` is in the overload signature** —
|
|
181
188
|
every `@overload` that includes `**options` requires
|
|
182
|
-
`@raise [ArgumentError] if unsupported options are provided`. The
|
|
183
|
-
always raises this at bind time for unknown keys
|
|
184
|
-
block declares **no** options (only `operand` entries),
|
|
185
|
-
signature entirely — then no `@raise [ArgumentError]` is
|
|
189
|
+
`@raise [ArgumentError] if unsupported options are provided`. The `Arguments` DSL
|
|
190
|
+
always raises this at bind time for unknown keys via `validate_unsupported_options!`.
|
|
191
|
+
For commands whose `arguments` block declares **no** options (only `operand` entries),
|
|
192
|
+
drop `**options` from the signature entirely — then no `@raise [ArgumentError]` is
|
|
193
|
+
needed.
|
|
186
194
|
- **`**options` in `@overload` without `@param options [Hash]`** — whenever an
|
|
187
195
|
`@overload` signature includes `**options`, a corresponding `@param options [Hash]`
|
|
188
196
|
tag is required. For commands whose `arguments` block declares **no** options (only
|
|
@@ -337,8 +345,8 @@ For each command file, run through these checks in order:
|
|
|
337
345
|
tags) — every command class is `@api private` at the class level, but `call` is
|
|
338
346
|
the public contract and must be marked `@api public`
|
|
339
347
|
- [ ] whenever the `@overload` signature includes `**options`, include
|
|
340
|
-
`@raise [ArgumentError] if unsupported options are provided` — the
|
|
341
|
-
|
|
348
|
+
`@raise [ArgumentError] if unsupported options are provided` — the `Arguments`
|
|
349
|
+
DSL always raises this at bind time for unknown keys via `validate_unsupported_options!`
|
|
342
350
|
- [ ] `@raise [Git::FailedError]` uses the canonical generic wording — **never**
|
|
343
351
|
enumerate specific failure causes; use the form that matches the command's
|
|
344
352
|
declared exit-status range:
|
|
@@ -65,11 +65,6 @@ needed.
|
|
|
65
65
|
reviewing `Git::Commands::*` classes during implementation
|
|
66
66
|
- [Facade Implementation](../facade-implementation/SKILL.md) — scaffolding and
|
|
67
67
|
reviewing `Git::Repository::*` facade methods during implementation
|
|
68
|
-
- [Extract Command from Lib](../extract-command-from-lib/SKILL.md) — migrating a
|
|
69
|
-
`#command` call in `Git::Lib` into a `Git::Commands::*` class
|
|
70
|
-
- [Extract Facade from Base/Lib](../extract-facade-from-base-lib/SKILL.md) —
|
|
71
|
-
migrating a public method from `Git::Base` / `Git::Lib` into a
|
|
72
|
-
`Git::Repository::*` facade method
|
|
73
68
|
|
|
74
69
|
## Core TDD Principles
|
|
75
70
|
|
|
@@ -210,8 +205,8 @@ When all tasks are complete, proceed to **Phase 3: FINALIZE**.
|
|
|
210
205
|
- **Keep It Minimal:** Only write enough of a test to get an expected, failing
|
|
211
206
|
result (the test should fail for the *right* reason).
|
|
212
207
|
- **Execute and Analyze:** Run the specific test file (e.g.,
|
|
213
|
-
`bundle exec rspec spec/unit/git/commands/<command>_spec.rb`
|
|
214
|
-
|
|
208
|
+
`bundle exec rspec spec/unit/git/commands/<command>_spec.rb`) and analyze the
|
|
209
|
+
output.
|
|
215
210
|
- **Confirm Expected Failure:** Confirm it fails with an expected error (e.g.,
|
|
216
211
|
assertion failure or missing definition).
|
|
217
212
|
- **Validate:** If the test passes without implementation, the test is invalid or
|
|
@@ -479,20 +474,31 @@ Each task follows this cycle: **RED → GREEN → REFACTOR → VERIFY → COMMIT
|
|
|
479
474
|
**RED:** Write a failing test that describes the desired behavior.
|
|
480
475
|
|
|
481
476
|
```ruby
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
477
|
+
# spec/unit/git/commands/example_spec.rb
|
|
478
|
+
it 'passes the --force flag when force: true is given' do
|
|
479
|
+
expect_command_capturing('example', '--force').and_return(command_result(''))
|
|
480
|
+
|
|
481
|
+
described_class.new(execution_context).call(force: true)
|
|
485
482
|
end
|
|
486
|
-
# Run: bundle exec
|
|
483
|
+
# Run: bundle exec rspec spec/unit/git/commands/example_spec.rb
|
|
484
|
+
# → fails: NameError (Git::Commands::Example is not defined yet)
|
|
487
485
|
```
|
|
488
486
|
|
|
489
487
|
**GREEN:** Write minimal code to make the test pass.
|
|
490
488
|
|
|
491
489
|
```ruby
|
|
492
|
-
|
|
493
|
-
|
|
490
|
+
# lib/git/commands/example.rb
|
|
491
|
+
module Git
|
|
492
|
+
module Commands
|
|
493
|
+
class Example < Base
|
|
494
|
+
arguments do
|
|
495
|
+
literal 'example'
|
|
496
|
+
flag_option :force
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
end
|
|
494
500
|
end
|
|
495
|
-
# Run: bundle exec
|
|
501
|
+
# Run: bundle exec rspec spec/unit/git/commands/example_spec.rb → passes
|
|
496
502
|
```
|
|
497
503
|
|
|
498
504
|
**REFACTOR:** Improve code quality without changing behavior, then run all tests.
|
|
@@ -10,7 +10,7 @@ is loaded by subagents during the [Facade Implementation](SKILL.md) workflow.
|
|
|
10
10
|
- [Topic module selection](#topic-module-selection)
|
|
11
11
|
- [Existing modules](#existing-modules)
|
|
12
12
|
- [Decision rules for adding a new module](#decision-rules-for-adding-a-new-module)
|
|
13
|
-
- [
|
|
13
|
+
- [Choosing a module for a new facade method](#choosing-a-module-for-a-new-facade-method)
|
|
14
14
|
- [Naming a new topic module](#naming-a-new-topic-module)
|
|
15
15
|
- [Designing a facade method](#designing-a-facade-method)
|
|
16
16
|
- [Choosing the return type](#choosing-the-return-type)
|
|
@@ -85,16 +85,15 @@ methods is fine when the topic is genuinely distinct; the question is always
|
|
|
85
85
|
*fit*, not count. Default to extending an existing module whenever the new method
|
|
86
86
|
plausibly fits there.
|
|
87
87
|
|
|
88
|
-
####
|
|
88
|
+
#### Choosing a module for a new facade method
|
|
89
89
|
|
|
90
|
-
When
|
|
90
|
+
When placing a single facade method without a planned batch:
|
|
91
91
|
|
|
92
|
-
1. Before deciding placement, scan `Git::
|
|
93
|
-
on the same git topic (e.g. when
|
|
94
|
-
|
|
92
|
+
1. Before deciding placement, scan existing `Git::Repository::*` modules for
|
|
93
|
+
sibling methods on the same git topic (e.g. when adding a method related to
|
|
94
|
+
branches, check `Git::Repository::Branching` for existing siblings).
|
|
95
95
|
2. If those siblings form a coherent topic that does not fit any existing module,
|
|
96
|
-
create the new module
|
|
97
|
-
a home.
|
|
96
|
+
create the new module so subsequent additions have a home.
|
|
98
97
|
3. Otherwise place the method in the closest existing module. Revisit module
|
|
99
98
|
organization later if a distinct topic emerges; promote the cluster to its own
|
|
100
99
|
module in a single `refactor(repository):` commit at that point.
|
|
@@ -133,11 +132,10 @@ cases, orchestration sequence otherwise.
|
|
|
133
132
|
|
|
134
133
|
Apply these rules in order:
|
|
135
134
|
|
|
136
|
-
1. **
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
migration; capture the legacy return in the Step 2 plan.
|
|
135
|
+
1. **Changing an existing `Git::Repository` method?** Preserve the existing return
|
|
136
|
+
type exactly — same shape, same nil/empty semantics. Backward compatibility for
|
|
137
|
+
callers of `Git::Repository` is the public contract; capture the existing return
|
|
138
|
+
in the Step 2 plan.
|
|
141
139
|
2. **No legacy method (greenfield facade method)?** Choose the return type from
|
|
142
140
|
the public-API perspective, in this order of preference:
|
|
143
141
|
1. A **domain object** (`Git::BranchInfo`, `Git::DiffResult`, …) when the
|
|
@@ -158,11 +156,10 @@ Apply these rules in order:
|
|
|
158
156
|
The Ruby signature is part of the public contract — just as binding as the
|
|
159
157
|
return type. Apply these rules in order:
|
|
160
158
|
|
|
161
|
-
1. **
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
diff against it after implementation.
|
|
159
|
+
1. **Changing an existing `Git::Repository` method?** Preserve the existing
|
|
160
|
+
signature exactly: same positional arguments in the same order, same defaults,
|
|
161
|
+
same `opts = {}` vs. `**options` shape, same nil/sentinel semantics. Capture the
|
|
162
|
+
existing signature in the Step 2 plan and diff against it after implementation.
|
|
166
163
|
2. **No legacy method (greenfield facade method)?** Design the signature from
|
|
167
164
|
the public-API perspective:
|
|
168
165
|
1. **Positional arguments** for the natural domain identifiers the method
|
|
@@ -197,7 +194,7 @@ patterns](#argument-pre-processing-patterns).
|
|
|
197
194
|
When the facade method takes no options hash, does no pre-processing, and only
|
|
198
195
|
a trivial post-processing step (such as `.stdout.chomp`), it is a single-line
|
|
199
196
|
delegation. For example, a hypothetical `Git::Repository::Inspection#current_branch`
|
|
200
|
-
preserving
|
|
197
|
+
preserving the `String` return type contract:
|
|
201
198
|
|
|
202
199
|
```ruby
|
|
203
200
|
# Return the name of the currently checked-out branch
|
|
@@ -491,7 +488,7 @@ or via `include`). `include` copies private instance methods onto the host class
|
|
|
491
488
|
so any caller with a `Git::Repository` instance can `repo.send(:helper, ...)`.
|
|
492
489
|
This:
|
|
493
490
|
|
|
494
|
-
1. Re-creates the `Git::Lib`
|
|
491
|
+
1. Re-creates the god-class problem `Git::Lib` had — the reason the redesign introduced topic modules.
|
|
495
492
|
2. Couples every topic module silently to ambient mixin state.
|
|
496
493
|
3. Is not actually private and not `@api`-marked, so YARD/tooling cannot enforce it.
|
|
497
494
|
|
|
@@ -782,9 +779,9 @@ body.
|
|
|
782
779
|
|
|
783
780
|
### Changing the legacy return type or signature on extraction
|
|
784
781
|
|
|
785
|
-
When
|
|
782
|
+
When adding or changing a `Git::Repository` facade method, returning a
|
|
786
783
|
different type, accepting a different positional/keyword shape, or changing
|
|
787
|
-
nil-handling silently breaks every caller. Capture the
|
|
784
|
+
nil-handling silently breaks every caller. Capture the existing contract in the
|
|
788
785
|
Step 2 plan and diff before/after — see
|
|
789
786
|
[Choosing the return type](#choosing-the-return-type) rule 1 and
|
|
790
787
|
[Choosing the method signature](#choosing-the-method-signature) rule 1.
|
|
@@ -48,9 +48,6 @@ Facade Implementation review: Git::Repository::Committing#commit.
|
|
|
48
48
|
reviewing tests)
|
|
49
49
|
- [Facade YARD Documentation](../facade-yard-documentation/SKILL.md) — facade-specific
|
|
50
50
|
YARD rules for module-level and method-level docs
|
|
51
|
-
- [Extract Facade from Base/Lib](../extract-facade-from-base-lib/SKILL.md) — when a
|
|
52
|
-
new facade method is migrated from `Git::Base` or `Git::Lib`, the extraction
|
|
53
|
-
workflow drives this skill in scaffold/update mode
|
|
54
51
|
- [Command Implementation](../command-implementation/SKILL.md) — the underlying
|
|
55
52
|
`Git::Commands::*` classes a facade method calls. Scaffold any missing command
|
|
56
53
|
class first.
|
|
@@ -69,8 +66,6 @@ The user provides:
|
|
|
69
66
|
2. **Git operation(s)** — which `Git::Commands::*` class(es) the method orchestrates.
|
|
70
67
|
If the relevant command class does not exist yet, scaffold it first via
|
|
71
68
|
[Command Implementation](../command-implementation/SKILL.md).
|
|
72
|
-
3. **Optional context** — the source `Git::Lib` / `Git::Base` method when migrating
|
|
73
|
-
(handled by [Extract Facade from Base/Lib](../extract-facade-from-base-lib/SKILL.md)).
|
|
74
69
|
|
|
75
70
|
> **Note:** `Git::Repository` is intentionally empty during early phases of the
|
|
76
71
|
> redesign. Its `initialize(execution_context:)` constructor is introduced
|