git 5.0.0.beta.2 → 5.0.0.beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) 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 +86 -23
  38. data/Rakefile +3 -21
  39. data/UPGRADING.md +219 -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 +287 -6
  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 +25 -13
  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 +400 -314
  255. data/redesign/3_architecture_implementation.md +81 -30
  256. data/redesign/Phase 4 - Step A.md +6 -0
  257. data/redesign/Phase 4 - Step B.md +921 -0
  258. data/redesign/Phase 4 - Step C.md +833 -0
  259. data/redesign/c1a-public-api-scope.tsv +256 -0
  260. data/redesign/phase-4-step-b-test-audit.tsv +485 -0
  261. data/tasks/yard.rake +24 -17
  262. metadata +24 -58
  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/lib/git/repository/configuring.rb +0 -351
  268. data/tasks/test.rake +0 -25
  269. /data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -0
  270. /data/.github/{skills → skills-deprecated}/review-backward-compatibility/SKILL.md +0 -0
data/lib/git/object.rb CHANGED
@@ -9,11 +9,37 @@ module Git
9
9
  # represents a git object
10
10
  class Object
11
11
  # A base class for all Git objects
12
+ #
13
+ # @api private
14
+ #
12
15
  class AbstractObject
13
- attr_accessor :objectish, :type, :mode
16
+ # @return [String] the object name, SHA, ref, or treeish path
17
+ #
18
+ attr_accessor :objectish
19
+
20
+ # @return [String, nil] the git object type
21
+ #
22
+ attr_accessor :type
14
23
 
24
+ # @return [String, nil] the file mode from tree listings
25
+ #
26
+ attr_accessor :mode
27
+
28
+ # Sets the size of the git object in bytes
29
+ #
30
+ # @example Set the size to 60 bytes
31
+ # object.size = 60
32
+ #
33
+ # @return [Integer] the size of the git object in bytes
34
+ #
15
35
  attr_writer :size
16
36
 
37
+ # Creates a lazy wrapper for a git object
38
+ #
39
+ # @param base [Git::Repository] the repository used to query object data
40
+ #
41
+ # @param objectish [String, #to_s] the object name, SHA, ref, or treeish path
42
+ #
17
43
  def initialize(base, objectish)
18
44
  @base = base
19
45
  @objectish = objectish.to_s
@@ -23,10 +49,18 @@ module Git
23
49
  @sha = nil
24
50
  end
25
51
 
52
+ # Returns the resolved SHA for this object
53
+ #
54
+ # @return [String] the resolved object SHA
55
+ #
26
56
  def sha
27
57
  @sha ||= object_repository.rev_parse(@objectish)
28
58
  end
29
59
 
60
+ # Returns the size of this object in bytes
61
+ #
62
+ # @return [Integer] the object size in bytes
63
+ #
30
64
  def size
31
65
  @size ||= object_repository.cat_file_size(@objectish)
32
66
  end
@@ -76,56 +110,152 @@ module Git
76
110
  end
77
111
  end
78
112
 
113
+ # Returns the object contents split into lines
114
+ #
115
+ # @return [Array<String>] the raw contents split on newline boundaries
116
+ #
79
117
  def contents_array
80
118
  contents.split("\n")
81
119
  end
82
120
 
121
+ # Returns the original object expression
122
+ #
123
+ # @return [String] the object name, SHA, ref, or treeish path
124
+ #
83
125
  def to_s
84
126
  @objectish
85
127
  end
86
128
 
