git 5.6.0 → 6.0.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -16
  3. data/CONTRIBUTING.md +44 -31
  4. data/README.md +135 -67
  5. data/UPGRADING.md +915 -268
  6. data/git.gemspec +6 -8
  7. data/lib/git/author_info.rb +1 -2
  8. data/lib/git/commands/base.rb +22 -2
  9. data/lib/git/commands/cat_file/raw.rb +0 -68
  10. data/lib/git/commands/maintenance/register.rb +0 -4
  11. data/lib/git/commands/maintenance/run.rb +0 -4
  12. data/lib/git/commands/maintenance/start.rb +0 -4
  13. data/lib/git/commands/maintenance/stop.rb +0 -4
  14. data/lib/git/commands/maintenance/unregister.rb +0 -4
  15. data/lib/git/commands/maintenance.rb +0 -2
  16. data/lib/git/commands/show_ref/exclude_existing.rb +1 -1
  17. data/lib/git/commands/show_ref/exists.rb +0 -5
  18. data/lib/git/commands/show_ref/list.rb +1 -1
  19. data/lib/git/commands/show_ref/verify.rb +1 -1
  20. data/lib/git/commands/show_ref.rb +1 -1
  21. data/lib/git/commands/worktree/repair.rb +0 -5
  22. data/lib/git/diff_path_status.rb +2 -2
  23. data/lib/git/encoding_utils.rb +25 -0
  24. data/lib/git/errors.rb +23 -5
  25. data/lib/git/factories.rb +361 -125
  26. data/lib/git/log.rb +3 -75
  27. data/lib/git/object.rb +4 -185
  28. data/lib/git/path_resolver.rb +104 -36
  29. data/lib/git/repository/branching.rb +21 -189
  30. data/lib/git/repository/committing.rb +0 -25
  31. data/lib/git/repository/context_helpers.rb +249 -155
  32. data/lib/git/repository/diffing.rb +2 -44
  33. data/lib/git/repository/merging.rb +32 -54
  34. data/lib/git/repository/object_operations.rb +121 -338
  35. data/lib/git/repository/remote_operations.rb +7 -219
  36. data/lib/git/repository/staging.rb +6 -184
  37. data/lib/git/repository/stashing.rb +126 -130
  38. data/lib/git/repository/status_operations.rb +1 -54
  39. data/lib/git/repository/worktree_operations.rb +31 -118
  40. data/lib/git/repository.rb +20 -299
  41. data/lib/git/system_call_guard.rb +95 -0
  42. data/lib/git/version.rb +1 -1
  43. data/lib/git.rb +47 -364
  44. metadata +25 -19
  45. data/lib/git/author.rb +0 -46
  46. data/lib/git/branch.rb +0 -693
  47. data/lib/git/branches.rb +0 -194
  48. data/lib/git/remote.rb +0 -191
  49. data/lib/git/stash.rb +0 -124
  50. data/lib/git/stashes.rb +0 -198
  51. data/lib/git/status.rb +0 -384
  52. data/lib/git/worktree.rb +0 -180
  53. data/lib/git/worktrees.rb +0 -152
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb847c9e15258e66f25f6856a2ceb170213e9ae310d061035ef23501e6e0cd72
4
- data.tar.gz: eca3a73ec5bf9f979d4576375062ceaeb71a78b54f12660b3b4386c2920792e9
3
+ metadata.gz: 04c9988878153d94e7c7baa55e8cb8448481dce6e47e1d4543f939da6030f2d2
4
+ data.tar.gz: 825b4a86376dfc8edf269c96888378feab99a20267ffe79586c463a5ff3781cf
5
5
  SHA512:
6
- metadata.gz: 3842eadabba8c7bead2147b438ca51597ca0acc129b7d33b41f942750d29cb7e5910b1ca92e3f50cf7bc440afb9f5ed203a97f38b72c19b09025f4e7317849f2
7
- data.tar.gz: 558adf7d3f23639b9143dcf3b9092739caba6415e066a8273f491f0589f3af06851dc15fd1776b2bad3e406d01429da76cce72c7e05f3c7ac57858bc3a771645
6
+ metadata.gz: 3c44791c9050523531380f79c32cced923090ec01fc6942979f914c898d35f35565a46ff1c54ca6b94ef6c6f0e42145296e268a5efb489bf198538c45ce9fbc9
7
+ data.tar.gz: 1ee7810b277015e405ec2832653af755f6f241d74cb67292b3cf4df6a25f9406755d60df48dc68665067982f6761a3553411e8a4ce2ac701bc0b9fd6c4b35658
data/CHANGELOG.md CHANGED
@@ -5,36 +5,152 @@
5
5
 
6
6
  # Change Log
7
7
 
8
- ## [5.6.0](https://github.com/ruby-git/ruby-git/compare/v5.5.0...v5.6.0) (2026-09-12)
8
+ ## [6.0.0](https://github.com/ruby-git/ruby-git/compare/v5.4.1...v6.0.0) (2026-10-28)
9
9
 
10
10
 
