git 5.0.0.beta.3 → 5.0.0.beta.5

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 (269) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +27 -0
  3. data/.github/copilot-instructions.md +3 -8
  4. data/.github/hooks/bin-setup-on-worktree.json +11 -0
  5. data/.github/hooks/run-bin-setup-once.sh +14 -0
  6. data/.github/skills/breaking-change-analysis/SKILL.md +6 -9
  7. data/.github/skills/ci-cd-troubleshooting/SKILL.md +2 -2
  8. data/.github/skills/command-implementation/REFERENCE.md +34 -33
  9. data/.github/skills/command-implementation/SKILL.md +5 -4
  10. data/.github/skills/command-test-conventions/SKILL.md +13 -9
  11. data/.github/skills/command-yard-documentation/SKILL.md +14 -6
  12. data/.github/skills/development-workflow/SKILL.md +20 -14
  13. data/.github/skills/facade-implementation/REFERENCE.md +19 -22
  14. data/.github/skills/facade-implementation/SKILL.md +0 -5
  15. data/.github/skills/facade-test-conventions/SKILL.md +4 -7
  16. data/.github/skills/facade-yard-documentation/SKILL.md +8 -2
  17. data/.github/skills/make-skill-template/SKILL.md +53 -3
  18. data/.github/skills/pr-readiness-review/SKILL.md +22 -2
  19. data/.github/skills/project-context/SKILL.md +16 -23
  20. data/.github/skills/pull-request-review/SKILL.md +2 -2
  21. data/.github/skills/rebase/SKILL.md +148 -0
  22. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +1 -1
  23. data/.github/skills/resolve-feedback/SKILL.md +288 -0
  24. data/.github/skills/review-arguments-dsl/CHECKLIST.md +3 -3
  25. data/.github/skills/reviewing-skills/SKILL.md +28 -3
  26. data/.github/skills/test-debugging/SKILL.md +20 -19
  27. data/.github/skills/yard-documentation/SKILL.md +671 -483
  28. data/.github/skills/yard-documentation/element-rules.md +162 -0
  29. data/.github/skills-deprecated/README.md +21 -0
  30. data/.github/{skills → skills-deprecated}/extract-command-from-lib/SKILL.md +9 -9
  31. data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/SKILL.md +12 -12
  32. data/.github/workflows/continuous_integration.yml +3 -2
  33. data/.rubocop.yml +7 -39
  34. data/.yard-lint.yml +75 -0
  35. data/CONTRIBUTING.md +186 -174
  36. data/Gemfile +17 -0
  37. data/README.md +79 -12
  38. data/Rakefile +3 -21
  39. data/UPGRADING.md +268 -70
  40. data/docker/test/Dockerfile +32 -0
  41. data/docker/test/docker-compose.yml +0 -0
  42. data/git.gemspec +3 -4
  43. data/lib/git/author.rb +20 -1
  44. data/lib/git/branch.rb +26 -6
  45. data/lib/git/branch_delete_failure.rb +3 -0
  46. data/lib/git/branch_delete_result.rb +6 -3
  47. data/lib/git/branch_info.rb +6 -6
  48. data/lib/git/command_line/base.rb +6 -13
  49. data/lib/git/command_line/capturing.rb +67 -10
  50. data/lib/git/command_line/result.rb +0 -8
  51. data/lib/git/command_line/streaming.rb +45 -5
  52. data/lib/git/command_line.rb +4 -3
  53. data/lib/git/commands/add.rb +61 -53
  54. data/lib/git/commands/am/abort.rb +2 -2
  55. data/lib/git/commands/am/apply.rb +109 -98
  56. data/lib/git/commands/am/continue.rb +2 -2
  57. data/lib/git/commands/am/quit.rb +2 -2
  58. data/lib/git/commands/am/retry.rb +4 -2
  59. data/lib/git/commands/am/show_current_patch.rb +1 -1
  60. data/lib/git/commands/am/skip.rb +2 -2
  61. data/lib/git/commands/am.rb +2 -2
  62. data/lib/git/commands/apply.rb +7 -2
  63. data/lib/git/commands/archive/list_formats.rb +3 -3
  64. data/lib/git/commands/archive.rb +7 -2
  65. data/lib/git/commands/arguments.rb +1370 -359
  66. data/lib/git/commands/base.rb +111 -13
  67. data/lib/git/commands/branch/copy.rb +29 -21
  68. data/lib/git/commands/branch/create.rb +72 -68
  69. data/lib/git/commands/branch/delete.rb +25 -17
  70. data/lib/git/commands/branch/list.rb +76 -60
  71. data/lib/git/commands/branch/move.rb +29 -21
  72. data/lib/git/commands/branch/set_upstream.rb +8 -8
  73. data/lib/git/commands/branch/show_current.rb +3 -3
  74. data/lib/git/commands/branch/unset_upstream.rb +4 -8
  75. data/lib/git/commands/branch.rb +2 -2
  76. data/lib/git/commands/cat_file/batch.rb +36 -20
  77. data/lib/git/commands/cat_file/filtered.rb +12 -12
  78. data/lib/git/commands/cat_file/raw.rb +13 -13
  79. data/lib/git/commands/cat_file.rb +4 -4
  80. data/lib/git/commands/checkout/branch.rb +7 -5
  81. data/lib/git/commands/checkout/files.rb +5 -4
  82. data/lib/git/commands/checkout.rb +4 -4
  83. data/lib/git/commands/checkout_index.rb +5 -4
  84. data/lib/git/commands/clean.rb +6 -4
  85. data/lib/git/commands/clone.rb +5 -4
  86. data/lib/git/commands/commit.rb +5 -4
  87. data/lib/git/commands/commit_tree.rb +5 -4
  88. data/lib/git/commands/config_option_syntax/add.rb +7 -4
  89. data/lib/git/commands/config_option_syntax/get.rb +9 -5
  90. data/lib/git/commands/config_option_syntax/get_all.rb +7 -4
  91. data/lib/git/commands/config_option_syntax/get_color.rb +8 -4
  92. data/lib/git/commands/config_option_syntax/get_color_bool.rb +7 -4
  93. data/lib/git/commands/config_option_syntax/get_regexp.rb +8 -4
  94. data/lib/git/commands/config_option_syntax/get_urlmatch.rb +8 -4
  95. data/lib/git/commands/config_option_syntax/list.rb +8 -4
  96. data/lib/git/commands/config_option_syntax/remove_section.rb +7 -2
  97. data/lib/git/commands/config_option_syntax/rename_section.rb +7 -2
  98. data/lib/git/commands/config_option_syntax/replace_all.rb +7 -2
  99. data/lib/git/commands/config_option_syntax/set.rb +7 -2
  100. data/lib/git/commands/config_option_syntax/unset.rb +7 -4
  101. data/lib/git/commands/config_option_syntax/unset_all.rb +7 -2
  102. data/lib/git/commands/describe.rb +5 -4
  103. data/lib/git/commands/diff.rb +13 -12
  104. data/lib/git/commands/diff_files.rb +7 -6
  105. data/lib/git/commands/diff_index.rb +10 -7
  106. data/lib/git/commands/fetch.rb +6 -4
  107. data/lib/git/commands/fsck.rb +6 -4
  108. data/lib/git/commands/gc.rb +6 -4
  109. data/lib/git/commands/grep.rb +6 -5
  110. data/lib/git/commands/init.rb +6 -4
  111. data/lib/git/commands/log.rb +287 -285
  112. data/lib/git/commands/ls_files.rb +69 -65
  113. data/lib/git/commands/ls_remote.rb +62 -56
  114. data/lib/git/commands/ls_tree.rb +50 -46
  115. data/lib/git/commands/maintenance/register.rb +25 -23
  116. data/lib/git/commands/maintenance/run.rb +7 -2
  117. data/lib/git/commands/maintenance/start.rb +7 -2
  118. data/lib/git/commands/maintenance/stop.rb +7 -2
  119. data/lib/git/commands/maintenance/unregister.rb +7 -2
  120. data/lib/git/commands/merge/abort.rb +2 -2
  121. data/lib/git/commands/merge/continue.rb +2 -2
  122. data/lib/git/commands/merge/quit.rb +2 -2
  123. data/lib/git/commands/merge/start.rb +7 -2
  124. data/lib/git/commands/merge.rb +2 -2
  125. data/lib/git/commands/merge_base.rb +7 -2
  126. data/lib/git/commands/mv.rb +7 -2
  127. data/lib/git/commands/name_rev.rb +7 -2
  128. data/lib/git/commands/pull.rb +7 -2
  129. data/lib/git/commands/push.rb +7 -2
  130. data/lib/git/commands/read_tree.rb +7 -2
  131. data/lib/git/commands/remote/add.rb +7 -2
  132. data/lib/git/commands/remote/get_url.rb +4 -2
  133. data/lib/git/commands/remote/list.rb +4 -2
  134. data/lib/git/commands/remote/prune.rb +4 -2
  135. data/lib/git/commands/remote/remove.rb +4 -2
  136. data/lib/git/commands/remote/rename.rb +4 -2
  137. data/lib/git/commands/remote/set_branches.rb +9 -2
  138. data/lib/git/commands/remote/set_head.rb +12 -5
  139. data/lib/git/commands/remote/set_url.rb +9 -2
  140. data/lib/git/commands/remote/set_url_add.rb +11 -2
  141. data/lib/git/commands/remote/set_url_delete.rb +9 -2
  142. data/lib/git/commands/remote/show.rb +18 -12
  143. data/lib/git/commands/remote/update.rb +19 -12
  144. data/lib/git/commands/remote.rb +2 -2
  145. data/lib/git/commands/repack.rb +67 -63
  146. data/lib/git/commands/reset.rb +51 -44
  147. data/lib/git/commands/rev_parse.rb +135 -128
  148. data/lib/git/commands/revert/abort.rb +2 -2
  149. data/lib/git/commands/revert/continue.rb +7 -2
  150. data/lib/git/commands/revert/quit.rb +2 -2
  151. data/lib/git/commands/revert/skip.rb +2 -2
  152. data/lib/git/commands/revert/start.rb +7 -2
  153. data/lib/git/commands/revert.rb +2 -2
  154. data/lib/git/commands/rm.rb +35 -36
  155. data/lib/git/commands/show.rb +1 -1
  156. data/lib/git/commands/show_ref/exclude_existing.rb +3 -4
  157. data/lib/git/commands/show_ref/exists.rb +15 -13
  158. data/lib/git/commands/show_ref/list.rb +39 -35
  159. data/lib/git/commands/show_ref/verify.rb +29 -27
  160. data/lib/git/commands/show_ref.rb +4 -4
  161. data/lib/git/commands/stash/apply.rb +31 -25
  162. data/lib/git/commands/stash/branch.rb +10 -8
  163. data/lib/git/commands/stash/clear.rb +7 -5
  164. data/lib/git/commands/stash/create.rb +10 -8
  165. data/lib/git/commands/stash/drop.rb +15 -9
  166. data/lib/git/commands/stash/list.rb +9 -5
  167. data/lib/git/commands/stash/pop.rb +21 -12
  168. data/lib/git/commands/stash/push.rb +20 -11
  169. data/lib/git/commands/stash/show.rb +21 -12
  170. data/lib/git/commands/stash/store.rb +19 -10
  171. data/lib/git/commands/stash.rb +2 -2
  172. data/lib/git/commands/status.rb +7 -2
  173. data/lib/git/commands/symbolic_ref/delete.rb +18 -14
  174. data/lib/git/commands/symbolic_ref/read.rb +24 -20
  175. data/lib/git/commands/symbolic_ref/update.rb +20 -17
  176. data/lib/git/commands/symbolic_ref.rb +4 -4
  177. data/lib/git/commands/tag/create.rb +45 -42
  178. data/lib/git/commands/tag/delete.rb +5 -3
  179. data/lib/git/commands/tag/list.rb +47 -44
  180. data/lib/git/commands/tag/verify.rb +12 -12
  181. data/lib/git/commands/tag.rb +2 -2
  182. data/lib/git/commands/update_ref/batch.rb +6 -1
  183. data/lib/git/commands/update_ref/delete.rb +19 -21
  184. data/lib/git/commands/update_ref/update.rb +22 -25
  185. data/lib/git/commands/update_ref.rb +4 -4
  186. data/lib/git/commands/version.rb +14 -11
  187. data/lib/git/commands/worktree/add.rb +50 -51
  188. data/lib/git/commands/worktree/list.rb +17 -17
  189. data/lib/git/commands/worktree/lock.rb +12 -12
  190. data/lib/git/commands/worktree/move.rb +16 -16
  191. data/lib/git/commands/worktree/prune.rb +2 -2
  192. data/lib/git/commands/worktree/remove.rb +2 -2
  193. data/lib/git/commands/worktree/repair.rb +2 -2
  194. data/lib/git/commands/worktree/unlock.rb +2 -2
  195. data/lib/git/commands/write_tree.rb +2 -2
  196. data/lib/git/commands.rb +4 -3
  197. data/lib/git/config.rb +47 -1
  198. data/lib/git/configuring.rb +89 -15
  199. data/lib/git/detached_head_info.rb +4 -1
  200. data/lib/git/diff.rb +2 -5
  201. data/lib/git/diff_file_numstat_info.rb +3 -1
  202. data/lib/git/diff_file_patch_info.rb +3 -1
  203. data/lib/git/diff_file_raw_info.rb +3 -1
  204. data/lib/git/diff_info.rb +8 -15
  205. data/lib/git/diff_path_status.rb +16 -3
  206. data/lib/git/diff_result.rb +3 -1
  207. data/lib/git/diff_stats.rb +15 -0
  208. data/lib/git/dirstat_info.rb +24 -8
  209. data/lib/git/encoding_utils.rb +32 -1
  210. data/lib/git/errors.rb +19 -9
  211. data/lib/git/escaped_path.rb +55 -3
  212. data/lib/git/execution_context/repository.rb +15 -0
  213. data/lib/git/execution_context.rb +76 -74
  214. data/lib/git/file_ref.rb +6 -3
  215. data/lib/git/fsck_object.rb +8 -0
  216. data/lib/git/fsck_result.rb +26 -15
  217. data/lib/git/log.rb +152 -5
  218. data/lib/git/object.rb +284 -8
  219. data/lib/git/parsers/branch.rb +18 -0
  220. data/lib/git/parsers/cat_file.rb +2 -2
  221. data/lib/git/parsers/diff.rb +213 -5
  222. data/lib/git/parsers/fsck.rb +11 -0
  223. data/lib/git/parsers/ls_remote.rb +1 -1
  224. data/lib/git/parsers/stash.rb +51 -0
  225. data/lib/git/parsers/tag.rb +38 -0
  226. data/lib/git/remote.rb +34 -2
  227. data/lib/git/repository/branching.rb +23 -21
  228. data/lib/git/repository/committing.rb +46 -6
  229. data/lib/git/repository/context_helpers.rb +45 -16
  230. data/lib/git/repository/diffing.rb +32 -23
  231. data/lib/git/repository/factories.rb +153 -28
  232. data/lib/git/repository/inspecting.rb +1 -1
  233. data/lib/git/repository/logging.rb +169 -30
  234. data/lib/git/repository/maintenance.rb +1 -1
  235. data/lib/git/repository/merging.rb +3 -3
  236. data/lib/git/repository/object_operations.rb +108 -14
  237. data/lib/git/repository/remote_operations.rb +150 -171
  238. data/lib/git/repository/shared_private.rb +7 -5
  239. data/lib/git/repository/staging.rb +36 -12
  240. data/lib/git/repository/stashing.rb +16 -16
  241. data/lib/git/repository/status_operations.rb +1 -1
  242. data/lib/git/repository/worktree_operations.rb +1 -1
  243. data/lib/git/repository.rb +123 -63
  244. data/lib/git/stash.rb +16 -21
  245. data/lib/git/stash_info.rb +4 -4
  246. data/lib/git/stashes.rb +20 -26
  247. data/lib/git/status.rb +21 -7
  248. data/lib/git/tag_delete_failure.rb +3 -0
  249. data/lib/git/tag_delete_result.rb +6 -3
  250. data/lib/git/tag_info.rb +1 -0
  251. data/lib/git/url.rb +12 -5
  252. data/lib/git/version.rb +6 -4
  253. data/lib/git/version_constraint.rb +4 -0
  254. data/lib/git.rb +434 -313
  255. data/redesign/3_architecture_implementation.md +59 -29
  256. data/redesign/Phase 4 - Step B.md +921 -0
  257. data/redesign/Phase 4 - Step C.md +833 -0
  258. data/redesign/c1a-public-api-scope.tsv +256 -0
  259. data/redesign/phase-4-step-b-test-audit.tsv +485 -0
  260. data/redesign/reverse_dependencies.sql +44 -0
  261. data/tasks/yard.rake +24 -17
  262. metadata +25 -57
  263. data/commitlint.test +0 -4
  264. data/lib/git/args_builder.rb +0 -103
  265. data/lib/git/command_line_result.rb +0 -8
  266. data/lib/git/deprecation.rb +0 -9
  267. data/tasks/test.rake +0 -25
  268. /data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -0
  269. /data/.github/{skills → skills-deprecated}/review-backward-compatibility/SKILL.md +0 -0