129
+ # Searches this object for matching tracked file contents
130
+ #
131
+ # Always searches this object's resolved SHA. A caller-provided `:object`
132
+ # option is ignored.
133
+ #
134
+ # @param string [String] the pattern to search for
135
+ #
136
+ # @param path_limiter [String, Pathname, Array<String, Pathname>, nil]
137
+ # path or paths to limit the search to
138
+ #
139
+ # @param opts [Hash] additional grep options
140
+ #
141
+ # @option opts [Boolean, nil] :ignore_case (nil) ignore case
142
+ # distinctions in the pattern and file contents
143
+ #
144
+ # Alias: :i
145
+ #
146
+ # @option opts [Boolean, nil] :invert_match (nil) select non-matching
147
+ # lines
148
+ #
149
+ # Alias: :v
150
+ #
151
+ # @option opts [Boolean, nil] :extended_regexp (nil) use POSIX extended
152
+ # regular expressions for the pattern
153
+ #
154
+ # Alias: :E
155
+ #
156
+ # @return [Hash<String, Array<Array(Integer, String)>>] matching lines by path
157
+ #
87
158
  def grep(string, path_limiter = nil, opts = {})
88
159
  object_repository.grep(string, path_limiter, opts.merge(object: sha))
89
160
  end
90
161
 
162
+ # Returns a diff from this object to another object
163
+ #
164
+ # @param objectish [String] the object name, SHA, ref, or treeish path to diff
165
+ # against
166
+ #
167
+ # @return [Git::Diff] the diff between the two objects
168
+ #
91
169
  def diff(objectish)
92
170
  Git::Diff.new(@base, @objectish, objectish)
93
171
  end
94
172
 
173
+ # Returns a log scoped to this object
174
+ #
175
+ # @param count [Integer] maximum number of commits to include
176
+ #
177
+ # @return [Git::Log] the scoped log object
178
+ #
95
179
  def log(count = 30)
96
180
  Git::Log.new(@base, count).object(@objectish)
97
181
  end
98
182
 
99
183
  # Creates an archive of this object and writes it to a file
100
184
  #
101
- # @api public
185
+ # @example Archive a tree to a zip file
186
+ # git.object('v1.0').archive('/tmp/release.zip', format: 'zip')
187
+ #
188
+ # @example Archive a tree to a temporary tar file
189
+ # git.object('v2.6').archive(nil, format: 'tar')
190
+ #
191
+ # @example Archive a tree to a tgz file with a path prefix
192
+ # git.object('v2.6').archive('/tmp/release.tgz', format: 'tgz', prefix: 'test/')
193
+ #
194
+ # @example Archive one directory with a path prefix
195
+ # git.object('v2.6').archive(
196
+ # '/tmp/ex-dir.tar',
197
+ # format: 'tar',
198
+ # prefix: 'test/',
199
+ # path: 'ex_dir/'
200
+ # )
102
201
  #
103
202
  # @param file [String, nil] destination file path; a temp file is created if `nil`
104
203
  #
105
204
  # @param opts [Hash] archive options (see {Git::Repository#archive})
106
205
  #
206
+ # @option opts [String] :format ('zip') archive format: `'tar'`, `'zip'`,
207
+ # or `'tgz'`
208
+ #
209
+ # @option opts [String] :prefix (nil) prefix prepended to every filename
210
+ # in the archive
211
+ #
212
+ # @option opts [String] :path (nil) path within the tree to include
213
+ #
214
+ # @option opts [String] :remote (nil) retrieve the archive from a remote
215
+ # repository
216
+ #
217
+ # @option opts [Boolean, nil] :add_gzip (nil) apply gzip compression after
218
+ # writing the archive
219
+ #
107
220
  # @return [String] the path to the written archive file
108
221
  #
222
+ # @raise [ArgumentError] when archive options or destination path are invalid
223
+ #
109
224
  # @raise [Git::FailedError] if `git archive` fails
110
225
  #
111
- # @example Archive a tree to a zip file
112
- # git.object('v1.0').archive('/tmp/release.zip', format: 'zip')
226
+ # @api public
113
227
  #
114
228
  def archive(file = nil, opts = {})
115
229
  object_repository.archive(@objectish, file, opts)
116
230
  end
117
231
 
232
+ # Returns whether this object is a tree
233
+ #
234
+ # @return [Boolean] `true` when this object is a tree
235
+ #
118
236
  def tree? = false
119
237
 
238
+ # Returns whether this object is a blob
239
+ #
240
+ # @return [Boolean] `true` when this object is a blob
241
+ #
120
242
  def blob? = false
