git 4.3.2 → 5.0.0.beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. checksums.yaml +4 -4
  2. data/.github/copilot-instructions.md +73 -2705
  3. data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +188 -0
  4. data/.github/pull_request_template.md +3 -1
  5. data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
  6. data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
  7. data/.github/skills/command-implementation/REFERENCE.md +993 -0
  8. data/.github/skills/command-implementation/SKILL.md +229 -0
  9. data/.github/skills/command-test-conventions/SKILL.md +660 -0
  10. data/.github/skills/command-yard-documentation/SKILL.md +426 -0
  11. data/.github/skills/dependency-management/SKILL.md +72 -0
  12. data/.github/skills/development-workflow/SKILL.md +506 -0
  13. data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
  14. data/.github/skills/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +22 -0
  15. data/.github/skills/extract-facade-from-base-lib/SKILL.md +600 -0
  16. data/.github/skills/facade-implementation/REFERENCE.md +840 -0
  17. data/.github/skills/facade-implementation/SKILL.md +274 -0
  18. data/.github/skills/facade-test-conventions/SKILL.md +394 -0
  19. data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
  20. data/.github/skills/make-skill-template/SKILL.md +176 -0
  21. data/.github/skills/pr-readiness-review/SKILL.md +185 -0
  22. data/.github/skills/project-context/SKILL.md +313 -0
  23. data/.github/skills/pull-request-review/SKILL.md +168 -0
  24. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
  25. data/.github/skills/release-management/SKILL.md +125 -0
  26. data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
  27. data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
  28. data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
  29. data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
  30. data/.github/skills/reviewing-skills/SKILL.md +189 -0
  31. data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
  32. data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
  33. data/.github/skills/test-debugging/SKILL.md +160 -0
  34. data/.github/skills/yard-documentation/SKILL.md +793 -0
  35. data/.github/workflows/continuous_integration.yml +3 -2
  36. data/.github/workflows/enforce_conventional_commits.yml +1 -1
  37. data/.github/workflows/experimental_continuous_integration.yml +2 -2
  38. data/.github/workflows/release.yml +3 -4
  39. data/.gitignore +8 -0
  40. data/.husky/pre-commit +13 -0
  41. data/.release-please-manifest.json +1 -1
  42. data/.rspec +3 -0
  43. data/.rubocop.yml +12 -3
  44. data/.rubocop_todo.yml +23 -5
  45. data/.yardopts +1 -0
  46. data/CHANGELOG.md +0 -40
  47. data/CONTRIBUTING.md +694 -53
  48. data/README.md +67 -15
  49. data/Rakefile +61 -9
  50. data/UPGRADING.md +141 -0
  51. data/commitlint.test +4 -0
  52. data/git.gemspec +18 -7
  53. data/lib/git/args_builder.rb +0 -8
  54. data/lib/git/branch.rb +369 -43
  55. data/lib/git/branch_delete_failure.rb +31 -0
  56. data/lib/git/branch_delete_result.rb +63 -0
  57. data/lib/git/branch_info.rb +178 -0
  58. data/lib/git/branches.rb +122 -24
  59. data/lib/git/command_line/base.rb +255 -0
  60. data/lib/git/command_line/capturing.rb +251 -0
  61. data/lib/git/command_line/result.rb +96 -0
  62. data/lib/git/command_line/streaming.rb +196 -0
  63. data/lib/git/command_line.rb +43 -322
  64. data/lib/git/command_line_result.rb +4 -88
  65. data/lib/git/commands/add.rb +131 -0
  66. data/lib/git/commands/am/abort.rb +43 -0
  67. data/lib/git/commands/am/apply.rb +252 -0
  68. data/lib/git/commands/am/continue.rb +43 -0
  69. data/lib/git/commands/am/quit.rb +43 -0
  70. data/lib/git/commands/am/retry.rb +47 -0
  71. data/lib/git/commands/am/show_current_patch.rb +64 -0
  72. data/lib/git/commands/am/skip.rb +42 -0
  73. data/lib/git/commands/am.rb +33 -0
  74. data/lib/git/commands/apply.rb +237 -0
  75. data/lib/git/commands/archive/list_formats.rb +46 -0
  76. data/lib/git/commands/archive.rb +140 -0
  77. data/lib/git/commands/arguments.rb +3510 -0
  78. data/lib/git/commands/base.rb +404 -0
  79. data/lib/git/commands/branch/copy.rb +94 -0
  80. data/lib/git/commands/branch/create.rb +173 -0
  81. data/lib/git/commands/branch/delete.rb +80 -0
  82. data/lib/git/commands/branch/list.rb +162 -0
  83. data/lib/git/commands/branch/move.rb +94 -0
  84. data/lib/git/commands/branch/set_upstream.rb +86 -0
  85. data/lib/git/commands/branch/show_current.rb +49 -0
  86. data/lib/git/commands/branch/unset_upstream.rb +57 -0
  87. data/lib/git/commands/branch.rb +34 -0
  88. data/lib/git/commands/cat_file/batch.rb +369 -0
  89. data/lib/git/commands/cat_file/filtered.rb +105 -0
  90. data/lib/git/commands/cat_file/raw.rb +216 -0
  91. data/lib/git/commands/cat_file.rb +49 -0
  92. data/lib/git/commands/checkout/branch.rb +151 -0
  93. data/lib/git/commands/checkout/files.rb +115 -0
  94. data/lib/git/commands/checkout.rb +38 -0
  95. data/lib/git/commands/checkout_index.rb +105 -0
  96. data/lib/git/commands/clean.rb +100 -0
  97. data/lib/git/commands/clone.rb +240 -0
  98. data/lib/git/commands/commit.rb +272 -0
  99. data/lib/git/commands/commit_tree.rb +100 -0
  100. data/lib/git/commands/config_option_syntax/add.rb +83 -0
  101. data/lib/git/commands/config_option_syntax/get.rb +117 -0
  102. data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
  103. data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
  104. data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
  105. data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
  106. data/lib/git/commands/config_option_syntax/get_urlmatch.rb +107 -0
  107. data/lib/git/commands/config_option_syntax/list.rb +107 -0
  108. data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
  109. data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
  110. data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
  111. data/lib/git/commands/config_option_syntax/set.rb +114 -0
  112. data/lib/git/commands/config_option_syntax/unset.rb +89 -0
  113. data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
  114. data/lib/git/commands/config_option_syntax.rb +56 -0
  115. data/lib/git/commands/describe.rb +155 -0
  116. data/lib/git/commands/diff.rb +656 -0
  117. data/lib/git/commands/diff_files.rb +518 -0
  118. data/lib/git/commands/diff_index.rb +496 -0
  119. data/lib/git/commands/fetch.rb +352 -0
  120. data/lib/git/commands/fsck.rb +136 -0
  121. data/lib/git/commands/gc.rb +132 -0
  122. data/lib/git/commands/grep.rb +338 -0
  123. data/lib/git/commands/init.rb +99 -0
  124. data/lib/git/commands/log.rb +632 -0
  125. data/lib/git/commands/ls_files.rb +191 -0
  126. data/lib/git/commands/ls_remote.rb +155 -0
  127. data/lib/git/commands/ls_tree.rb +131 -0
  128. data/lib/git/commands/maintenance/register.rb +75 -0
  129. data/lib/git/commands/maintenance/run.rb +104 -0
  130. data/lib/git/commands/maintenance/start.rb +66 -0
  131. data/lib/git/commands/maintenance/stop.rb +55 -0
  132. data/lib/git/commands/maintenance/unregister.rb +79 -0
  133. data/lib/git/commands/maintenance.rb +31 -0
  134. data/lib/git/commands/merge/abort.rb +44 -0
  135. data/lib/git/commands/merge/continue.rb +44 -0
  136. data/lib/git/commands/merge/quit.rb +46 -0
  137. data/lib/git/commands/merge/start.rb +245 -0
  138. data/lib/git/commands/merge.rb +28 -0
  139. data/lib/git/commands/merge_base.rb +86 -0
  140. data/lib/git/commands/mv.rb +77 -0
  141. data/lib/git/commands/name_rev.rb +114 -0
  142. data/lib/git/commands/pull.rb +377 -0
  143. data/lib/git/commands/push.rb +246 -0
  144. data/lib/git/commands/read_tree.rb +149 -0
  145. data/lib/git/commands/remote/add.rb +91 -0
  146. data/lib/git/commands/remote/get_url.rb +66 -0
  147. data/lib/git/commands/remote/list.rb +54 -0
  148. data/lib/git/commands/remote/prune.rb +61 -0
  149. data/lib/git/commands/remote/remove.rb +52 -0
  150. data/lib/git/commands/remote/rename.rb +69 -0
  151. data/lib/git/commands/remote/set_branches.rb +63 -0
  152. data/lib/git/commands/remote/set_head.rb +82 -0
  153. data/lib/git/commands/remote/set_url.rb +71 -0
  154. data/lib/git/commands/remote/set_url_add.rb +61 -0
  155. data/lib/git/commands/remote/set_url_delete.rb +64 -0
  156. data/lib/git/commands/remote/show.rb +71 -0
  157. data/lib/git/commands/remote/update.rb +72 -0
  158. data/lib/git/commands/remote.rb +42 -0
  159. data/lib/git/commands/repack.rb +277 -0
  160. data/lib/git/commands/reset.rb +147 -0
  161. data/lib/git/commands/rev_parse.rb +297 -0
  162. data/lib/git/commands/revert/abort.rb +45 -0
  163. data/lib/git/commands/revert/continue.rb +57 -0
  164. data/lib/git/commands/revert/quit.rb +47 -0
  165. data/lib/git/commands/revert/skip.rb +44 -0
  166. data/lib/git/commands/revert/start.rb +153 -0
  167. data/lib/git/commands/revert.rb +29 -0
  168. data/lib/git/commands/rm.rb +114 -0
  169. data/lib/git/commands/show.rb +632 -0
  170. data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
  171. data/lib/git/commands/show_ref/exists.rb +78 -0
  172. data/lib/git/commands/show_ref/list.rb +145 -0
  173. data/lib/git/commands/show_ref/verify.rb +120 -0
  174. data/lib/git/commands/show_ref.rb +42 -0
  175. data/lib/git/commands/stash/apply.rb +75 -0
  176. data/lib/git/commands/stash/branch.rb +65 -0
  177. data/lib/git/commands/stash/clear.rb +41 -0
  178. data/lib/git/commands/stash/create.rb +58 -0
  179. data/lib/git/commands/stash/drop.rb +67 -0
  180. data/lib/git/commands/stash/list.rb +39 -0
  181. data/lib/git/commands/stash/pop.rb +78 -0
  182. data/lib/git/commands/stash/push.rb +103 -0
  183. data/lib/git/commands/stash/show.rb +149 -0
  184. data/lib/git/commands/stash/store.rb +63 -0
  185. data/lib/git/commands/stash.rb +38 -0
  186. data/lib/git/commands/status.rb +169 -0
  187. data/lib/git/commands/symbolic_ref/delete.rb +68 -0
  188. data/lib/git/commands/symbolic_ref/read.rb +95 -0
  189. data/lib/git/commands/symbolic_ref/update.rb +76 -0
  190. data/lib/git/commands/symbolic_ref.rb +38 -0
  191. data/lib/git/commands/tag/create.rb +139 -0
  192. data/lib/git/commands/tag/delete.rb +55 -0
  193. data/lib/git/commands/tag/list.rb +143 -0
  194. data/lib/git/commands/tag/verify.rb +71 -0
  195. data/lib/git/commands/tag.rb +26 -0
  196. data/lib/git/commands/update_ref/batch.rb +140 -0
  197. data/lib/git/commands/update_ref/delete.rb +92 -0
  198. data/lib/git/commands/update_ref/update.rb +106 -0
  199. data/lib/git/commands/update_ref.rb +42 -0
  200. data/lib/git/commands/version.rb +57 -0
  201. data/lib/git/commands/worktree/add.rb +140 -0
  202. data/lib/git/commands/worktree/list.rb +64 -0
  203. data/lib/git/commands/worktree/lock.rb +58 -0
  204. data/lib/git/commands/worktree/management_base.rb +51 -0
  205. data/lib/git/commands/worktree/move.rb +66 -0
  206. data/lib/git/commands/worktree/prune.rb +67 -0
  207. data/lib/git/commands/worktree/remove.rb +63 -0
  208. data/lib/git/commands/worktree/repair.rb +76 -0
  209. data/lib/git/commands/worktree/unlock.rb +47 -0
  210. data/lib/git/commands/worktree.rb +43 -0
  211. data/lib/git/commands/write_tree.rb +68 -0
  212. data/lib/git/commands.rb +87 -0
  213. data/lib/git/config.rb +17 -0
  214. data/lib/git/config_entry_info.rb +106 -0
  215. data/lib/git/configuring.rb +665 -0
  216. data/lib/git/deprecation.rb +9 -0
  217. data/lib/git/detached_head_info.rb +54 -0
  218. data/lib/git/diff.rb +293 -7
  219. data/lib/git/diff_file_numstat_info.rb +29 -0
  220. data/lib/git/diff_file_patch_info.rb +134 -0
  221. data/lib/git/diff_file_raw_info.rb +127 -0
  222. data/lib/git/diff_info.rb +169 -0
  223. data/lib/git/diff_path_status.rb +67 -19
  224. data/lib/git/diff_result.rb +32 -0
  225. data/lib/git/diff_stats.rb +51 -14
  226. data/lib/git/dirstat_info.rb +86 -0
  227. data/lib/git/errors.rb +65 -2
  228. data/lib/git/execution_context/global.rb +31 -0
  229. data/lib/git/execution_context/repository.rb +136 -0
  230. data/lib/git/execution_context.rb +501 -0
  231. data/lib/git/file_ref.rb +74 -0
  232. data/lib/git/fsck_object.rb +9 -9
  233. data/lib/git/fsck_result.rb +1 -1
  234. data/lib/git/log.rb +9 -2
  235. data/lib/git/object.rb +90 -27
  236. data/lib/git/parsers/branch.rb +224 -0
  237. data/lib/git/parsers/cat_file.rb +111 -0
  238. data/lib/git/parsers/config_entry.rb +110 -0
  239. data/lib/git/parsers/diff.rb +585 -0
  240. data/lib/git/parsers/fsck.rb +133 -0
  241. data/lib/git/parsers/grep.rb +42 -0
  242. data/lib/git/parsers/ls_remote.rb +79 -0
  243. data/lib/git/parsers/ls_tree.rb +58 -0
  244. data/lib/git/parsers/stash.rb +208 -0
  245. data/lib/git/parsers/tag.rb +257 -0
  246. data/lib/git/remote.rb +120 -9
  247. data/lib/git/repository/branching.rb +743 -0
  248. data/lib/git/repository/committing.rb +187 -0
  249. data/lib/git/repository/configuring.rb +351 -0
  250. data/lib/git/repository/context_helpers.rb +264 -0
  251. data/lib/git/repository/diffing.rb +775 -0
  252. data/lib/git/repository/factories.rb +682 -0
  253. data/lib/git/repository/inspecting.rb +252 -0
  254. data/lib/git/repository/logging.rb +247 -0
  255. data/lib/git/repository/maintenance.rb +65 -0
  256. data/lib/git/repository/merging.rb +357 -0
  257. data/lib/git/repository/object_operations.rb +1199 -0
  258. data/lib/git/repository/path_resolver.rb +207 -0
  259. data/lib/git/repository/remote_operations.rb +898 -0
  260. data/lib/git/repository/shared_private.rb +51 -0
  261. data/lib/git/repository/staging.rb +554 -0
  262. data/lib/git/repository/stashing.rb +143 -0
  263. data/lib/git/repository/status_operations.rb +201 -0
  264. data/lib/git/repository/worktree_operations.rb +159 -0
  265. data/lib/git/repository.rb +203 -1
  266. data/lib/git/stash.rb +78 -4
  267. data/lib/git/stash_info.rb +104 -0
  268. data/lib/git/stashes.rb +125 -13
  269. data/lib/git/status.rb +215 -18
  270. data/lib/git/tag_delete_failure.rb +31 -0
  271. data/lib/git/tag_delete_result.rb +63 -0
  272. data/lib/git/tag_info.rb +105 -0
  273. data/lib/git/version.rb +109 -2
  274. data/lib/git/version_constraint.rb +81 -0
  275. data/lib/git/worktree.rb +108 -6
  276. data/lib/git/worktrees.rb +94 -7
  277. data/lib/git.rb +260 -61
  278. data/redesign/1_architecture_existing.md +54 -18
  279. data/redesign/2_architecture_redesign.md +365 -46
  280. data/redesign/3_architecture_implementation.md +1497 -63
  281. data/redesign/Phase 4 - Step A.md +360 -0
  282. data/redesign/beta_release.md +107 -0
  283. data/redesign/c1c2_audit.md +566 -0
  284. data/redesign/c1c2_bucket6_lib_orphans.md +626 -0
  285. data/redesign/config_design.rb +501 -0
  286. data/tasks/gem_tasks.rake +4 -0
  287. data/tasks/npm_tasks.rake +7 -0
  288. data/tasks/rspec.rake +48 -0
  289. data/tasks/test.rake +13 -1
  290. data/tasks/yard.rake +34 -7
  291. metadata +365 -22
  292. data/lib/git/base.rb +0 -1128
  293. data/lib/git/index.rb +0 -6
  294. data/lib/git/lib.rb +0 -2277
  295. data/lib/git/path.rb +0 -38
  296. data/lib/git/working_directory.rb +0 -6
  297. /data/{release-please-config.json → .release-please-config.json} +0 -0
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Git
4
+ # Represents a git version constraint with minimum and upper bound versions
5
+ #
6
+ # Used by {Git::Commands::Base.requires_git_version} to declare version requirements
7
+ # and by {Git::VersionError} to report constraint violations.
8
+ #
9
+ # @example Minimum version only
10
+ # constraint = Git::VersionConstraint.new(min: Git::Version.parse('2.30.0'))
11
+ # constraint.too_old?(Git::Version.parse('2.28.0')) #=> true
12
+ # constraint.too_new?(Git::Version.parse('2.28.0')) #=> false
13
+ #
14
+ # @example Upper bound only
15
+ # constraint = Git::VersionConstraint.new(before: Git::Version.parse('2.50.0'))
16
+ # constraint.too_old?(Git::Version.parse('2.51.0')) #=> false
17
+ # constraint.too_new?(Git::Version.parse('2.51.0')) #=> true
18
+ #
19
+ # @example Both bounds
20
+ # constraint = Git::VersionConstraint.new(
21
+ # min: Git::Version.parse('2.30.0'),
22
+ # before: Git::Version.parse('2.50.0')
23
+ # )
24
+ # constraint.satisfied_by?(Git::Version.parse('2.40.0')) #=> true
25
+ #
26
+ # @api public
27
+ #
28
+ VersionConstraint = Data.define(:min, :before) do
29
+ # @param min [Git::Version, nil] minimum version (inclusive)
30
+ # @param before [Git::Version, nil] upper bound version (exclusive)
31
+ def initialize(min: nil, before: nil)
32
+ super
33
+ end
34
+
35
+ # Check if the given version is too old (below the minimum)
36
+ #
37
+ # @param version [Git::Version] the version to check
38
+ #
39
+ # @return [Boolean] true if version is below the minimum, false otherwise
40
+ #
41
+ def too_old?(version)
42
+ return false unless min
43
+
44
+ version < min
45
+ end
46
+
47
+ # Check if the given version is too new (at or past the upper bound)
48
+ #
49
+ # @param version [Git::Version] the version to check
50
+ #
51
+ # @return [Boolean] true if version is at or past the upper bound, false otherwise
52
+ #
53
+ def too_new?(version)
54
+ return false unless before
55
+
56
+ version >= before
57
+ end
58
+
59
+ # Check if the given version satisfies this constraint
60
+ #
61
+ # @param version [Git::Version] the version to check
62
+ #
63
+ # @return [Boolean] true if the version satisfies the constraint
64
+ #
65
+ def satisfied_by?(version)
66
+ !too_old?(version) && !too_new?(version)
67
+ end
68
+
69
+ # Return a human-readable representation of this constraint
70
+ #
71
+ # @return [String] the constraint in git version range form
72
+ #
73
+ def to_s
74
+ return ">= #{min}, < #{before}" if min && before
75
+ return ">= #{min}" if min
76
+ return "< #{before}" if before
77
+
78
+ 'any version'
79
+ end
80
+ end
81
+ end
data/lib/git/worktree.rb CHANGED
@@ -1,12 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'git/path'
4
-
5
3
  module Git
