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
@@ -67,15 +67,34 @@ module Git
67
67
 
68
68
  # Field indices for parsed output
69
69
  module Fields
70
+ # Index of the full object ID (`%H`) field
70
71
  OID = 0
72
+
73
+ # Index of the abbreviated object ID (`%h`) field
71
74
  SHORT_OID = 1
75
+
76
+ # Index of the reflog selector (`%gd`) field
72
77
  REFLOG = 2
78
+
79
+ # Index of the reflog subject (`%gs`) field
73
80
  MESSAGE = 3
81
+
82
+ # Index of the author name (`%an`) field
74
83
  AUTHOR_NAME = 4
84
+
85
+ # Index of the author email (`%ae`) field
75
86
  AUTHOR_EMAIL = 5
87
+
88
+ # Index of the author date (`%aI`) field
76
89
  AUTHOR_DATE = 6
90
+
91
+ # Index of the committer name (`%cn`) field
77
92
  COMMITTER_NAME = 7
93
+
94
+ # Index of the committer email (`%ce`) field
78
95
  COMMITTER_EMAIL = 8
96
+
97
+ # Index of the committer date (`%cI`) field
79
98
  COMMITTER_DATE = 9
80
99
  end
81
100
 
@@ -92,6 +111,7 @@ module Git
92
111
  # # => [#<Git::StashInfo index: 0, ...>]
93
112
  #
94
113
  # @param stdout [String] output from git stash list --format=...
114
+ #
95
115
  # @return [Array<Git::StashInfo>] parsed stash information
96
116
  #
97
117
  # @raise [Git::UnexpectedResultError] if stash output cannot be parsed
@@ -104,7 +124,9 @@ module Git
104
124
  # Parse a single stash list line into a StashInfo object
105
125
  #
106
126
  # @param line [String] a line from git stash list output (custom format)
127
+ #
107
128
  # @param expected_index [Integer] the expected stash index for validation
129
+ #
108
130
  # @param all_lines [Array<String>] all output lines (for error messages)
109
131
  #
110
132
  # @return [Git::StashInfo] parsed stash info
@@ -121,7 +143,9 @@ module Git
121
143
  # Build a StashInfo from parsed format parts
122
144
  #
123
145
  # @param parts [Array<String>] the parsed format fields
146
+ #
124
147
  # @param expected_index [Integer] fallback index if not parseable from reflog
148
+ #
125
149
  # @return [Git::StashInfo]
126
150
  #
127
151
  def build_stash_info(parts, expected_index)
@@ -133,13 +157,23 @@ module Git
133
157
  # Build StashInfo attributes hash from parsed parts
134
158
  #
135
159
  # @param parts [Array<String>] the parsed format fields
160
+ #
136
161
  # @param index [Integer] the resolved stash index
162
+ #
137
163
  # @return [Hash] attributes for StashInfo.new
138
164
  #
139
165
  def stash_info_attrs(parts, index)
140
166
  core_attrs(parts, index).merge(author_attrs(parts)).merge(committer_attrs(parts))
141
167
  end
142
168
 
169
+ # Build core StashInfo attributes from parsed fields
170
+ #
171
+ # @param parts [Array<String>] the parsed format fields
172
+ #
173
+ # @param index [Integer] the resolved stash index
174
+ #
175
+ # @return [Hash<Symbol, Object>] core attributes for StashInfo.new
176
+ #
143
177
  def core_attrs(parts, index)
144
178
  {
145
179
  index: index, name: parts[Fields::REFLOG], oid: parts[Fields::OID],
@@ -148,6 +182,12 @@ module Git
148
182
  }
149
183
  end
150
184
 
185
+ # Build author-related StashInfo attributes from parsed fields
186
+ #
187
+ # @param parts [Array<String>] the parsed format fields
188
+ #
189
+ # @return [Hash<Symbol, String>] author attributes for StashInfo.new
190
+ #
151
191
  def author_attrs(parts)
152
192
  {
153
193
  author_name: parts[Fields::AUTHOR_NAME], author_email: parts[Fields::AUTHOR_EMAIL],
@@ -155,6 +195,12 @@ module Git
155
195
  }