121
243
 
244
+ # Returns whether this object is a commit
245
+ #
246
+ # @return [Boolean] `true` when this object is a commit
247
+ #
122
248
  def commit? = false
123
249
 
250
+ # Returns whether this object is a tag
251
+ #
252
+ # @return [Boolean] `true` when this object is a tag
253
+ #
124
254
  def tag? = false
125
255
 
126
256
  private
127
257
 
128
- # @return [Git::Repository]
258
+ # @return [Git::Repository] the repository used for object lookup
129
259
  #
130
260
  def object_repository
131
261
  @base
@@ -134,11 +264,23 @@ module Git
134
264
 
135
265
  # A Git blob object
136
266
  class Blob < AbstractObject
267
+ # Creates a blob object wrapper
268
+ #
269
+ # @param base [Git::Repository] the repository used to query object data
270
+ #
271
+ # @param sha [String] the blob SHA or object expression
272
+ #
273
+ # @param mode [String, nil] the file mode from tree listings
274
+ #
137
275
  def initialize(base, sha, mode = nil)
138
276
  super(base, sha)
139
277
  @mode = mode
140
278
  end
141
279
 
280
+ # Returns whether this object is a blob
281
+ #
282
+ # @return [Boolean] `true`
283
+ #
142
284
  def blob?
143
285
  true
144
286
  end
@@ -146,6 +288,14 @@ module Git
146
288
 
147
289
  # A Git tree object
148
290
  class Tree < AbstractObject
291
+ # Creates a tree object wrapper
292
+ #
293
+ # @param base [Git::Repository] the repository used to query object data
294
+ #
295
+ # @param sha [String] the tree SHA or object expression
296
+ #
297
+ # @param mode [String, nil] the file mode from tree listings
298
+ #
149
299
  def initialize(base, sha, mode = nil)
150
300
  super(base, sha)
151
301
  @mode = mode
@@ -153,29 +303,53 @@ module Git
153
303
  @blobs = nil
154
304
  end
155
305
 
306
+ # Returns child blobs and subtrees keyed by name
307
+ #
308
+ # @return [Hash<String, Git::Object::AbstractObject>] child objects by name
309
+ #
156
310
  def children
157
311
  blobs.merge(subtrees)
158
312
  end
159
313
 
314
+ # Returns blobs directly under this tree
315
+ #
316
+ # @return [Hash<String, Git::Object::Blob>] blob objects by filename
317
+ #
160
318
  def blobs
161
319
  @blobs ||= check_tree[:blobs]
162
320
  end
163
321
  alias files blobs
164
322
 
323
+ # Returns subtrees directly under this tree
324
+ #
325
+ # @return [Hash<String, Git::Object::Tree>] subtree objects by directory name
326
+ #
165
327
  def trees
166
328
  @trees ||= check_tree[:trees]
167
329
  end
168
330
  alias subtrees trees
169
331
  alias subdirectories trees
170
332
 
333
+ # Returns the full tree listing for this tree
334
+ #
335
+ # @return [Hash] parsed recursive tree data
336
+ #
171
337
  def full_tree
172
338
  object_repository.full_tree(@objectish)
173
339
  end
174
340
 
341
+ # Returns the maximum depth of this tree
342
+ #
343
+ # @return [Integer] maximum tree depth
344
+ #
175
345
  def depth
176
346
  object_repository.tree_depth(@objectish)
177
347
  end
178
348
 
349
+ # Returns whether this object is a tree
350
+ #
351
+ # @return [Boolean] `true`
352
+ #
179
353
  def tree?
180
354
  true
181
355
  end
@@ -203,6 +377,14 @@ module Git
203
377
 
204
378
  # A Git commit object
205
379
  class Commit < AbstractObject
380
+ # Creates a commit object wrapper
381
+ #
382
+ # @param base [Git::Repository] the repository used to query object data
383
+ #
384
+ # @param sha [String] the commit SHA or object expression
385
+ #
386
+ # @param init [Hash, nil] parsed commit data used to initialize eagerly
387
+ #
206
388
  def initialize(base, sha, init = nil)
