git 5.0.0.beta.1 → 5.0.0.beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +6 -0
- data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +188 -0
- data/.github/skills/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +22 -0
- data/.github/skills/extract-facade-from-base-lib/SKILL.md +28 -14
- data/.github/skills/facade-implementation/SKILL.md +14 -0
- data/.github/skills/facade-test-conventions/SKILL.md +14 -0
- data/.rubocop.yml +5 -0
- data/README.md +51 -11
- data/UPGRADING.md +141 -0
- data/git.gemspec +5 -0
- data/lib/git/branch.rb +7 -18
- data/lib/git/branches.rb +2 -10
- data/lib/git/command_line/base.rb +10 -0
- data/lib/git/command_line/capturing.rb +5 -3
- data/lib/git/command_line/streaming.rb +5 -3
- data/lib/git/command_line.rb +3 -3
- data/lib/git/commands/base.rb +7 -6
- data/lib/git/commands/cat_file/batch.rb +6 -1
- data/lib/git/commands/cat_file/raw.rb +7 -1
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +5 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +1 -1
- data/lib/git/commands/update_ref/batch.rb +1 -1
- data/lib/git/commands/version.rb +5 -0
- data/lib/git/commands.rb +5 -7
- data/lib/git/config.rb +17 -0
- data/lib/git/config_entry_info.rb +106 -0
- data/lib/git/configuring.rb +665 -0
- data/lib/git/deprecation.rb +9 -0
- data/lib/git/diff.rb +4 -8
- data/lib/git/diff_path_status.rb +2 -13
- data/lib/git/diff_stats.rb +1 -9
- data/lib/git/execution_context/global.rb +3 -28
- data/lib/git/execution_context/repository.rb +30 -41
- data/lib/git/execution_context.rb +43 -24
- data/lib/git/log.rb +3 -9
- data/lib/git/object.rb +14 -21
- data/lib/git/parsers/config_entry.rb +110 -0
- data/lib/git/parsers/ls_remote.rb +79 -0
- data/lib/git/remote.rb +7 -20
- data/lib/git/repository/branching.rb +183 -12
- data/lib/git/repository/committing.rb +64 -68
- data/lib/git/repository/configuring.rb +208 -13
- data/lib/git/repository/context_helpers.rb +264 -0
- data/lib/git/repository/factories.rb +682 -0
- data/lib/git/repository/inspecting.rb +99 -0
- data/lib/git/repository/maintenance.rb +65 -0
- data/lib/git/repository/merging.rb +63 -1
- data/lib/git/repository/object_operations.rb +133 -35
- data/lib/git/repository/path_resolver.rb +1 -1
- data/lib/git/repository/remote_operations.rb +166 -21
- data/lib/git/repository/staging.rb +187 -23
- data/lib/git/repository/stashing.rb +39 -3
- data/lib/git/repository/status_operations.rb +21 -0
- data/lib/git/repository.rb +68 -129
- data/lib/git/stash.rb +2 -9
- data/lib/git/stashes.rb +2 -7
- data/lib/git/status.rb +8 -17
- data/lib/git/version.rb +2 -2
- data/lib/git/worktree.rb +2 -15
- data/lib/git/worktrees.rb +2 -15
- data/lib/git.rb +180 -77
- data/redesign/3_architecture_implementation.md +148 -111
- data/redesign/Phase 4 - Step A.md +360 -0
- data/redesign/beta_release.md +107 -0
- data/redesign/c1c2_audit.md +566 -0
- data/redesign/c1c2_bucket6_lib_orphans.md +626 -0
- data/redesign/config_design.rb +501 -0
- metadata +19 -5
- data/lib/git/base.rb +0 -1204
- data/lib/git/lib.rb +0 -2855
|
@@ -9,11 +9,12 @@ risk and allows for a gradual, controlled migration to the new architecture.
|
|
|
9
9
|
- [Facade Modules Completed](#facade-modules-completed)
|
|
10
10
|
- [Facade module naming convention](#facade-module-naming-convention)
|
|
11
11
|
- [Next Task](#next-task)
|
|
12
|
-
- [Phase
|
|
12
|
+
- [D2 / Phase 4 is the remaining redesign step](#d2--phase-4-is-the-remaining-redesign-step)
|
|
13
|
+
- [Phase 3 Overview](#phase-3-overview)
|
|
13
14
|
- [Workstream A — Fill facade coverage gaps](#workstream-a--fill-facade-coverage-gaps)
|
|
14
15
|
- [Workstream B — C0: Redirect `Git::Base` factory methods to `facade_repository`](#workstream-b--c0-redirect-gitbase-factory-methods-to-facade_repository)
|
|
15
16
|
- [Workstream C — C1: Prepare and flip top-level entry points to return `Git::Repository`](#workstream-c--c1-prepare-and-flip-top-level-entry-points-to-return-gitrepository)
|
|
16
|
-
- [Workstream D —
|
|
17
|
+
- [Workstream D — C3: Remove compatibility fallbacks](#workstream-d--c3-remove-compatibility-fallbacks)
|
|
17
18
|
- [Workstream E — Migrate or deprecate instance helper methods](#workstream-e--migrate-or-deprecate-instance-helper-methods)
|
|
18
19
|
- [Workstream F — `Git` module utility methods still using `Git::Lib` directly](#workstream-f--git-module-utility-methods-still-using-gitlib-directly)
|
|
19
20
|
- [Phase 3 dependency order](#phase-3-dependency-order)
|
|
@@ -31,6 +32,10 @@ risk and allows for a gradual, controlled migration to the new architecture.
|
|
|
31
32
|
- [⏳ Commands To Migrate](#-commands-to-migrate)
|
|
32
33
|
- [Phase 3: Refactoring the Public Interface](#phase-3-refactoring-the-public-interface)
|
|
33
34
|
- [Phase 4: Final Cleanup and Release Preparation](#phase-4-final-cleanup-and-release-preparation)
|
|
35
|
+
- [Phase 4 step graph](#phase-4-step-graph)
|
|
36
|
+
- [Step A — Remove old code](#step-a--remove-old-code)
|
|
37
|
+
- [Step B — Finalize test suite](#step-b--finalize-test-suite)
|
|
38
|
+
- [Step C — Update documentation](#step-c--update-documentation)
|
|
34
39
|
|
|
35
40
|
## Progress Tracker
|
|
36
41
|
|
|
@@ -38,44 +43,68 @@ risk and allows for a gradual, controlled migration to the new architecture.
|
|
|
38
43
|
| ----- | ------ | ----------- | :--------------: | :--------------: |
|
|
39
44
|
| Phase 1 | ✅ Complete | Foundation and scaffolding | 5% | 100% |
|
|
40
45
|
| Phase 2 | ✅ Complete | Migrating commands (all checklist items done) | 40% | 100% |
|
|
41
|
-
| Phase 3 |
|
|
46
|
+
| Phase 3 | ✅ Complete | Refactoring public interface — see [Facade Modules Completed](#facade-modules-completed) and [Facade coverage checklist](#facade-coverage-checklist) | 45% | 100% |
|
|
42
47
|
| Phase 4 | 🔲 Not Started | Final cleanup and release | 10% | 0% |
|
|
43
|
-
| **TOTAL** | -- | -- | **100%** | **
|
|
48
|
+
| **TOTAL** | -- | -- | **100%** | **90%** |
|
|
44
49
|
|
|
45
50
|
### Facade Modules Completed
|
|
46
51
|
|
|
47
52
|
| Module | File | Included in `Git::Repository` | `Git::Base` delegates |
|
|
48
53
|
| ------ | ---- | ------------------------------ | --------------------- |
|
|
49
|
-
| `Git::Repository::Staging` | `lib/git/repository/staging.rb` | ✅ | `add`, `reset`, `rm`, `clean`, `ignored_files` |
|
|
54
|
+
| `Git::Repository::Staging` | `lib/git/repository/staging.rb` | ✅ | `add`, `reset`, `reset_hard`, `apply`, `apply_mail`, `read_tree`, `rm`, `mv`, `clean`, `ignored_files` |
|
|
50
55
|
| `Git::Repository::Committing` | `lib/git/repository/committing.rb` | ✅ | `commit`, `commit_all`, `write_tree`; `commit_tree` and `write_and_commit_tree` wrap the SHA result in `Git::Object::Commit.new(self, ...)` |
|
|
51
|
-
| `Git::Repository::Branching` | `lib/git/repository/branching.rb` | ✅ | `checkout`, `checkout_file`, `checkout_index`, `current_branch`, `local_branch?`, `remote_branch?`, `branch?`, `branch_delete`, `branch_new`, `branch_contains`, `branches_all`, `update_ref` |
|
|
56
|
+
| `Git::Repository::Branching` | `lib/git/repository/branching.rb` | ✅ | `checkout`, `checkout_file`, `checkout_index`, `current_branch`, `current_branch_state`, `local_branch?`, `remote_branch?`, `branch?`, `branch`, `branches`, `branch_delete`, `branch_new`, `change_head_branch`, `branch_contains`, `branches_all`, `update_ref` |
|
|
57
|
+
| `Git::Repository::ContextHelpers` | `lib/git/repository/context_helpers.rb` | ✅ | `chdir`, `with_index`, `with_temp_index`, `with_working`, `with_temp_working`, `set_index`, `set_working` |
|
|
52
58
|
| `Git::Repository::Merging` | `lib/git/repository/merging.rb` | ✅ | `merge`, `revert`, `each_conflict`; `merge_base` wraps the returned SHA strings in `Git::Object::Commit.new(self, ...)` instances |
|
|
53
|
-
| `Git::Repository::RemoteOperations` | `lib/git/repository/remote_operations.rb` | ✅ | `fetch`, `pull`, `push`, `add_remote
|
|
54
|
-
| `Git::Repository::Stashing` | `lib/git/repository/stashing.rb` | ✅ | `stash_save`, `stash_apply`, `stash_clear`, `stashes_all` |
|
|
55
|
-
| `Git::Repository::Diffing` | `lib/git/repository/diffing.rb` | ✅ | `
|
|
56
|
-
| `Git::Repository::Inspecting` | `lib/git/repository/inspecting.rb` | ✅ | `show`, `fsck` |
|
|
57
|
-
| `Git::Repository::ObjectOperations` | `lib/git/repository/object_operations.rb` | ✅ | `rev_parse`, `tree_depth`, `ls_tree`, `grep`, `archive`, `tags`, `add_tag`, `delete_tag` |
|
|
59
|
+
| `Git::Repository::RemoteOperations` | `lib/git/repository/remote_operations.rb` | ✅ | `fetch`, `pull`, `push`, `remote_add` (alias: `add_remote`), `remote_remove` (alias: `remove_remote`), `remote_set_url` (alias: `set_remote_url`), `config_remote`, `remote`, `remotes`, `ls_remote`, `remote_set_branches` |
|
|
60
|
+
| `Git::Repository::Stashing` | `lib/git/repository/stashing.rb` | ✅ | `stash_list`, `stash_save`, `stash_apply`, `stash_clear`, `stashes_all` |
|
|
61
|
+
| `Git::Repository::Diffing` | `lib/git/repository/diffing.rb` | ✅ | `diff_full`, `diff_numstat`, `diff_stats`, `diff`, `diff_path_status` (alias: `diff_name_status`), `diff_files`, `diff_index` |
|
|
62
|
+
| `Git::Repository::Inspecting` | `lib/git/repository/inspecting.rb` | ✅ | `describe`, `show`, `fsck` |
|
|
58
63
|
| `Git::Repository::Logging` | `lib/git/repository/logging.rb` | ✅ | `log`, `full_log_commits` |
|
|
59
|
-
| `Git::Repository::
|
|
60
|
-
| `Git::Repository::
|
|
64
|
+
| `Git::Repository::Maintenance` | `lib/git/repository/maintenance.rb` | ✅ | `repack`, `gc` |
|
|
65
|
+
| `Git::Repository::ObjectOperations` | `lib/git/repository/object_operations.rb` | ✅ | `cat_file_contents`, `cat_file_size`, `cat_file_type`, `cat_file_commit`, `cat_file_tag`, `rev_parse`, `tag_sha`, `full_tree`, `tree_depth`, `name_rev`, `ls_tree`, `grep`, `archive`, `gblob`, `gcommit`, `gtree`, `tag`, `object`, `tags`, `add_tag`, `delete_tag` |
|
|
66
|
+
| `Git::Repository::StatusOperations` | `lib/git/repository/status_operations.rb` | ✅ | `ls_files`, `no_commits?` / `empty?`, `untracked_files`, `status` |
|
|
67
|
+
| `Git::Repository::Configuring` | `lib/git/repository/configuring.rb` | ✅ | `config`, `config_get`, `config_list`, `config_set`, `global_config`, `global_config_get`, `global_config_list`, `global_config_set` |
|
|
61
68
|
| `Git::Repository::WorktreeOperations` | `lib/git/repository/worktree_operations.rb` | ✅ | `worktrees_all`, `worktree_add`, `worktree_remove`, `worktree_prune`, `worktree`, `worktrees` |
|
|
62
69
|
|
|
63
70
|
#### Facade module naming convention
|
|
64
71
|
|
|
65
|
-
New topic modules follow a **
|
|
72
|
+
New topic modules follow a **three-tier** convention:
|
|
66
73
|
|
|
67
74
|
- **Gerund** (verb-ing) when a single action word clearly names the whole module:
|
|
68
|
-
`Staging`, `Committing`, `Branching`, `Merging`, `Logging`, `Diffing`, `Stashing`,
|
|
75
|
+
`Staging`, `Committing`, `Branching`, `Merging`, `Logging`, `Diffing`, `Stashing`,
|
|
76
|
+
`Configuring`, `Inspecting`.
|
|
69
77
|
- **Noun + `Operations`** when the module is a mixed bag of methods grouped by git
|
|
70
78
|
concept rather than a single action: `RemoteOperations`, `ObjectOperations`,
|
|
71
79
|
`StatusOperations`, `WorktreeOperations`.
|
|
80
|
+
- **Descriptive utility names** for cross-cutting helpers or housekeeping APIs that
|
|
81
|
+
are not domain-object names: `ContextHelpers`, `Maintenance`.
|
|
72
82
|
|
|
73
83
|
Do **not** use plain nouns that clash with existing domain-object class names
|
|
74
84
|
such as `Branch`, `Diff`, `Log`, `Object`, `Remote`, `Status`, `Worktree`, etc.
|
|
75
85
|
|
|
76
86
|
### Next Task
|
|
77
87
|
|
|
78
|
-
#### Phase
|
|
88
|
+
#### D2 / Phase 4 is the remaining redesign step
|
|
89
|
+
|
|
90
|
+
F1 and F2 are both ✅ complete. All Phase 4 prerequisites are now satisfied, and
|
|
91
|
+
the remaining unchecked redesign item is D2.
|
|
92
|
+
|
|
93
|
+
Phase 4 (final cleanup and release — deleting `Git::Base`/`Git::Lib`) can now begin.
|
|
94
|
+
The first cleanup PR should remove the `base_object` / `from_base` bridge in the
|
|
95
|
+
same releasable change that deletes or retires `Git::Base`.
|
|
96
|
+
The following are also required and are already ✅ complete:
|
|
97
|
+
|
|
98
|
+
| Step | Status |
|
|
99
|
+
| ---- | ------ |
|
|
100
|
+
| C1c-2: public-API parity audit and remediation sweep | ✅ |
|
|
101
|
+
| E: block-based helper/path-context methods migrated | ✅ |
|
|
102
|
+
|
|
103
|
+
Steps C1d-1, C1d-2, and C1d-3 are ✅ complete (see their detail sections below for full specs).
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
#### Phase 3 Overview
|
|
79
108
|
|
|
80
109
|
All 9 domain-object migrations are ✅ complete:
|
|
81
110
|
|
|
@@ -91,19 +120,10 @@ All 9 domain-object migrations are ✅ complete:
|
|
|
91
120
|
| `Git::Branches` | [PR #1356](https://github.com/ruby-git/ruby-git/pull/1356), [PR #1357](https://github.com/ruby-git/ruby-git/pull/1357), [PR #1358](https://github.com/ruby-git/ruby-git/pull/1358), [PR #1359](https://github.com/ruby-git/ruby-git/pull/1359) |
|
|
92
121
|
| `Git::Worktree` + `Git::Worktrees` | — |
|
|
93
122
|
|
|
94
|
-
The
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
- C moves construction/global state and flips the top-level entry points
|
|
99
|
-
- D removes compatibility bridges
|
|
100
|
-
- E migrates helper/path-context methods
|
|
101
|
-
- F removes the last `Git` module utility calls that still route through `Git::Lib`
|
|
102
|
-
|
|
103
|
-
The required `Git::Commands::*` classes already exist (`Clone`, `LsRemote`,
|
|
104
|
-
`ConfigOptionSyntax::*`, `Rm`, `Clean`, `Show`, `Fsck`, etc.). The remaining work is
|
|
105
|
-
facade/adapter wiring, parser reuse, and public-API parity decisions — not new
|
|
106
|
-
command-layer scaffolding. The full scope is defined in Workstreams A–F below.
|
|
123
|
+
The work was organized into six workstreams (A–F). All workstreams that are
|
|
124
|
+
prerequisites for C1d are now ✅ complete. F1 and F2 are both ✅ complete — F2
|
|
125
|
+
moved the remaining `Git` module utility methods off `Git::Lib`. Phase 4 is
|
|
126
|
+
ready to proceed.
|
|
107
127
|
|
|
108
128
|
**Sequencing** (see [Phase 3 dependency order](#phase-3-dependency-order) for the
|
|
109
129
|
reasoning behind each edge):
|
|
@@ -121,8 +141,8 @@ graph LR
|
|
|
121
141
|
C1a-2 --> C1c-2
|
|
122
142
|
C1b --> C1c-2
|
|
123
143
|
C1c-1 --> C1c-2
|
|
124
|
-
C1c-2 --> C1d
|
|
125
|
-
C1d --> D1 --> Phase4["Phase 4"]
|
|
144
|
+
C1c-2 --> C1d-1
|
|
145
|
+
C1d-1 --> C1d-2 --> C1d-3 --> D1 --> Phase4["Phase 4"]
|
|
126
146
|
D2 --> Phase4
|
|
127
147
|
F1 --> Phase4
|
|
128
148
|
F2 --> Phase4
|
|
@@ -177,9 +197,10 @@ These are read-only repository inspection operations that don't fit an existing
|
|
|
177
197
|
|
|
178
198
|
Files touched: `lib/git/repository/inspecting.rb` (new), `lib/git/repository.rb` (add `include Git::Repository::Inspecting`), `spec/unit/git/repository/inspecting_spec.rb` (new), `lib/git/base.rb`
|
|
179
199
|
|
|
180
|
-
**
|
|
181
|
-
`gc`, `apply`, `apply_mail`, `read_tree`, and `
|
|
182
|
-
|
|
200
|
+
**Later covered by C1c-2:** lower-level public methods such as `describe`,
|
|
201
|
+
`repack`, `gc`, `apply`, `apply_mail`, `read_tree`, and `cat_file_*` were
|
|
202
|
+
subsequently migrated into `Inspecting`, `Maintenance`, `Staging`, and
|
|
203
|
+
`ObjectOperations` before `Git.open` started returning `Git::Repository`.
|
|
183
204
|
|
|
184
205
|
---
|
|
185
206
|
|
|
@@ -228,7 +249,7 @@ This workstream is intentionally split into two PRs because the path/accessor
|
|
|
228
249
|
state work is independent of the clone/init work, and combining them would make a
|
|
229
250
|
very large PR.
|
|
230
251
|
|
|
231
|
-
**Step C1a-1 — Path state, accessors, and `.open`/`.bare` factories**
|
|
252
|
+
**Step C1a-1 — Path state, accessors, and `.open`/`.bare` factories** ✅
|
|
232
253
|
|
|
233
254
|
| `Git::Base` class method | Target |
|
|
234
255
|
| --- | --- |
|
|
@@ -242,7 +263,7 @@ must also expose the path/accessor surface currently provided by `Git::Base`: `d
|
|
|
242
263
|
|
|
243
264
|
Files touched: `lib/git/repository.rb`, `lib/git/base.rb`
|
|
244
265
|
|
|
245
|
-
**Step C1a-2 — `.clone` and `.init` factories**
|
|
266
|
+
**Step C1a-2 — `.clone` and `.init` factories** ✅
|
|
246
267
|
|
|
247
268
|
| `Git::Base` / `Git` method | Target |
|
|
248
269
|
| --- | --- |
|
|
@@ -259,7 +280,7 @@ Workstream F.
|
|
|
259
280
|
|
|
260
281
|
Files touched: `lib/git/repository.rb`, `lib/git/base.rb`, `lib/git.rb`
|
|
261
282
|
|
|
262
|
-
**Step C1b — Move global config singleton ownership off `Git::Base`**
|
|
283
|
+
**Step C1b — Move global config singleton ownership off `Git::Base`** ✅
|
|
263
284
|
|
|
264
285
|
`Git.configure` and `Git.config` both delegate to `Base.config`, which returns the
|
|
265
286
|
`Git::Base`-owned `Git::Config` singleton. When `Git::Base` is deleted, these break.
|
|
@@ -286,7 +307,7 @@ documented as a v5 breaking change or already deprecated for removal. This audit
|
|
|
286
307
|
the gate that prevents the entry-point flip from silently dropping public methods
|
|
287
308
|
just because `Git::Base` still exists in the tree.
|
|
288
309
|
|
|
289
|
-
**Step C1c-1 — Signature-compatibility guidance and process**
|
|
310
|
+
**Step C1c-1 — Signature-compatibility guidance and process** ✅
|
|
290
311
|
|
|
291
312
|
Update extraction and review skills to document the signature-compatibility
|
|
292
313
|
classification policy (legacy-contract vs 5.x-native), parity-check requirements,
|
|
@@ -305,7 +326,7 @@ Files touched: `.github/skills/extract-facade-from-base-lib/SKILL.md`,
|
|
|
305
326
|
|
|
306
327
|
Tracked as [Issue #1369](https://github.com/ruby-git/ruby-git/issues/1369).
|
|
307
328
|
|
|
308
|
-
**Step C1c-2 — End-of-Phase-3 public-API parity audit and remediation sweep**
|
|
329
|
+
**Step C1c-2 — End-of-Phase-3 public-API parity audit and remediation sweep** ✅
|
|
309
330
|
|
|
310
331
|
Compare every public `Git::Base` method against `Git::Repository`; fix mismatches
|
|
311
332
|
or explicitly record each as a documented v5 breaking change. No unclassified
|
|
@@ -317,7 +338,7 @@ Required audit buckets:
|
|
|
317
338
|
| --- | --- |
|
|
318
339
|
| Path/accessors | `dir`, `repo`, `index`, `repo_size` must exist on `Git::Repository` (C1a-1 owns this) |
|
|
319
340
|
| Compatibility aliases/wrappers | `remove`, `revparse`, `diff_name_status`, `reset_hard`, `is_local_branch?`, `is_remote_branch?`, `is_branch?`, `checkout` must be migrated or intentionally removed with upgrade notes (`checkout` is called by `Git.export` on the `Git.clone` result) |
|
|
320
|
-
| Low-level public methods | `describe
|
|
341
|
+
| Low-level public methods | Resolved in the current tree: `describe` → `Inspecting`; `repack`/`gc` → `Maintenance`; `apply`/`apply_mail`/`read_tree` → `Staging`; `cat_file_*` → `ObjectOperations`. Any intentional removals still require upgrade notes. |
|
|
321
342
|
| Factory/domain-object returns | Confirm B plus A2/A3 cover `branch`, `branches`, `remote`, `remotes`, `tag`, `tags`, object factories, and tag create/delete return shapes |
|
|
322
343
|
| Keyword-arg facades | For `legacy-contract` methods, preserve the exact 4.x call shape (including rare `**opts` signatures); for `5.x-native` methods, use `opts = {}` style for consistency |
|
|
323
344
|
|
|
@@ -326,15 +347,38 @@ Files touched: `lib/git/repository/*.rb` (topic modules for migrated methods),
|
|
|
326
347
|
|
|
327
348
|
Tracked as [Issue #1370](https://github.com/ruby-git/ruby-git/issues/1370).
|
|
328
349
|
|
|
329
|
-
|
|
350
|
+
##### Step C1d-1 — Flip entry points
|
|
330
351
|
|
|
331
352
|
With C1a, C1b, C1c, A, B, and E in place, update `Git.open`, `Git.clone`,
|
|
332
353
|
`Git.init`, and `Git.bare` in `lib/git.rb` to call `Git::Repository.*` and return
|
|
333
354
|
`Git::Repository` directly, bypassing `Git::Base` entirely.
|
|
334
355
|
|
|
356
|
+
**Prerequisite fix before landing C1d-1:** delete `spec/integration/git/lib/config_spec.rb`
|
|
357
|
+
after confirming behavior coverage exists in `spec/integration/git/repository/configuring_spec.rb`.
|
|
358
|
+
The `def lib = self` shim causes `subject(:lib) { repo.lib }` to return `Git::Repository` (self),
|
|
359
|
+
which triggers deprecation warnings from every deprecated alias call (config_set, config_get,
|
|
360
|
+
global_config_set, etc.) in that spec.
|
|
361
|
+
|
|
362
|
+
##### Step C1d-2 — Eliminate internal `.lib` callers
|
|
363
|
+
|
|
364
|
+
Clean up all `.lib` callers from tests while the silent `def lib = self` shim is still in
|
|
365
|
+
place, then add `Git::Deprecation.behavior = :raise` to both test suites. See the phase table
|
|
366
|
+
in the [Next Task](#next-task) section for the full per-phase breakdown.
|
|
367
|
+
|
|
368
|
+
##### Step C1d-3 — Remove dead fallbacks and add deprecation warning
|
|
369
|
+
|
|
370
|
+
- Add `diff_numstat` delegator to `Git::Base` (prerequisite: not currently defined there)
|
|
371
|
+
- Remove dead `respond_to?` + `.lib` fallback branches from `lib/git/diff.rb`,
|
|
372
|
+
`lib/git/diff_stats.rb`, `lib/git/diff_path_status.rb`, `lib/git/status.rb`
|
|
373
|
+
- Replace `def lib = self` in `lib/git/repository.rb` with a `Git::Deprecation.warn` body
|
|
374
|
+
(removal version: v6.0.0; returns `self`)
|
|
375
|
+
- Remove `command_capturing`, `command_streaming`, and private `env_overrides` from
|
|
376
|
+
`lib/git/repository.rb` — these were added only to feed the silent shim
|
|
377
|
+
- Add unit test asserting the deprecation warning and `self` return
|
|
378
|
+
|
|
335
379
|
---
|
|
336
380
|
|
|
337
|
-
#### Workstream D —
|
|
381
|
+
#### Workstream D — C3: Remove compatibility fallbacks
|
|
338
382
|
|
|
339
383
|
⚠️ These are v5-only cleanup steps. They are not 4.x-compatible and must be kept out
|
|
340
384
|
of 4.x release candidates unless an explicit breaking-change decision has already
|
|
@@ -379,20 +423,6 @@ After D1, domain objects should assume their provider is `Git::Repository` (or a
|
|
|
379
423
|
compatible object that implements the repository facade methods directly), not an
|
|
380
424
|
object with a `.lib` escape hatch.
|
|
381
425
|
|
|
382
|
-
##### Step D2 — Remove the `base_object` bridge
|
|
383
|
-
|
|
384
|
-
⚠️ Do **not** ship D2 as a standalone PR while `Git::Base` remains functional.
|
|
385
|
-
`Git::Base#facade_repository` currently depends on
|
|
386
|
-
`Git::ExecutionContext::Repository.from_base(self)`, so deleting the bridge before
|
|
387
|
-
deleting or retiring `Git::Base` would leave the tree unreleasable.
|
|
388
|
-
|
|
389
|
-
D2 belongs in the Phase 4 old-code deletion PR (or in the same v5 cleanup PR that
|
|
390
|
-
removes `Git::Base` as a usable public entry point):
|
|
391
|
-
|
|
392
|
-
- Delete `attr_reader :base_object`
|
|
393
|
-
- Remove `base_object:` from `#initialize` and body
|
|
394
|
-
- Remove or convert `from_base` factory
|
|
395
|
-
|
|
396
426
|
---
|
|
397
427
|
|
|
398
428
|
#### Workstream E — Migrate or deprecate instance helper methods
|
|
@@ -405,7 +435,7 @@ helpers would drop existing public `Git::Base` behavior.
|
|
|
405
435
|
`Git::Repository`. They must either be migrated before `Git::Base` can be deleted,
|
|
406
436
|
or explicitly deprecated with removal in v6.0. The recommended path is migration.
|
|
407
437
|
|
|
408
|
-
**Step E — Migrate block-based helper/path-context methods to `Git::Repository`**
|
|
438
|
+
**Step E — Migrate block-based helper/path-context methods to `Git::Repository`** ✅
|
|
409
439
|
|
|
410
440
|
| `Git::Base` method | Proposed destination | Notes |
|
|
411
441
|
| --- | --- | --- |
|
|
@@ -419,8 +449,8 @@ or explicitly deprecated with removal in v6.0. The recommended path is migration
|
|
|
419
449
|
removed at the same time, since `with_index`/`with_working` depend on the same
|
|
420
450
|
invalidation logic.
|
|
421
451
|
|
|
422
|
-
Files touched: `lib/git/repository.rb
|
|
423
|
-
|
|
452
|
+
Files touched: `lib/git/repository/context_helpers.rb`, `lib/git/base.rb`,
|
|
453
|
+
`spec/unit/git/repository/` (new or extended spec)
|
|
424
454
|
|
|
425
455
|
---
|
|
426
456
|
|
|
@@ -434,7 +464,7 @@ Three `Git`-module-level methods bypass `Git::Repository` entirely and call
|
|
|
434
464
|
non-`Git::Lib` adapter path using `Git::ExecutionContext::Global` plus existing
|
|
435
465
|
parsing logic.
|
|
436
466
|
|
|
437
|
-
**Step F1 — Move `Git.ls_remote` and `Git.default_branch` off `Git::Lib`**
|
|
467
|
+
**Step F1 — Move `Git.ls_remote` and `Git.default_branch` off `Git::Lib`** ✅
|
|
438
468
|
|
|
439
469
|
| `Git` module method | Current path | Required work |
|
|
440
470
|
| --- | --- | --- |
|
|
@@ -449,7 +479,7 @@ use the same command class.
|
|
|
449
479
|
Files touched: `lib/git.rb`, `lib/git/base.rb`, and parser/helper code extracted
|
|
450
480
|
from `Git::Lib` as needed
|
|
451
481
|
|
|
452
|
-
**Step F2 — Move `Git.global_config`, `#config`, and `#global_config` off `Git::Lib`**
|
|
482
|
+
**Step F2 — Move `Git.global_config`, `#config`, and `#global_config` off `Git::Lib`** ✅
|
|
453
483
|
|
|
454
484
|
| `Git` module method | Current path | Required work |
|
|
455
485
|
| --- | --- | --- |
|
|
@@ -494,19 +524,15 @@ classified as a v5-only PR with upgrade-note coverage before it lands.
|
|
|
494
524
|
| A4 | ✅ | Add `Inspecting#show` and `#fsck` | 4.x-compatible | `Git::Base#show` and `#fsck` remain behavior-compatible and delegate internally. |
|
|
495
525
|
| B | ✅ | Redirect `Git::Base` domain-object factories | 4.x-compatible | Method signatures and return types stay the same; only the internal provider changes to `Git::Repository`. Split into object/tag factories and branch/remote factories if the PR grows. |
|
|
496
526
|
| C1a-1 | ✅ | Add `Git::Repository.open`/`.bare`, path state, and `dir`/`repo`/`index`/`repo_size` | 4.x-compatible additive | `Git.open`/`.bare` still return `Git::Base`; new repository factories are additive until C1d. |
|
|
497
|
-
| C1a-2 |
|
|
498
|
-
| C1b |
|
|
499
|
-
| E |
|
|
500
|
-
| F1 |
|
|
501
|
-
| F2 |
|
|
502
|
-
| C1c-1 |
|
|
503
|
-
| C1c-2 |
|
|
504
|
-
| C1d |
|
|
505
|
-
| D1 |
|
|
506
|
-
| D2 / Phase 4 | ⬜ | Remove `base_object`/`from_base` with `Git::Base` deletion or retirement | v5 cleanup | Must land with the old-code deletion path; not releasable as a standalone PR while `Git::Base#facade_repository` depends on it. |
|
|
507
|
-
|
|
508
|
-
---
|
|
509
|
-
|
|
527
|
+
| C1a-2 | ✅ | Add `Git::Repository.clone`/`.init` | 4.x-compatible additive | `Git.clone`/`.init` still return `Git::Base`; clone/init behavior is duplicated behind new factories without changing public entry points. |
|
|
528
|
+
| C1b | [#1385](https://github.com/ruby-git/ruby-git/pull/1385) ✅ | Move global config ownership | 4.x-compatible | `Git.config`, `Git.configure`, and `Git::Base.config` keep working; `Git::Base.config` remains as a delegator. |
|
|
529
|
+
| E | ✅ | Add repository helper/path-context methods | 4.x-compatible additive | `Git::Base` helpers keep working; `Git::Repository` gains equivalent behavior before any top-level return-type change. Split index helpers and working-directory helpers if needed. |
|
|
530
|
+
| F1 | ✅ | Move `Git.ls_remote` and `Git.default_branch` off `Git::Lib` | 4.x-compatible | Return formats and error behavior match current 4.x-compatible behavior. |
|
|
531
|
+
| F2 | ✅ | Move `Git.global_config`, module `#config`, and module `#global_config` off `Git::Lib` | 4.x-compatible | Config methods keep the same return formats and write behavior. |
|
|
532
|
+
| C1c-1 | ✅ | Guidance/process: signature-compatibility policy for extraction and review ([#1369](https://github.com/ruby-git/ruby-git/issues/1369)) | 4.x-compatible / docs-only | Guidance and review checklists define legacy-contract vs 5.x-native signatures, including test expectations. |
|
|
533
|
+
| C1c-2 | ✅ | End-of-Phase-3 public-API parity audit and remediation sweep ([#1370](https://github.com/ruby-git/ruby-git/issues/1370)) | 4.x-compatible | All four parity audit buckets resolved (fix or documented removal) before C1d; no unclassified compatibility gap remains. |
|
|
534
|
+
| C1d | ✅ | Flip `Git.open`/`.clone`/`.init`/`.bare` to return `Git::Repository` | v5 boundary | Explicit breaking change because class identity changes from `Git::Base` to `Git::Repository`; method-level parity must be complete first. Split into C1d-1 (entry point flip), C1d-2 (eliminate internal .lib callers + add deprecation enforcement to both test suites), and C1d-3 (remove dead fallbacks + replace silent lib shim with real deprecation warning). |
|
|
535
|
+
| D1 | ✅ | Remove domain-object `Git::Base` guards and `@base.lib` fallbacks | v5 cleanup | Explicitly drops direct `Git::Base` provider support in domain-object constructors; normal factory-created objects remain supported. |
|
|
510
536
|
#### Phase 3 completion criteria
|
|
511
537
|
|
|
512
538
|
Use this table to decide whether a checklist item can be marked complete. A step is
|
|
@@ -526,7 +552,6 @@ done only when its code, focused specs, and delegation/cleanup checks are all tr
|
|
|
526
552
|
| C1c-2: public-API parity audit and remediation | End-of-Phase-3 sweep complete (Issue #1370): a public-method inventory compares `Git::Base` and `Git::Repository`; every surviving public method has a repository implementation and focused coverage; every intentional removal has an upgrade-note/deprecation decision; no unclassified compatibility gap remains. |
|
|
527
553
|
| C1d: entry-point flip | `Git.open`, `Git.clone`, `Git.init`, and `Git.bare` return `Git::Repository`; common existing workflows still pass through those entry points; YARD return docs are updated; no top-level factory method calls `Git::Base.*`; full suite passes. |
|
|
528
554
|
| D1: domain-object fallback removal | No `is_a?(Git::Base)` guards remain; no `@base.lib` fallback remains in domain objects; direct `Git::Base` provider support is documented as a v5-only removal; full suite passes. |
|
|
529
|
-
| D2 / Phase 4: `base_object` bridge removal | `Git::ExecutionContext::Repository` no longer accepts or exposes `base_object`; `from_base` is removed or converted to a non-`Git::Base` path; this lands only with the PR that deletes or retires `Git::Base`, so no releasable state contains a broken `Git::Base#facade_repository`. |
|
|
530
555
|
| E: instance helper methods | `Git::Repository` implements or explicitly deprecates `chdir`, `with_index`, `with_temp_index`, `with_working`, `with_temp_working`, `set_index`, and `set_working`; context rebuilding after index/worktree changes is covered by specs; helpers yield the same values and restore state after block exit/errors. |
|
|
531
556
|
| F: `Git` module utilities off `Git::Lib` | `Git.default_branch`, `Git.global_config`, `Git.ls_remote`, module instance `#config`, and module instance `#global_config` no longer call `Git::Lib.new`; `Git::Base.repository_default_branch` migrated to use `Git::Commands::LsRemote` directly; existing `LsRemote` and `ConfigOptionSyntax` commands provide the behavior; parser/helper code needed from `Git::Lib` has moved; `grep -n 'Lib.new' lib/git.rb` returns no matches. |
|
|
532
557
|
|
|
@@ -542,15 +567,14 @@ done only when its code, focused specs, and delegation/cleanup checks are all tr
|
|
|
542
567
|
| A4: new `Inspecting` — `show`, `fsck` | ✅ |
|
|
543
568
|
| B (C0): `Git::Base` factory delegation wiring | ✅ |
|
|
544
569
|
| C1a-1: `Git::Repository.open`/`.bare`, path state (`dir`, `repo`, `index`, `repo_size`) | ✅ |
|
|
545
|
-
| C1a-2: `Git::Repository.clone`/`.init` (no `Git::Lib` dependency) |
|
|
546
|
-
| C1b: Global config ownership (`Base.config` → `Git::Config`) |
|
|
547
|
-
| C1c-1: Guidance/process updates for signature compatibility (#1369) |
|
|
548
|
-
| C1c-2: End-of-Phase-3 public-API parity audit and remediation (#1370) |
|
|
549
|
-
| C1d: Entry-point flip (`Git.open` etc. → `Git::Repository`) |
|
|
550
|
-
| D1 (C3): Remove `is_a?(Git::Base)` guards + `@base.lib` fallbacks |
|
|
551
|
-
|
|
|
552
|
-
|
|
|
553
|
-
| F: `Git` module utilities (`default_branch`, `global_config`, `ls_remote`) off `Git::Lib` | ⬜ (Phase 4 prereq) |
|
|
570
|
+
| C1a-2: `Git::Repository.clone`/`.init` (no `Git::Lib` dependency) | ✅ |
|
|
571
|
+
| C1b: Global config ownership (`Base.config` → `Git::Config`) | ✅ |
|
|
572
|
+
| C1c-1: Guidance/process updates for signature compatibility (#1369) | ✅ |
|
|
573
|
+
| C1c-2: End-of-Phase-3 public-API parity audit and remediation (#1370) | ✅ |
|
|
574
|
+
| C1d: Entry-point flip (`Git.open` etc. → `Git::Repository`) | ✅ |
|
|
575
|
+
| D1 (C3): Remove `is_a?(Git::Base)` guards + `@base.lib` fallbacks | ✅ |
|
|
576
|
+
| E: Instance helpers (`#chdir`, `#with_index`, `#with_temp_index`, `#with_working`, `#with_temp_working`) | ✅ |
|
|
577
|
+
| F: `Git` module utilities (`default_branch`, `global_config`, `ls_remote`) off `Git::Lib` | ✅ |
|
|
554
578
|
|
|
555
579
|
#### Quality gates (per step)
|
|
556
580
|
|
|
@@ -580,7 +604,7 @@ logic. The gem will be fully functional after this phase.*
|
|
|
580
604
|
1. **Create New Directory Structure**
|
|
581
605
|
|
|
582
606
|
- `lib/git/commands/` ✅
|
|
583
|
-
- `lib/git/repository/` ✅ — populated with
|
|
607
|
+
- `lib/git/repository/` ✅ — populated with 15 included modules in Phase 3 (see [Facade Modules Completed](#facade-modules-completed))
|
|
584
608
|
|
|
585
609
|
2. **Eliminate Custom Path Classes**
|
|
586
610
|
|
|
@@ -602,14 +626,14 @@ logic. The gem will be fully functional after this phase.*
|
|
|
602
626
|
- `Git::ExecutionContext::Global` subclass in `lib/git/execution_context/global.rb` ✅
|
|
603
627
|
|
|
604
628
|
- `Git::Repository` in `lib/git/repository.rb` ✅
|
|
605
|
-
- Now includes
|
|
629
|
+
- Now includes 15 modules via `include` (see [Facade Modules Completed](#facade-modules-completed))
|
|
606
630
|
|
|
607
631
|
- `Git::Commands::Arguments` DSL in `lib/git/commands/arguments.rb` ✅
|
|
608
632
|
- Provides declarative argument definition for command classes
|
|
609
633
|
|
|
610
634
|
4. **Set Up RSpec Environment**
|
|
611
635
|
|
|
612
|
-
RSpec configured and working alongside
|
|
636
|
+
RSpec configured and working alongside Test::Unit. Specs live in `spec/` and can be
|
|
613
637
|
run with `bundle exec rspec`. ✅
|
|
614
638
|
|
|
615
639
|
## Phase 2: The Strangler Fig Pattern - Migrating Commands
|
|
@@ -1254,7 +1278,7 @@ future work:
|
|
|
1254
1278
|
instantiate and call the new `Git::Commands::Add` object, passing `self` as the
|
|
1255
1279
|
context.
|
|
1256
1280
|
|
|
1257
|
-
- **Verify**: Run the full test suite (both
|
|
1281
|
+
- **Verify**: Run the full test suite (both Test::Unit and RSpec). The existing tests
|
|
1258
1282
|
for `g.add` should still pass, but they will now be executing the new, refactored
|
|
1259
1283
|
code.
|
|
1260
1284
|
|
|
@@ -1483,7 +1507,9 @@ order: Basic Snapshotting → Branching & Merging → etc.
|
|
|
1483
1507
|
***Goal**: Switch the public-facing classes to use the new architecture directly,
|
|
1484
1508
|
breaking the final ties to the old implementation.*
|
|
1485
1509
|
|
|
1486
|
-
> **Status**:
|
|
1510
|
+
> **Status**: Phase 3 is ✅ complete. Tasks 1 and 2 are both complete; the remaining
|
|
1511
|
+
> redesign work is the Phase 4 cleanup described in the [Next Task](#next-task)
|
|
1512
|
+
> section above.
|
|
1487
1513
|
|
|
1488
1514
|
1. **Add `binary_path:` to `Git::ExecutionContext`** ✅
|
|
1489
1515
|
|
|
@@ -1493,43 +1519,54 @@ breaking the final ties to the old implementation.*
|
|
|
1493
1519
|
stopgap in `Git.run_git_version` was replaced with
|
|
1494
1520
|
`Git::Commands::Version.new(Git::ExecutionContext::Global.new(...)).call`.
|
|
1495
1521
|
|
|
1496
|
-
2. **Implement the Facade**
|
|
1522
|
+
2. **Implement the Facade** ✅
|
|
1497
1523
|
|
|
1498
|
-
`Git::Repository` now includes
|
|
1499
|
-
[Facade Modules Completed](#facade-modules-completed)).
|
|
1500
|
-
corresponding methods via `facade_repository
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1524
|
+
`Git::Repository` now includes 15 modules via `include` in
|
|
1525
|
+
`lib/git/repository.rb` (see [Facade Modules Completed](#facade-modules-completed)).
|
|
1526
|
+
`Git::Base` wraps the corresponding methods via `facade_repository`, and the
|
|
1527
|
+
end-of-Phase-3 parity sweep landed the remaining low-level facade coverage
|
|
1528
|
+
needed before the entry-point flip — including `describe`, `show`, `fsck`,
|
|
1529
|
+
`apply`, `apply_mail`, `read_tree`, `cat_file_*`, `repack`, `gc`, helper/path
|
|
1530
|
+
context methods, and the remaining remote/tag convenience APIs.
|
|
1505
1531
|
|
|
1506
1532
|
## Phase 4: Final Cleanup and Release Preparation
|
|
1507
1533
|
|
|
1508
1534
|
***Goal**: Remove all old code, finalize the test suite, and prepare for the v5.0.0
|
|
1509
1535
|
release.*
|
|
1510
1536
|
|
|
1511
|
-
|
|
1537
|
+
### Phase 4 step graph
|
|
1512
1538
|
|
|
1513
|
-
|
|
1539
|
+
```mermaid
|
|
1540
|
+
graph LR
|
|
1541
|
+
A --> B
|
|
1542
|
+
B --> C
|
|
1543
|
+
```
|
|
1514
1544
|
|
|
1515
|
-
|
|
1545
|
+
#### Step A — Remove old code
|
|
1516
1546
|
|
|
1517
|
-
|
|
1547
|
+
- Delete `attr_reader :base_object`, remove `base_object:` from `#initialize`, and remove or convert `from_base`.
|
|
1548
|
+
- Delete the `Git::Lib` class entirely.
|
|
1549
|
+
- Delete the `Git::Base` class file.
|
|
1550
|
+
- Remove any other dead code that was part of the old implementation.
|
|
1518
1551
|
|
|
1519
|
-
|
|
1552
|
+
**Done when**: `lib/git/lib.rb` and `lib/git/base.rb` are deleted; `Git::ExecutionContext::Repository` no longer accepts or exposes `base_object`; no references to `Git::Lib` or `Git::Base` remain in `lib/`.
|
|
1520
1553
|
|
|
1521
|
-
|
|
1554
|
+
**Planning tip**: Before generating a deletion plan, audit all remaining callers of `Git::Lib`, `Git::Base`, and `from_base` across `lib/` and `spec/`. The bridge removal and `Git::Base` deletion must land atomically in the same PR — plan for a single large deletion commit rather than incremental removals.
|
|
1522
1555
|
|
|
1523
|
-
|
|
1556
|
+
#### Step B — Finalize test suite
|
|
1524
1557
|
|
|
1525
|
-
|
|
1558
|
+
- Convert any remaining, relevant Test::Unit tests to RSpec.
|
|
1559
|
+
- Remove the `test-unit` dependency from the `Gemfile`.
|
|
1560
|
+
- Ensure the RSpec suite has comprehensive coverage for the new architecture.
|
|
1526
1561
|
|
|
1527
|
-
|
|
1562
|
+
**Done when**: The `tests/` directory is empty or removed; `test-unit` is no longer
|
|
1563
|
+
in `Gemfile`; RSpec is the sole test framework.
|
|
1528
1564
|
|
|
1529
|
-
|
|
1565
|
+
#### Step C — Update documentation
|
|
1530
1566
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1567
|
+
- Thoroughly document the new public API (`Git`, `Git::Repository`, etc.).
|
|
1568
|
+
- Mark all internal classes (`ExecutionContext`, `Commands`, `*Path`) with `@api private` in the YARD documentation.
|
|
1569
|
+
- Update the `README.md` and create a `UPGRADING.md` guide explaining the breaking changes for v5.0.0.
|
|
1533
1570
|
|
|
1534
|
-
|
|
1535
|
-
|
|
1571
|
+
**Done when**: `yard stats` reports no missing docs on public API; `UPGRADING.md`
|
|
1572
|
+
covers all breaking changes; `README.md` reflects the new entry points.
|