6
4
  # A worktree in a Git repository
5
+ #
6
+ # Represents a single linked or main worktree. Constructed by
7
+ # {Git::Repository::WorktreeOperations#worktree} or populated by
8
+ # {Git::Worktrees}.
9
+ #
10
+ # @example Add and remove a linked worktree
11
+ # worktree = repo.worktree('/path/to/new-worktree')
12
+ # worktree.add
13
+ # worktree.remove
14
+ #
15
+ # @api public
16
+ #
7
17
  class Worktree
8
- attr_accessor :full, :dir
18
+ # Full worktree descriptor including the optional commitish
19
+ #
20
+ # @return [String] the filesystem path, space-separated with the commitish
21
+ # when one was given at construction time
22
+ #
23
+ attr_accessor :full
24
+
25
+ # Filesystem path of this worktree
26
+ #
27
+ # @return [String] the filesystem path of the worktree directory
28
+ #
29
+ attr_accessor :dir
9
30
 
31
+ # Creates a new Worktree object
32
+ #
33
+ # @param base [Git::Repository] the repository that owns this
34
+ # worktree
35
+ #
36
+ # @param dir [String] filesystem path of the worktree
37
+ #
38
+ # @param gcommit [String, nil] commitish associated with the worktree;
39
+ # when non-nil it is appended to {#full}
40
+ #
41
+ # @return [void]
42
+ #
10
43
  def initialize(base, dir, gcommit = nil)