data/README.md CHANGED
@@ -26,10 +26,13 @@ Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?log
26
26
  - [Errors Raised By This Gem](#errors-raised-by-this-gem)
27
27
  - [Specifying And Handling Timeouts](#specifying-and-handling-timeouts)
28
28
  - [Deprecations](#deprecations)
29
+ - [Upgrading from v4.x to v5.0.0](#upgrading-from-v4x-to-v500)
29
30
  - [Project Policies](#project-policies)
30
31
  - [Ruby Version Support Policy](#ruby-version-support-policy)
31
32
  - [Git Version Support Policy](#git-version-support-policy)
32
33
  - [📢 Project Announcements 📢](#-project-announcements-)
34
+ - [2026-07-13: v5.0.0.beta.5 Released](#2026-07-13-v500beta5-released)
35
+ - [2026-07-11: v5.0.0.beta.4 Released](#2026-07-11-v500beta4-released)
33
36
  - [2026-06-26: v5.0.0.beta.3 Released](#2026-06-26-v500beta3-released)
34
37
  - [2026-06-25: v5.0.0.beta.2 Released](#2026-06-25-v500beta2-released)
35
38
  - [2026-06-04: v5.0.0.beta.1 Released](#2026-06-04-v500beta1-released)
@@ -64,24 +67,12 @@ Install the gem and add to the application's Gemfile by executing:
64
67
  bundle add git
65
68
  ```
66
69
 
67
- to install version 1.x:
68
-
69
- ```shell
70
- bundle add git --version "~> 1.19"
71
- ```
72
-
73
70
  If bundler is not being used to manage dependencies, install the gem by executing:
74
71
 
75
72
  ```shell
76
73
  gem install git
77
74
  ```
78
75
 
79
- to install version 1.x:
80
-
81
- ```shell
82
- gem install git --version "~> 1.19"
83
- ```
84
-
85
76
  ## Quick Start
86
77
 
87
78
  All functionality for this gem starts with the top-level
@@ -594,6 +585,18 @@ You can silence deprecation warnings by adding this line to your source code:
594
585
  Git::Deprecation.behavior = :silence
595
586
  ```
596
587
 
588
+ Or by setting this environment variable before loading the gem:
589
+
590
+ ```sh
591
+ GIT_DEPRECATION_BEHAVIOR=silence
592
+ ```
593
+
594
+ Accepted environment variable values are the behavior names supported by your
595
+ installed ActiveSupport version.
596
+
597
+ If `GIT_DEPRECATION_BEHAVIOR` is set to an unsupported value, loading the gem
598
+ raises `ArgumentError` with the accepted behavior names.
599
+
597
600
  See [the Active Support Deprecation
598
601
  documentation](https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html)
599
602
  for more details.
@@ -602,6 +605,14 @@ If deprecation warnings are silenced, you should reenable them before upgrading
602
605
  git gem to the next major version. This will make it easier to identify changes
603
606
  needed for the upgrade.
604
607
 
608
+ For the full list of deprecated methods and their replacements, see
609
+ [UPGRADING.md](UPGRADING.md).
610
+
611
+ ## Upgrading from v4.x to v5.0.0
612
+
613
+ v5.0.0 is a major release with breaking changes. See
614
+ [UPGRADING.md](UPGRADING.md) for a comprehensive migration guide.
615
+
605
616
  ## Project Policies
606
617
 
607
618
  These documents set expectations for behavior, contribution workflows, AI-assisted
@@ -654,6 +665,62 @@ notes.
654
665
 
655
666
  ## 📢 Project Announcements 📢
656
667
 
668
+ ### 2026-07-13: v5.0.0.beta.5 Released
669
+
670
+ We have published
671
+ [`git v5.0.0.beta.5`](https://rubygems.org/gems/git/versions/5.0.0.beta.5) as our
672
+ fifth pre-release.
673
+
674
+ The main user-visible change is a temporary compatibility shim for users who
675
+ monkeypatch `Git::Base`. In v5.0.0, `Git::Base` has been replaced by
676
+ `Git::Repository`; the shim forwards methods defined on `Git::Base` to repository
677
+ instances and emits deprecation warnings so applications can migrate those patches
678
+ to `Git::Repository` before v6.0.0.
679
+
680
+ **To try the beta**, add the pre-release version to your `Gemfile`:
681
+
682
+ ```ruby
683
+ gem 'git', '~> 5.0.0.beta'
684
+ ```
685
+
686
+ Or install it directly:
687
+
688
+ ```sh
689
+ gem install git --pre
690
+ ```
691
+
692
+ The intent is full backward compatibility with v4.x, but given the size and scope of
693
+ the redesign, some incompatibilities may exist. Please give the latest beta a try and
694
+ [open an issue](https://github.com/ruby-git/ruby-git/issues) if you hit anything
695
+ unexpected — your feedback helps us ship a solid v5.0.0.
696
+
697
+ See [UPGRADING.md](UPGRADING.md) for a full list of deprecations and breaking changes.
698
+
699
+ ### 2026-07-11: v5.0.0.beta.4 Released
700
+
701
+ The architectural redesign is **feature complete** and we have published
702
+ [`git v5.0.0.beta.4`](https://rubygems.org/gems/git/versions/5.0.0.beta.4) as our
703
+ fourth pre-release.
704
+
705
+ **To try the beta**, add the pre-release version to your `Gemfile`:
706
+
707
+ ```ruby
708
+ gem 'git', '~> 5.0.0.beta'
709
+ ```
710
+
711
+ Or install it directly:
712
+
713
+ ```sh
714
+ gem install git --pre
715
+ ```
716
+
717
+ The intent is full backward compatibility with v4.x, but given the size and scope of
718
+ the redesign, some incompatibilities may exist. Please give the latest beta a try and
719
+ [open an issue](https://github.com/ruby-git/ruby-git/issues) if you hit anything
720
+ unexpected — your feedback helps us ship a solid v5.0.0.
721
+
722
+ See [UPGRADING.md](UPGRADING.md) for a full list of deprecations and breaking changes.
723
+
657
724
  ### 2026-06-26: v5.0.0.beta.3 Released
658
725
 
659
726
  The architectural redesign is approximately **93% complete** and we have published
data/Rakefile CHANGED
@@ -5,29 +5,11 @@ require 'rake/clean'
5
5
  # Load all .rake files from tasks and its subdirectories.
6
6
  Dir.glob('tasks/**/*.rake').each { |r| load r }
7
7
 
8
- desc 'Run all tests (TestUnit and RSpec)'
9
- task 'test-all': %i[test spec]
10
-
11
- desc 'Run all tests in parallel (TestUnit and RSpec run concurrently)'
12
- task 'test-all:parallel' do
13
- errors = []
14
- mutex = Mutex.new
15
- threads = %w[test:parallel spec:parallel].map do |t|
16
- Thread.new do
17
- Rake::Task[t].invoke
18
- rescue Exception => e # rubocop:disable Lint/RescueException
19
- mutex.synchronize { errors << e }
20
- end
21
- end
22
- threads.each(&:join)
23
- raise errors.first if errors.any?
24
- end
25
-
26
- default_tasks = %i[test spec:unit spec:integration rubocop]
8
+ default_tasks = %i[spec:unit spec:integration rubocop]
27
9
  default_tasks << :yard if Rake::Task.task_defined?(:yard)
28
10
  default_tasks << :build
29
11
 
30
- default_tasks_parallel = %w[test:parallel spec:unit:parallel spec:integration:parallel rubocop]
12
+ default_tasks_parallel = %w[spec:unit:parallel spec:integration:parallel rubocop]
31
13
  default_tasks_parallel << :yard if Rake::Task.task_defined?(:yard)
32
14
  default_tasks_parallel << :build
33
15
 
@@ -54,7 +36,7 @@ module Rake
54
36
  # rake rubocop # => do not output the task name
55
37
  # rake rubocop yard # => output task name for rubocop and yard
56
38
  top_level_tasks = Rake.application.top_level_tasks
57
- box("Rake task: #{name}") unless top_level_tasks.length == 1 && name == top_level_tasks[0]
39
+ box("rake #{name}") unless top_level_tasks.length == 1 && name == top_level_tasks[0]
58
40
  original_execute(args)
59
41
  end
60
42
 
data/UPGRADING.md CHANGED
@@ -1,83 +1,190 @@
1
1
  # Upgrading the `git` Gem
2
2
 
3
- > **⚠️ Work in progress v5.0.0 is currently in beta.**
4
- > This document is updated incrementally as development continues and is not yet
5
- > complete. If you encounter a compatibility problem not covered here, please
6
- > [open an issue](https://github.com/ruby-git/ruby-git/issues).
3
+ This document covers breaking changes and migration steps when upgrading the
4
+ `git` gem to a new major version. Each section describes what changed and how
5
+ to update your code when upgrading from the preceding major version.
7
6
 
8
- - [Upgrading from v4.x to v5.x](#upgrading-from-v4x-to-v5x)
7
+ - [Upgrading to v5.x](#upgrading-to-v5x)
9
8
  - [Overview](#overview)
10
- - [`Git::Lib` removal](#gitlib-removal)
11
- - [Methods with a direct replacement](#methods-with-a-direct-replacement)
12
- - [Methods with no replacement](#methods-with-no-replacement)
13
- - [Internal plumbing methods (no replacement)](#internal-plumbing-methods-no-replacement)
9
+ - [Breaking changes](#breaking-changes)
10
+ - [`Git::Base` removed](#gitbase-removed)
11
+ - [Return type of `Git.open`, `Git.clone`, `Git.init`, `Git.bare`](#return-type-of-gitopen-gitclone-gitinit-gitbare)
12
+ - [Unsupported options raise `ArgumentError`](#unsupported-options-raise-argumenterror)
13
+ - [`Git::Lib` removed](#gitlib-removed)
14
+ - [`Git::Log#object` is not a path limiter](#gitlogobject-is-not-a-path-limiter)
15
+ - [`Git::CommandLineResult` deprecated](#gitcommandlineresult-deprecated)
14
16
  - [Deprecated methods](#deprecated-methods)
17
+ - [Facade method renames](#facade-method-renames)
18
+ - [v4.x-style configuration methods](#v4x-style-configuration-methods)
19
+ - [`Git` module mixin deprecations](#git-module-mixin-deprecations)
15
20
 
16
- ## Upgrading from v4.x to v5.x
21
+ ## Upgrading to v5.x
17
22
 
18
23
  ### Overview
19
24
 
20
- The primary goal of v5.0.0 is to move everyone onto a new internal architecture
21
- while keeping the existing v4.x API working. The vast majority of v4.x code
22
- requires no changes to run on v5.x.
25
+ v5.0.0 delivers a new internal architecture while keeping the v4.x API working
26
+ for the vast majority of users. Most v4.x code requires **no changes** to run on
27
+ v5.x.
23
28
 
24
- The new architecture delivered in v5.0.0 is the foundation for future API
25
- improvements across upcoming major releases.
29
+ The new architecture introduces a layered design (`Git::Commands`,
30
+ `Git::Repository`, and associated parsers). Compatibility shims — deprecated
31
+ forwarding methods that map old call patterns to the new API — ensure that v4.x
32
+ code continues to work. These shims emit deprecation warnings that tell you
33
+ exactly what to change and what will be eliminated in v6.0.0.
26
34
 
27
- The new architecture introduces a layered design (`Git::Commands`, `Git::Repository`,
28
- and associated parsers). Compatibility shims deprecated forwarding methods that map
29
- old call patterns to the new API ensure that v4.x code continues to work. These
30
- shims emit deprecation warnings that tell you exactly what to change and what will be
31
- eliminated in a future major release (most likely v6.0.0).
35
+ Hard breaks are limited to a small number of things that had no safe migration
36
+ path. These are described in the [Breaking changes](#breaking-changes) section,
37
+ followed by [Deprecated methods](#deprecated-methods) that still work in v5.x
38
+ but are removed in v6.0.0.
32
39
 
33
- Hard breaks are limited to a small number of methods that had no safe
34
- migration path — these are described in detail below.
35
-
36
- Our intent is to make upgrading to v5.x as smooth as possible. For information
37
- on how to suppress or configure deprecation warnings, see the
40
+ For information on how to suppress or configure deprecation warnings, see the
38
41
  [Deprecations](README.md#deprecations) section of the README.
39
42
 
43
+ **Changes at a glance:**
44
+
45
+ | Change | Type | Impact | Action required |
46
+ |--------|------|--------|-----------------|
47
+ | `Git::Base` removed | Hard break | High for code that references it by name | Replace with `Git::Repository` (returned by `Git.open` etc.) |
48
+ | `Git::Lib` removed | Hard break | High for `.lib.*` callers | Use the equivalent method directly on the repo object (see table below) |
49
+ | `Git.open` etc. return `Git::Repository` (not `Git::Base`) | Hard break | Low for most callers; breaks `is_a?(Git::Base)` | Update type checks and update `be_a(Git::Base)` in tests |
50
+ | Unsupported options now raise `ArgumentError` | Behavior change | Medium for code passing unknown or misspelled options | Check option names against the documented API |
51
+ | `Git::Log#object` is not a path limiter | Behavior change | Medium for code that used `object(path)` to filter logs by path | Use `Git::Log#path` for path filtering |
52
+ | `Git::CommandLineResult` deprecated | Deprecation (removed in v6.0.0) | Low; only affects code that references the constant by name | Use `Git::CommandLine::Result` instead |
53
+
40
54
  ---
41
55
 
42
- ### `Git::Lib` removal
56
+ ### Breaking changes
43
57
 
44
- The object returned by `Git.open`, `Git.clone`, and `Git.init` — the object
45
- you call methods on to interact with your repository — inadvertently exposed
46
- a `#lib` method that gave access to `Git::Lib`, the gem's internal
47
- implementation class. This was never intended to be public; it was an
48
- implementation detail that leaked out. `Git::Lib` is removed in v5.0.0.
58
+ #### `Git::Base` removed
49
59
 
50
- Calling `#lib` on the repository object returns `self` with a deprecation
51
- warning so that existing `g.lib.*` call chains continue to work during
52
- migration. The `#lib` method itself is removed in v6.0.0. Calls to methods
53
- that have no replacement (see below) raise `NoMethodError` with an
54
- informative message.
60
+ `Git::Base` the class previously returned by `Git.open`, `Git.clone`,
61
+ `Git.init`, and `Git.bare` is removed in v5.0.0. The replacement is
62
+ `Git::Repository`, which is returned by all four entry points and exposes the
63
+ same public API.
55
64
 
56
- Most public behavior previously accessible via `g.lib.*` is available
57
- directly on the repository object (i.e., `g.*`). A small number of methods
58
- have no replacement — see below. The sections below list every affected method.
65
+ **Code that must be updated:**
59
66
 
60
- #### Methods with a direct replacement
67
+ ```ruby
68
+ # v4.x — explicit Git::Base reference (raises NameError in v5.x)
69
+ repo = Git::Base.new(working_directory: '/path/to/repo')
61
70
 
62
- All of the following `g.lib.*` calls work in v5.x but emit a deprecation
63
- warning. Migrate to the replacement shown to silence the `g.lib.*` deprecation
64
- warning; note that some replacements are themselves deprecated — see the table
65
- notes for the final migration target.
71
+ # v5.x use the entry-point methods; do not construct Git::Repository directly
72
+ repo = Git.open('/path/to/repo')
73
+ ```
66
74
 
67
- | Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
68
- |---------------------------------------------------|-------------|
69
- | `g.lib.config_get(name)` | `g.config(name)` |
70
- | `g.lib.config_list` | `g.config` |
71
- | `g.lib.config_set(name, value)` | `g.config(name, value)` |
75
+ ```ruby
76
+ # v4.x — type-checking against Git::Base (raises NameError in v5.x because Git::Base is removed)
77
+ raise unless repo.is_a?(Git::Base)
78
+
79
+ # v5.x check against Git::Repository
80
+ raise unless repo.is_a?(Git::Repository)
81
+ ```
82
+
83
+ ```ruby
84
+ # v4.x — requiring the internal file (raises LoadError in v5.x)
85
+ require 'git/base'
86
+
87
+ # v5.x — the public entry point is git itself; no internal require needed
88
+ require 'git'
89
+ ```
90
+
91
+ **Public API is preserved:** `Git::Repository` provides every method that
92
+ `Git::Base` did. Code that simply calls methods on the object returned by
93
+ `Git.open` (e.g., `repo.commit`, `repo.status`, `repo.add`) requires no
94
+ changes.
95
+
96
+ ---
97
+
98
+ #### Return type of `Git.open`, `Git.clone`, `Git.init`, `Git.bare`
99
+
100
+ `Git.open`, `Git.clone`, `Git.init`, and `Git.bare` now return
101
+ `Git::Repository` instead of `Git::Base`.
102
+
103
+ For most callers this is transparent — the returned object responds to the same
104
+ methods. Code that explicitly checks `is_a?(Git::Base)` or `be_a(Git::Base)` in
105
+ tests must be updated:
106
+
107
+ ```ruby
108
+ # v4.x
109
+ expect(Git.open(repo_path)).to be_a(Git::Base)
110
+
111
+ # v5.x
112
+ expect(Git.open(repo_path)).to be_a(Git::Repository)
113
+ ```
114
+
115
+ `Git::Repository` does not define `.open`, `.bare`, `.clone`, or `.init` class
116
+ methods. Always use `Git.open`, `Git.bare`, `Git.clone`, and `Git.init` to
117
+ construct a repository object.
118
+
119
+ ---
120
+
121
+ #### Unsupported options raise `ArgumentError`
122
+
123
+ v5.x validates options more strictly for factory methods and command APIs.
124
+ Unknown options that were silently ignored in v4.x may now raise
125
+ `ArgumentError`. Check option names against the documented API when upgrading,
126
+ especially for calls that pass keyword options through helper methods or shared
127
+ option hashes.
128
+
129
+ For example, `Git.clone` supports `log:`, not `logger:`. A misspelled or
130
+ unsupported option that v4.x ignored must be corrected:
131
+
132
+ ```ruby
133
+ # v4.x — silently ignored; did not configure clone logging
134
+ Git.clone(url, path, logger: logger)
135
+
136
+ # v5.x — use the documented option name
137
+ Git.clone(url, path, log: logger)
138
+ ```
139
+
140
+ ---
141
+
142
+ #### `Git::Lib` removed
143
+
144
+ The object returned by `Git.open`, `Git.clone`, `Git.init`, and `Git.bare` previously
145
+ exposed a `#lib` method that gave access to `Git::Lib`, the gem's internal
146
+ implementation class. `Git::Lib` is removed in v5.0.0.
147
+
148
+ In v5.x, calling `#lib` on a repo object returns `self` with a deprecation
149
+ warning. This means `g.lib.some_method(args)` is forwarded to
150
+ `g.some_method(args)` — but only if `some_method` exists on `Git::Repository`.
151
+ Methods that were unique to `Git::Lib` and have no counterpart on
152
+ `Git::Repository` raise `NoMethodError` immediately. The `#lib` method itself
153
+ is removed in v6.0.0.
154
+
155
+ Most public behavior previously accessible via `g.lib.*` is available directly
156
+ on the repository object (`g.*`). See the tables below for every affected
157
+ method.
158
+
159
+ ##### Methods that work via the `#lib` shim (with deprecation warning)
160
+
161
+ The following v4.x `g.lib.*` call shapes are forwarded to their `Git::Repository`
162
+ counterpart by the `#lib → self` shim. They emit a deprecation warning; migrate
163
+ to the replacement shown to silence it.
164
+
165
+ > **Note — config return type change:** `g.lib.config_get(name)` returned a
166
+ > `String`; `g.lib.config_list` returned a `Hash`.
167
+ > The v5.x replacements `config_get` and `config_list` return
168
+ > `Git::ConfigEntryInfo` and `Array<Git::ConfigEntryInfo>` respectively — richer
169
+ > objects that expose `.value` (the String), `.key`, `.scope`, and `.origin`.
170
+ >
171
+ > If you only need the String value:
172
+ > - `g.config_get(name)&.value` → replaces `g.lib.config_get(name)`
173
+ > - `g.config_list.to_h { |e| [e.key, e.value] }` → replaces `g.lib.config_list`
174
+ >
175
+ > If your code was using the v4.x public `g.config(name)` API (not `g.lib.*`),
176
+ > that deprecated bridge still returns a `String` in v5.x and continues to work
177
+ > until v6.0.0.
178
+
179
+ | v4.x call | Replacement in v5.x |
180
+ |-----------|---------------------|
181
+ | `g.lib.config_get(name)` | `g.config_get(name)` — returns `Git::ConfigEntryInfo`; use `.value` for the String |
182
+ | `g.lib.config_list` | `g.config_list` — returns `Array<Git::ConfigEntryInfo>` |
183
+ | `g.lib.config_set(name, value)` | `g.config_set(name, value)` |
72
184
  | `g.lib.git_version` | `g.git_version` |
73
- | `g.lib.global_config_get(name)` | `g.global_config(name)` |
74
- | `g.lib.global_config_list` | `g.global_config` |
75
- | `g.lib.global_config_set(name, value)` | `g.global_config(name, value)` |
76
- | `g.lib.parse_config(file)` | `g.config(file: file)` |
77
- | `g.lib.stash_list` | `g.stash_list` *(also deprecated — use `g.stashes_all`)* |
185
+ | `g.lib.stash_list` | `g.stashes_all` |
78
186
  | `g.lib.unmerged` | `g.unmerged` |
79
187
  | `g.lib.change_head_branch(name)` | `g.change_head_branch(name)` |
80
- | `g.lib.branch_current` | `g.current_branch` |
81
188
  | `g.lib.ls_remote(location, opts)` | `g.ls_remote(location, opts)` |
82
189
  | `g.lib.current_branch_state` | `g.current_branch_state` |
83
190
 
@@ -89,13 +196,27 @@ notes for the final migration target.
89
196
  > (`Git::Lib::HeadState.new(:active, 'main')`), update to keyword construction:
90
197
  > `Git::Repository::Branching::HeadState.new(state: :active, name: 'main')`.
91
198
 
92
- #### Methods with no replacement
199
+ ##### Methods that raise `NoMethodError` in v5.x
200
+
201
+ These `Git::Lib` method names have no counterpart on `Git::Repository`, so
202
+ `g.lib.method_name` raises `NoMethodError` even in v5.x (the `#lib → self`
203
+ shim cannot forward them). Update call sites directly:
204
+
205
+ | v4.x call | Replacement in v5.x |
206
+ |-----------|---------------------|
207
+ | `g.lib.global_config_get(name)` | `g.config_get(name, global: true)` |
208
+ | `g.lib.global_config_list` | `g.config_list(global: true)` |
209
+ | `g.lib.global_config_set(name, value)` | `g.config_set(name, value, global: true)` |
210
+ | `g.lib.branch_current` | `g.current_branch` |
211
+ | `g.lib.parse_config(file)` | `g.config_list(file: file)` |
212
+
213
+ ##### Methods with no replacement
93
214
 
94
215
  | v4.x call | Notes |
95
216
  |-----------|-------|
96
217
  | `g.lib.list_files(ref_dir)` | Walked `.git/refs/` directly. Use `g.branches`, `g.tags`, or `g.remotes` instead. |
97
218
 
98
- #### Internal plumbing methods (no replacement)
219
+ ##### Internal plumbing methods (no replacement)
99
220
 
100
221
  The following methods were technically public on `Git::Lib` but are internal
101
222
  helpers with no plausible external use. They have no replacement in v5.0.0:
@@ -115,27 +236,104 @@ helpers with no plausible external use. They have no replacement in v5.0.0:
115
236
 
116
237
  ---
117
238
 
239
+ #### `Git::Log#object` is not a path limiter
240
+
241
+ In previous 4.x releases, some uses of `Git::Log#object(path)` could appear to
242
+ filter log output by path when combined with `#between` or other revision range
243
+ options. This relied on ambiguous `git log` argument handling and was not the
244
+ intended API for path filtering.
245
+
246
+ In v5.x, `Git::Log#object` should be treated as a revision expression. When both
247
+ `#object` and `#between` are specified, `#between` takes precedence. Code that
248
+ used `#object` to limit commits to a path should use `#path` instead.
249
+
250
+ ```ruby
251
+ # v4.x — ambiguous; could appear to filter commits touching this path
252
+ git.log(500).object('cookbooks/mycookbook').between('1.0.0', 'HEAD').execute
253
+
254
+ # v5.x — use #path for path filtering
255
+ git.log(500).path('cookbooks/mycookbook').between('1.0.0', 'HEAD').execute
256
+
257
+ # #object remains appropriate for revision expressions
258
+ git.log.object('HEAD~10..HEAD').execute
259
+ ```
260
+
261
+ ---
262
+
263
+ #### `Git::CommandLineResult` deprecated
264
+
265
+ `Git::CommandLineResult` was an alias for `Git::CommandLine::Result` introduced
266
+ for backward compatibility. It is deprecated in v5.0.0 and removed in v6.0.0.
267
+ Accessing `Git::CommandLineResult` emits a deprecation warning.
268
+
269
+ ```ruby
270
+ # v4.x
271
+ result.is_a?(Git::CommandLineResult)
272
+
273
+ # v5.x
274
+ result.is_a?(Git::CommandLine::Result)
275
+ ```
276
+
277
+ This change is only relevant if your code references `Git::CommandLineResult`
278
+ by name (typically in type checks or documentation). Code that simply uses the
279
+ result object returned by git commands is unaffected.
280
+
281
+ ---
282
+
118
283
  ### Deprecated methods
119
284
 
120
- The following methods are available in v5.x with deprecation warnings and
121
- are removed in v6.0.0.
285
+ The following methods are available in v5.x with deprecation warnings and are
286
+ removed in v6.0.0. Migrate to the replacement shown to silence the warnings.
287
+
288
+ #### Facade method renames
289
+
290
+ Five methods were renamed to follow the project's `noun_verb` naming convention.
291
+ The old names continue to work but emit deprecation warnings:
122
292
 
123
293
  | Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
124
- |---------------------------------------------------|-------------|
125
- | `g.config_get(name)` | `g.config(name)` |
126
- | `g.config_list` | `g.config` |
127
- | `g.config_set(name, value)` | `g.config(name, value)` |
128
- | `g.global_config_get(name)` | `g.global_config(name)` |
129
- | `g.global_config_list` | `g.global_config` |
130
- | `g.global_config_set(name, value)` | `g.global_config(name, value)` |
131
- | `g.parse_config(file)` | `g.config(file: file)` |
132
- | `g.stash_list` | `g.stashes_all` |
294
+ |-----------------------------------------------------|-------------|
133
295
  | `g.add_remote(name, url, opts)` | `g.remote_add(name, url, opts)` |
134
296
  | `g.remove_remote(name)` | `g.remote_remove(name)` |
135
297
  | `g.set_remote_url(name, url)` | `g.remote_set_url(name, url)` |
136
298
  | `g.add_tag(name, ...)` | `g.tag_add(name, ...)` |
137
299
  | `g.delete_tag(name)` | `g.tag_delete(name)` |
138
- | `include Git; config(...)` | `Git.open(Dir.pwd).config(...)` |
139
- | `include Git; global_config(...)` | `Git.global_config(...)` |
300
+
301
+ #### v4.x-style configuration methods
302
+
303
+ The v4.x `config` and `global_config` methods accepted varying argument shapes
304
+ to read, write, or list configuration. These are replaced by separate,
305
+ purpose-named methods.
306
+
307
+ > **Return type change:** The v4.x `g.config(name)` returned a `String` and
308
+ > `g.config` returned a `Hash`. The v5.x replacements `config_get` and
309
+ > `config_list` return `Git::ConfigEntryInfo` and `Array<Git::ConfigEntryInfo>`
310
+ > respectively. Use `.value` to get the String value:
311
+ > - `g.config_get(name)&.value` → String or nil
312
+ > - `g.config_list.to_h { |e| [e.key, e.value] }` → Hash (key → value)
313
+
314
+ | Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
315
+ |-----------------------------------------------------|-------------|
316
+ | `g.config(name)` | `g.config_get(name)` — returns `Git::ConfigEntryInfo`; use `.value` for the String |
317
+ | `g.config` | `g.config_list` — returns `Array<Git::ConfigEntryInfo>` |
318
+ | `g.config(name, value)` | `g.config_set(name, value)` |
319
+ | `g.global_config(name)` | `g.config_get(name, global: true)` |
320
+ | `g.global_config` | `g.config_list(global: true)` |
321
+ | `g.global_config(name, value)` | `g.config_set(name, value, global: true)` |
322
+ | `g.parse_config(file)` | `g.config_list(file: file)` |
323
+ | `g.stash_list` | `g.stashes_all` |
324
+
325
+ #### `Git` module mixin deprecations
326
+
327
+ Extending or including the `Git` module to call `config` and `global_config`
328
+ as bare methods is deprecated:
329
+
330
+ | Deprecated usage | Replacement |
331
+ |-----------------|-------------|
332
+ | `include Git; config(name)` | `Git.open(Dir.pwd).config_get(name)` |
333
+ | `include Git; config(name, value)` | `Git.open(Dir.pwd).config_set(name, value)` |
334
+ | `include Git; config` | `Git.open(Dir.pwd).config_list` |
335
+ | `include Git; global_config(name)` | `Git.config_get(name, global: true)` |
336
+ | `include Git; global_config(name, value)` | `Git.config_set(name, value, global: true)` |
337
+ | `include Git; global_config` | `Git.config_list(global: true)` |
140
338
 
141
339
  ---
@@ -0,0 +1,32 @@
1
+ FROM ruby
2
+
3
+ WORKDIR /ruby-git
4
+
5
+
6
+ ADD Gemfile git.gemspec ./
7
+ ADD lib/git/version.rb ./lib/git/version.rb
8
+
9
+ # `git.gemspec`'s `spec.files` shells out to `git ls-files`, which Bundler
10
+ # evaluates below via the Gemfile's `gemspec` directive. Rather than relying
11
+ # on the host's `.git` (which, for a build context copied from a linked git
12
+ # worktree, is a file pointing at an absolute host path that doesn't exist
13
+ # in the image — breaking every git command with "fatal: not a git
14
+ # repository"), always initialize a throwaway repo scoped to the image. This
15
+ # also keeps the image self-contained and avoids ever copying the
16
+ # (potentially large) host `.git` directory in (see `.dockerignore`). A
17
+ # second commit is added below once the full source tree is present, so the
18
+ # final file list is complete.
19
+ RUN git init -q && \
20
+ git -c user.email=docker@example.com -c user.name=docker add -A && \
21
+ git -c user.email=docker@example.com -c user.name=docker commit -q -m 'Throwaway repo for Docker test run'
22
+
23
+ RUN bundle install
24
+
25
+ ADD . .
26
+
27
+ # Refresh the throwaway repo now that the full source tree is present, so
28
+ # `git ls-files` reflects every file for `rake build`'s `spec.files`.
29
+ RUN git -c user.email=docker@example.com -c user.name=docker add -A && \
30
+ git -c user.email=docker@example.com -c user.name=docker commit -q -m 'Add full source' --allow-empty
31
+
32
+ ENTRYPOINT ["bundle", "exec", "rake", "default"]
File without changes
data/git.gemspec CHANGED
@@ -37,8 +37,6 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency 'create_github_release', '~> 2.1'
38
38
  spec.add_development_dependency 'fuubar', '~> 2.5'
39
39
  spec.add_development_dependency 'main_branch_shared_rubocop_config', '~> 0.1'
40
- spec.add_development_dependency 'minitar', '~> 1.1'
41
- spec.add_development_dependency 'mocha', '~> 2.8'
42
40
  spec.add_development_dependency 'parallel_tests', '~> 5.6'
43
41
  spec.add_development_dependency 'rake', '~> 13.3'
44
42
  spec.add_development_dependency 'rspec', '~> 3.13'
@@ -46,7 +44,6 @@ Gem::Specification.new do |spec|
46
44
  spec.add_development_dependency 'simplecov', '~> 0.22'
47
45
  spec.add_development_dependency 'simplecov-lcov', '~> 0.9'
48
46
  spec.add_development_dependency 'simplecov-rspec', '~> 0.4'
49
- spec.add_development_dependency 'test-unit', '~> 3.7'
50
47
 
51
48
  if RUBY_ENGINE == 'truffleruby' && Gem::Version.new(RUBY_ENGINE_VERSION) < Gem::Version.new('34.0.0')
52
49
  # i18n 1.15+ uses Fiber.[] (Ruby 3.2 Fiber storage) which TruffleRuby < 34.0.0 does not implement
@@ -58,7 +55,9 @@ Gem::Specification.new do |spec|
58
55
  spec.add_development_dependency 'redcarpet', '~> 3.6'
59
56
  spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
60
57
  spec.add_development_dependency 'yard_example_test', '~> 0.2', '>= 0.2.1'
61
- spec.add_development_dependency 'yardstick', '~> 0.9'
58
+
59
+ # yard-lint requires Ruby >= 3.3, so it is only installed on Ruby 3.3+.
60
+ spec.add_development_dependency 'yard-lint', '~> 1.8' if Gem.ruby_version >= Gem::Version.new('3.3.0')
62
61
  end
63
62
 
64
63
  # Specify which files should be added to the gem when it is released.
data/lib/git/author.rb CHANGED
@@ -2,9 +2,28 @@
2
2
 
3
3
  module Git
4
4
  # An author in a Git commit
5
+ #
6
+ # @api public
7
+ #
5
8
  class Author
6
- attr_accessor :name, :email, :date
9
+ # @return [String, nil] the author's name
10
+ attr_accessor :name
7
11
 
12
+ # @return [String, nil] the author's email
13
+ attr_accessor :email
14
+
15
+ # @return [Time, nil] the date the change was authored (author date, not committer date)
16
+ attr_accessor :date
17
+
18
+ # Initializes a new Author object from a string
19
+ #
20
+ # @example
21
+ # Git::Author.new("John Doe <john.doe@example.com> 1627849923 +0200")
22
+ #
23
+ # @param author_string [String] the author string
24
+ #
25
+ # @return [void]
26
+ #
8
27
  def initialize(author_string)
9
28
  return unless (m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string))
10
29