207
389
  super(base, sha)
208
390
  @tree = nil
@@ -215,20 +397,37 @@ module Git
215
397
  from_data(init)
216
398
  end
217
399
 
400
+ # Returns the commit message
401
+ #
402
+ # @return [String] the commit message without the trailing newline
403
+ #
218
404
  def message
219
405
  check_commit
220
406
  @message
221
407
  end
222
408
 
409
+ # Returns the symbolic name for this commit
410
+ #
411
+ # @return [String] the name produced by `git name-rev`
412
+ #
223
413
  def name
224
414
  object_repository.name_rev(sha)
225
415
  end
226
416
 
417
+ # Returns the tree for this commit
418
+ #
419
+ # @return [Git::Object::Tree] the commit tree
420
+ #
227
421
  def gtree
228
422
  check_commit
229
423
  Tree.new(@base, @tree)
230
424
  end
231
425
 
426
+ # Returns the first parent commit
427
+ #
428
+ # @return [Git::Object::Commit, nil] the first parent commit, or `nil`
429
+ # for a root commit
430
+ #
232
431
  def parent
233
432
  parents.first
234
433
  end
@@ -245,6 +444,10 @@ module Git
245
444
  @author
246
445
  end
247
446
 
447
+ # Returns the author date
448
+ #
449
+ # @return [Time] the author timestamp
450
+ #
248
451
  def author_date
249
452
  author.date
250
453
  end
@@ -255,15 +458,31 @@ module Git
255
458
  @committer
256
459
  end
257
460
 
461
+ # Returns the committer date
462
+ #
463
+ # @return [Time] the committer timestamp
464
+ #
258
465
  def committer_date
259
466
  committer.date
260
467
  end
261
468
  alias date committer_date
262
469
 
470
+ # Returns the diff between this commit and its first parent
471
+ #
472
+ # @return [Git::Diff] the diff from the first parent to this commit
473
+ #
263
474
  def diff_parent
264
475
  diff(parent)
265
476
  end
266
477
 
478
+ # Sets parsed commit data on this commit object
479
+ #
480
+ # @param data [Hash] parsed commit data
481
+ #
482
+ # @return [void]
483
+ #
484
+ # @deprecated use {#from_data} instead
485
+ #
267
486
  def set_commit(data) # rubocop:disable Naming/AccessorMethodName