11
44
  @full = dir
12
45
  @full += " #{gcommit}" unless gcommit.nil?
@@ -15,25 +48,94 @@ module Git
15
48
  @gcommit = gcommit
16
49
  end
17
50
 
51
+ # Returns the commit (or commitish string) associated with this worktree
52
+ #
53
+ # When a commitish string was supplied at construction time (e.g. by
54
+ # {Git::Worktrees} which passes the raw SHA from `git worktree list`), that
55
+ # string is returned as-is. Otherwise the value is lazily resolved on first
56
+ # call via `worktree_repository.gcommit(@full)` and the result is memoized.
57
+ #
58
+ # @example When resolved lazily (no commitish at construction)
59
+ # worktree = repo.worktree('/path/to/wt')
60
+ # worktree.gcommit # => #<Git::Object::Commit ...>
61
+ #
62
+ # @example When the commitish was given at construction
63
+ # worktree = repo.worktrees['/path/to/wt']
64
+ # worktree.gcommit # => "4bef5ab8c9..." (raw SHA string)
65
+ #
66
+ # @return [Git::Object::Commit, String] a commit object when lazily
67
+ # resolved, or the raw commitish string when pre-set at construction
68
+ #
69
+ # @raise [Git::FailedError] if git must resolve the commit and exits with a
70
+ # non-zero exit status
71
+ #
18
72
  def gcommit
