git 4.4.0 → 5.0.0.beta.1
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.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +67 -2705
- data/.github/pull_request_template.md +3 -1
- data/.github/skills/breaking-change-analysis/SKILL.md +102 -0
- data/.github/skills/ci-cd-troubleshooting/SKILL.md +264 -0
- data/.github/skills/command-implementation/REFERENCE.md +993 -0
- data/.github/skills/command-implementation/SKILL.md +229 -0
- data/.github/skills/command-test-conventions/SKILL.md +660 -0
- data/.github/skills/command-yard-documentation/SKILL.md +426 -0
- data/.github/skills/dependency-management/SKILL.md +72 -0
- data/.github/skills/development-workflow/SKILL.md +506 -0
- data/.github/skills/extract-command-from-lib/SKILL.md +487 -0
- data/.github/skills/extract-facade-from-base-lib/SKILL.md +586 -0
- data/.github/skills/facade-implementation/REFERENCE.md +840 -0
- data/.github/skills/facade-implementation/SKILL.md +260 -0
- data/.github/skills/facade-test-conventions/SKILL.md +380 -0
- data/.github/skills/facade-yard-documentation/SKILL.md +429 -0
- data/.github/skills/make-skill-template/SKILL.md +176 -0
- data/.github/skills/pr-readiness-review/SKILL.md +185 -0
- data/.github/skills/project-context/SKILL.md +313 -0
- data/.github/skills/pull-request-review/SKILL.md +168 -0
- data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +131 -0
- data/.github/skills/release-management/SKILL.md +125 -0
- data/.github/skills/review-arguments-dsl/CHECKLIST.md +788 -0
- data/.github/skills/review-arguments-dsl/SKILL.md +214 -0
- data/.github/skills/review-backward-compatibility/SKILL.md +275 -0
- data/.github/skills/review-cross-command-consistency/SKILL.md +139 -0
- data/.github/skills/reviewing-skills/SKILL.md +189 -0
- data/.github/skills/rspec-unit-testing-standards/SKILL.md +639 -0
- data/.github/skills/tdd-refactor-step/SKILL.md +236 -0
- data/.github/skills/test-debugging/SKILL.md +160 -0
- data/.github/skills/yard-documentation/SKILL.md +793 -0
- data/.github/workflows/continuous_integration.yml +3 -2
- data/.github/workflows/enforce_conventional_commits.yml +1 -1
- data/.github/workflows/experimental_continuous_integration.yml +2 -2
- data/.github/workflows/release.yml +3 -4
- data/.gitignore +8 -0
- data/.husky/pre-commit +13 -0
- data/.release-please-manifest.json +1 -1
- data/.rspec +3 -0
- data/.rubocop.yml +7 -3
- data/.rubocop_todo.yml +23 -5
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -53
- data/CONTRIBUTING.md +694 -53
- data/README.md +17 -17
- data/Rakefile +61 -9
- data/commitlint.test +4 -0
- data/git.gemspec +14 -8
- data/lib/git/args_builder.rb +0 -8
- data/lib/git/base.rb +488 -412
- data/lib/git/branch.rb +117 -59
- data/lib/git/branch_delete_failure.rb +31 -0
- data/lib/git/branch_delete_result.rb +63 -0
- data/lib/git/branch_info.rb +178 -0
- data/lib/git/branches.rb +130 -24
- data/lib/git/command_line/base.rb +245 -0
- data/lib/git/command_line/capturing.rb +249 -0
- data/lib/git/command_line/result.rb +96 -0
- data/lib/git/command_line/streaming.rb +194 -0
- data/lib/git/command_line.rb +43 -322
- data/lib/git/command_line_result.rb +4 -88
- data/lib/git/commands/add.rb +131 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +252 -0
- data/lib/git/commands/am/continue.rb +43 -0
- data/lib/git/commands/am/quit.rb +43 -0
- data/lib/git/commands/am/retry.rb +47 -0
- data/lib/git/commands/am/show_current_patch.rb +64 -0
- data/lib/git/commands/am/skip.rb +42 -0
- data/lib/git/commands/am.rb +33 -0
- data/lib/git/commands/apply.rb +237 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +140 -0
- data/lib/git/commands/arguments.rb +3510 -0
- data/lib/git/commands/base.rb +403 -0
- data/lib/git/commands/branch/copy.rb +94 -0
- data/lib/git/commands/branch/create.rb +173 -0
- data/lib/git/commands/branch/delete.rb +80 -0
- data/lib/git/commands/branch/list.rb +162 -0
- data/lib/git/commands/branch/move.rb +94 -0
- data/lib/git/commands/branch/set_upstream.rb +86 -0
- data/lib/git/commands/branch/show_current.rb +49 -0
- data/lib/git/commands/branch/unset_upstream.rb +57 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +364 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +210 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +151 -0
- data/lib/git/commands/checkout/files.rb +115 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +105 -0
- data/lib/git/commands/clean.rb +100 -0
- data/lib/git/commands/clone.rb +240 -0
- data/lib/git/commands/commit.rb +272 -0
- data/lib/git/commands/commit_tree.rb +100 -0
- data/lib/git/commands/config_option_syntax/add.rb +83 -0
- data/lib/git/commands/config_option_syntax/get.rb +117 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +91 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +93 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +115 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +102 -0
- data/lib/git/commands/config_option_syntax/list.rb +107 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +74 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +78 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +104 -0
- data/lib/git/commands/config_option_syntax/set.rb +114 -0
- data/lib/git/commands/config_option_syntax/unset.rb +89 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +89 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +155 -0
- data/lib/git/commands/diff.rb +656 -0
- data/lib/git/commands/diff_files.rb +518 -0
- data/lib/git/commands/diff_index.rb +496 -0
- data/lib/git/commands/fetch.rb +352 -0
- data/lib/git/commands/fsck.rb +136 -0
- data/lib/git/commands/gc.rb +132 -0
- data/lib/git/commands/grep.rb +338 -0
- data/lib/git/commands/init.rb +99 -0
- data/lib/git/commands/log.rb +632 -0
- data/lib/git/commands/ls_files.rb +191 -0
- data/lib/git/commands/ls_remote.rb +155 -0
- data/lib/git/commands/ls_tree.rb +131 -0
- data/lib/git/commands/maintenance/register.rb +75 -0
- data/lib/git/commands/maintenance/run.rb +104 -0
- data/lib/git/commands/maintenance/start.rb +66 -0
- data/lib/git/commands/maintenance/stop.rb +55 -0
- data/lib/git/commands/maintenance/unregister.rb +79 -0
- data/lib/git/commands/maintenance.rb +31 -0
- data/lib/git/commands/merge/abort.rb +44 -0
- data/lib/git/commands/merge/continue.rb +44 -0
- data/lib/git/commands/merge/quit.rb +46 -0
- data/lib/git/commands/merge/start.rb +245 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +86 -0
- data/lib/git/commands/mv.rb +77 -0
- data/lib/git/commands/name_rev.rb +114 -0
- data/lib/git/commands/pull.rb +377 -0
- data/lib/git/commands/push.rb +246 -0
- data/lib/git/commands/read_tree.rb +149 -0
- data/lib/git/commands/remote/add.rb +91 -0
- data/lib/git/commands/remote/get_url.rb +66 -0
- data/lib/git/commands/remote/list.rb +54 -0
- data/lib/git/commands/remote/prune.rb +61 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +69 -0
- data/lib/git/commands/remote/set_branches.rb +63 -0
- data/lib/git/commands/remote/set_head.rb +82 -0
- data/lib/git/commands/remote/set_url.rb +71 -0
- data/lib/git/commands/remote/set_url_add.rb +61 -0
- data/lib/git/commands/remote/set_url_delete.rb +64 -0
- data/lib/git/commands/remote/show.rb +71 -0
- data/lib/git/commands/remote/update.rb +72 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +277 -0
- data/lib/git/commands/reset.rb +147 -0
- data/lib/git/commands/rev_parse.rb +297 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +57 -0
- data/lib/git/commands/revert/quit.rb +47 -0
- data/lib/git/commands/revert/skip.rb +44 -0
- data/lib/git/commands/revert/start.rb +153 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +114 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +120 -0
- data/lib/git/commands/show_ref/exists.rb +78 -0
- data/lib/git/commands/show_ref/list.rb +145 -0
- data/lib/git/commands/show_ref/verify.rb +120 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +75 -0
- data/lib/git/commands/stash/branch.rb +65 -0
- data/lib/git/commands/stash/clear.rb +41 -0
- data/lib/git/commands/stash/create.rb +58 -0
- data/lib/git/commands/stash/drop.rb +67 -0
- data/lib/git/commands/stash/list.rb +39 -0
- data/lib/git/commands/stash/pop.rb +78 -0
- data/lib/git/commands/stash/push.rb +103 -0
- data/lib/git/commands/stash/show.rb +149 -0
- data/lib/git/commands/stash/store.rb +63 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +169 -0
- data/lib/git/commands/symbolic_ref/delete.rb +68 -0
- data/lib/git/commands/symbolic_ref/read.rb +95 -0
- data/lib/git/commands/symbolic_ref/update.rb +76 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +139 -0
- data/lib/git/commands/tag/delete.rb +55 -0
- data/lib/git/commands/tag/list.rb +143 -0
- data/lib/git/commands/tag/verify.rb +71 -0
- data/lib/git/commands/tag.rb +26 -0
- data/lib/git/commands/update_ref/batch.rb +140 -0
- data/lib/git/commands/update_ref/delete.rb +92 -0
- data/lib/git/commands/update_ref/update.rb +106 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +52 -0
- data/lib/git/commands/worktree/add.rb +140 -0
- data/lib/git/commands/worktree/list.rb +64 -0
- data/lib/git/commands/worktree/lock.rb +58 -0
- data/lib/git/commands/worktree/management_base.rb +51 -0
- data/lib/git/commands/worktree/move.rb +66 -0
- data/lib/git/commands/worktree/prune.rb +67 -0
- data/lib/git/commands/worktree/remove.rb +63 -0
- data/lib/git/commands/worktree/repair.rb +76 -0
- data/lib/git/commands/worktree/unlock.rb +47 -0
- data/lib/git/commands/worktree.rb +43 -0
- data/lib/git/commands/write_tree.rb +68 -0
- data/lib/git/commands.rb +89 -0
- data/lib/git/detached_head_info.rb +54 -0
- data/lib/git/diff.rb +297 -7
- data/lib/git/diff_file_numstat_info.rb +29 -0
- data/lib/git/diff_file_patch_info.rb +134 -0
- data/lib/git/diff_file_raw_info.rb +127 -0
- data/lib/git/diff_info.rb +169 -0
- data/lib/git/diff_path_status.rb +78 -19
- data/lib/git/diff_result.rb +32 -0
- data/lib/git/diff_stats.rb +59 -14
- data/lib/git/dirstat_info.rb +86 -0
- data/lib/git/errors.rb +65 -2
- data/lib/git/execution_context/global.rb +56 -0
- data/lib/git/execution_context/repository.rb +147 -0
- data/lib/git/execution_context.rb +482 -0
- data/lib/git/file_ref.rb +74 -0
- data/lib/git/fsck_object.rb +9 -9
- data/lib/git/fsck_result.rb +1 -1
- data/lib/git/lib.rb +1606 -1028
- data/lib/git/log.rb +15 -2
- data/lib/git/object.rb +92 -22
- data/lib/git/parsers/branch.rb +224 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/diff.rb +585 -0
- data/lib/git/parsers/fsck.rb +133 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/stash.rb +208 -0
- data/lib/git/parsers/tag.rb +257 -0
- data/lib/git/remote.rb +133 -9
- data/lib/git/repository/branching.rb +572 -0
- data/lib/git/repository/committing.rb +191 -0
- data/lib/git/repository/configuring.rb +156 -0
- data/lib/git/repository/diffing.rb +775 -0
- data/lib/git/repository/inspecting.rb +153 -0
- data/lib/git/repository/logging.rb +247 -0
- data/lib/git/repository/merging.rb +295 -0
- data/lib/git/repository/object_operations.rb +1101 -0
- data/lib/git/repository/path_resolver.rb +207 -0
- data/lib/git/repository/remote_operations.rb +753 -0
- data/lib/git/repository/shared_private.rb +51 -0
- data/lib/git/repository/staging.rb +390 -0
- data/lib/git/repository/stashing.rb +107 -0
- data/lib/git/repository/status_operations.rb +180 -0
- data/lib/git/repository/worktree_operations.rb +159 -0
- data/lib/git/repository.rb +264 -1
- data/lib/git/stash.rb +85 -4
- data/lib/git/stash_info.rb +104 -0
- data/lib/git/stashes.rb +130 -13
- data/lib/git/status.rb +226 -18
- data/lib/git/tag_delete_failure.rb +31 -0
- data/lib/git/tag_delete_result.rb +63 -0
- data/lib/git/tag_info.rb +105 -0
- data/lib/git/version.rb +109 -2
- data/lib/git/version_constraint.rb +81 -0
- data/lib/git/worktree.rb +120 -5
- data/lib/git/worktrees.rb +107 -7
- data/lib/git.rb +117 -56
- data/redesign/1_architecture_existing.md +54 -18
- data/redesign/2_architecture_redesign.md +365 -46
- data/redesign/3_architecture_implementation.md +1451 -54
- data/tasks/gem_tasks.rake +4 -0
- data/tasks/npm_tasks.rake +7 -0
- data/tasks/rspec.rake +48 -0
- data/tasks/test.rake +13 -1
- data/tasks/yard.rake +34 -7
- metadata +348 -19
- data/lib/git/index.rb +0 -6
- data/lib/git/path.rb +0 -38
- data/lib/git/working_directory.rb +0 -6
- /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,52 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'git/
|
|
3
|
+
require 'git/base'
|
|
4
4
|
|
|
5
5
|
module Git
|
|
6
6
|
# A worktree in a Git repository
|
|
7
|
+
#
|
|
8
|
+
# Represents a single linked or main worktree. Constructed by
|
|
9
|
+
# {Git::Repository::WorktreeOperations#worktree} or populated by
|
|
10
|
+
# {Git::Worktrees}.
|
|
11
|
+
#
|
|
12
|
+
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy form)
|
|
13
|
+
# as the `base` argument. The `is_a?(Git::Base)` guard routes git operations
|
|
14
|
+
# through the facade repository and will be removed when {Git::Base} is
|
|
15
|
+
# deleted in Phase 4.
|
|
16
|
+
#
|
|
17
|
+
# @example Add and remove a linked worktree
|
|
18
|
+
# worktree = repo.worktree('/path/to/new-worktree')
|
|
19
|
+
# worktree.add
|
|
20
|
+
# worktree.remove
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
#
|
|
7
24
|
class Worktree
|
|
8
|
-
|
|
25
|
+
# Full worktree descriptor including the optional commitish
|
|
26
|
+
#
|
|
27
|
+
# @return [String] the filesystem path, space-separated with the commitish
|
|
28
|
+
# when one was given at construction time
|
|
29
|
+
#
|
|
30
|
+
attr_accessor :full
|
|
9
31
|
|
|
32
|
+
# Filesystem path of this worktree
|
|
33
|
+
#
|
|
34
|
+
# @return [String] the filesystem path of the worktree directory
|
|
35
|
+
#
|
|
36
|
+
attr_accessor :dir
|
|
37
|
+
|
|
38
|
+
# Creates a new Worktree object
|
|
39
|
+
#
|
|
40
|
+
# @param base [Git::Base, Git::Repository] the repository that owns this
|
|
41
|
+
# worktree
|
|
42
|
+
#
|
|
43
|
+
# @param dir [String] filesystem path of the worktree
|
|
44
|
+
#
|
|
45
|
+
# @param gcommit [String, nil] commitish associated with the worktree;
|
|
46
|
+
# when non-nil it is appended to {#full}
|
|
47
|
+
#
|
|
48
|
+
# @return [void]
|
|
49
|
+
#
|
|
10
50
|
def initialize(base, dir, gcommit = nil)
|
|
11
51
|
@full = dir
|
|
12
52
|
@full += " #{gcommit}" unless gcommit.nil?
|
|
@@ -15,25 +55,100 @@ module Git
|
|
|
15
55
|
@gcommit = gcommit
|
|
16
56
|
end
|
|
17
57
|
|
|
58
|
+
# Returns the commit (or commitish string) associated with this worktree
|
|
59
|
+
#
|
|
60
|
+
# When a commitish string was supplied at construction time (e.g. by
|
|
61
|
+
# {Git::Worktrees} which passes the raw SHA from `git worktree list`), that
|
|
62
|
+
# string is returned as-is. Otherwise the value is lazily resolved on first
|
|
63
|
+
# call via `worktree_repository.gcommit(@full)` and the result is memoized.
|
|
64
|
+
#
|
|
65
|
+
# @example When resolved lazily (no commitish at construction)
|
|
66
|
+
# worktree = repo.worktree('/path/to/wt')
|
|
67
|
+
# worktree.gcommit # => #<Git::Object::Commit ...>
|
|
68
|
+
#
|
|
69
|
+
# @example When the commitish was given at construction
|
|
70
|
+
# worktree = repo.worktrees['/path/to/wt']
|
|
71
|
+
# worktree.gcommit # => "4bef5ab8c9..." (raw SHA string)
|
|
72
|
+
#
|
|
73
|
+
# @return [Git::Object::Commit, String] a commit object when lazily
|
|
74
|
+
# resolved, or the raw commitish string when pre-set at construction
|
|
75
|
+
#
|
|
76
|
+
# @raise [Git::FailedError] if git must resolve the commit and exits with a
|
|
77
|
+
# non-zero exit status
|
|
78
|
+
#
|
|
18
79
|
def gcommit
|
|
19
|
-
@gcommit ||=
|
|
80
|
+
@gcommit ||= worktree_repository.gcommit(@full)
|
|
20
81
|
@gcommit
|
|
21
82
|
end
|
|
22
83
|
|
|
84
|
+
# Creates this worktree on disk
|
|
85
|
+
#
|
|
86
|
+
# Runs `git worktree add` for {#dir}, optionally at the commitish passed
|
|
87
|
+
# at construction time.
|
|
88
|
+
#
|
|
89
|
+
# @example Add a worktree
|
|
90
|
+
# worktree = repo.worktree('/path/to/new-worktree')
|
|
91
|
+
# worktree.add
|
|
92
|
+
#
|
|
93
|
+
# @return [String] stdout from the git command
|
|
94
|
+
#
|
|
95
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
96
|
+
#
|
|
23
97
|
def add
|
|
24
|
-
|
|
98
|
+
worktree_repository.worktree_add(@dir, @gcommit)
|
|
25
99
|
end
|
|
26
100
|
|
|
101
|
+
# Removes this worktree from disk
|
|
102
|
+
#
|
|
103
|
+
# Runs `git worktree remove` for {#dir}.
|
|
104
|
+
#
|
|
105
|
+
# @example Remove a worktree
|
|
106
|
+
# worktree.remove
|
|
107
|
+
#
|
|
108
|
+
# @return [String] stdout from the git command (typically empty)
|
|
109
|
+
#
|
|
110
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
111
|
+
#
|
|
27
112
|
def remove
|
|
28
|
-
|
|
113
|
+
worktree_repository.worktree_remove(@dir)
|
|
29
114
|
end
|
|
30
115
|
|
|
116
|
+
# Returns an array containing the full worktree descriptor
|
|
117
|
+
#
|
|
118
|
+
# @example Get the descriptor array
|
|
119
|
+
# worktree.to_a # => ["/path/to/worktree"]
|
|
120
|
+
#
|
|
121
|
+
# @return [Array<String>] array containing the full worktree descriptor
|
|
122
|
+
#
|
|
31
123
|
def to_a
|
|
32
124
|
[@full]
|
|
33
125
|
end
|
|
34
126
|
|
|
127
|
+
# Returns the full worktree descriptor as a string
|
|
128
|
+
#
|
|
129
|
+
# @example Get the descriptor string
|
|
130
|
+
# worktree.to_s # => "/path/to/worktree"
|
|
131
|
+
#
|
|
132
|
+
# @return [String] the full worktree descriptor (path and optional commitish)
|
|
133
|
+
#
|
|
35
134
|
def to_s
|
|
36
135
|
@full
|
|
37
136
|
end
|
|
137
|
+
|
|
138
|
+
private
|
|
139
|
+
|
|
140
|
+
# Resolves the {Git::Repository} for worktree operations
|
|
141
|
+
#
|
|
142
|
+
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy).
|
|
143
|
+
# The `is_a?(Git::Base)` guard will be removed when {Git::Base} is deleted
|
|
144
|
+
# in Phase 4.
|
|
145
|
+
#
|
|
146
|
+
# @return [Git::Repository] the repository used for worktree operations
|
|
147
|
+
#
|
|
148
|
+
# @api private
|
|
149
|
+
#
|
|
150
|
+
def worktree_repository
|
|
151
|
+
@base.is_a?(Git::Base) ? @base.facade_repository : @base
|
|
152
|
+
end
|
|
38
153
|
end
|
|
39
154
|
end
|
data/lib/git/worktrees.rb
CHANGED
|
@@ -1,47 +1,147 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'git/base'
|
|
4
|
+
|
|
3
5
|
module Git
|
|
4
|
-
#
|
|
6
|
+
# Collection of all Git worktrees in a repository
|
|
7
|
+
#
|
|
8
|
+
# Wraps every linked and main worktree and provides enumeration and
|
|
9
|
+
# path-based lookup.
|
|
10
|
+
#
|
|
11
|
+
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy
|
|
12
|
+
# form) as the `base` argument. The `is_a?(Git::Base)` guard routes git
|
|
13
|
+
# operations through the facade repository and will be removed when
|
|
14
|
+
# {Git::Base} is deleted in Phase 4.
|
|
15
|
+
#
|
|
16
|
+
# @example Enumerate all worktrees
|
|
17
|
+
# worktrees = repo.worktrees
|
|
18
|
+
# worktrees.each { |wt| puts wt.dir }
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
#
|
|
5
22
|
class Worktrees
|
|
6
23
|
include Enumerable
|
|
7
24
|
|
|
25
|
+
# Creates a new Worktrees collection populated from the given repository
|
|
26
|
+
#
|
|
27
|
+
# @param base [Git::Base, Git::Repository] the repository to enumerate
|
|
28
|
+
# worktrees from
|
|
29
|
+
#
|
|
30
|
+
# @return [void]
|
|
31
|
+
#
|
|
32
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
33
|
+
#
|
|
8
34
|
def initialize(base)
|
|
9
35
|
@worktrees = {}
|
|
10
36
|
|
|
11
37
|
@base = base
|
|
12
38
|
|
|
13
|
-
|
|
14
|
-
@base.lib.worktrees_all.each do |w|
|
|
39
|
+
worktree_repository.worktrees_all.each do |w|
|
|
15
40
|
@worktrees[w[0]] = Git::Worktree.new(@base, w[0], w[1])
|
|
16
41
|
end
|
|
17
42
|
end
|
|
18
43
|
|
|
19
|
-
#
|
|
20
|
-
|
|
44
|
+
# Returns the number of worktrees in the collection
|
|
45
|
+
#
|
|
46
|
+
# @example Count all worktrees
|
|
47
|
+
# repo.worktrees.size # => 2
|
|
48
|
+
#
|
|
49
|
+
# @return [Integer] the total number of worktrees
|
|
50
|
+
#
|
|
21
51
|
def size
|
|
22
52
|
@worktrees.size
|
|
23
53
|
end
|
|
24
54
|
|
|
55
|
+
# Iterates over every worktree in the collection
|
|
56
|
+
#
|
|
57
|
+
# @overload each
|
|
58
|
+
#
|
|
59
|
+
# @example Get an enumerator over all worktrees
|
|
60
|
+
# enum = repo.worktrees.each
|
|
61
|
+
#
|
|
62
|
+
# @return [Enumerator<Git::Worktree>] an enumerator over all worktrees
|
|
63
|
+
#
|
|
64
|
+
# @overload each(&block)
|
|
65
|
+
#
|
|
66
|
+
# @example Print every worktree path
|
|
67
|
+
# repo.worktrees.each { |wt| puts wt.dir }
|
|
68
|
+
#
|
|
69
|
+
# @return [Array<Git::Worktree>] the full list of worktrees
|
|
70
|
+
#
|
|
71
|
+
# @yield [worktree] passes each worktree to the block
|
|
72
|
+
#
|
|
73
|
+
# @yieldparam worktree [Git::Worktree] a worktree in the repository
|
|
74
|
+
#
|
|
75
|
+
# @yieldreturn [void]
|
|
76
|
+
#
|
|
25
77
|
def each(&)
|
|
26
78
|
@worktrees.values.each(&)
|
|
27
79
|
end
|
|
28
80
|
|
|
81
|
+
# Returns the worktree with the given path
|
|
82
|
+
#
|
|
83
|
+
# Supports lookup by the filesystem path of the worktree directory or by
|
|
84
|
+
# the full worktree descriptor (path and optional commitish).
|
|
85
|
+
#
|
|
86
|
+
# @example Look up a worktree by path
|
|
87
|
+
# repo.worktrees['/path/to/linked-worktree']
|
|
88
|
+
#
|
|
89
|
+
# @param worktree_name [#to_s] the path (or full descriptor) of the
|
|
90
|
+
# worktree to retrieve
|
|
91
|
+
#
|
|
92
|
+
# @return [Git::Worktree, nil] the matching worktree, or `nil` if not found
|
|
93
|
+
#
|
|
29
94
|
def [](worktree_name)
|
|
30
95
|
@worktrees.values.each_with_object(@worktrees) do |worktree, worktrees|
|
|
31
96
|
worktrees[worktree.full] ||= worktree
|
|
32
97
|
end[worktree_name.to_s]
|
|
33
98
|
end
|
|
34
99
|
|
|
100
|
+
# Returns a string listing all worktrees, one per line
|
|
101
|
+
#
|
|
102
|
+
# @example Display all worktrees
|
|
103
|
+
# puts repo.worktrees.to_s
|
|
104
|
+
#
|
|
105
|
+
# @return [String] a newline-separated listing of worktree descriptors
|
|
106
|
+
#
|
|
35
107
|
def to_s
|
|
36
|
-
out = ''
|
|
108
|
+
out = +''
|
|
37
109
|
@worktrees.each_value do |b|
|
|
38
110
|
out << b.to_s << "\n"
|
|
39
111
|
end
|
|
40
112
|
out
|
|
41
113
|
end
|
|
42
114
|
|
|
115
|
+
# Removes stale administrative files for worktrees that no longer exist
|
|
116
|
+
#
|
|
117
|
+
# Runs `git worktree prune` to clean up any lingering worktree metadata
|
|
118
|
+
# for linked worktrees whose directories have been deleted.
|
|
119
|
+
#
|
|
120
|
+
# @example Prune stale worktree metadata
|
|
121
|
+
# repo.worktrees.prune
|
|
122
|
+
#
|
|
123
|
+
# @return [String] stdout from the git command (typically empty)
|
|
124
|
+
#
|
|
125
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
126
|
+
#
|
|
43
127
|
def prune
|
|
44
|
-
|
|
128
|
+
worktree_repository.worktree_prune
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
# Resolves the {Git::Repository} for this collection of worktrees
|
|
134
|
+
#
|
|
135
|
+
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy).
|
|
136
|
+
# The `is_a?(Git::Base)` guard will be removed when {Git::Base} is deleted
|
|
137
|
+
# in Phase 4.
|
|
138
|
+
#
|
|
139
|
+
# @return [Git::Repository] the repository used to enumerate worktrees
|
|
140
|
+
#
|
|
141
|
+
# @api private
|
|
142
|
+
#
|
|
143
|
+
def worktree_repository
|
|
144
|
+
@base.is_a?(Git::Base) ? @base.facade_repository : @base
|
|
45
145
|
end
|
|
46
146
|
end
|
|
47
147
|
end
|
data/lib/git.rb
CHANGED
|
@@ -1,57 +1,63 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'active_support'
|
|
3
4
|
require 'active_support/deprecation'
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# configured according to the GIT_DEPRECATION_BEHAVIOR environment variable.
|
|
8
|
-
#
|
|
6
|
+
require 'git/version'
|
|
7
|
+
|
|
9
8
|
module Git
|
|
10
|
-
# The deprecation instance used to emit deprecation warnings for the Git gem
|
|
11
|
-
#
|
|
12
|
-
# @api public
|
|
13
9
|
Deprecation = ActiveSupport::Deprecation.new('5.0.0', 'Git')
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Deprecation.behavior = behavior.to_sym
|
|
26
|
-
end
|
|
11
|
+
# Minimum git version required by this gem
|
|
12
|
+
#
|
|
13
|
+
# Commands and features may require newer versions, but this is the absolute
|
|
14
|
+
# minimum supported version for the gem as a whole.
|
|
15
|
+
#
|
|
16
|
+
# @return [Git::Version]
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
#
|
|
20
|
+
MINIMUM_GIT_VERSION = Version.parse('2.28.0')
|
|
27
21
|
end
|
|
28
22
|
|
|
29
23
|
require 'git/author'
|
|
30
|
-
require 'git/base'
|
|
31
24
|
require 'git/branch'
|
|
25
|
+
require 'git/branch_info'
|
|
32
26
|
require 'git/branches'
|
|
33
27
|
require 'git/command_line_result'
|
|
34
28
|
require 'git/command_line'
|
|
29
|
+
require 'git/commands/init'
|
|
35
30
|
require 'git/config'
|
|
36
31
|
require 'git/diff'
|
|
32
|
+
require 'git/diff_file_numstat_info'
|
|
33
|
+
require 'git/diff_file_patch_info'
|
|
34
|
+
require 'git/diff_file_raw_info'
|
|
35
|
+
require 'git/diff_info'
|
|
36
|
+
require 'git/parsers/diff'
|
|
37
|
+
require 'git/diff_result'
|
|
38
|
+
require 'git/dirstat_info'
|
|
37
39
|
require 'git/encoding_utils'
|
|
38
40
|
require 'git/errors'
|
|
39
41
|
require 'git/escaped_path'
|
|
42
|
+
require 'git/execution_context'
|
|
43
|
+
require 'git/file_ref'
|
|
40
44
|
require 'git/fsck_object'
|
|
41
45
|
require 'git/fsck_result'
|
|
42
|
-
require 'git/
|
|
46
|
+
require 'git/version_constraint'
|
|
43
47
|
require 'git/lib'
|
|
44
48
|
require 'git/log'
|
|
45
49
|
require 'git/object'
|
|
46
|
-
require 'git/path'
|
|
47
50
|
require 'git/remote'
|
|
48
51
|
require 'git/repository'
|
|
52
|
+
require 'git/base'
|
|
49
53
|
require 'git/status'
|
|
50
54
|
require 'git/stash'
|
|
55
|
+
require 'git/stash_info'
|
|
51
56
|
require 'git/stashes'
|
|
57
|
+
require 'git/tag_delete_failure'
|
|
58
|
+
require 'git/tag_delete_result'
|
|
59
|
+
require 'git/tag_info'
|
|
52
60
|
require 'git/url'
|
|
53
|
-
require 'git/version'
|
|
54
|
-
require 'git/working_directory'
|
|
55
61
|
require 'git/worktree'
|
|
56
62
|
require 'git/worktrees'
|
|
57
63
|
|
|
@@ -62,29 +68,13 @@ require 'git/worktrees'
|
|
|
62
68
|
#
|
|
63
69
|
# @author Scott Chacon (mailto:schacon@gmail.com)
|
|
64
70
|
#
|
|
65
|
-
module Git
|
|
66
|
-
# Internal alias for Git::Lib, used by the gem itself after the public constant
|
|
67
|
-
# is deprecated. Code outside the gem should not reference this constant.
|
|
68
|
-
# @api private
|
|
69
|
-
LibImpl = remove_const(:Lib)
|
|
70
|
-
|
|
71
|
-
# @api private
|
|
72
|
-
def self.const_missing(name)
|
|
73
|
-
return super unless name == :Lib
|
|
74
|
-
|
|
75
|
-
Git::Deprecation.warn(
|
|
76
|
-
'Git::Lib is deprecated and will be removed in version 5.x. ' \
|
|
77
|
-
'Use the #lib accessor on the object returned by Git.init, Git.open, or Git.clone instead.'
|
|
78
|
-
)
|
|
79
|
-
const_set(:Lib, LibImpl)
|
|
80
|
-
end
|
|
81
|
-
|
|
71
|
+
module Git
|
|
82
72
|
# g.config('user.name', 'Scott Chacon') # sets value
|
|
83
73
|
# g.config('user.email', 'email@email.com') # sets value
|
|
84
74
|
# g.config('user.name') # returns 'Scott Chacon'
|
|
85
75
|
# g.config # returns whole config hash
|
|
86
76
|
def config(name = nil, value = nil)
|
|
87
|
-
lib =
|
|
77
|
+
lib = Git::Lib.new
|
|
88
78
|
if name && value
|
|
89
79
|
# set value
|
|
90
80
|
lib.config_set(name, value)
|
|
@@ -158,9 +148,9 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
158
148
|
#
|
|
159
149
|
# @param directory [Pathname, nil] The directory to clone into
|
|
160
150
|
#
|
|
161
|
-
# If `directory` is a relative
|
|
162
|
-
# given. If `
|
|
163
|
-
# directory.
|
|
151
|
+
# If `directory` is a relative path it is relative to the `:chdir` option if
|
|
152
|
+
# given. If `:chdir` is not given, `directory` is relative to the current
|
|
153
|
+
# working directory.
|
|
164
154
|
#
|
|
165
155
|
# If `nil`, `directory` will be set to the basename of the last component of
|
|
166
156
|
# the path from the `repository_url`. For example, for the URL:
|
|
@@ -211,9 +201,14 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
211
201
|
# @option options [String] :origin Use the value instead `origin` to track
|
|
212
202
|
# the upstream repository.
|
|
213
203
|
#
|
|
214
|
-
# @option options [Pathname] :
|
|
215
|
-
#
|
|
216
|
-
# `
|
|
204
|
+
# @option options [Pathname] :chdir Run `git clone` from within this directory.
|
|
205
|
+
#
|
|
206
|
+
# The `directory` parameter (or the repository basename when `directory` is nil)
|
|
207
|
+
# is resolved relative to `:chdir`, just as if you had `cd`'d into it before
|
|
208
|
+
# running `git clone`. The returned path is the join of `:chdir` and the
|
|
209
|
+
# cloned directory path.
|
|
210
|
+
#
|
|
211
|
+
# @option options [Pathname] :path Deprecated — use `:chdir` instead.
|
|
217
212
|
#
|
|
218
213
|
# @option options [Boolean] :recursive After the clone is created, initialize
|
|
219
214
|
# all submodules within, using their default settings.
|
|
@@ -226,8 +221,10 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
226
221
|
#
|
|
227
222
|
# @example Clone into a different directory `my-ruby-git`
|
|
228
223
|
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', 'my-ruby-git')
|
|
229
|
-
#
|
|
230
|
-
#
|
|
224
|
+
#
|
|
225
|
+
# @example Clone into a specific parent directory
|
|
226
|
+
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', chdir: '/path/to/projects')
|
|
227
|
+
# # clones into /path/to/projects/ruby-git
|
|
231
228
|
#
|
|
232
229
|
# @example Create a bare repository in the directory `ruby-git.git`
|
|
233
230
|
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true)
|
|
@@ -255,8 +252,6 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
255
252
|
# of the cloned local working copy or cloned repository.
|
|
256
253
|
#
|
|
257
254
|
def self.clone(repository_url, directory = nil, options = {})
|
|
258
|
-
clone_to_options = options.slice(:bare, :mirror)
|
|
259
|
-
directory ||= Git::URL.clone_to(repository_url, **clone_to_options)
|
|
260
255
|
Base.clone(repository_url, directory, options)
|
|
261
256
|
end
|
|
262
257
|
|
|
@@ -322,7 +317,7 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
322
317
|
# g.config('user.name') # returns 'Scott Chacon'
|
|
323
318
|
# g.config # returns whole config hash
|
|
324
319
|
def self.global_config(name = nil, value = nil)
|
|
325
|
-
lib =
|
|
320
|
+
lib = Git::Lib.new(nil, nil)
|
|
326
321
|
if name && value
|
|
327
322
|
# set value
|
|
328
323
|
lib.global_config_set(name, value)
|
|
@@ -364,6 +359,8 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
364
359
|
# and converted to an absolute path using
|
|
365
360
|
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
366
361
|
#
|
|
362
|
+
# @option options [Pathname] :separate_git_dir Alias for `:repository`.
|
|
363
|
+
#
|
|
367
364
|
# @option options [String, nil] :git_ssh An optional custom SSH command
|
|
368
365
|
#
|
|
369
366
|
# - If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
|
|
@@ -392,7 +389,30 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
392
389
|
# @see https://git-scm.com/docs/git-init git init
|
|
393
390
|
#
|
|
394
391
|
def self.init(directory = '.', options = {})
|
|
395
|
-
|
|
392
|
+
require_relative 'git/commands/init'
|
|
393
|
+
|
|
394
|
+
options = options.dup
|
|
395
|
+
options[:repository] ||= options.delete(:separate_git_dir)
|
|
396
|
+
init_opts = options.slice(:bare, :initial_branch)
|
|
397
|
+
init_opts[:separate_git_dir] = options[:repository] if options.key?(:repository)
|
|
398
|
+
Git::Commands::Init.new(Git::Lib.new(nil, options[:log])).call(directory, **init_opts)
|
|
399
|
+
|
|
400
|
+
open_initialized_repository(directory, options)
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Open the repository after initialization
|
|
404
|
+
#
|
|
405
|
+
# @param directory [String] the directory containing the repository
|
|
406
|
+
# @param options [Hash] the options hash
|
|
407
|
+
# @return [Git::Base] the opened repository
|
|
408
|
+
# @api private
|
|
409
|
+
#
|
|
410
|
+
private_class_method def self.open_initialized_repository(directory, options)
|
|
411
|
+
if options[:bare]
|
|
412
|
+
Git.bare(options[:repository] || directory, options.slice(:log, :git_ssh).compact)
|
|
413
|
+
else
|
|
414
|
+
Git.open(directory, options.slice(:log, :git_ssh, :index, :repository).compact)
|
|
415
|
+
end
|
|
396
416
|
end
|
|
397
417
|
|
|
398
418
|
# returns a Hash containing information about the references
|
|
@@ -404,7 +424,7 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
404
424
|
# @param [String|NilClass] location the target repository location or nil for '.'
|
|
405
425
|
# @return [{String=>Hash}] the available references of the target repo.
|
|
406
426
|
def self.ls_remote(location = nil, options = {})
|
|
407
|
-
|
|
427
|
+
Git::Lib.new.ls_remote(location, options)
|
|
408
428
|
end
|
|
409
429
|
|
|
410
430
|
# Open a an existing Git working directory
|
|
@@ -461,6 +481,37 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
461
481
|
Base.open(working_dir, options)
|
|
462
482
|
end
|
|
463
483
|
|
|
484
|
+
# Return the version of a git binary as a {Git::Version}
|
|
485
|
+
#
|
|
486
|
+
# @param binary_path [String, nil] path to the git binary; defaults to
|
|
487
|
+
# `Git::Base.config.binary_path`
|
|
488
|
+
#
|
|
489
|
+
# @return [Git::Version] the parsed git version
|
|
490
|
+
#
|
|
491
|
+
# @raise [Git::UnexpectedResultError] if the version output cannot be parsed
|
|
492
|
+
#
|
|
493
|
+
# @raise [Git::FailedError] if the git binary exits with a non-zero status
|
|
494
|
+
#
|
|
495
|
+
# @raise [Git::Error] if the binary is not found or fails to launch
|
|
496
|
+
#
|
|
497
|
+
# @example Default binary
|
|
498
|
+
# Git.git_version #=> #<Git::Version 2.42.0>
|
|
499
|
+
#
|
|
500
|
+
# @example Explicit binary path
|
|
501
|
+
# Git.git_version('/opt/homebrew/bin/git') #=> #<Git::Version 2.42.0>
|
|
502
|
+
#
|
|
503
|
+
def self.git_version(binary_path = nil)
|
|
504
|
+
path = binary_path || Git::Base.config.binary_path
|
|
505
|
+
Git::Lib.cached_git_version(path) { run_git_version(path) }
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# @api private
|
|
509
|
+
def self.run_git_version(path)
|
|
510
|
+
output = Git::Commands::Version.new(Git::ExecutionContext::Global.new(binary_path: path)).call.stdout
|
|
511
|
+
Git::Version.parse(output)
|
|
512
|
+
end
|
|
513
|
+
private_class_method :run_git_version
|
|
514
|
+
|
|
464
515
|
# Return the version of the git binary
|
|
465
516
|
#
|
|
466
517
|
# @example
|
|
@@ -468,7 +519,17 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
468
519
|
#
|
|
469
520
|
# @return [Array<Integer>] the version of the git binary
|
|
470
521
|
#
|
|
522
|
+
# @deprecated Use {Git.git_version} instead, which returns a {Git::Version} (not an Array).
|
|
523
|
+
# For the legacy array shape, call: `Git.git_version.to_a`.
|
|
524
|
+
# The optional binary_path argument is preserved: `Git.git_version(binary_path)`.
|
|
525
|
+
#
|
|
471
526
|
def self.binary_version(binary_path = Git::Base.config.binary_path)
|
|
472
|
-
|
|
527
|
+
Git::Deprecation.warn(
|
|
528
|
+
'Git.binary_version is deprecated and will be removed in 6.0. ' \
|
|
529
|
+
'Use Git.git_version instead, which returns a Git::Version ' \
|
|
530
|
+
'(not an Array). For the legacy array shape, call: Git.git_version.to_a. ' \
|
|
531
|
+
'The optional binary_path argument is preserved: Git.git_version(binary_path).'
|
|
532
|
+
)
|
|
533
|
+
git_version(binary_path).to_a
|
|
473
534
|
end
|
|
474
535
|
end
|