156
196
  end
157
197
 
198
+ # Build committer-related StashInfo attributes from parsed fields
199
+ #
200
+ # @param parts [Array<String>] the parsed format fields
201
+ #
202
+ # @return [Hash<Symbol, String>] committer attributes for StashInfo.new
203
+ #
158
204
  def committer_attrs(parts)
159
205
  {
160
206
  committer_name: parts[Fields::COMMITTER_NAME], committer_email: parts[Fields::COMMITTER_EMAIL],
@@ -165,6 +211,7 @@ module Git
165
211
  # Extract the stash index from a reflog selector
166
212
  #
167
213
  # @param reflog_selector [String] e.g., "stash@\\{0}"
214
+ #
168
215
  # @return [Integer, nil] the index or nil if not found
169
216
  #
170
217
  def extract_index(reflog_selector)
@@ -175,6 +222,7 @@ module Git
175
222
  # Extract the branch name from a stash message
176
223
  #
177
224
  # @param message [String] the stash message
225
+ #
178
226
  # @return [String, nil] the branch name or nil for custom messages
179
227
  #
180
228
  def extract_branch(message)
@@ -185,8 +233,11 @@ module Git
185
233
  # Generate error message for unexpected stash line format
186
234
  #
187
235
  # @param lines [Array<String>] all output lines
236
+ #
188
237
  # @param line [String] the problematic line
238
+ #
189
239
  # @param index [Integer] the stash index
240
+ #
190
241
  # @return [String] formatted error message
191
242
  #
192
243
  def unexpected_stash_line_error(lines, line, index)
@@ -94,6 +94,7 @@ module Git
94
94
  # # => [#<Git::TagInfo name: "v1.0.0", ...>]
95
95
  #
96
96
  # @param stdout [String] output from git tag --list --format=...
97
+ #
97
98
  # @return [Array<Git::TagInfo>] parsed tag information
98
99
  #
99
100
  # @raise [Git::UnexpectedResultError] if any record has unexpected format
@@ -116,8 +117,11 @@ module Git
116
117
  # these are converted to nil by {#parse_optional_field} and {#parse_message}.
117
118
  #
118
119
  # @param record [String] a single tag record from git tag --format output
120
+ #
119
121
  # @param index [Integer] record index for error reporting
122
+ #
120
123
  # @param all_records [Array<String>] all output records for error messages
124
+ #
121
125
  # @return [Git::TagInfo] tag info with all fields populated
122
126
  #
123
127
  # @raise [Git::UnexpectedResultError] if record format is unexpected
@@ -135,6 +139,7 @@ module Git
135
139
  # Build a TagInfo object from parsed parts
136
140
  #
137
141
  # @param parts [Array<String>] the parsed format fields
142
+ #
138
143
  # @return [Git::TagInfo]
139
144
  #
140
145
  # @note For annotated tags:
@@ -150,10 +155,31 @@ module Git
150
155
  build_tag_info_object(parts, oid, target_oid)
151
156
  end
152
157
 
158
+ # Resolves canonical and target object OIDs from git tag format fields
159
+ #
160
+ # @param objecttype [String] the object type from git output
161
+ #
162
+ # @param objectname [String] the object OID from %(objectname)
163
+ #
164
+ # @param dereferenced [String] the object OID from %(*objectname)
165
+ #
166
+ # @return [Array((String, nil), String)] the two-element tuple
167
+ # `[oid, target_oid]`
168
+ #
153
169
  def resolve_oids(objecttype, objectname, dereferenced)
154
170
  objecttype == 'tag' ? [objectname, dereferenced] : [nil, objectname]
155
171
  end
156
172
 
173
+ # Builds a TagInfo object from normalized parser values
174
+ #
175
+ # @param parts [Array<String>] the parsed format fields
176
+ #
177
+ # @param oid [String, nil] the tag object's OID or nil for lightweight tags
178
+ #
179
+ # @param target_oid [String] the target object OID
180
+ #
181
+ # @return [Git::TagInfo] the tag info with all fields populated
182
+ #
157
183
  def build_tag_info_object(parts, oid, target_oid)
158
184
  Git::TagInfo.new(
159
185
  name: parts[0], oid: oid, target_oid: target_oid, objecttype: parts[3],
@@ -165,6 +191,7 @@ module Git
165
191
  # Parse an optional field, returning nil if empty
166
192
  #
167
193
  # @param value [String] the field value
194
+ #
168
195
  # @return [String, nil] the value or nil if empty
169
196
  #
170
197
  def parse_optional_field(value)
@@ -175,7 +202,9 @@ module Git
175
202
  # Strips trailing newlines that git adds to %(contents) output
176
203
  #
177
204
  # @param objecttype [String] the object type ('tag' or 'commit')
205
+ #
178
206
  # @param message [String] the raw message field
207
+ #
179
208
  # @return [String, nil] the message or nil
180
209
  #
181
210
  def parse_message(objecttype, message)
@@ -190,6 +219,7 @@ module Git
190
219
  # # => ["v1.0.0"]
191
220
  #
192
221
  # @param stdout [String] command stdout
222
+ #
193
223
  # @return [Array<String>] names of successfully deleted tags
194
224
  #
195
225
  def parse_deleted_tags(stdout)
@@ -203,6 +233,7 @@ module Git
203
233
  # # => {"missing" => "error: tag 'missing' not found."}
204
234
  #
205
235
  # @param stderr [String] command stderr
236
+ #
206
237
  # @return [Hash<String, String>] map of tag name to error message
207
238
  #
208
239
  def parse_error_messages(stderr)
@@ -215,9 +246,13 @@ module Git
215
246
  # Build the TagDeleteResult from parsed data
216
247
  #
217
248
  # @param requested_names [Array<String>] originally requested tag names
249
+ #
218
250
  # @param existing_tags [Hash<String, Git::TagInfo>] tags that existed before delete
251
+ #
219
252
  # @param deleted_names [Array<String>] names confirmed deleted in stdout
253
+ #
220
254
  # @param error_map [Hash<String, String>] map of tag name to error message
255
+ #
221
256
  # @return [Git::TagDeleteResult] the result object
222
257
  #
223
258
  def build_delete_result(requested_names, existing_tags, deleted_names, error_map)
@@ -234,8 +269,11 @@ module Git
234
269
  # Generate error message for unexpected tag record format
235
270
  #
236
271
  # @param records [Array<String>] all output records
272
+ #
237
273
  # @param record [String] the problematic record
274
+ #
238
275
  # @param index [Integer] the record index
276
+ #
239
277
  # @return [String] formatted error message
240
278
  #
241
279
  def unexpected_tag_record_error(records, record, index)
data/lib/git/remote.rb CHANGED
@@ -59,7 +59,31 @@ module Git
59
59
  # @example Fetch from origin
60
60
  # git.remote('origin').fetch
61
61
  #
62
- # @param opts [Hash] fetch options (see `Git::Repository#fetch`)
62
+ # @param opts [Hash] options for the fetch command
63
+ #
64
+ # @option opts [Boolean, nil] :tags (nil) fetch all tags from the remote
65
+ # (`--tags`)
66
+ #
67
+ # @option opts [Boolean, nil] :prune (nil) remove remote-tracking references
68
+ # that no longer exist on the remote (`--prune`)
69
+ #
70
+ # @option opts [Boolean, nil] :prune_tags (nil) remove local tags that no
71
+ # longer exist on the remote (`--prune-tags`)
72
+ #
73
+ # @option opts [Boolean, nil] :force (nil) override the fast-forward check
74
+ # when using explicit refspecs (`--force`)
75
+ #
76
+ # @option opts [Boolean, nil] :update_head_ok (nil) allow `git fetch` to
77
+ # update the branch pointed to by `HEAD` (`--update-head-ok`)
78
+ #
79
+ # @option opts [Boolean, nil] :unshallow (nil) convert a shallow clone into a
80
+ # full repository (`--unshallow`)
81
+ #
82
+ # @option opts [String, Integer, nil] :depth (nil) limit history to N commits
83
+ # from each branch tip (`--depth=N`)
84
+ #
85
+ # @option opts [String, Array<String>, nil] :ref (nil) one or more refspecs to
86
+ # fetch as positional arguments after the remote name
63
87
  #
64
88
  # @return [String] git's stdout from the fetch
65
89
  #
@@ -107,7 +131,7 @@ module Git
107
131
  # @example Remove the upstream remote
108
132
  # git.remote('upstream').remove
109
133
  #
110
- # @return [Git::CommandLineResult] the result of `git remote remove`
134
+ # @return [Git::CommandLine::Result] the result of `git remote remove`
111
135
  #
112
136
  # @raise [Git::FailedError] if git exits with a non-zero exit status
113
137
  #
@@ -136,6 +160,14 @@ module Git
136
160
  @base
137
161
  end
138
162
 
163
+ # Builds branch metadata for a remote-tracking branch
164
+ #
165
+ # @param refname [String] remote-tracking branch name (for example,
166
+ # `'origin/main'`)
167
+ #
168
+ # @return [Git::BranchInfo] minimal branch metadata for constructing
169
+ # {Git::Branch}
170
+ #
139
171
  def build_branch_info(refname)
140
172
  Git::BranchInfo.new(
141
173
  refname: refname,
@@ -24,11 +24,13 @@ module Git
24
24
  #
25
25
  # Included by {Git::Repository}.
26
26
  #
27
- # @api public
27
+ # @api private
28
28
  #
29
29
  module Branching # rubocop:disable Metrics/ModuleLength
30
30
  # Represents the state of HEAD in a repository
31
31
  #
32
+ # @api private
33
+ #
32
34
  # @!attribute [r] state
33
35
  # @return [Symbol] one of `:active`, `:unborn`, or `:detached`
34
36
  #
@@ -343,7 +345,7 @@ module Git
343
345
  # @param start_point [String, nil] the commit, branch, or tag to start the
344
346
  # new branch from; defaults to the current HEAD when `nil`
345
347
  #
346
- # @param options [Hash] reserved; must be empty — no options are currently
348
+ # @param branch_options [Hash] reserved; must be empty — no options are currently
347
349
  # supported
348
350
  #
349
351
  # @return [void]
@@ -352,14 +354,14 @@ module Git
352
354
  #
353
355
  # @raise [Git::FailedError] if git exits with a non-zero exit status
354
356
  #
355
- def branch_new(branch, start_point = nil, options = {})
356
- if start_point.is_a?(Hash) && options.empty?
357
- options = start_point
357
+ def branch_new(branch, start_point = nil, branch_options = {})
358
+ if start_point.is_a?(Hash) && branch_options.empty?
359
+ branch_options = start_point
358
360
  start_point = nil
359
361
  end
360
362
 
361
- SharedPrivate.assert_valid_opts!(BRANCH_NEW_ALLOWED_OPTS, **options)
362
- Git::Commands::Branch::Create.new(@execution_context).call(branch, start_point, **options)
363
+ SharedPrivate.assert_valid_opts!(BRANCH_NEW_ALLOWED_OPTS, **branch_options)
364
+ Git::Commands::Branch::Create.new(@execution_context).call(branch, start_point, **branch_options)
363
365
 
364
366
  nil
365
367
  end
@@ -432,6 +434,12 @@ module Git
432
434
  # repo.change_head_branch('my-branch')
433
435
  # # HEAD now points at refs/heads/my-branch before any commits exist
434
436
  #
437
+ # @param branch_name [String] the branch name to point HEAD at
438
+ #
439
+ # @return [void]
440
+ #
441
+ # @raise [Git::FailedError] if git exits with a non-zero exit status
442
+ #
435
443
  # @note Pointing HEAD at a branch that does not yet exist places the
436
444
  # repository in unborn-branch state. This is intentional for repository
437
445
  # initialization workflows — for example, setting a custom default branch
@@ -439,12 +447,6 @@ module Git
439
447
  # The repository will appear to have no commits until the first commit is
440
448
  # made on the new branch.
441
449
  #
442
- # @param branch_name [String] the branch name to point HEAD at
443
- #
444
- # @return [void]
445
- #
446
- # @raise [Git::FailedError] if git exits with a non-zero exit status
447
- #
448
450
  def change_head_branch(branch_name)
449
451
  Git::Commands::SymbolicRef::Update.new(@execution_context).call('HEAD', "refs/heads/#{branch_name}")
450
452
  nil
@@ -547,7 +549,7 @@ module Git
547
549
  #
548
550
  # @param commit [String] the commit SHA to point the branch at
549
551
  #
550
- # @return [Git::CommandLineResult] the result of calling `git update-ref`
552
+ # @return [Git::CommandLine::Result] the result of calling `git update-ref`
551
553
  #
552
554
  # @raise [Git::FailedError] if git exits with a non-zero exit status
553
555
  #
@@ -652,7 +654,7 @@ module Git
652
654
  #
653
655
  # @param branch [String, nil] the branch argument passed to {#checkout}
654
656
  #
655
- # @param options [Hash] the raw options passed to {#checkout}
657
+ # @param checkout_options [Hash] the raw options passed to {#checkout}
656
658
  #
657
659
  # @return [Array] a two-element tuple `[target, options]` containing the
658
660
  # translated checkout arguments
@@ -663,13 +665,13 @@ module Git
663
665
  #
664
666
  # @api private
665
667
  #
666
- def translate_checkout_opts(branch, options)
667
- if options[:new_branch] == true || options[:b] == true
668
- [options[:start_point], options.except(:new_branch, :b, :start_point).merge(b: branch)]
669
- elsif options[:new_branch].is_a?(String)
670
- [branch, options.except(:new_branch).merge(b: options[:new_branch])]
668
+ def translate_checkout_opts(branch, checkout_options)
669
+ if checkout_options[:new_branch] == true || checkout_options[:b] == true
670
+ [checkout_options[:start_point], checkout_options.except(:new_branch, :b, :start_point).merge(b: branch)]
671
+ elsif checkout_options[:new_branch].is_a?(String)
672
+ [branch, checkout_options.except(:new_branch).merge(b: checkout_options[:new_branch])]
671
673
  else
672
- [branch, options]
674
+ [branch, checkout_options]
673
675
  end
674
676
  end
675
677
 
@@ -12,7 +12,7 @@ module Git
12
12
  #
13
13
  # Included by {Git::Repository}.
14
14
  #
15
- # @api public
15
+ # @api private
16
16
  #
17
17
  module Committing
18
18
  # Option keys accepted by {#commit}
@@ -59,7 +59,7 @@ module Git
59
59
  #
60
60
  # @option opts [String] :date (nil) override the author date
61
61
  #
62
- # @option opts [Boolean, nil] :gpg_sign (nil) GPG-sign the commit
62
+ # @option opts [Boolean, String, nil] :gpg_sign (nil) GPG-sign the commit
63
63
  #
64
64
  # @option opts [Boolean, nil] :no_gpg_sign (nil) disable GPG signing
65
65
  #
@@ -94,10 +94,35 @@ module Git
94
94
  # @example Commit all changes with a message
95
95
  # repo.commit_all('Update everything')
96
96
  #
97
- # @param message [String] the commit message
97
+ # @param message [String, nil] the commit message; pass `nil` to omit
98
+ # (e.g. when using `:amend` to reuse the previous message)
98
99
  #
99
100
  # @param opts [Hash] additional options forwarded to {#commit}
100
101
  #
102
+ # @option opts [Boolean, nil] :all (nil) ignored because this method
103
+ # always commits with `all: true`
104
+ #
105
+ # @option opts [Boolean, nil] :amend (nil) replace the tip of the current
106
+ # branch with a new commit
107
+ #
108
+ # @option opts [Boolean, nil] :allow_empty (nil) allow committing with no
109
+ # changes
110
+ #
111
+ # @option opts [Boolean, nil] :allow_empty_message (nil) allow committing
112
+ # with an empty message
113
+ #
114
+ # @option opts [String] :author (nil) override the commit author in
115
+ # `A U Thor <author@example.com>` format
116
+ #
117
+ # @option opts [String] :date (nil) override the author date
118
+ #
119
+ # @option opts [Boolean, String, nil] :gpg_sign (nil) GPG-sign the commit
120
+ #
121
+ # @option opts [Boolean, nil] :no_gpg_sign (nil) disable GPG signing
122
+ #
123
+ # @option opts [Boolean, nil] :no_verify (nil) bypass the pre-commit and
124
+ # commit-msg hooks
125
+ #
101
126
  # @return [String] git's stdout from the commit
102
127
  #
103
128
  # @raise [ArgumentError] when unsupported options are provided
@@ -120,10 +145,11 @@ module Git
120
145
  #
121
146
  # @param opts [Hash] options for the commit-tree command
122
147
  #
123
- # @option opts [String] :m (nil) the commit message (short form)
148
+ # @option opts [String, Array<String>] :m (nil) the commit message
149
+ # paragraph(s) (short form)
124
150
  #
125
- # @option opts [String] :message (nil) the commit message (normalized
126
- # to `:m` before passing to the command)
151
+ # @option opts [String, Array<String>] :message (nil) the commit message
152
+ # paragraph(s) (normalized to `:m` before passing to the command)
127
153
  #
128
154
  # @option opts [String, Array<String>] :p (nil) parent commit SHA(s)
129
155
  #
@@ -173,6 +199,20 @@ module Git
173
199
  #
174
200
  # @param opts [Hash] options forwarded to {#commit_tree}
175
201
  #
202
+ # @option opts [String, Array<String>] :m (nil) the commit message
203
+ # paragraph(s) (short form)
204
+ #
205
+ # @option opts [String, Array<String>] :message (nil) the commit message
206
+ # paragraph(s) (normalized to `:m` before passing to the command)
207
+ #
208
+ # @option opts [String, Array<String>] :p (nil) parent commit SHA(s)
209
+ #
210
+ # @option opts [String] :parent (nil) a single parent commit SHA
211
+ # (normalized to `:p`)
212
+ #
213
+ # @option opts [Array<String>] :parents (nil) multiple parent commit
214
+ # SHAs (normalized to `:p`)
215
+ #
176
216
  # @return [String] the SHA of the newly created commit object
177
217
  #
178
218
  # @raise [ArgumentError] when unsupported options are provided
@@ -15,7 +15,7 @@ module Git
15
15
  #
16
16
  # Included by {Git::Repository}.
17
17
  #
18
- # @api public
18
+ # @api private
19
19
  #
20
20
  module ContextHelpers
21
21
  # Changes the current working directory to the repository working directory
@@ -27,17 +27,17 @@ module Git
27
27
  # repo.add('hello.txt')
28
28
  # end
29
29
  #
30
+ # @return [Object] the value returned by the block
31
+ #
32
+ # @raise [ArgumentError] if the repository has no working directory (bare
33
+ # repository)
34
+ #
30
35
  # @yield [dir] the repository working directory
31
36
  #
32
37
  # @yieldparam dir [Pathname] the working directory path
33
38
  #
34
39
  # @yieldreturn [Object] returned as the method's return value
35
40
  #
36
- # @return [Object] the value returned by the block
37
- #
38
- # @raise [ArgumentError] if the repository has no working directory (bare
39
- # repository)
40
- #
41
41
  def chdir
42
42
  raise ArgumentError, 'cannot chdir: repository has no working directory (bare repository)' if dir.nil?
43
43
 
@@ -58,14 +58,14 @@ module Git
58
58
  #
59
59
  # @param new_index [String, Pathname] path to the replacement index file
60
60
  #
61
+ # @return [Object] the value returned by the block
62
+ #
61
63
  # @yield [repo] the repository instance with the new index active
62
64
  #
63
65
  # @yieldparam repo [Git::Repository] `self`
64
66
  #
65
67
  # @yieldreturn [Object] returned as the method's return value
66
68
  #
67
- # @return [Object] the value returned by the block
68
- #
69
69
  def with_index(new_index) # :yields: self
70
70
  old_context = @execution_context
71
71
  set_index(new_index, must_exist: false)
@@ -90,14 +90,14 @@ module Git
90
90
  # repo.write_tree
91
91
  # end
92
92
  #
93
+ # @return [Object] the value returned by the block
94
+ #
93
95
  # @yield [repo] the repository instance with the temporary index active
94
96
  #
95
97
  # @yieldparam repo [Git::Repository] `self`
96
98
  #
97
99
  # @yieldreturn [Object] returned as the method's return value
98
100
  #
99
- # @return [Object] the value returned by the block
100
- #
101
101
  def with_temp_index(&) # :yields: self
102
102
  # Use a unique temp directory so the index file path is collision-free
103
103
  # and does not exist until git writes it. An existing empty file would
@@ -127,6 +127,10 @@ module Git
127
127
  # @param work_dir [String, Pathname] path to the replacement working
128
128
  # directory
129
129
  #
130
+ # @return [Object] the value returned by the block
131
+ #
132
+ # @raise [ArgumentError] if `work_dir` does not exist on disk
133
+ #
130
134
  # @yield [repo] the repository instance with the new working directory
131
135
  # active
132
136
  #
@@ -134,10 +138,6 @@ module Git
134
138
  #
135
139
  # @yieldreturn [Object] returned as the method's return value
136
140
  #
137
- # @return [Object] the value returned by the block
138
- #
139
- # @raise [ArgumentError] if `work_dir` does not exist on disk
140
- #
141
141
  def with_working(work_dir) # :yields: self
142
142
  old_context = @execution_context
143
143
  set_working(work_dir)
@@ -158,6 +158,8 @@ module Git
158
158
  # File.write('scratch.txt', 'temporary content')
159
159
  # end
160
160
  #
161
+ # @return [Object] the value returned by the block
162
+ #
161
163
  # @yield [repo] the repository instance with the temporary working
162
164
  # directory active
163
165
  #
@@ -165,8 +167,6 @@ module Git
165
167
  #
166
168
  # @yieldreturn [Object] returned as the method's return value
167
169
  #
168
- # @return [Object] the value returned by the block
169
- #
170
170
  def with_temp_working(&block) # :yields: self
171
171
  Dir.mktmpdir('temp-workdir') { |temp_dir| with_working(temp_dir, &block) }
172
172
  end
@@ -231,6 +231,14 @@ module Git
231
231
 
232
232
  private
233
233
 
234
+ # Resolves deprecated `check` argument semantics with `must_exist:`
235
+ #
236
+ # @param check [Boolean, nil] deprecated positional existence-check value
237
+ #
238
+ # @param must_exist [Boolean, nil] keyword existence-check override
239
+ #
240
+ # @return [Boolean] whether path existence must be enforced
241
+ #
234
242
  def context_helpers_deprecate_check_argument(check, must_exist)
235
243
  if !check.nil? && defined?(Git::Deprecation)
236
244
  Git::Deprecation.warn(
@@ -250,12 +258,33 @@ module Git
250
258
  must_exist | check
251
259
  end
252
260
 
261
+ # Expands `path` and validates existence when required
262
+ #
263
+ # @param path [String, Pathname] path to normalize and validate
264
+ #
265
+ # @param must_exist [Boolean] whether the expanded path must already exist
266
+ #
267
+ # @return [Pathname] the expanded absolute path
268
+ #
269
+ # @raise [ArgumentError] if `must_exist` is `true` and the path does not exist
270
+ #
253
271
  def context_helpers_validate_path(path, must_exist)
254
272
  Pathname.new(File.expand_path(path.to_s)).tap do |expanded_path|
255
273
  raise ArgumentError, "path does not exist: #{expanded_path}" if must_exist && !expanded_path.exist?
256
274
  end
257
275
  end
258
276
 
277
+ # Rebuilds the repository execution context with selected overrides
278
+ #
279
+ # @param overrides [Hash] execution-context attributes to override
280
+ #
281
+ # @option overrides [String, nil] :git_index_file replacement index file path
282
+ #
283
+ # @option overrides [String, nil] :git_work_dir replacement working directory
284
+ # path
285
+ #
286
+ # @return [void]
287
+ #
259
288
  def context_helpers_rebuild_context(**overrides)
260
289
  @execution_context = @execution_context.dup_with(**overrides)
261
290
  end