19
- @gcommit ||= @base.gcommit(@full)
73
+ @gcommit ||= worktree_repository.gcommit(@full)
20
74
  @gcommit
21
75
  end
22
76
 
77
+ # Creates this worktree on disk
78
+ #
79
+ # Runs `git worktree add` for {#dir}, optionally at the commitish passed
80
+ # at construction time.
81
+ #
82
+ # @example Add a worktree
83
+ # worktree = repo.worktree('/path/to/new-worktree')
84
+ # worktree.add
85
+ #
86
+ # @return [String] stdout from the git command
87
+ #
88
+ # @raise [Git::FailedError] if git exits with a non-zero exit status
89
+ #
23
90
  def add
24
- @base.lib.worktree_add(@dir, @gcommit)
91
+ worktree_repository.worktree_add(@dir, @gcommit)
25
92
  end
26
93
 
94
+ # Removes this worktree from disk
95
+ #
96
+ # Runs `git worktree remove` for {#dir}.
97
+ #
98
+ # @example Remove a worktree
99
+ # worktree.remove
100
+ #
101
+ # @return [String] stdout from the git command (typically empty)
102
+ #
103
+ # @raise [Git::FailedError] if git exits with a non-zero exit status
104
+ #
27
105
  def remove
28
- @base.lib.worktree_remove(@dir)
106
+ worktree_repository.worktree_remove(@dir)
29
107
  end