11
- ### Features
12
-
13
- * **repository:** Deprecate with_* context helper blocks that declare no parameter ([231b65c](https://github.com/ruby-git/ruby-git/commit/231b65c435e9b3d9cdbf8b113b3aba9313da5110)), closes [#1835](https://github.com/ruby-git/ruby-git/issues/1835)
14
-
15
-
16
- ### Other Changes
17
-
18
- * **export:** Describe what a failed .git removal leaves behind ([bd08096](https://github.com/ruby-git/ruby-git/commit/bd080964e44a11594202726e3823a8cafad62bd5)), closes [#1823](https://github.com/ruby-git/ruby-git/issues/1823)
19
-
20
- ## [5.5.0](https://github.com/ruby-git/ruby-git/compare/v5.4.1...v5.5.0) (2026-09-10)
11
+ ### ⚠ BREAKING CHANGES
21
12
 
13
+ * Git::Repository no longer defines object_contents, object_size, object_type, commit_data, tag_data, revparse, namerev, or diff_name_status. Call cat_file_contents, cat_file_size, cat_file_type, cat_file_commit, cat_file_tag, rev_parse, name_rev, and diff_path_status instead.
14
+ * **errors:** the minimum activesupport version is now 7.0.9 (was 5.0).
15
+ * **deprecation:** Git::Deprecation.deprecation_horizon is now "in a future major release" (was "6.0.0"). Code that parses it as a version raises.
16
+ * **factories:** raise ArgumentError when Git.init receives an unknown option key
17
+ * **factories:** raise ArgumentError when Git.open or Git.bare receives an unknown option key
18
+ * **factories:** Git.init and Git.clone expand a ~-prefixed directory and a ~-prefixed :repository option to the home directory instead of passing the literal ~ to git. Git.clone also expands a ~-prefixed :chdir option.
19
+ * **path_resolver:** a relative :repository or :index option passed to a factory method is expanded against the process working directory instead of the working directory or git directory. Callers who relied on the old expansion pass the joined path explicitly.
20
+ * **repository:** Git::Repository#archive raises Git::Error instead of a Zlib::Error subclass when gzip compression fails; the Zlib::Error is available through cause.
21
+ * **stash:** Git::Repository#stash_store raises Git::UnexpectedResultError instead of returning nil when the stored commit is missing from the stash list.
22
+ * **tag:** Git::Repository#tag_create raises Git::UnexpectedResultError instead of returning nil when the tag it created is missing from the tag list.
23
+ * **remote:** Git::Remote is removed and referencing it raises NameError; Git::Repository no longer defines remote or config_remote. Use Git::Repository#remote_list, which returns Array<Git::RemoteInfo>, and the name-based remote operations; filter Git::Repository#config_list on the "remote.<name>." key prefix for entries Git::RemoteInfo does not model.
24
+ * **branch:** Git::Branch and Git::Branches are removed and referencing them raises NameError; Git::Repository no longer defines branch or branches, and Git::Remote no longer defines branch. Use Git::Repository#branch_list, which returns Array<Git::BranchInfo>, and the name-based branch operations.
25
+ * **worktree:** Git::Worktree, Git::Worktrees, Git::Repository#worktree, Git::Repository#worktrees, and Git::Repository#worktrees_all are removed. Git::Repository#worktree_add returns a Git::WorktreeInfo instead of the git worktree add output String.
26
+ * **stash:** Git::Stash, Git::Stashes, Git::Repository#stashes_all, and Git::Repository#stash_save are removed. Git::Repository#stash_list returns Array<Git::StashInfo>, newest first, instead of a String; stash_infos remains as an alias.
27
+ * **status:** Git::Status and Git::Status::StatusFile are removed and referencing them raises NameError; Git::Repository no longer defines status. Use Git::Repository#status_info, which returns Git::StatusInfo holding one
28
+ * **author:** Git::Author is removed; referencing it raises NameError. Use
29
+ * Git::Repository no longer defines remotes; call remote_list (or remote_names) instead. Git::Branch no longer defines stashes; call Git::Repository#stash_infos instead. Git::Commands::CatFile::Raw no longer accepts the allow_unknown_type option and raises ArgumentError when it is passed; there is no replacement.
30
+ * Git::Repository#config, Git::Repository#global_config, Git.global_config, and the config and global_config instance methods of the Git module no longer exist. Use config_get, config_set, and config_list (with
31
+ * **log:** Git::Log no longer includes Enumerable or defines each, size, to_s, first, last, or []. Call Git::Log#execute and use the Git::Log::Result it returns. Git::Object::Commit no longer defines set_commit; call from_data instead.
32
+ * **repository:** Git::Repository no longer defines empty?, reset_hard, conflicts, is_local_branch?, is_remote_branch?, is_branch?, or branches_all. Call no_commits?, reset(commitish, hard: true), each_conflict, local_branch?, remote_branch?, branch?, and branch_list instead.
33
+ * **repository:** Git::Repository#clean no longer accepts :ff or :force_force, diff_path_status no longer accepts :path, and commit no longer accepts :add_all; each raises ArgumentError. set_working and set_index no longer take a positional check argument. Use force: 2, :path_limiter, :all, and must_exist: instead.
34
+ * **repository:** with_index, with_temp_index, with_working, and with_temp_working raise ArgumentError when called without a block or with a block that declares no positional parameter. Declare the parameter and call methods on it. See UPGRADING.md.
35
+ * **repository:** with_index, with_temp_index, with_working, and with_temp_working yield a separate Git::Repository bound to the temporary index or working tree instead of rebinding the receiver. Code that ignores the block parameter and calls the outer repository inside the block now runs against the original index or working tree; use the block parameter. See UPGRADING.md.
36
+ * **export:** Git.export(url, dir, remote: name) raises ArgumentError instead of silently ignoring the option. Delete the option from the call; there is no replacement because the remote name was never observable in the exported tree.
37
+ * Git.clone no longer accepts :path, :recursive, or :remote and raises ArgumentError when given one. Use :chdir, :recurse_submodules, and :origin instead.
38
+ * Git.binary_version no longer exists; use Git.git_version (call .to_a for the legacy Array). Git.ls_remote(nil) raises ArgumentError; omit the argument or pass '.'.
39
+ * The Git::Base constant no longer exists, so is_a?(Git::Base) checks and monkeypatches of Git::Base raise NameError. Include an application-owned module into Git::Repository instead.
40
+ * Git::Repository#lib no longer exists. Call the facade method directly on the repository object.
41
+ * Git::CommandLineResult no longer exists. Use
42
+ * Git::Object::Tag no longer exists, Git::Repository no longer defines tag, tags, or tag_add, and Git::Object.new no longer accepts an is_tag argument. Use tag_list and tag_create on Git::Repository, which return
43
+ * Git::Repository no longer defines add_remote, remove_remote, set_remote_url, add_tag, or delete_tag. Call remote_add, remote_remove, remote_set_url, tag_create, and tag_delete instead.
44
+ * addressable 2.9.0 or later is required. Applications whose bundle caps addressable below 2.9.0 must update that dependency or stay on the latest v5.x release.
45
+ * git 2.43.0 or later is required. Ubuntu 22.04 users must install a newer git or stay on v5.x.
46
+ * Ruby 3.3.0 or later is required. Applications on Ruby 3.2 must upgrade Ruby or stay on the latest v5.x release.
22
47
 
23
48
  ### Features
24
49
 
25
- * **export:** Warn when the :remote option is passed to Git.export ([55a9810](https://github.com/ruby-git/ruby-git/commit/55a9810b7681a510781e55b17026ec6e13dcbfa5)), closes [#1820](https://github.com/ruby-git/ruby-git/issues/1820)
50
+ * **author:** Remove Git::Author ([315eec2](https://github.com/ruby-git/ruby-git/commit/315eec2378066416756fdb5a8428c0480c8a9f41)), closes [#1728](https://github.com/ruby-git/ruby-git/issues/1728)
51
+ * **branch:** Remove Git::Branch and Git::Branches ([bbe3a83](https://github.com/ruby-git/ruby-git/commit/bbe3a833fc4b4aec8ea5b1c101b3effbf9bc8776)), closes [#1723](https://github.com/ruby-git/ruby-git/issues/1723) [#1631](https://github.com/ruby-git/ruby-git/issues/1631)
52
+ * **export:** Reject the :remote option to Git.export ([6d46862](https://github.com/ruby-git/ruby-git/commit/6d468624f5253b094a2aa0af545b6c77693fbe66)), closes [#1820](https://github.com/ruby-git/ruby-git/issues/1820)
53
+ * **factories:** Accept an :index option in Git.bare ([333d609](https://github.com/ruby-git/ruby-git/commit/333d6090bbd07cbd05a89e76ba5991327caeaf66)), closes [#1868](https://github.com/ruby-git/ruby-git/issues/1868)
54
+ * **factories:** Raise ArgumentError when Git.init receives an unknown option key ([0ffc8cd](https://github.com/ruby-git/ruby-git/commit/0ffc8cdd057a1466f76c3eb78af87a3cb9f60086)), closes [#1913](https://github.com/ruby-git/ruby-git/issues/1913) [#1869](https://github.com/ruby-git/ruby-git/issues/1869)
55
+ * **factories:** Raise ArgumentError when Git.open or Git.bare receives an unknown option key ([3991893](https://github.com/ruby-git/ruby-git/commit/39918933688eeeea2a00e5877adfac81cf809915)), closes [#1869](https://github.com/ruby-git/ruby-git/issues/1869)
56
+ * **log:** Remove the Git::Log Enumerable interface and Commit#set_commit ([a2d2934](https://github.com/ruby-git/ruby-git/commit/a2d29345b7dfb52a819f52eb1bfebba526806a02)), closes [#1775](https://github.com/ruby-git/ruby-git/issues/1775)
57
+ * Raise the minimum supported git version to 2.43.0 ([103a8da](https://github.com/ruby-git/ruby-git/commit/103a8da449c509ac801800a928b886f6efb5ffcf)), closes [#1140](https://github.com/ruby-git/ruby-git/issues/1140)
58
+ * **remote:** Remove Git::Remote and Git::Repository#config_remote ([39ee9c5](https://github.com/ruby-git/ruby-git/commit/39ee9c509927a7273fbaafc074dafe50d5f8e771)), closes [#1724](https://github.com/ruby-git/ruby-git/issues/1724)
59
+ * Remove Git::CommandLineResult ([cff038a](https://github.com/ruby-git/ruby-git/commit/cff038a17dbeb5d17dfdea9f6c0d7bb504141a8c)), closes [#1770](https://github.com/ruby-git/ruby-git/issues/1770)
60
+ * Remove Git::Object::Tag ([d826a0a](https://github.com/ruby-git/ruby-git/commit/d826a0a6fa2cbfc0759f186c564078052ca1d172)), closes [#1726](https://github.com/ruby-git/ruby-git/issues/1726)
61
+ * Remove Git::Repository#lib ([5778196](https://github.com/ruby-git/ruby-git/commit/5778196619ff05117c2a86e0366aa0375e05001e)), closes [#1769](https://github.com/ruby-git/ruby-git/issues/1769)
62
+ * Remove Git::Repository#remotes, Git::Branch#stashes, and allow_unknown_type ([b3353d3](https://github.com/ruby-git/ruby-git/commit/b3353d3d82928a02ba288a9efda17d4e70359ca1)), closes [#1725](https://github.com/ruby-git/ruby-git/issues/1725)
63
+ * Remove Git.binary_version and the Git.ls_remote(nil) shim ([a31e9db](https://github.com/ruby-git/ruby-git/commit/a31e9db2f9f27ee75f87ed4ead9672daab630b16)), closes [#1773](https://github.com/ruby-git/ruby-git/issues/1773)
64
+ * Remove the eight renamed facade aliases ([0fb37d7](https://github.com/ruby-git/ruby-git/commit/0fb37d71f13a1162aecaa909b3a233770fd1a22b)), closes [#1924](https://github.com/ruby-git/ruby-git/issues/1924)
65
+ * Remove the five renamed facade methods ([bde6f52](https://github.com/ruby-git/ruby-git/commit/bde6f52ab39d1704fdb35058b7072559ccdf91df)), closes [#1772](https://github.com/ruby-git/ruby-git/issues/1772)
66
+ * Remove the Git::Base compatibility shim ([70d3e27](https://github.com/ruby-git/ruby-git/commit/70d3e279bf26c34a6d24203b054c9418eeda3dbb)), closes [#1768](https://github.com/ruby-git/ruby-git/issues/1768)
67
+ * Remove the Git.clone legacy options (:path, :recursive, :remote) ([bde02ee](https://github.com/ruby-git/ruby-git/commit/bde02eee7cfc24a7a510d5a3fcb67fa9818b4cd6)), closes [#1774](https://github.com/ruby-git/ruby-git/issues/1774)
68
+ * Remove the v4.x-style configuration API ([b5dd9ba](https://github.com/ruby-git/ruby-git/commit/b5dd9ba7723d7cecd243ddeee2a65884a5612d94)), closes [#1771](https://github.com/ruby-git/ruby-git/issues/1771)
69
+ * **repository:** Deprecate Git::Repository#set_index and #set_working ([7f7511d](https://github.com/ruby-git/ruby-git/commit/7f7511d4470f0645669bb9b512b20fa885b27306)), closes [#1833](https://github.com/ruby-git/ruby-git/issues/1833)
70
+ * **repository:** Remove the seven renamed Git::Repository methods ([ae1fecf](https://github.com/ruby-git/ruby-git/commit/ae1fecf791d4962e2e354a3b30fd12ab9961108f)), closes [#1777](https://github.com/ruby-git/ruby-git/issues/1777)
71
+ * **repository:** Remove the v4.x option shims from clean, diff_path_status, commit, and set_* ([65fed59](https://github.com/ruby-git/ruby-git/commit/65fed59669e228d1480a3afe52768fba0bb4c756)), closes [#1776](https://github.com/ruby-git/ruby-git/issues/1776)
72
+ * **repository:** Require a block parameter on the with_* context helpers ([6f7776e](https://github.com/ruby-git/ruby-git/commit/6f7776e637fb84c8436e454cb561821a40c7d4cf))
73
+ * **stash:** Remove the legacy stash API and return StashInfo from stash_list ([f73c0bc](https://github.com/ruby-git/ruby-git/commit/f73c0bcab84dee56f13e8230a888c8da3552b380)), closes [#1634](https://github.com/ruby-git/ruby-git/issues/1634)
74
+ * **status:** Remove Git::Status and Git::Status::StatusFile ([51cb33f](https://github.com/ruby-git/ruby-git/commit/51cb33f9c511704952b0137ffe30d104eeeaa901)), closes [#1727](https://github.com/ruby-git/ruby-git/issues/1727)
75
+ * **worktree:** Remove the legacy worktree API and return WorktreeInfo from worktree_add ([a7a87b7](https://github.com/ruby-git/ruby-git/commit/a7a87b70d70be5f4d8086b76c4b470e6223a49bb)), closes [#1635](https://github.com/ruby-git/ruby-git/issues/1635)
26
76
 
27
77
 
28
78
  ### Bug Fixes
29
79
 
30
- * **export:** Drop the redundant checkout that broke Git.export for tags ([5e8422d](https://github.com/ruby-git/ruby-git/commit/5e8422d2361bff43959a0bba2254118087907a2a)), closes [#1815](https://github.com/ruby-git/ruby-git/issues/1815)
80
+ * **commands:** Close the stdin pipe's write end when the writer thread cannot start ([8667db2](https://github.com/ruby-git/ruby-git/commit/8667db2f6a2fa16116264387fb78cd87fa8b763d)), closes [#1860](https://github.com/ruby-git/ruby-git/issues/1860)
81
+ * **commands:** Raise Git::Error when the stdin writer thread cannot be started ([a61eafc](https://github.com/ruby-git/ruby-git/commit/a61eafc54eaa72444b917fd890bc381716f7738b)), closes [#1860](https://github.com/ruby-git/ruby-git/issues/1860)
82
+ * **commands:** Raise Git::Error when with_stdin cannot create a pipe ([e5d0c04](https://github.com/ruby-git/ruby-git/commit/e5d0c0477ddbe7dc2b7b8fa2070e92eaea63877f)), closes [#1811](https://github.com/ruby-git/ruby-git/issues/1811)
83
+ * Declare logger as a runtime dependency ([d38b4c1](https://github.com/ruby-git/ruby-git/commit/d38b4c1cab06a9c5809e9b93fe078e87c5d98116))
84
+ * **deprecation:** Load what the log, notify, and report behaviors need ([5cb1db3](https://github.com/ruby-git/ruby-git/commit/5cb1db3a6e6ccbf340f3928bbe129ffb2894e2d7))
85
+ * Detect a missing lychee without a shell probe ([f3bf20f](https://github.com/ruby-git/ruby-git/commit/f3bf20fb2e14cfebb8c47dca08e32224f8d90c74))
86
+ * **encoding:** Scrub lines whose detected encoding has no Ruby converter ([517cd99](https://github.com/ruby-git/ruby-git/commit/517cd99f4a7087c2fa04a775f4daf3ee6cb6af99)), closes [#1810](https://github.com/ruby-git/ruby-git/issues/1810)
87
+ * **errors:** Make the Git::GitExecuteError warning follow the deprecation policy ([e16a405](https://github.com/ruby-git/ruby-git/commit/e16a405ceb3942ddbbfefee939f9c307866163c8)), closes [#1908](https://github.com/ruby-git/ruby-git/issues/1908)
88
+ * **errors:** Raise Git::Error instead of a bare SystemCallError from filesystem calls ([c6aa107](https://github.com/ruby-git/ruby-git/commit/c6aa107af294483e7f53ee0cf3095f61364ee089)), closes [#1804](https://github.com/ruby-git/ruby-git/issues/1804)
89
+ * **export:** Drop the redundant checkout that broke Git.export for tags ([5b444b4](https://github.com/ruby-git/ruby-git/commit/5b444b44ddc3a648d2f543ba56cf3472108a8647)), closes [#1815](https://github.com/ruby-git/ruby-git/issues/1815)
90
+ * **export:** Say what the destination holds when removing .git fails ([510713d](https://github.com/ruby-git/ruby-git/commit/510713d5bccd7d76b38ab4d3a2fcade57baafbcb))
91
+ * **factories:** Make ~ mean the home directory in every factory path ([b03cfcc](https://github.com/ruby-git/ruby-git/commit/b03cfccddddae1b8d65b16c1cd77203b9a56fc5b)), closes [#1873](https://github.com/ruby-git/ruby-git/issues/1873)
92
+ * **path_resolver:** Expand relative :repository and :index against the process cwd ([5196d8e](https://github.com/ruby-git/ruby-git/commit/5196d8e28a369302bfe855f43694eff43b5343ea)), closes [#1871](https://github.com/ruby-git/ruby-git/issues/1871)
93
+ * **repository:** Raise Git::Error when archive gzip compression fails ([f21c895](https://github.com/ruby-git/ruby-git/commit/f21c8958fed66fdfce4c66253342872f4695483e)), closes [#1812](https://github.com/ruby-git/ruby-git/issues/1812)
94
+ * **stash:** Raise UnexpectedResultError when stash_store cannot find the stored entry ([64486c7](https://github.com/ruby-git/ruby-git/commit/64486c7fa86ad88add3f5aaea8f9f6d0792e4615)), closes [#1855](https://github.com/ruby-git/ruby-git/issues/1855)
95
+ * **tag:** Raise UnexpectedResultError when tag_create cannot find the new tag ([de6c8d8](https://github.com/ruby-git/ruby-git/commit/de6c8d8adbe204ef66f3f6a201c945e4ac47b24b)), closes [#1849](https://github.com/ruby-git/ruby-git/issues/1849)
31
96
 
32
97
 
33
98
  ### Other Changes
34
99
 
35
- * **export:** Document the deprecated :remote option to Git.export ([3806d2b](https://github.com/ruby-git/ruby-git/commit/3806d2b5a6fdb167006097df83c783573024a521)), closes [#1820](https://github.com/ruby-git/ruby-git/issues/1820)
36
- * Name the 5.x maintenance branch alongside 4.x ([ad30718](https://github.com/ruby-git/ruby-git/commit/ad30718a61cb89c343c84c71feb1c94cf3995f28))
37
- * Run the CI, commitlint, release, and cache workflows for the 5.x branch ([7c3fd13](https://github.com/ruby-git/ruby-git/commit/7c3fd13994104c2c6b6564cc41d1e3c4e614255a))
100
+ * **branch:** Follow up on the review of the branch and remote removal ([7aa2f18](https://github.com/ruby-git/ruby-git/commit/7aa2f18ed58be1f1e906c83a060c3bad13a62c93)), closes [#1851](https://github.com/ruby-git/ruby-git/issues/1851)
101
+ * Clarify v5.x option validation scope ([0d15421](https://github.com/ruby-git/ruby-git/commit/0d1542121003b92a70eb25b4f45ee985cbcd69db))
102
+ * **commands:** Drop version gates below the 2.43.0 floor ([bd97b2f](https://github.com/ruby-git/ruby-git/commit/bd97b2f3240546fbe0d07ab6f7f303b4246a4c83))
103
+ * Comment the hooks that mutate ENV and the working directory ([ea4c197](https://github.com/ruby-git/ruby-git/commit/ea4c1975e5f3385d6c3f8c8937ceefa19a3ceffd))
104
+ * **deprecation:** Retire the version horizon as a source of warning text ([137e5b7](https://github.com/ruby-git/ruby-git/commit/137e5b7312038815a08a4e0b59feb9ec23b05da1)), closes [#1908](https://github.com/ruby-git/ruby-git/issues/1908)
105
+ * Describe the with_* helpers in ADR-0009 as yielding a derived repository ([f99194c](https://github.com/ruby-git/ruby-git/commit/f99194cd64bf812a2bbb90363afac48121df818e)), closes [#1830](https://github.com/ruby-git/ruby-git/issues/1830)
106
+ * **export:** Cover the state Git.export leaves when removing .git fails ([8fe1fdd](https://github.com/ruby-git/ruby-git/commit/8fe1fdddb3e178d953534e43799cb2a59ee99c4e))
107
+ * **export:** Describe what a failed .git removal leaves behind ([7995d83](https://github.com/ruby-git/ruby-git/commit/7995d83197b9664d51904aaa6c9be6c8db33ca85))
108
+ * **fsck:** Correct command integration spec ([e550f72](https://github.com/ruby-git/ruby-git/commit/e550f727c5b6e36430b8851b112d701ddd9b1382))
109
+ * Make test:gem load the gem from an isolated install ([4709a13](https://github.com/ruby-git/ruby-git/commit/4709a1370a9282a35eea699f45cc9ebc3fa65d30)), closes [#1882](https://github.com/ruby-git/ruby-git/issues/1882)
110
+ * Name Git::CommandLine::Result in spec descriptions ([406b396](https://github.com/ruby-git/ruby-git/commit/406b396537d1b9e0e93ab931c80f7b349505c34c))
111
+ * Name the 5.x maintenance branch alongside 4.x ([f264747](https://github.com/ruby-git/ruby-git/commit/f2647470ac064fc1ac8c48e974fe3bd1faf0ae99))
112
+ * Name the removal horizon in every [@deprecated](https://github.com/deprecated) YARD tag ([9cfd7cf](https://github.com/ruby-git/ruby-git/commit/9cfd7cf5933146a73ecb8825b0875576f14ca64c)), closes [#1917](https://github.com/ruby-git/ruby-git/issues/1917)
113
+ * Name the restore checkout in the failure-state notes ([bec03f8](https://github.com/ruby-git/ruby-git/commit/bec03f8e9f7b3f6bdaf46d665f1f4f6586ab7f2b))
114
+ * **path_resolver:** Remove the unreachable git-binary-not-found rescue ([3623f59](https://github.com/ruby-git/ruby-git/commit/3623f5954b2b68b38cd41f37d8fc9af4d34f3cf2))
115
+ * Raise required_ruby_version to 3.3 and drop the Ruby 3.3 gates on yard-lint ([a551fb4](https://github.com/ruby-git/ruby-git/commit/a551fb4231bca57db4964f3527ae344d91208aa7)), closes [#1722](https://github.com/ruby-git/ruby-git/issues/1722)
116
+ * **readme:** Announce the 5.x branch and the v6.0.0 line on main ([4510e7d](https://github.com/ruby-git/ruby-git/commit/4510e7dabf1952447a6a66883a14c627158dcb59))
117
+ * **readme:** Announce the deletion of the v1 and master branches ([6c8251f](https://github.com/ruby-git/ruby-git/commit/6c8251f617481a143206cb9f513336e3b442701c)), closes [#1786](https://github.com/ruby-git/ruby-git/issues/1786)
118
+ * **readme:** Derive the JRuby and TruffleRuby floors from the MRI floor ([16558cf](https://github.com/ruby-git/ruby-git/commit/16558cfedd153796cc18c5ddd190c26d39ceb556))
119
+ * **readme:** Replace the v5.0.0 release banner with a v6.0.0 development note ([6bb4e80](https://github.com/ruby-git/ruby-git/commit/6bb4e80cf3d7df1531b3ed919e5274174238c1cf))
120
+ * **readme:** Replace the v6.0.0 development note with the release banner ([adf27e7](https://github.com/ruby-git/ruby-git/commit/adf27e720bc0db20ccbfc2f5c5ec6b6e9436afe9))
121
+ * **readme:** State that deprecation warnings fire on every call ([f1426f4](https://github.com/ruby-git/ruby-git/commit/f1426f408f1de2ec29056b8f17be287d19ceac9f)), closes [#1909](https://github.com/ruby-git/ruby-git/issues/1909)
122
+ * Record ADR-0008 on converting errors from outside the gem at the boundary ([64344da](https://github.com/ruby-git/ruby-git/commit/64344daa40f22d2b26cd87b7139b27a81a7a8a4b))
123
+ * Record ADR-0009 on what a failed operation leaves behind ([1cedde3](https://github.com/ruby-git/ruby-git/commit/1cedde35421505f88dc9a62b5ecffaf9e0708be8))
124
+ * Reject BREAKING CHANGE footers that release-please would truncate ([84ca7ba](https://github.com/ruby-git/ruby-git/commit/84ca7ba8d511827c70b943d7d776f7a103cb9c2b))
125
+ * Release v6.0.0 as the next version from main ([dbee8b9](https://github.com/ruby-git/ruby-git/commit/dbee8b9abfdb224893b6ca26e7531f53c241c448))
126
+ * Remove git version skips at or below 2.43.0 ([61a87b1](https://github.com/ruby-git/ruby-git/commit/61a87b1d5e43e65b7735b5abd983cdd46f783bb0))
127
+ * Remove the diff fixture's submodule setup, which always failed ([8240b30](https://github.com/ruby-git/ruby-git/commit/8240b30dd20490a921c17b033edfd53b4380c80b))
128
+ * Replace Ruby 3.2 with 3.3 in the CI and cache-warming matrices ([6970c25](https://github.com/ruby-git/ruby-git/commit/6970c2532c79f5189b7b1454fc2287f90468d172))
129
+ * Replace the release-as config pin with a Release-As commit footer ([ebb7605](https://github.com/ruby-git/ruby-git/commit/ebb7605183b766759ef078ea48e41881f48ef5fb))
130
+ * **repository:** State the failure state of in_branch and merge_into in a note tag ([a4a5059](https://github.com/ruby-git/ruby-git/commit/a4a5059de5183662811cd1203f2c69956937395f))
131
+ * **repository:** Yield a derived repository from the with_* context helpers ([56e7a35](https://github.com/ruby-git/ruby-git/commit/56e7a356219d1c9abca1f3acc0c10775458d2286)), closes [#1830](https://github.com/ruby-git/ruby-git/issues/1830)
132
+ * Require addressable 2.9 or later ([e790d13](https://github.com/ruby-git/ruby-git/commit/e790d13a0ebfc877c003c874178faa55bd295600)), closes [#1221](https://github.com/ruby-git/ruby-git/issues/1221)
133
+ * Restructure the diff fixture so it needs no rubocop disables ([85158af](https://github.com/ruby-git/ruby-git/commit/85158af4813fa58e656779f91995a6c734fe6ec4))
134
+ * Review the prose in README.md and UPGRADING.md ([be7f48c](https://github.com/ruby-git/ruby-git/commit/be7f48c2355a58c35c8ef957908ff9670cd21852))
135
+ * Rework ADR-0009 after review and link it from the facade skills ([44c41f5](https://github.com/ruby-git/ruby-git/commit/44c41f5a905bbed594f203a44049a724eb807154))
136
+ * **skills:** Add an rspec-integration-testing-standards override ([bb97e0a](https://github.com/ruby-git/ruby-git/commit/bb97e0a9ffe14615bb85ee819ee6446ac78f3da2)), closes [#1874](https://github.com/ruby-git/ruby-git/issues/1874)
137
+ * **skills:** Add the README banner swaps to the release checklists ([54ed695](https://github.com/ruby-git/ruby-git/commit/54ed695f714b496ba4926f58df3b24be2bcf999d))
138
+ * **skills:** Add the sections every skill is required to have ([8a0c878](https://github.com/ruby-git/ruby-git/commit/8a0c878c64c389f6bfd0c6cf9b685cb3cf2106a4))
139
+ * **skills:** Add the testing-guide override skill ([54818b7](https://github.com/ruby-git/ruby-git/commit/54818b76502871b30824a0eeffab93d266c5c223))
140
+ * **skills:** Check the failure-state note before flagging a missing restore ([b18e1f1](https://github.com/ruby-git/ruby-git/commit/b18e1f1c6aa29a7f506c59f7f8d3ab4aaf70685a))
141
+ * **skills:** Make rspec-unit-testing-standards a thin override of the plugin skill ([aa41348](https://github.com/ruby-git/ruby-git/commit/aa41348b7a399d2f919da3d9cd94d1070bff9f6b))
142
+ * **skills:** Make tdd-refactor-step a thin override of the plugin skill ([8977ac8](https://github.com/ruby-git/ruby-git/commit/8977ac8b004b4f3c6cefbcd65e7e0568b572770f))
143
+ * **skills:** Make test-debugging a thin override of the plugin skill ([8323c10](https://github.com/ruby-git/ruby-git/commit/8323c1095053b7a63921a6ce29eb014304a1cdc1))
144
+ * **skills:** Prefer not touching global state over restoring it ([784d4d4](https://github.com/ruby-git/ruby-git/commit/784d4d42cc13046f09c6844332d559c520f96017))
145
+ * **skills:** Record the Git::CommandLineResult removal in the skill references ([070c73b](https://github.com/ruby-git/ruby-git/commit/070c73b7ab85257a1e613498c81f965cb7a45d8f))
146
+ * **skills:** Record the Git::Object::Tag removal in the skill references ([6503b7a](https://github.com/ruby-git/ruby-git/commit/6503b7a84ec5e69aa99e49798c69e227b2230e71))
147
+ * **skills:** Record the Release-As pin and two-PR shape of a maintenance branch cut ([4db3834](https://github.com/ruby-git/ruby-git/commit/4db383464f3e6ea73d2d41ac6e89311208ac94d8))
148
+ * **skills:** Update the tag example in the facade-implementation guardrail ([3a9f1a0](https://github.com/ruby-git/ruby-git/commit/3a9f1a028162f46a3c742a313286f46031b3a851))
149
+ * State the Ruby 3.3 floor in UPGRADING.md, CONTRIBUTING.md, and the agent skills ([00ecc30](https://github.com/ruby-git/ruby-git/commit/00ecc30b6f5de576089db8c9e70154119ff08b05))
150
+ * State what a failure leaves behind for the operations ADR-0009 covers ([a136d72](https://github.com/ruby-git/ruby-git/commit/a136d72aa8ab03a42c1504bd5ca8418fca28361d)), closes [#1831](https://github.com/ruby-git/ruby-git/issues/1831)
151
+ * **upgrading:** Name the v5.x APIs that validate option names ([acbe015](https://github.com/ruby-git/ruby-git/commit/acbe01537839c8de1b50ec0c9d8ae5b1db2422f2))
152
+ * **upgrading:** Name the v6 section by series ([d3ad986](https://github.com/ruby-git/ruby-git/commit/d3ad986e731159bdcef8e2342a52d0a7871fe5d0))
153
+ * **upgrading:** Organize the v6.x section around what the reader has to do ([1f6eace](https://github.com/ruby-git/ruby-git/commit/1f6eace1b21a926b2eb0a34029ac21d1c573550d))
38
154
 
39
155
  ## [5.4.1](https://github.com/ruby-git/ruby-git/compare/v5.4.0...v5.4.1) (2026-09-04)
40
156
 
data/CONTRIBUTING.md CHANGED
@@ -93,9 +93,9 @@ prerequisite is missing.
93
93
 
94
94
  | Tool | Required version | Notes |
95
95
  | --- | --- | --- |
96
- | Ruby | `>= 3.2.0` (matches `required_ruby_version` in [`git.gemspec`](git.gemspec)) | A version manager such as [rbenv](https://github.com/rbenv/rbenv), [asdf](https://asdf-vm.com/), [chruby](https://github.com/postmodern/chruby), or [rvm](https://rvm.io/) is recommended so you can match the project's CI matrix. |
96
+ | Ruby | `>= 3.3.0` (matches `required_ruby_version` in [`git.gemspec`](git.gemspec)) | A version manager such as [rbenv](https://github.com/rbenv/rbenv), [asdf](https://asdf-vm.com/), [chruby](https://github.com/postmodern/chruby), or [rvm](https://rvm.io/) is recommended so you can match the project's CI matrix. |
97
97
  | Bundler | Any 2.x or 4.x | Install with `gem install bundler`. |
98
- | git | `>= 2.28.0` (matches `git.gemspec` `requirements`) | Older git versions are not supported and the test suite will not pass against them. |
98
+ | git | `>= 2.43.0` (matches `git.gemspec` `requirements`) | Older git versions are not supported and the test suite will not pass against them. |
99
99
  | Node.js / npm | Optional | Required only to install the local Conventional Commit `commit-msg` hook (Husky + commitlint). If npm is missing, `bin/setup` will warn and continue. CI will still validate commit messages. |
100
100
  | [lychee](https://lychee.cli.rs) | `>= 0.24.0` | Runs the markdown link check (`rake markdown:links`), which is part of the default task. The floor comes from [`.lychee.toml`](.lychee.toml): older releases cannot parse the enum form of `include_fragments`. Install with `brew install lychee` (macOS), `snap install lychee` (Ubuntu), `pacman -S lychee` (Arch), `winget install --id lycheeverse.lychee` (Windows), or see the [install docs](https://github.com/lycheeverse/lychee#installation). |
101
101
 
@@ -227,7 +227,9 @@ major series:
227
227
  cut from `5.x`.
228
228
  - **`5.x`** and **`4.x`**: The maintenance branches for the v5.x and v4.x series. Each
229
229
  receives bug fixes and security fixes, and backward-compatible features at the
230
- maintainers' discretion.
230
+ maintainers' discretion. A fix that changes the class of a raised exception is
231
+ backported only when it passes the rescue-compatibility test in
232
+ [Branch & PR Strategy](.github/copilot-instructions.md#branch--pr-strategy).
231
233
 
232
234
  The README's [Release support policy](README.md#release-support-policy) says how long
233
235
  each major series is supported.
@@ -236,7 +238,7 @@ When submitting a pull request:
236
238
 
237
239
  - **New features and breaking changes**: Target the `main` branch
238
240
  - **Bug fixes**: Target `main`, and maintainers will backport to the maintenance
239
- branches if applicable
241
+ branches if applicable and the change passes the rescue-compatibility test above
240
242
  - **Security fixes**: Target `main` and every affected maintenance branch, or only a
241
243
  maintenance branch if the issue affects that series alone
242
244
 
@@ -302,9 +304,13 @@ guidance that mirrors maintainer expectations:
302
304
  - [`review-arguments-dsl`](.github/skills/review-arguments-dsl/SKILL.md): audits
303
305
  `arguments do ... end` blocks against the git CLI
304
306
  - [`rspec-unit-testing-standards`](.github/skills/rspec-unit-testing-standards/SKILL.md),
307
+ [`rspec-integration-testing-standards`](.github/skills/rspec-integration-testing-standards/SKILL.md),
308
+ [`rspec-base-standards`](.github/skills/rspec-base-standards/SKILL.md),
305
309
  [`command-test-conventions`](.github/skills/command-test-conventions/SKILL.md), and
306
310
  [`facade-test-conventions`](.github/skills/facade-test-conventions/SKILL.md): testing
307
311
  conventions for new and updated code
312
+ - [`testing-guide`](.github/skills/testing-guide/SKILL.md): the vocabulary those
313
+ conventions are written in, and how this project applies the shared testing guide
308
314
  - [`yard-documentation`](.github/skills/yard-documentation/SKILL.md),
309
315
  [`command-yard-documentation`](.github/skills/command-yard-documentation/SKILL.md), and
310
316
  [`facade-yard-documentation`](.github/skills/facade-yard-documentation/SKILL.md):
@@ -906,6 +912,15 @@ The `BREAKING CHANGE:` footer flags a backward incompatible change even if the
906
912
  type is not marked with an exclamation mark. Other footers are allowed
907
913
  but not acted upon.
908
914
 
915
+ A `BREAKING CHANGE:` footer must come out of release-please's stricter parser as you
916
+ wrote it. The `release-please/breaking-change-intact` rule checks this, and its error
917
+ names the line, says why release-please cuts it short, and says how to rewrap. The
918
+ rule comes from the commitlint plugin in
919
+ [commitlint/release-please](commitlint/release-please), installed as a `file:`
920
+ dependency; `npm test` runs its tests. The plugin arrives through `npm install`, and
921
+ the commit-msg hook refuses every commit until a clone that predates it reruns
922
+ `npm install`.
923
+
909
924
  See [the Conventional Commits
910
925
  specification](https://www.conventionalcommits.org/en/v1.0.0/) for more details.
911
926
 
@@ -978,10 +993,18 @@ process.stdin.on('end', () =>
978
993
  `SPEC=spec/unit/...` on `rake spec` runs the unit specs and skips
979
994
  `spec:integration`. A glob matching nothing anywhere fails the task outright.
980
995
 
981
- This project uses RSpec (`spec/`) as its sole test framework. Structure,
982
- naming, setup, stubbing, and coverage rules for unit specs are defined in the
983
- [`rspec-unit-testing-standards`](.github/skills/rspec-unit-testing-standards/SKILL.md)
984
- skill. Follow it when writing or reviewing specs under `spec/unit/`.
996
+ This project uses RSpec (`spec/`) as its sole test framework. Structure, naming,
997
+ setup, stubbing, and coverage rules for specs are defined in the `jcouball-testing`
998
+ plugin's unit, integration, and base standards, with this project's changes in the
999
+ [`rspec-unit-testing-standards`](.github/skills/rspec-unit-testing-standards/SKILL.md),
1000
+ [`rspec-integration-testing-standards`](.github/skills/rspec-integration-testing-standards/SKILL.md),
1001
+ and [`rspec-base-standards`](.github/skills/rspec-base-standards/SKILL.md) skills.
1002
+ Follow the unit standards for specs under `spec/unit/` and the integration standards
1003
+ for specs under `spec/integration/`. The terms those rules use, and the reasoning
1004
+ behind them, are in the
1005
+ [testing guide](https://github.com/jcouball/agent-plugins/blob/main/plugins/testing/docs/testing-guide.md);
1006
+ the [`testing-guide`](.github/skills/testing-guide/SKILL.md) skill says how this
1007
+ project applies it.
985
1008
 
986
1009
  #### Test coverage policy
987
1010
 
@@ -1077,10 +1100,11 @@ When a branch is hard to cover, apply these in order:
1077
1100
  criteria, so the required justification lives in the directive itself.
1078
1101
 
1079
1102
  **Coverage is a floor on evidence, not a proof of correctness.** A test written only
1080
- to execute a line, without asserting a meaningful outcome, violates Rule 24 of the
1081
- [`rspec-unit-testing-standards`](.github/skills/rspec-unit-testing-standards/SKILL.md)
1082
- skill and will be rejected in review even though it turns the report green. The
1083
- threshold exists to surface untested behavior, not to be satisfied.
1103
+ to execute a line, without asserting a meaningful outcome, violates the rule on
1104
+ asserting observable behavior in the
1105
+ [`rspec-base-standards`](.github/skills/rspec-base-standards/SKILL.md) skill and will
1106
+ be rejected in review even though it turns the report green. The threshold exists to
1107
+ surface untested behavior, not to be satisfied.
1084
1108
 
1085
1109
  To see exactly what is uncovered:
1086
1110
 
@@ -1109,25 +1133,14 @@ This project uses two types of RSpec tests, organized by directory:
1109
1133
  git behavior. Integration tests create temporary repositories using `Dir.mktmpdir`
1110
1134
  and run real git commands through the gem's public API.
1111
1135
 
1112
- Integration tests validate that the gem correctly interacts with git, not that git
1113
- itself works correctly. They should verify:
1114
-
1115
- - That the gem's mocked command expectations match real git output format
1116
- - That the gem correctly handles real git behavior (e.g., unicode in branch names)
1117
- - That command options produce expected git behavior
1118
- - Edge cases that are difficult to mock reliably
1119
-
1120
- **Integration test guidelines**:
1121
-
1122
- - Keep tests minimal and purposeful; only create what's needed for the test
1123
- - Focus on key behaviors that unit tests can't verify
1124
- - Don't test git's functionality; test the gem's interaction with git
1125
- - Use the shared context `'in an empty repository'` for temporary repo setup
1126
- - Use `Git::IntegrationTestHelpers` methods for file operations
1127
- - Each test should verify one specific git interaction pattern
1128
-
1129
- **Example**: An integration test for branch listing should verify that the gem
1130
- correctly parses git's branch list format, not that git can create branches.
1136
+ Integration tests check what the unit tests stub out: that the arguments the gem
1137
+ builds work with real git, and that git writes the output its parsers expect. They
1138
+ test the gem's interaction with git, not git itself. The rules for writing them,
1139
+ including how to build and pin temporary repositories, how to start git, and how to
1140
+ assert on results and errors, are in the
1141
+ [RSpec integration testing standards](.github/skills/rspec-integration-testing-standards/SKILL.md)
1142
+ skill, which applies ruby-git's changes on top of the `jcouball-testing` plugin's
1143
+ rules.
1131
1144
 
1132
1145
  While working on specific features, you can run tests using:
1133
1146