git 1.19.1 → 5.5.0
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/.yardopts +5 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +689 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +1175 -97
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +476 -320
- data/UPGRADING.md +1138 -0
- data/git.gemspec +124 -36
- data/lib/git/author.rb +39 -7
- data/lib/git/author_info.rb +66 -0
- data/lib/git/branch.rb +615 -65
- data/lib/git/branch_delete_failure.rb +34 -0
- data/lib/git/branch_delete_result.rb +66 -0
- data/lib/git/branch_info.rb +237 -0
- data/lib/git/branches.rb +167 -44
- data/lib/git/command_line/base.rb +247 -0
- data/lib/git/command_line/capturing.rb +308 -0
- data/lib/git/command_line/result.rb +88 -0
- data/lib/git/command_line/streaming.rb +236 -0
- data/lib/git/command_line.rb +52 -0
- data/lib/git/commands/add.rb +139 -0
- data/lib/git/commands/am/abort.rb +43 -0
- data/lib/git/commands/am/apply.rb +263 -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 +49 -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 +242 -0
- data/lib/git/commands/archive/list_formats.rb +46 -0
- data/lib/git/commands/archive.rb +145 -0
- data/lib/git/commands/arguments.rb +4521 -0
- data/lib/git/commands/base.rb +502 -0
- data/lib/git/commands/branch/copy.rb +102 -0
- data/lib/git/commands/branch/create.rb +177 -0
- data/lib/git/commands/branch/delete.rb +88 -0
- data/lib/git/commands/branch/list.rb +178 -0
- data/lib/git/commands/branch/move.rb +102 -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 +53 -0
- data/lib/git/commands/branch.rb +34 -0
- data/lib/git/commands/cat_file/batch.rb +385 -0
- data/lib/git/commands/cat_file/filtered.rb +105 -0
- data/lib/git/commands/cat_file/raw.rb +271 -0
- data/lib/git/commands/cat_file.rb +49 -0
- data/lib/git/commands/checkout/branch.rb +153 -0
- data/lib/git/commands/checkout/files.rb +116 -0
- data/lib/git/commands/checkout.rb +38 -0
- data/lib/git/commands/checkout_index.rb +106 -0
- data/lib/git/commands/clean.rb +102 -0
- data/lib/git/commands/clone.rb +241 -0
- data/lib/git/commands/commit.rb +273 -0
- data/lib/git/commands/commit_tree.rb +101 -0
- data/lib/git/commands/config_option_syntax/add.rb +86 -0
- data/lib/git/commands/config_option_syntax/get.rb +121 -0
- data/lib/git/commands/config_option_syntax/get_all.rb +118 -0
- data/lib/git/commands/config_option_syntax/get_color.rb +95 -0
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +96 -0
- data/lib/git/commands/config_option_syntax/get_regexp.rb +119 -0
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +111 -0
- data/lib/git/commands/config_option_syntax/list.rb +111 -0
- data/lib/git/commands/config_option_syntax/remove_section.rb +79 -0
- data/lib/git/commands/config_option_syntax/rename_section.rb +83 -0
- data/lib/git/commands/config_option_syntax/replace_all.rb +109 -0
- data/lib/git/commands/config_option_syntax/set.rb +119 -0
- data/lib/git/commands/config_option_syntax/unset.rb +92 -0
- data/lib/git/commands/config_option_syntax/unset_all.rb +94 -0
- data/lib/git/commands/config_option_syntax.rb +56 -0
- data/lib/git/commands/describe.rb +156 -0
- data/lib/git/commands/diff.rb +657 -0
- data/lib/git/commands/diff_files.rb +519 -0
- data/lib/git/commands/diff_index.rb +499 -0
- data/lib/git/commands/fetch.rb +354 -0
- data/lib/git/commands/fsck.rb +138 -0
- data/lib/git/commands/gc.rb +134 -0
- data/lib/git/commands/grep.rb +339 -0
- data/lib/git/commands/init.rb +101 -0
- data/lib/git/commands/log.rb +634 -0
- data/lib/git/commands/ls_files.rb +195 -0
- data/lib/git/commands/ls_remote.rb +161 -0
- data/lib/git/commands/ls_tree.rb +135 -0
- data/lib/git/commands/maintenance/register.rb +77 -0
- data/lib/git/commands/maintenance/run.rb +109 -0
- data/lib/git/commands/maintenance/start.rb +71 -0
- data/lib/git/commands/maintenance/stop.rb +60 -0
- data/lib/git/commands/maintenance/unregister.rb +84 -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 +250 -0
- data/lib/git/commands/merge.rb +28 -0
- data/lib/git/commands/merge_base.rb +91 -0
- data/lib/git/commands/mv.rb +82 -0
- data/lib/git/commands/name_rev.rb +119 -0
- data/lib/git/commands/pull.rb +382 -0
- data/lib/git/commands/push.rb +251 -0
- data/lib/git/commands/read_tree.rb +154 -0
- data/lib/git/commands/remote/add.rb +96 -0
- data/lib/git/commands/remote/get_url.rb +68 -0
- data/lib/git/commands/remote/list.rb +56 -0
- data/lib/git/commands/remote/prune.rb +63 -0
- data/lib/git/commands/remote/remove.rb +52 -0
- data/lib/git/commands/remote/rename.rb +76 -0
- data/lib/git/commands/remote/set_branches.rb +70 -0
- data/lib/git/commands/remote/set_head.rb +89 -0
- data/lib/git/commands/remote/set_url.rb +78 -0
- data/lib/git/commands/remote/set_url_add.rb +70 -0
- data/lib/git/commands/remote/set_url_delete.rb +71 -0
- data/lib/git/commands/remote/show.rb +77 -0
- data/lib/git/commands/remote/update.rb +79 -0
- data/lib/git/commands/remote.rb +42 -0
- data/lib/git/commands/repack.rb +281 -0
- data/lib/git/commands/reset.rb +154 -0
- data/lib/git/commands/rev_parse.rb +304 -0
- data/lib/git/commands/revert/abort.rb +45 -0
- data/lib/git/commands/revert/continue.rb +62 -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 +158 -0
- data/lib/git/commands/revert.rb +29 -0
- data/lib/git/commands/rm.rb +113 -0
- data/lib/git/commands/show.rb +632 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +119 -0
- data/lib/git/commands/show_ref/exists.rb +80 -0
- data/lib/git/commands/show_ref/list.rb +149 -0
- data/lib/git/commands/show_ref/verify.rb +122 -0
- data/lib/git/commands/show_ref.rb +42 -0
- data/lib/git/commands/stash/apply.rb +81 -0
- data/lib/git/commands/stash/branch.rb +67 -0
- data/lib/git/commands/stash/clear.rb +43 -0
- data/lib/git/commands/stash/create.rb +60 -0
- data/lib/git/commands/stash/drop.rb +73 -0
- data/lib/git/commands/stash/list.rb +43 -0
- data/lib/git/commands/stash/pop.rb +87 -0
- data/lib/git/commands/stash/push.rb +112 -0
- data/lib/git/commands/stash/show.rb +158 -0
- data/lib/git/commands/stash/store.rb +72 -0
- data/lib/git/commands/stash.rb +38 -0
- data/lib/git/commands/status.rb +174 -0
- data/lib/git/commands/symbolic_ref/delete.rb +72 -0
- data/lib/git/commands/symbolic_ref/read.rb +99 -0
- data/lib/git/commands/symbolic_ref/update.rb +79 -0
- data/lib/git/commands/symbolic_ref.rb +38 -0
- data/lib/git/commands/tag/create.rb +142 -0
- data/lib/git/commands/tag/delete.rb +57 -0
- data/lib/git/commands/tag/list.rb +146 -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 +145 -0
- data/lib/git/commands/update_ref/delete.rb +90 -0
- data/lib/git/commands/update_ref/update.rb +103 -0
- data/lib/git/commands/update_ref.rb +42 -0
- data/lib/git/commands/version.rb +60 -0
- data/lib/git/commands/worktree/add.rb +139 -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 +88 -0
- data/lib/git/config.rb +72 -5
- data/lib/git/config_entry_info.rb +106 -0
- data/lib/git/configuring.rb +795 -0
- data/lib/git/detached_head_info.rb +57 -0
- data/lib/git/diff.rb +437 -86
- data/lib/git/diff_file_numstat_info.rb +31 -0
- data/lib/git/diff_file_patch_info.rb +136 -0
- data/lib/git/diff_file_raw_info.rb +129 -0
- data/lib/git/diff_info.rb +162 -0
- data/lib/git/diff_path_status.rb +107 -0
- data/lib/git/diff_result.rb +34 -0
- data/lib/git/diff_stats.rb +111 -0
- data/lib/git/dirstat_info.rb +102 -0
- data/lib/git/encoding_utils.rb +32 -1
- data/lib/git/errors.rb +285 -0
- data/lib/git/escaped_path.rb +57 -5
- data/lib/git/execution_context/global.rb +31 -0
- data/lib/git/execution_context/repository.rb +151 -0
- data/lib/git/execution_context.rb +559 -0
- data/lib/git/factories.rb +813 -0
- data/lib/git/file_ref.rb +77 -0
- data/lib/git/fsck_object.rb +56 -0
- data/lib/git/fsck_result.rb +132 -0
- data/lib/git/log.rb +306 -90
- data/lib/git/object.rb +563 -141
- data/lib/git/parsers/branch.rb +240 -0
- data/lib/git/parsers/cat_file.rb +111 -0
- data/lib/git/parsers/config_entry.rb +110 -0
- data/lib/git/parsers/diff.rb +792 -0
- data/lib/git/parsers/fsck.rb +144 -0
- data/lib/git/parsers/grep.rb +42 -0
- data/lib/git/parsers/ls_remote.rb +79 -0
- data/lib/git/parsers/ls_tree.rb +58 -0
- data/lib/git/parsers/remote.rb +162 -0
- data/lib/git/parsers/stash.rb +292 -0
- data/lib/git/parsers/status.rb +251 -0
- data/lib/git/parsers/tag.rb +341 -0
- data/lib/git/parsers/worktree.rb +185 -0
- data/lib/git/path_resolver.rb +206 -0
- data/lib/git/remote.rb +165 -12
- data/lib/git/remote_info.rb +203 -0
- data/lib/git/repository/branching.rb +964 -0
- data/lib/git/repository/committing.rb +246 -0
- data/lib/git/repository/context_helpers.rb +293 -0
- data/lib/git/repository/diffing.rb +785 -0
- data/lib/git/repository/inspecting.rb +252 -0
- data/lib/git/repository/logging.rb +410 -0
- data/lib/git/repository/maintenance.rb +65 -0
- data/lib/git/repository/merging.rb +451 -0
- data/lib/git/repository/object_operations.rb +1551 -0
- data/lib/git/repository/remote_operations.rb +984 -0
- data/lib/git/repository/shared_private.rb +120 -0
- data/lib/git/repository/staging.rb +587 -0
- data/lib/git/repository/stashing.rb +623 -0
- data/lib/git/repository/status_operations.rb +249 -0
- data/lib/git/repository/worktree_operations.rb +339 -0
- data/lib/git/repository.rb +484 -2
- data/lib/git/stash.rb +109 -12
- data/lib/git/stash_info.rb +102 -0
- data/lib/git/stashes.rb +169 -26
- data/lib/git/status.rb +308 -122
- data/lib/git/status_file_info.rb +258 -0
- data/lib/git/status_info.rb +189 -0
- data/lib/git/tag_delete_failure.rb +34 -0
- data/lib/git/tag_delete_result.rb +66 -0
- data/lib/git/tag_info.rb +99 -0
- data/lib/git/url.rb +15 -8
- data/lib/git/version.rb +113 -2
- data/lib/git/version_constraint.rb +85 -0
- data/lib/git/worktree.rb +150 -8
- data/lib/git/worktree_info.rb +128 -0
- data/lib/git/worktrees.rb +118 -13
- data/lib/git.rb +632 -234
- metadata +369 -54
- data/.github/stale.yml +0 -25
- data/.github/workflows/continuous_integration.yml +0 -49
- data/.gitignore +0 -10
- data/Dockerfile.changelog-rs +0 -12
- data/Gemfile +0 -5
- data/ISSUE_TEMPLATE.md +0 -15
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/Rakefile +0 -60
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/base.rb +0 -711
- data/lib/git/command_line_result.rb +0 -86
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/index.rb +0 -5
- data/lib/git/lib.rb +0 -1328
- data/lib/git/path.rb +0 -31
- data/lib/git/signaled_error.rb +0 -50
- data/lib/git/working_directory.rb +0 -4
data/lib/git/url.rb
CHANGED
|
@@ -8,9 +8,10 @@ module Git
|
|
|
8
8
|
# Any URL that can be passed to `git clone` can be parsed by this class.
|
|
9
9
|
#
|
|
10
10
|
# @see https://git-scm.com/docs/git-clone#_git_urls GIT URLs
|
|
11
|
-
# @see https://github.com/sporkmonger/addressable Addresable::URI
|
|
12
11
|
#
|
|
13
|
-
# @
|
|
12
|
+
# @see https://github.com/sporkmonger/addressable Addressable::URI
|
|
13
|
+
#
|
|
14
|
+
# @api private
|
|
14
15
|
#
|
|
15
16
|
class URL
|
|
16
17
|
# Regexp used to match a Git URL with an alternative SSH syntax
|
|
@@ -23,14 +24,14 @@ module Git
|
|
|
23
24
|
:(?!/) # : serparator is required, but must not be followed by /
|
|
24
25
|
(?<path>.*?) # path is required
|
|
25
26
|
$
|
|
26
|
-
}x
|
|
27
|
+
}x
|
|
27
28
|
|
|
28
29
|
# Parse a Git URL and return an Addressable::URI object
|
|
29
30
|
#
|
|
30
31
|
# The URI returned can be converted back to a string with 'to_s'. This is
|
|
31
32
|
# guaranteed to return the same URL string that was parsed.
|
|
32
33
|
#
|
|
33
|
-
# @example
|
|
34
|
+
# @example Parsing clone target from HTTPS and local paths
|
|
34
35
|
# uri = Git::URL.parse('https://github.com/ruby-git/ruby-git.git')
|
|
35
36
|
# #=> #<Addressable::URI:0x44c URI:https://github.com/ruby-git/ruby-git.git>
|
|
36
37
|
# uri.scheme #=> "https"
|
|
@@ -54,11 +55,15 @@ module Git
|
|
|
54
55
|
|
|
55
56
|
# The directory `git clone` would use for the repository directory for the given URL
|
|
56
57
|
#
|
|
57
|
-
# @example
|
|
58
|
+
# @example Deriving the clone directory name
|
|
58
59
|
# Git::URL.clone_to('https://github.com/ruby-git/ruby-git.git') #=> 'ruby-git'
|
|
59
60
|
#
|
|
60
61
|
# @param url [String] the Git URL containing the repository directory
|
|
61
62
|
#
|
|
63
|
+
# @param bare [Boolean] whether the repository should be cloned as bare
|
|
64
|
+
#
|
|
65
|
+
# @param mirror [Boolean] whether the repository should be cloned as a mirror
|
|
66
|
+
#
|
|
62
67
|
# @return [String] the name of the repository directory
|
|
63
68
|
#
|
|
64
69
|
def self.clone_to(url, bare: false, mirror: false)
|
|
@@ -80,7 +85,7 @@ module Git
|
|
|
80
85
|
# This class is necessary to ensure that #to_s returns the same string
|
|
81
86
|
# that was passed to the initializer.
|
|
82
87
|
#
|
|
83
|
-
# @api
|
|
88
|
+
# @api private
|
|
84
89
|
#
|
|
85
90
|
class GitAltURI < Addressable::URI
|
|
86
91
|
# Create a new GitAltURI object
|
|
@@ -90,7 +95,9 @@ module Git
|
|
|
90
95
|
# uri.to_s #=> 'james@github.com/james/ruby-git'
|
|
91
96
|
#
|
|
92
97
|
# @param user [String, nil] the user from the URL or nil
|
|
98
|
+
#
|
|
93
99
|
# @param host [String] the host from the URL
|
|
100
|
+
#
|
|
94
101
|
# @param path [String] the path from the URL
|
|
95
102
|
#
|
|
96
103
|
def initialize(user:, host:, path:)
|
|
@@ -118,9 +125,9 @@ module Git
|
|
|
118
125
|
#
|
|
119
126
|
def to_s
|
|
120
127
|
if user
|
|
121
|
-
"#{user}@#{host}:#{path[1
|
|
128
|
+
"#{user}@#{host}:#{path[1..]}"
|
|
122
129
|
else
|
|
123
|
-
"#{host}:#{path[1
|
|
130
|
+
"#{host}:#{path[1..]}"
|
|
124
131
|
end
|
|
125
132
|
end
|
|
126
133
|
end
|
data/lib/git/version.rb
CHANGED
|
@@ -1,5 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Git
|
|
2
4
|
# The current gem version
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
+
#
|
|
6
|
+
# @return [String] the current gem version
|
|
7
|
+
VERSION = '5.5.0'
|
|
8
|
+
|
|
9
|
+
# Represents a git version with major, minor, and patch components
|
|
10
|
+
#
|
|
11
|
+
# Git versions follow a strict major.minor.patch format. This class provides
|
|
12
|
+
# parsing from git command output (which may include platform suffixes) and
|
|
13
|
+
# comparison operations for version gating.
|
|
14
|
+
#
|
|
15
|
+
# @!attribute [r] major
|
|
16
|
+
# The major version number
|
|
17
|
+
#
|
|
18
|
+
# @return [Integer]
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [r] minor
|
|
21
|
+
# The minor version number
|
|
22
|
+
#
|
|
23
|
+
# @return [Integer]
|
|
24
|
+
#
|
|
25
|
+
# @!attribute [r] patch
|
|
26
|
+
# The patch version number
|
|
27
|
+
#
|
|
28
|
+
# @return [Integer]
|
|
29
|
+
#
|
|
30
|
+
# @example Creating a version directly
|
|
31
|
+
# version = Git::Version.new(2, 42, 1)
|
|
32
|
+
# version.to_s #=> "2.42.1"
|
|
33
|
+
#
|
|
34
|
+
# @example Parsing from git version output
|
|
35
|
+
# Git::Version.parse('git version 2.42.1') #=> Git::Version.new(2, 42, 1)
|
|
36
|
+
# Git::Version.parse('2.39.2 (Apple Git-143)') #=> Git::Version.new(2, 39, 2)
|
|
37
|
+
#
|
|
38
|
+
# @example Parsing versions with platform suffixes
|
|
39
|
+
# Git::Version.parse('2.42.0.windows.1') #=> Git::Version.new(2, 42, 0)
|
|
40
|
+
#
|
|
41
|
+
# @example Comparing versions
|
|
42
|
+
# Git::Version.new(2, 42, 1) > Git::Version.new(2, 28, 0) #=> true
|
|
43
|
+
#
|
|
44
|
+
# @api public
|
|
45
|
+
#
|
|
46
|
+
Version = Data.define(:major, :minor, :patch) do
|
|
47
|
+
include Comparable
|
|
48
|
+
|
|
49
|
+
# Parse a version string into a Version object
|
|
50
|
+
#
|
|
51
|
+
# Handles git's version output format, stripping platform suffixes
|
|
52
|
+
# (like `.windows.1` or `.vfs.0`) and padding two-segment versions
|
|
53
|
+
# to three segments.
|
|
54
|
+
#
|
|
55
|
+
# @example Parse various version string formats
|
|
56
|
+
# Git::Version.parse('2.42.1') #=> Git::Version.new(2, 42, 1)
|
|
57
|
+
# Git::Version.parse('git version 2.42.1') #=> Git::Version.new(2, 42, 1)
|
|
58
|
+
# Git::Version.parse('2.42.0.windows.1') #=> Git::Version.new(2, 42, 0)
|
|
59
|
+
#
|
|
60
|
+
# @param string [String] version string to parse
|
|
61
|
+
#
|
|
62
|
+
# @return [Git::Version] the parsed version
|
|
63
|
+
#
|
|
64
|
+
# @raise [Git::UnexpectedResultError] if the string cannot be parsed as a version
|
|
65
|
+
#
|
|
66
|
+
def self.parse(string)
|
|
67
|
+
version_match = string&.match(/(\d+)\.(\d+)(?:\.(\d+))?/)
|
|
68
|
+
raise Git::UnexpectedResultError, "Invalid version: #{string.inspect}" unless version_match
|
|
69
|
+
|
|
70
|
+
major = version_match[1].to_i
|
|
71
|
+
minor = version_match[2].to_i
|
|
72
|
+
patch = (version_match[3] || '0').to_i
|
|
73
|
+
|
|
74
|
+
new(major, minor, patch)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Compare this version to another
|
|
78
|
+
#
|
|
79
|
+
# @param other [Git::Version] the version to compare to
|
|
80
|
+
#
|
|
81
|
+
# @return [Integer] -1, 0, or 1
|
|
82
|
+
#
|
|
83
|
+
def <=>(other)
|
|
84
|
+
[major, minor, patch] <=> [other.major, other.minor, other.patch]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Return the version as a dotted string
|
|
88
|
+
#
|
|
89
|
+
# @return [String] the version in "major.minor.patch" format
|
|
90
|
+
#
|
|
91
|
+
def to_s
|
|
92
|
+
"#{major}.#{minor}.#{patch}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Return a readable representation
|
|
96
|
+
#
|
|
97
|
+
# @return [String] inspect string
|
|
98
|
+
#
|
|
99
|
+
def inspect
|
|
100
|
+
"#<Git::Version #{self}>"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Return the version as an array of integers
|
|
104
|
+
#
|
|
105
|
+
# Useful when legacy code expects the array shape returned by the
|
|
106
|
+
# deprecated `Git::Lib#current_command_version` method.
|
|
107
|
+
#
|
|
108
|
+
# @example Get version as integer components
|
|
109
|
+
# Git.git_version.to_a #=> [2, 42, 0]
|
|
110
|
+
#
|
|
111
|
+
# @return [Array<Integer>] [major, minor, patch]
|
|
112
|
+
def to_a
|
|
113
|
+
deconstruct
|
|
114
|
+
end
|
|
115
|
+
end
|
|
5
116
|
end
|
|
@@ -0,0 +1,85 @@
|
|
|
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
|
+
# Initialize a new VersionConstraint
|
|
30
|
+
#
|
|
31
|
+
# @param min [Git::Version, nil] minimum version (inclusive)
|
|
32
|
+
#
|
|
33
|
+
# @param before [Git::Version, nil] upper bound version (exclusive)
|
|
34
|
+
#
|
|
35
|
+
def initialize(min: nil, before: nil)
|
|
36
|
+
super
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Check if the given version is too old (below the minimum)
|
|
40
|
+
#
|
|
41
|
+
# @param version [Git::Version] the version to check
|
|
42
|
+
#
|
|
43
|
+
# @return [Boolean] true if version is below the minimum, false otherwise
|
|
44
|
+
#
|
|
45
|
+
def too_old?(version)
|
|
46
|
+
return false unless min
|
|
47
|
+
|
|
48
|
+
version < min
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Check if the given version is too new (at or past the upper bound)
|
|
52
|
+
#
|
|
53
|
+
# @param version [Git::Version] the version to check
|
|
54
|
+
#
|
|
55
|
+
# @return [Boolean] true if version is at or past the upper bound, false otherwise
|
|
56
|
+
#
|
|
57
|
+
def too_new?(version)
|
|
58
|
+
return false unless before
|
|
59
|
+
|
|
60
|
+
version >= before
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Check if the given version satisfies this constraint
|
|
64
|
+
#
|
|
65
|
+
# @param version [Git::Version] the version to check
|
|
66
|
+
#
|
|
67
|
+
# @return [Boolean] true if the version satisfies the constraint
|
|
68
|
+
#
|
|
69
|
+
def satisfied_by?(version)
|
|
70
|
+
!too_old?(version) && !too_new?(version)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Return a human-readable representation of this constraint
|
|
74
|
+
#
|
|
75
|
+
# @return [String] the constraint in git version range form
|
|
76
|
+
#
|
|
77
|
+
def to_s
|
|
78
|
+
return ">= #{min}, < #{before}" if min && before
|
|
79
|
+
return ">= #{min}" if min
|
|
80
|
+
return "< #{before}" if before
|
|
81
|
+
|
|
82
|
+
'any version'
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
data/lib/git/worktree.rb
CHANGED
|
@@ -1,38 +1,180 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Git
|
|
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
|
+
# @deprecated Use {Git::Repository::WorktreeOperations#worktree_list} and the
|
|
16
|
+
# path-based worktree operations on {Git::Repository} instead
|
|
17
|
+
#
|
|
18
|
+
# {Git::Repository::WorktreeOperations#worktree_list} returns immutable
|
|
19
|
+
# {Git::WorktreeInfo} value objects. Operations that lived on this class are
|
|
20
|
+
# called on the repository with the worktree path instead (for example
|
|
21
|
+
# {Git::Repository::WorktreeOperations#worktree_add} and
|
|
22
|
+
# {Git::Repository::WorktreeOperations#worktree_remove}). {#gcommit},
|
|
23
|
+
# {#add}, and {#remove} each emit a deprecation warning; the `dir`, `full`,
|
|
24
|
+
# `to_s`, and `to_a` readers do not.
|
|
25
|
+
#
|
|
26
|
+
# @api public
|
|
27
|
+
#
|
|
28
|
+
class Worktree
|
|
29
|
+
# Full worktree descriptor including the optional commitish
|
|
30
|
+
#
|
|
31
|
+
# @return [String] the filesystem path, space-separated with the commitish
|
|
32
|
+
# when one was given at construction time
|
|
33
|
+
#
|
|
34
|
+
attr_accessor :full
|
|
4
35
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
36
|
+
# Filesystem path of this worktree
|
|
37
|
+
#
|
|
38
|
+
# @return [String] the filesystem path of the worktree directory
|
|
39
|
+
#
|
|
40
|
+
attr_accessor :dir
|
|
8
41
|
|
|
42
|
+
# Creates a new Worktree object
|
|
43
|
+
#
|
|
44
|
+
# @param base [Git::Repository] the repository that owns this
|
|
45
|
+
# worktree
|
|
46
|
+
#
|
|
47
|
+
# @param dir [String] filesystem path of the worktree
|
|
48
|
+
#
|
|
49
|
+
# @param gcommit [String, nil] commitish associated with the worktree;
|
|
50
|
+
# when non-nil it is appended to {#full}
|
|
51
|
+
#
|
|
52
|
+
# @return [void]
|
|
53
|
+
#
|
|
9
54
|
def initialize(base, dir, gcommit = nil)
|
|
10
55
|
@full = dir
|
|
11
|
-
@full +=
|
|
56
|
+
@full += " #{gcommit}" unless gcommit.nil?
|
|
12
57
|
@base = base
|
|
13
58
|
@dir = dir
|
|
14
59
|
@gcommit = gcommit
|
|
15
60
|
end
|
|
16
61
|
|
|
62
|
+
# Returns the commit (or commitish string) associated with this worktree
|
|
63
|
+
#
|
|
64
|
+
# When a commitish string was supplied at construction time (e.g. by
|
|
65
|
+
# {Git::Worktrees} which passes the raw SHA from `git worktree list`), that
|
|
66
|
+
# string is returned as-is. Otherwise the value is lazily resolved on first
|
|
67
|
+
# call via `worktree_repository.gcommit(@full)` and the result is memoized.
|
|
68
|
+
#
|
|
69
|
+
# @example When resolved lazily (no commitish at construction)
|
|
70
|
+
# worktree = repo.worktree('/path/to/wt')
|
|
71
|
+
# worktree.gcommit # => #<Git::Object::Commit ...>
|
|
72
|
+
#
|
|
73
|
+
# @example When the commitish was given at construction
|
|
74
|
+
# worktree = repo.worktrees['/path/to/wt']
|
|
75
|
+
# worktree.gcommit # => "4bef5ab8c9..." (raw SHA string)
|
|
76
|
+
#
|
|
77
|
+
# @return [Git::Object::Commit, String] a commit object when lazily
|
|
78
|
+
# resolved, or the raw commitish string when pre-set at construction
|
|
79
|
+
#
|
|
80
|
+
# @raise [Git::FailedError] if git must resolve the commit and exits with a
|
|
81
|
+
# non-zero exit status
|
|
82
|
+
#
|
|
83
|
+
# @deprecated Use {Git::WorktreeInfo#head} from
|
|
84
|
+
# {Git::Repository::WorktreeOperations#worktree_list} instead
|
|
85
|
+
#
|
|
86
|
+
# `head` is always the commit SHA as a `String` (or `nil` for a bare main
|
|
87
|
+
# worktree). Call `repo.gcommit(info.head)` for the commit object.
|
|
88
|
+
#
|
|
89
|
+
# @see Git::WorktreeInfo#head
|
|
90
|
+
#
|
|
17
91
|
def gcommit
|
|
18
|
-
|
|
92
|
+
Git::Deprecation.warn(
|
|
93
|
+
'Git::Worktree#gcommit is deprecated and will be removed in v6.0.0. ' \
|
|
94
|
+
'Use Git::WorktreeInfo#head from Git::Repository#worktree_list instead.'
|
|
95
|
+
)
|
|
96
|
+
@gcommit ||= worktree_repository.gcommit(@full)
|
|
19
97
|
@gcommit
|
|
20
98
|
end
|
|
21
99
|
|
|
100
|
+
# Creates this worktree on disk
|
|
101
|
+
#
|
|
102
|
+
# Runs `git worktree add` for {#dir}, optionally at the commitish passed
|
|
103
|
+
# at construction time.
|
|
104
|
+
#
|
|
105
|
+
# @example Add a worktree
|
|
106
|
+
# worktree = repo.worktree('/path/to/new-worktree')
|
|
107
|
+
# worktree.add
|
|
108
|
+
#
|
|
109
|
+
# @return [String] stdout from the git command
|
|
110
|
+
#
|
|
111
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
112
|
+
#
|
|
113
|
+
# @deprecated Use {Git::Repository::WorktreeOperations#worktree_add} instead
|
|
114
|
+
#
|
|
115
|
+
# @see Git::Repository::WorktreeOperations#worktree_add
|
|
116
|
+
#
|
|
22
117
|
def add
|
|
23
|
-
|
|
118
|
+
Git::Deprecation.warn(
|
|
119
|
+
'Git::Worktree#add is deprecated and will be removed in v6.0.0. ' \
|
|
120
|
+
'Use Git::Repository#worktree_add instead.'
|
|
121
|
+
)
|
|
122
|
+
worktree_repository.worktree_add(@dir, @gcommit)
|
|
24
123
|
end
|
|
25
124
|
|
|
125
|
+
# Removes this worktree from disk
|
|
126
|
+
#
|
|
127
|
+
# Runs `git worktree remove` for {#dir}.
|
|
128
|
+
#
|
|
129
|
+
# @example Remove a worktree
|
|
130
|
+
# worktree.remove
|
|
131
|
+
#
|
|
132
|
+
# @return [String] stdout from the git command (typically empty)
|
|
133
|
+
#
|
|
134
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
135
|
+
#
|
|
136
|
+
# @deprecated Use {Git::Repository::WorktreeOperations#worktree_remove} instead
|
|
137
|
+
#
|
|
138
|
+
# @see Git::Repository::WorktreeOperations#worktree_remove
|
|
139
|
+
#
|
|
26
140
|
def remove
|
|
27
|
-
|
|
141
|
+
Git::Deprecation.warn(
|
|
142
|
+
'Git::Worktree#remove is deprecated and will be removed in v6.0.0. ' \
|
|
143
|
+
'Use Git::Repository#worktree_remove instead.'
|
|
144
|
+
)
|
|
145
|
+
worktree_repository.worktree_remove(@dir)
|
|
28
146
|
end
|
|
29
147
|
|
|
148
|
+
# Returns an array containing the full worktree descriptor
|
|
149
|
+
#
|
|
150
|
+
# @example Get the descriptor array
|
|
151
|
+
# worktree.to_a # => ["/path/to/worktree"]
|
|
152
|
+
#
|
|
153
|
+
# @return [Array<String>] array containing the full worktree descriptor
|
|
154
|
+
#
|
|
30
155
|
def to_a
|
|
31
156
|
[@full]
|
|
32
157
|
end
|
|
33
158
|
|
|
159
|
+
# Returns the full worktree descriptor as a string
|
|
160
|
+
#
|
|
161
|
+
# @example Get the descriptor string
|
|
162
|
+
# worktree.to_s # => "/path/to/worktree"
|
|
163
|
+
#
|
|
164
|
+
# @return [String] the full worktree descriptor (path and optional commitish)
|
|
165
|
+
#
|
|
34
166
|
def to_s
|
|
35
167
|
@full
|
|
36
168
|
end
|
|
169
|
+
|
|
170
|
+
private
|
|
171
|
+
|
|
172
|
+
# @return [Git::Repository] the repository used for worktree operations
|
|
173
|
+
#
|
|
174
|
+
# @api private
|
|
175
|
+
#
|
|
176
|
+
def worktree_repository
|
|
177
|
+
@base
|
|
178
|
+
end
|
|
37
179
|
end
|
|
38
180
|
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Immutable value object for one entry of `git worktree list`
|
|
5
|
+
#
|
|
6
|
+
# Each entry carries what `git worktree list --porcelain` reports for a
|
|
7
|
+
# worktree: its path, the checked-out HEAD and branch, and whether it is bare,
|
|
8
|
+
# detached, locked, or prunable, with the reason git gives for the last two.
|
|
9
|
+
#
|
|
10
|
+
# @example A locked linked worktree with a branch checked out
|
|
11
|
+
# info = Git::WorktreeInfo.new(
|
|
12
|
+
# path: '/tmp/wt/linked',
|
|
13
|
+
# head: 'f3e2c1ffb860086504eeb27b77a1d0028b68fd8f',
|
|
14
|
+
# branch: 'refs/heads/linked',
|
|
15
|
+
# bare: false,
|
|
16
|
+
# detached: false,
|
|
17
|
+
# locked: true,
|
|
18
|
+
# lock_reason: 'on purpose',
|
|
19
|
+
# prunable: false,
|
|
20
|
+
# prune_reason: nil
|
|
21
|
+
# )
|
|
22
|
+
#
|
|
23
|
+
# info.path # => '/tmp/wt/linked'
|
|
24
|
+
# info.head # => 'f3e2c1ffb860086504eeb27b77a1d0028b68fd8f'
|
|
25
|
+
# info.branch # => 'refs/heads/linked'
|
|
26
|
+
# info.locked? # => true
|
|
27
|
+
# info.lock_reason # => 'on purpose'
|
|
28
|
+
# info.detached? # => false
|
|
29
|
+
# info.to_s # => '/tmp/wt/linked'
|
|
30
|
+
#
|
|
31
|
+
# @example Pass an entry back to a worktree operation
|
|
32
|
+
# info = repo.worktree_list.find { |w| w.branch == 'refs/heads/linked' }
|
|
33
|
+
# repo.worktree_remove(info)
|
|
34
|
+
#
|
|
35
|
+
# @see Git::Repository::WorktreeOperations#worktree_list for the repository
|
|
36
|
+
# method that returns these
|
|
37
|
+
#
|
|
38
|
+
# @api public
|
|
39
|
+
#
|
|
40
|
+
# @!attribute [r] path
|
|
41
|
+
# @return [String] the worktree directory as git reports it
|
|
42
|
+
#
|
|
43
|
+
# @!attribute [r] head
|
|
44
|
+
# @return [String, nil] the full object ID of the checked-out HEAD commit
|
|
45
|
+
# (the all-zero object ID when the branch has no commits yet), or nil for a
|
|
46
|
+
# bare main worktree
|
|
47
|
+
#
|
|
48
|
+
# @!attribute [r] branch
|
|
49
|
+
# @return [String, nil] the full refname of the checked-out branch (e.g.,
|
|
50
|
+
# 'refs/heads/main'), or nil when the worktree is bare or detached
|
|
51
|
+
#
|
|
52
|
+
# @!attribute [r] bare
|
|
53
|
+
# @return [Boolean] true if this is the main worktree of a bare repository
|
|
54
|
+
#
|
|
55
|
+
# @!attribute [r] detached
|
|
56
|
+
# @return [Boolean] true if HEAD is detached in this worktree
|
|
57
|
+
#
|
|
58
|
+
# @!attribute [r] locked
|
|
59
|
+
# @return [Boolean] true if the worktree is locked
|
|
60
|
+
#
|
|
61
|
+
# @!attribute [r] lock_reason
|
|
62
|
+
# @return [String, nil] the reason given when the worktree was locked, or nil
|
|
63
|
+
# when it is not locked or was locked without a reason
|
|
64
|
+
#
|
|
65
|
+
# @!attribute [r] prunable
|
|
66
|
+
# @return [Boolean] true if `git worktree prune` would remove this entry
|
|
67
|
+
#
|
|
68
|
+
# @!attribute [r] prune_reason
|
|
69
|
+
# @return [String, nil] git's explanation of why the entry is prunable, or
|
|
70
|
+
# nil when it is not prunable
|
|
71
|
+
#
|
|
72
|
+
WorktreeInfo = Data.define(
|
|
73
|
+
:path,
|
|
74
|
+
:head,
|
|
75
|
+
:branch,
|
|
76
|
+
:bare,
|
|
77
|
+
:detached,
|
|
78
|
+
:locked,
|
|
79
|
+
:lock_reason,
|
|
80
|
+
:prunable,
|
|
81
|
+
:prune_reason
|
|
82
|
+
) do
|
|
83
|
+
# Whether this is the main worktree of a bare repository
|
|
84
|
+
#
|
|
85
|
+
# @example
|
|
86
|
+
# info.bare? # => false
|
|
87
|
+
#
|
|
88
|
+
# @return [Boolean] true if the worktree is bare
|
|
89
|
+
def bare? = bare
|
|
90
|
+
|
|
91
|
+
# Whether HEAD is detached in this worktree
|
|
92
|
+
#
|
|
93
|
+
# @example
|
|
94
|
+
# info.detached? # => false
|
|
95
|
+
#
|
|
96
|
+
# @return [Boolean] true if HEAD is detached
|
|
97
|
+
def detached? = detached
|
|
98
|
+
|
|
99
|
+
# Whether the worktree is locked
|
|
100
|
+
#
|
|
101
|
+
# @example
|
|
102
|
+
# info.locked? # => true
|
|
103
|
+
#
|
|
104
|
+
# @return [Boolean] true if the worktree is locked
|
|
105
|
+
def locked? = locked
|
|
106
|
+
|
|
107
|
+
# Whether `git worktree prune` would remove this entry
|
|
108
|
+
#
|
|
109
|
+
# @example
|
|
110
|
+
# info.prunable? # => false
|
|
111
|
+
#
|
|
112
|
+
# @return [Boolean] true if the entry is prunable
|
|
113
|
+
def prunable? = prunable
|
|
114
|
+
|
|
115
|
+
# Returns the worktree path
|
|
116
|
+
#
|
|
117
|
+
# Lets an entry be passed directly to the worktree operations that take a
|
|
118
|
+
# path, such as {Git::Repository::WorktreeOperations#worktree_remove}.
|
|
119
|
+
#
|
|
120
|
+
# @example Convert to string
|
|
121
|
+
# info.to_s # => '/tmp/wt/linked'
|
|
122
|
+
#
|
|
123
|
+
# @return [String] the worktree path
|
|
124
|
+
def to_s
|
|
125
|
+
path
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|