30
108
 
109
+ # Returns an array containing the full worktree descriptor
110
+ #
111
+ # @example Get the descriptor array
112
+ # worktree.to_a # => ["/path/to/worktree"]
113
+ #
114
+ # @return [Array<String>] array containing the full worktree descriptor
115
+ #
31
116
  def to_a
32
117
  [@full]
33
118
  end
34
119
 
120
+ # Returns the full worktree descriptor as a string
121
+ #
122
+ # @example Get the descriptor string
123
+ # worktree.to_s # => "/path/to/worktree"
124
+ #
125
+ # @return [String] the full worktree descriptor (path and optional commitish)
126
+ #
35
127
  def to_s
36
128
  @full
37
129
  end
130
+
131
+ private
132
+
133
+ # @return [Git::Repository] the repository used for worktree operations
134
+ #
135
+ # @api private
136
+ #
137
+ def worktree_repository
138
+ @base
139
+ end
38
140
  end
39
141
  end
data/lib/git/worktrees.rb CHANGED
@@ -1,47 +1,134 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Git
4
- # object that holds all the available worktrees
4
+ # Collection of all Git worktrees in a repository
5
+ #
6
+ # Wraps every linked and main worktree and provides enumeration and
7
+ # path-based lookup.
8
+ #
9
+ # @example Enumerate all worktrees
10
+ # worktrees = repo.worktrees
11
+ # worktrees.each { |wt| puts wt.dir }
12
+ #
13
+ # @api public
14
+ #
5
15
  class Worktrees