268
487
  Git::Deprecation.warn(
269
488
  'Git::Object::Commit#set_commit is deprecated and will be removed in a future version. ' \
@@ -272,6 +491,12 @@ module Git
272
491
  from_data(data)
273
492
  end
274
493
 
494
+ # Loads parsed commit data into this commit object
495
+ #
496
+ # @param data [Hash] parsed commit data from `git cat-file commit`
497
+ #
498
+ # @return [void]
499
+ #
275
500
  def from_data(data)
276
501
  @sha ||= data['sha']
277
502
  @committer = Git::Author.new(data['committer'])
@@ -281,6 +506,10 @@ module Git
281
506
  @message = data['message'].chomp
282
507
  end
283
508
 
509
+ # Returns whether this object is a commit
510
+ #
511
+ # @return [Boolean] `true`
512
+ #
284
513
  def commit?
285
514
  true
286
515
  end
@@ -303,9 +532,9 @@ module Git
303
532
  # Annotated tags contain additional metadata such as the tagger's name, email, and
304
533
  # the date when the tag was created, along with a message.
305
534
  #
306
- # TODO: Annotated tags are not objects
307
- #
308
535
  class Tag < AbstractObject
536
+ # @return [String] the tag name
537
+ #
309
538
  attr_accessor :name
310
539
 
311
540
  # @overload initialize(base, name)
@@ -336,19 +565,37 @@ module Git
336
565
  @loaded = false
337
566
  end
338
567
 
568
+ # Returns whether this tag is annotated
569
+ #
570
+ # @return [Boolean] `true` when the tag has an annotated tag object
571
+ #
339
572
  def annotated?
340
573
  @annotated = @annotated.nil? ? (object_repository.cat_file_type(name) == 'tag') : @annotated
341
574
  end
342
575
 
576
+ # Returns the tag message
577
+ #
578
+ # @return [String, nil] the annotated tag message, or `nil` for a
579
+ # lightweight tag
580
+ #
343
581
  def message
344
582
  check_tag
345
583
  @message
346
584
  end
347
585
 
586
+ # Returns whether this object is a tag
587
+ #
588
+ # @return [Boolean] `true`
589
+ #
348
590
  def tag?
349
591
  true
350
592
  end
351
593
 
594
+ # Returns the tagger identity
595
+ #
596
+ # @return [Git::Author, nil] the tagger for an annotated tag, or `nil`
597
+ # for a lightweight tag
598
+ #
352
599
  def tagger
353
600
  check_tag
354
601
  @tagger
@@ -356,6 +603,10 @@ module Git
356
603
 
357
604
  private
358
605
 
606
+ # Loads annotated tag data when available
607
+ #
608
+ # @return [void]
609
+ #
359
610
  def check_tag
360
611
  return if @loaded
361
612
 
@@ -373,6 +624,17 @@ module Git
373
624
 
374
625
  # if we're calling this, we don't know what type it is yet
375
626
  # so this is our little factory method
627
+ #
628
+ # @param base [Git::Repository] the repository used to query object data
629
+ #
630
+ # @param objectish [String] the object name, SHA, ref, or treeish path
631
+ #
632
+ # @param type [String, nil] object type hint: `blob`, `commit`, or `tree`
633
+ #
634
+ # @param is_tag [Boolean] whether to construct a tag object
635
+ #
636
+ # @return [Git::Object::AbstractObject] the concrete object wrapper
637
+ #
376
638
  def self.new(base, objectish, type = nil, is_tag = false) # rubocop:disable Style/OptionalBooleanParameter
377
639
  return new_tag(base, objectish) if is_tag
378
640
 
@@ -387,12 +649,26 @@ module Git
387
649
  klass.new(base, objectish)
388
650
  end
389
651
 
652
+ # Creates a tag object through the deprecated factory path
653
+ #
654
+ # @param base [Git::Repository] the repository used to query object data
655
+ #
656
+ # @param objectish [String] the tag name or SHA
657
+ #
658
+ # @return [Git::Object::Tag] the tag object wrapper
659
+ #
660
+ # @deprecated use `Git::Object::Tag.new` instead
661
+ #
390
662
  private_class_method def self.new_tag(base, objectish)
391
663
  Git::Deprecation.warn('Git::Object.new with is_tag argument is deprecated. Use Git::Object::Tag.new instead.')
392
664
  Git::Object::Tag.new(base, objectish)
393
665
  end
394
666
 
395
- # @return [Git::Repository]
667
+ # Returns the repository used for object lookup
668
+ #
669
+ # @param base [Git::Repository] the repository to return
670
+ #
671
+ # @return [Git::Repository] the repository used for object lookup
396
672
  #
397
673
  private_class_method def self.object_repository_for(base)
398
674
  base
@@ -5,6 +5,10 @@ require 'git/branch_delete_result'
5
5
  require 'git/branch_delete_failure'
6
6
 
7
7
  module Git
8
+ # Internal parsers that translate raw git command output into structured Ruby objects.
9
+ #
10
+ # @api private
11
+ #
8
12
  module Parsers
9
13
  # Parser for git branch command output
10
14
  #
@@ -76,6 +80,7 @@ module Git
76
80
  # Parse a single formatted branch line
77
81
  #
78
82
  # @param line [String] the line to parse (pipe-delimited fields)
83
+ #
79
84
  # @return [Git::BranchInfo, nil] branch info object, or nil if line should be skipped
80
85
  #
81
86
  def parse_branch_line(line)
@@ -89,6 +94,7 @@ module Git
89
94
  # Build a BranchInfo from parsed fields
90
95
  #
91
96
  # @param fields [Array<String>] the parsed fields: [refname, objectname, head, worktreepath, symref, upstream]
97
+ #
92
98
  # @return [Git::BranchInfo] the branch info object
93
99
  #
94
100
  def build_branch_info(fields)
@@ -112,6 +118,7 @@ module Git
112
118
  # - "(not a branch)" for non-branch entries
113
119
  #
114
120
  # @param refname [String] the refname to check
121
+ #
115
122
  # @return [Boolean] true if this is a non-branch entry
116
123
  #
117
124
  def non_branch_entry?(refname)
@@ -125,6 +132,7 @@ module Git
125
132
  # - refs/remotes/origin/main -> remotes/origin/main
126
133
  #
127
134
  # @param refname [String] the full refname from git
135
+ #
128
136
  # @return [String] normalized refname
129
137
  #
130
138
  def normalize_refname(refname)
@@ -137,7 +145,9 @@ module Git
137
145
  # (worktreepath is non-empty AND it's not the current branch)
138
146
  #
139
147
  # @param worktreepath [String, nil] the worktree path from git output
148
+ #
140
149
  # @param current [Boolean] whether this is the current branch
150
+ #
141
151
  # @return [Boolean] true if checked out in another worktree
142
152
  #
143
153
  def in_other_worktree?(worktreepath, current)
@@ -148,6 +158,7 @@ module Git
148
158
  # Build upstream BranchInfo from upstream refname
149
159
  #
150
160
  # @param upstream_ref [String, nil] the upstream ref (e.g., 'refs/remotes/origin/main')
161
+ #
151
162
  # @return [Git::BranchInfo, nil] upstream branch info or nil
152
163
  #
153
164
  def build_upstream_info(upstream_ref)
@@ -166,6 +177,7 @@ module Git
166
177
  # Return value if non-empty, nil otherwise
167
178
  #
168
179
  # @param value [String, nil] the value to check
180
+ #
169
181
  # @return [String, nil] the value or nil
170
182
  #
171
183
  def presence(value)
@@ -179,6 +191,7 @@ module Git
179
191
  # # => ["feature"]
180
192
  #
181
193
  # @param stdout [String] command stdout
194
+ #
182
195
  # @return [Array<String>] names of successfully deleted branches
183
196
  #
184
197
  def parse_deleted_branches(stdout)
@@ -192,6 +205,7 @@ module Git
192
205
  # # => {"missing" => "error: branch 'missing' not found."}
193
206
  #
194
207
  # @param stderr [String] command stderr
208
+ #
195
209
  # @return [Hash<String, String>] map of branch name to error message
196
210
  #
197
211
  def parse_error_messages(stderr)
@@ -204,9 +218,13 @@ module Git
204
218
  # Build the BranchDeleteResult from parsed data
205
219
  #
206
220
  # @param requested_names [Array<String>] originally requested branch names
221
+ #
207
222
  # @param existing_branches [Hash<String, Git::BranchInfo>] branches that existed before delete
223
+ #
208
224
  # @param deleted_names [Array<String>] names confirmed deleted in stdout
225
+ #
209
226
  # @param error_map [Hash<String, String>] map of branch name to error message
227
+ #
210
228
  # @return [Git::BranchDeleteResult] the result object
211
229
  #
212
230
  def build_delete_result(requested_names, existing_branches, deleted_names, error_map)
@@ -86,6 +86,8 @@ module Git
86
86
  #
87
87
  # @param lines [Array<String>] mutable output lines from a cat-file response
88
88
  #
89
+ # @return [void]
90
+ #
89
91
  # @yield [key, value] each parsed header pair
90
92
  #
91
93
  # @yieldparam key [String] header field name
@@ -94,8 +96,6 @@ module Git
94
96
  #
95
97
  # @yieldreturn [void]
96
98
  #
97
- # @return [void]
98
- #
99
99
  # @api private
100
100
  #
101
101
  def each_header(lines)