6
16
  include Enumerable
7
17
 
18
+ # Creates a new Worktrees collection populated from the given repository
19
+ #
20
+ # @param base [Git::Repository] the repository to enumerate
21
+ # worktrees from
22
+ #
23
+ # @return [void]
24
+ #
25
+ # @raise [Git::FailedError] if git exits with a non-zero exit status
26
+ #
8
27
  def initialize(base)
9
28
  @worktrees = {}
10
29
 
11
30
  @base = base
12
31
 
13
- # Array contains [dir, git_hash]
14
- @base.lib.worktrees_all.each do |w|
32
+ worktree_repository.worktrees_all.each do |w|
15
33
  @worktrees[w[0]] = Git::Worktree.new(@base, w[0], w[1])
16
34
  end
17
35
  end
18
36
 
19
- # array like methods
20
-
37
+ # Returns the number of worktrees in the collection
38
+ #
39
+ # @example Count all worktrees
40
+ # repo.worktrees.size # => 2
41
+ #
42
+ # @return [Integer] the total number of worktrees
43
+ #
21
44
  def size
22
45
  @worktrees.size
23
46
  end
24
47
 
48
+ # Iterates over every worktree in the collection
49
+ #
50
+ # @overload each
51
+ #
52
+ # @example Get an enumerator over all worktrees
53
+ # enum = repo.worktrees.each
54
+ #
55
+ # @return [Enumerator<Git::Worktree>] an enumerator over all worktrees
56
+ #
57
+ # @overload each(&block)
58
+ #
59
+ # @example Print every worktree path
60
+ # repo.worktrees.each { |wt| puts wt.dir }
61
+ #
62
+ # @return [Array<Git::Worktree>] the full list of worktrees
63
+ #
64
+ # @yield [worktree] passes each worktree to the block
65
+ #
66
+ # @yieldparam worktree [Git::Worktree] a worktree in the repository
67
+ #
68
+ # @yieldreturn [void]
69
+ #
25
70
  def each(&)
26
71
  @worktrees.values.each(&)
27
72
  end
28
73
 
74
+ # Returns the worktree with the given path
75
+ #
76
+ # Supports lookup by the filesystem path of the worktree directory or by
77
+ # the full worktree descriptor (path and optional commitish).
78
+ #
79
+ # @example Look up a worktree by path
80
+ # repo.worktrees['/path/to/linked-worktree']
81
+ #
82
+ # @param worktree_name [#to_s] the path (or full descriptor) of the
83
+ # worktree to retrieve
84
+ #
85
+ # @return [Git::Worktree, nil] the matching worktree, or `nil` if not found
86
+ #
29
87
  def [](worktree_name)
30
88
  @worktrees.values.each_with_object(@worktrees) do |worktree, worktrees|
31
89
  worktrees[worktree.full] ||= worktree
32
90
  end[worktree_name.to_s]
33
91
  end
34
92
 
93
+ # Returns a string listing all worktrees, one per line
94
+ #
95
+ # @example Display all worktrees
96
+ # puts repo.worktrees.to_s
97
+ #
98
+ # @return [String] a newline-separated listing of worktree descriptors
99
+ #
35
100
  def to_s
36
- out = ''
101
+ out = +''
37
102
  @worktrees.each_value do |b|
38
103
  out << b.to_s << "\n"
39
104
  end
40
105
  out
41
106
  end
42
107
 
108
+ # Removes stale administrative files for worktrees that no longer exist
109
+ #
110
+ # Runs `git worktree prune` to clean up any lingering worktree metadata
111
+ # for linked worktrees whose directories have been deleted.
112
+ #
113
+ # @example Prune stale worktree metadata
114
+ # repo.worktrees.prune
115
+ #
116
+ # @return [String] stdout from the git command (typically empty)
117
+ #
118
+ # @raise [Git::FailedError] if git exits with a non-zero exit status
119
+ #
43
120
  def prune
44
- @base.lib.worktree_prune
121
+ worktree_repository.worktree_prune
122
+ end
123
+
124
+ private
125
+
126
+ # @return [Git::Repository] the repository used to enumerate worktrees
127
+ #
128
+ # @api private
129
+ #
130
+ def worktree_repository
131
+ @base
45
132
  end
46
133
  end
47
134
  end