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.rb
CHANGED
|
@@ -1,34 +1,101 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/deprecation'
|
|
4
|
+
|
|
5
|
+
# Define Git::Deprecation before requiring the rest of the library to ensure that
|
|
6
|
+
# any deprecation warnings emitted during the loading of the library are properly
|
|
7
|
+
# configured according to the GIT_DEPRECATION_BEHAVIOR environment variable.
|
|
8
|
+
#
|
|
9
|
+
module Git
|
|
10
|
+
# The deprecation instance used to emit deprecation warnings for the Git gem
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
Deprecation = ActiveSupport::Deprecation.new('6.0.0', 'Git')
|
|
14
|
+
|
|
15
|
+
# Configure a deprecation instance from a GIT_DEPRECATION_BEHAVIOR value
|
|
16
|
+
#
|
|
17
|
+
# @param deprecation [ActiveSupport::Deprecation] the deprecation instance to configure
|
|
18
|
+
#
|
|
19
|
+
# @param behavior [String, nil] the desired behavior name (e.g. `'silence'`); when
|
|
20
|
+
# `nil` the deprecation instance is left unchanged
|
|
21
|
+
#
|
|
22
|
+
# @return [void]
|
|
23
|
+
#
|
|
24
|
+
# @raise [ArgumentError] if `behavior` is not one of the keys of
|
|
25
|
+
# `ActiveSupport::Deprecation::DEFAULT_BEHAVIORS`
|
|
26
|
+
#
|
|
27
|
+
# @api private
|
|
28
|
+
#
|
|
29
|
+
def self.configure_deprecation_behavior(deprecation, behavior)
|
|
30
|
+
return if behavior.nil?
|
|
31
|
+
|
|
32
|
+
behavior = behavior.strip
|
|
33
|
+
allowed_behaviors = ActiveSupport::Deprecation::DEFAULT_BEHAVIORS.keys.map(&:to_s)
|
|
34
|
+
|
|
35
|
+
unless allowed_behaviors.include?(behavior)
|
|
36
|
+
raise ArgumentError,
|
|
37
|
+
"Invalid GIT_DEPRECATION_BEHAVIOR=#{behavior.inspect}; " \
|
|
38
|
+
"expected one of: #{allowed_behaviors.join(', ')}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
deprecation.behavior = behavior.to_sym
|
|
42
|
+
end
|
|
43
|
+
private_class_method :configure_deprecation_behavior
|
|
44
|
+
|
|
45
|
+
configure_deprecation_behavior(Deprecation, ENV.fetch('GIT_DEPRECATION_BEHAVIOR', nil))
|
|
46
|
+
end
|
|
5
47
|
|
|
6
48
|
require 'git/author'
|
|
7
|
-
require 'git/
|
|
49
|
+
require 'git/author_info'
|
|
8
50
|
require 'git/branch'
|
|
51
|
+
require 'git/branch_info'
|
|
9
52
|
require 'git/branches'
|
|
10
|
-
require 'git/
|
|
53
|
+
require 'git/command_line'
|
|
54
|
+
require 'process_executer'
|
|
11
55
|
require 'git/config'
|
|
56
|
+
require 'git/config_entry_info'
|
|
57
|
+
require 'git/parsers/config_entry'
|
|
58
|
+
require 'git/configuring'
|
|
59
|
+
require 'git/factories'
|
|
12
60
|
require 'git/diff'
|
|
61
|
+
require 'git/diff_file_numstat_info'
|
|
62
|
+
require 'git/diff_file_patch_info'
|
|
63
|
+
require 'git/diff_file_raw_info'
|
|
64
|
+
require 'git/diff_info'
|
|
65
|
+
require 'git/parsers/diff'
|
|
66
|
+
require 'git/diff_result'
|
|
67
|
+
require 'git/dirstat_info'
|
|
13
68
|
require 'git/encoding_utils'
|
|
69
|
+
require 'git/errors'
|
|
14
70
|
require 'git/escaped_path'
|
|
15
|
-
require 'git/
|
|
16
|
-
require 'git/
|
|
17
|
-
require 'git/
|
|
18
|
-
require 'git/
|
|
71
|
+
require 'git/execution_context'
|
|
72
|
+
require 'git/execution_context/global'
|
|
73
|
+
require 'git/file_ref'
|
|
74
|
+
require 'git/fsck_object'
|
|
75
|
+
require 'git/fsck_result'
|
|
76
|
+
require 'git/parsers/ls_remote'
|
|
77
|
+
require 'git/parsers/remote'
|
|
78
|
+
require 'git/parsers/status'
|
|
79
|
+
require 'git/version_constraint'
|
|
80
|
+
require 'git/commands'
|
|
19
81
|
require 'git/log'
|
|
20
82
|
require 'git/object'
|
|
21
|
-
require 'git/path'
|
|
22
83
|
require 'git/remote'
|
|
84
|
+
require 'git/remote_info'
|
|
23
85
|
require 'git/repository'
|
|
24
|
-
require 'git/signaled_error'
|
|
25
86
|
require 'git/status'
|
|
87
|
+
require 'git/status_file_info'
|
|
88
|
+
require 'git/status_info'
|
|
26
89
|
require 'git/stash'
|
|
90
|
+
require 'git/stash_info'
|
|
27
91
|
require 'git/stashes'
|
|
92
|
+
require 'git/tag_delete_failure'
|
|
93
|
+
require 'git/tag_delete_result'
|
|
94
|
+
require 'git/tag_info'
|
|
28
95
|
require 'git/url'
|
|
29
96
|
require 'git/version'
|
|
30
|
-
require 'git/working_directory'
|
|
31
97
|
require 'git/worktree'
|
|
98
|
+
require 'git/worktree_info'
|
|
32
99
|
require 'git/worktrees'
|
|
33
100
|
|
|
34
101
|
# The Git module provides the basic functions to open a git
|
|
@@ -36,161 +103,179 @@ require 'git/worktrees'
|
|
|
36
103
|
# open a bare repository, initialize a new repo or clone an
|
|
37
104
|
# existing remote repository.
|
|
38
105
|
#
|
|
39
|
-
# @author Scott Chacon (mailto:schacon@gmail.com)
|
|
40
|
-
#
|
|
41
106
|
module Git
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#g.config('user.name') # returns 'Scott Chacon'
|
|
45
|
-
#g.config # returns whole config hash
|
|
46
|
-
def config(name = nil, value = nil)
|
|
47
|
-
lib = Git::Lib.new
|
|
48
|
-
if(name && value)
|
|
49
|
-
# set value
|
|
50
|
-
lib.config_set(name, value)
|
|
51
|
-
elsif (name)
|
|
52
|
-
# return value
|
|
53
|
-
lib.config_get(name)
|
|
54
|
-
else
|
|
55
|
-
# return hash
|
|
56
|
-
lib.config_list
|
|
57
|
-
end
|
|
58
|
-
end
|
|
107
|
+
extend Git::Configuring
|
|
108
|
+
extend Git::Factories
|
|
59
109
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
110
|
+
# Minimum git version required by this gem
|
|
111
|
+
#
|
|
112
|
+
# Commands and features may require newer versions, but this is the absolute
|
|
113
|
+
# minimum supported version for the gem as a whole.
|
|
114
|
+
#
|
|
115
|
+
# @return [Git::Version]
|
|
116
|
+
#
|
|
117
|
+
# @api public
|
|
118
|
+
#
|
|
119
|
+
MINIMUM_GIT_VERSION = Version.parse('2.28.0')
|
|
63
120
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
121
|
+
# Compatibility shim for code that monkeypatches the `Git::Base` class from
|
|
122
|
+
# versions prior to 5.0.0.
|
|
123
|
+
#
|
|
124
|
+
# `Git::Base` is a module included in {Git::Repository}, so any instance
|
|
125
|
+
# methods added to `Git::Base` are automatically available on
|
|
126
|
+
# {Git::Repository} instances. A deprecation warning is emitted for each
|
|
127
|
+
# method added, encouraging migration to an application-owned extension module.
|
|
128
|
+
#
|
|
129
|
+
# @example Monkeypatching Git::Base (deprecated)
|
|
130
|
+
# module Git::Base
|
|
131
|
+
# def my_helper = "hello"
|
|
132
|
+
# end
|
|
133
|
+
# Git.open('.').my_helper # => "hello"
|
|
134
|
+
#
|
|
135
|
+
# @deprecated Move custom methods to an application-owned extension module and
|
|
136
|
+
# include or prepend it into {Git::Repository}.
|
|
137
|
+
#
|
|
138
|
+
# @api public
|
|
139
|
+
Base = Module.new do
|
|
140
|
+
# Emit a deprecation warning each time a method is defined in Git::Base so
|
|
141
|
+
# that authors of monkeypatches are nudged toward application-owned extensions.
|
|
142
|
+
def self.method_added(method_name)
|
|
143
|
+
Git::Deprecation.warn(
|
|
144
|
+
'Monkeypatching Git::Base is deprecated and will be removed in v6.0.0. ' \
|
|
145
|
+
"Move #{method_name} to an application-owned extension module for Git::Repository."
|
|
146
|
+
)
|
|
147
|
+
super
|
|
148
|
+
end
|
|
67
149
|
|
|
68
|
-
|
|
69
|
-
self.
|
|
150
|
+
# Raise a clear error when legacy code calls Git::Base.new directly.
|
|
151
|
+
def self.new(...)
|
|
152
|
+
raise NoMethodError,
|
|
153
|
+
'Git::Base.new is not supported. Use Git.open, Git.clone, or Git.init instead.'
|
|
154
|
+
end
|
|
70
155
|
end
|
|
71
156
|
|
|
72
|
-
|
|
157
|
+
Repository.include(Base)
|
|
158
|
+
|
|
159
|
+
# Intercept the first lookup of the deprecated `Git::CommandLineResult` constant
|
|
73
160
|
#
|
|
74
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
161
|
+
# When `name` is `:CommandLineResult`, caches and returns {Git::CommandLine::Result}
|
|
162
|
+
# after emitting a deprecation warning. Calls `super` for any other unknown constant,
|
|
163
|
+
# preserving normal Ruby `NameError` behavior.
|
|
77
164
|
#
|
|
78
|
-
# @
|
|
79
|
-
# What is a bare repository?
|
|
165
|
+
# @param name [Symbol] the name of the missing constant
|
|
80
166
|
#
|
|
81
|
-
# @
|
|
82
|
-
# repository = Git.bare('ruby-git.git')
|
|
83
|
-
# puts repository.log[0].sha #=> "64c6fa011d3287bab9158049c85f3e85718854a0"
|
|
167
|
+
# @return [Class] the resolved constant value
|
|
84
168
|
#
|
|
85
|
-
# @
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
169
|
+
# @api private
|
|
170
|
+
def self.const_missing(name)
|
|
171
|
+
return super unless name == :CommandLineResult
|
|
172
|
+
|
|
173
|
+
# Cache the constant first so subsequent accesses are zero-cost even if
|
|
174
|
+
# the deprecation behavior raises (e.g. in the test suite).
|
|
175
|
+
const_set(:CommandLineResult, Git::CommandLine::Result)
|
|
176
|
+
Git::Deprecation.warn(
|
|
177
|
+
'Git::CommandLineResult is deprecated and will be removed in v6.0.0. ' \
|
|
178
|
+
'Use Git::CommandLine::Result instead.'
|
|
179
|
+
)
|
|
180
|
+
Git::CommandLine::Result
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Gets or sets local git configuration options
|
|
89
184
|
#
|
|
90
|
-
# @
|
|
91
|
-
#
|
|
185
|
+
# @overload config(name, value)
|
|
186
|
+
# Set the value for the git named configuration option
|
|
92
187
|
#
|
|
93
|
-
#
|
|
94
|
-
# are logged at the `:info` level. Additional logging is done at the `:debug`
|
|
95
|
-
# level.
|
|
188
|
+
# @param name [String] the name of the git configuration option
|
|
96
189
|
#
|
|
97
|
-
#
|
|
98
|
-
# of the bare repository.
|
|
190
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
99
191
|
#
|
|
100
|
-
|
|
101
|
-
Base.bare(git_dir, options)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# Clone a repository into an empty or newly created directory
|
|
192
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
105
193
|
#
|
|
106
|
-
# @
|
|
107
|
-
#
|
|
194
|
+
# @overload config(name)
|
|
195
|
+
# Get the value for the git named configuration option
|
|
108
196
|
#
|
|
109
|
-
#
|
|
110
|
-
# from. See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
|
|
111
|
-
# for more information.
|
|
197
|
+
# @param name [String] the name of the git configuration option
|
|
112
198
|
#
|
|
113
|
-
#
|
|
199
|
+
# @return [String] the value of the git configuration option
|
|
114
200
|
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
# directory.
|
|
201
|
+
# @overload config()
|
|
202
|
+
# List all git configuration options
|
|
118
203
|
#
|
|
119
|
-
#
|
|
120
|
-
# the path from the `repository_url`. For example, for the URL:
|
|
121
|
-
# `https://github.com/org/repo.git`, `directory` will be set to `repo`.
|
|
204
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
122
205
|
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
# will be set to `foo`.
|
|
206
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
207
|
+
# Use `Git.config_get(name)`, `Git.config_set(name, value)`, or `Git.config_list` instead.
|
|
126
208
|
#
|
|
127
|
-
|
|
128
|
-
|
|
209
|
+
def config(name = nil, value = nil)
|
|
210
|
+
Git::Deprecation.warn(
|
|
211
|
+
'Git#config is deprecated and will be removed in v6.0.0. ' \
|
|
212
|
+
'Use Git.config_get(name), Git.config_set(name, value), or Git.config_list instead.'
|
|
213
|
+
)
|
|
214
|
+
Git.__send__(:legacy_config_set_get_list, name, value, global: false)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Configures the gem by yielding {Git::Config.instance} to the block
|
|
129
218
|
#
|
|
130
|
-
# @
|
|
131
|
-
#
|
|
219
|
+
# @example Set the global git binary path
|
|
220
|
+
# Git.configure { |c| c.binary_path = '/usr/local/bin/git' }
|
|
132
221
|
#
|
|
133
|
-
# @
|
|
134
|
-
# instead of the default branch.
|
|
222
|
+
# @return [void]
|
|
135
223
|
#
|
|
136
|
-
# @
|
|
137
|
-
# set on the newly created repository.
|
|
224
|
+
# @yield [config] yields the singleton config object
|
|
138
225
|
#
|
|
139
|
-
# @
|
|
140
|
-
# truncated to the specified number of commits.
|
|
226
|
+
# @yieldparam config [Git::Config] the singleton config object
|
|
141
227
|
#
|
|
142
|
-
# @
|
|
143
|
-
# clone according to the given filter
|
|
228
|
+
# @yieldreturn [void]
|
|
144
229
|
#
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
230
|
+
def self.configure
|
|
231
|
+
yield Git::Config.instance
|
|
232
|
+
nil
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# Returns the process-wide {Git::Config} singleton
|
|
148
236
|
#
|
|
149
|
-
# @
|
|
237
|
+
# @example Read the configured binary path
|
|
238
|
+
# Git.config.binary_path #=> "git"
|
|
150
239
|
#
|
|
151
|
-
# @
|
|
152
|
-
# the upstream repository.
|
|
240
|
+
# @return [Git::Config] the singleton config object
|
|
153
241
|
#
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
242
|
+
def self.config
|
|
243
|
+
Git::Config.instance
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# Gets or sets global git configuration options
|
|
247
|
+
#
|
|
248
|
+
# @overload global_config(name, value)
|
|
249
|
+
# Set the value for the git named configuration option
|
|
157
250
|
#
|
|
158
|
-
#
|
|
159
|
-
# all submodules within, using their default settings.
|
|
251
|
+
# @param name [String] the name of the git configuration option
|
|
160
252
|
#
|
|
161
|
-
#
|
|
162
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git')
|
|
253
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
163
254
|
#
|
|
164
|
-
#
|
|
165
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', branch: 'development')
|
|
255
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
166
256
|
#
|
|
167
|
-
# @
|
|
168
|
-
#
|
|
169
|
-
# # or:
|
|
170
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', path: 'my-ruby-git')
|
|
257
|
+
# @overload global_config(name)
|
|
258
|
+
# Get the value for the git named configuration option
|
|
171
259
|
#
|
|
172
|
-
#
|
|
173
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true)
|
|
260
|
+
# @param name [String] the name of the git configuration option
|
|
174
261
|
#
|
|
175
|
-
#
|
|
176
|
-
# git = Git.clone(
|
|
177
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
178
|
-
# config: 'submodule.recurse=true'
|
|
179
|
-
# )
|
|
262
|
+
# @return [String] the value of the git configuration option
|
|
180
263
|
#
|
|
181
|
-
# @
|
|
182
|
-
# git
|
|
183
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
184
|
-
# config: ['user.name=John Doe', 'user.email=john@doe.com']
|
|
185
|
-
# )
|
|
264
|
+
# @overload global_config()
|
|
265
|
+
# List all git configuration options
|
|
186
266
|
#
|
|
187
|
-
#
|
|
188
|
-
# of the cloned local working copy or cloned repository.
|
|
267
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
189
268
|
#
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
269
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
270
|
+
# Use `Git.config_get(name, global: true)`, `Git.config_set(name, value, global: true)`, or
|
|
271
|
+
# `Git.config_list(global: true)` instead.
|
|
272
|
+
def global_config(name = nil, value = nil)
|
|
273
|
+
Git::Deprecation.warn(
|
|
274
|
+
'Git#global_config is deprecated and will be removed in v6.0.0. ' \
|
|
275
|
+
'Use Git.config_get(name, global: true), Git.config_set(name, value, global: true), ' \
|
|
276
|
+
'or Git.config_list(global: true) instead.'
|
|
277
|
+
)
|
|
278
|
+
Git.__send__(:legacy_config_set_get_list, name, value, global: true)
|
|
194
279
|
end
|
|
195
280
|
|
|
196
281
|
# Returns the name of the default branch of the given repository
|
|
@@ -213,14 +298,16 @@ module Git
|
|
|
213
298
|
# @example with the logging option
|
|
214
299
|
# logger = Logger.new(STDOUT, level: Logger::INFO)
|
|
215
300
|
# Git.default_branch('.', log: logger) # => 'master'
|
|
216
|
-
#
|
|
301
|
+
# # Logs the executed git command to STDOUT, for example:
|
|
302
|
+
# # I, [2022-04-13T16:01:33.221596 #18415] INFO -- : git '-c' 'core.quotePath=true'
|
|
303
|
+
# # '-c' 'color.ui=false' ls-remote '--symref' '--' '.' 'HEAD' 2>&1
|
|
217
304
|
#
|
|
218
305
|
# @param repository [URI, Pathname, String] The (possibly remote) repository to get the default branch name for
|
|
219
306
|
#
|
|
220
307
|
# See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
|
|
221
308
|
# for more information.
|
|
222
309
|
#
|
|
223
|
-
# @param [Hash]
|
|
310
|
+
# @param options [Hash] The options for this command (see list of valid
|
|
224
311
|
# options below)
|
|
225
312
|
#
|
|
226
313
|
# @option options [Logger] :log A logger to use for Git operations. Git
|
|
@@ -230,154 +317,465 @@ module Git
|
|
|
230
317
|
# @return [String] the name of the default branch
|
|
231
318
|
#
|
|
232
319
|
def self.default_branch(repository, options = {})
|
|
233
|
-
|
|
320
|
+
context = Git::ExecutionContext::Global.new(logger: options[:log])
|
|
321
|
+
output = Git::Commands::LsRemote.new(context).call(repository, 'HEAD', symref: true).stdout
|
|
322
|
+
Git::Parsers::LsRemote.parse_default_branch(output)
|
|
234
323
|
end
|
|
235
324
|
|
|
236
|
-
#
|
|
237
|
-
#
|
|
238
|
-
#
|
|
239
|
-
#
|
|
240
|
-
#
|
|
241
|
-
#
|
|
242
|
-
# remote
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
325
|
+
# Clone a repository into `directory` then remove its `.git` directory
|
|
326
|
+
#
|
|
327
|
+
# Exports the current HEAD (or the specific branch given in <tt>options[:branch]</tt>)
|
|
328
|
+
# into the given `directory`. It then removes all traces of git from the directory.
|
|
329
|
+
#
|
|
330
|
+
# Takes the same options as {Git.clone} except that `:depth` defaults to 1 and
|
|
331
|
+
# `:remote` is ignored with a deprecation warning.
|
|
332
|
+
#
|
|
333
|
+
# @param repository_url [String, URI, Pathname] the repository to export from
|
|
334
|
+
#
|
|
335
|
+
# @param directory [String, Pathname, nil] the directory to export into; defaults to the
|
|
336
|
+
# repository basename
|
|
337
|
+
#
|
|
338
|
+
# @param options [Hash] options forwarded to {Git.clone} (`:depth` defaults to 1)
|
|
339
|
+
#
|
|
340
|
+
# @option options [String] :remote deprecated and ignored; delete it from the call.
|
|
341
|
+
# Passing it emits a deprecation warning and it will be removed in a future
|
|
342
|
+
# major release.
|
|
343
|
+
#
|
|
344
|
+
# @option options [String] :branch the branch or tag to export instead of HEAD.
|
|
345
|
+
# Give the short name (`main`, `v1.0.0`); a full ref path such as
|
|
346
|
+
# `refs/tags/v1.0.0` or a commit SHA is not accepted. Use `:revision` to
|
|
347
|
+
# export a SHA.
|
|
348
|
+
#
|
|
349
|
+
# @return [void]
|
|
350
|
+
#
|
|
351
|
+
def self.export(repository_url, directory = nil, options = {})
|
|
352
|
+
if options.key?(:remote)
|
|
353
|
+
Git::Deprecation.warn(
|
|
354
|
+
'The :remote option to Git.export is ignored, is deprecated, and will be removed in a future ' \
|
|
355
|
+
'major release. Delete it from the call.'
|
|
356
|
+
)
|
|
357
|
+
options.delete(:remote)
|
|
358
|
+
end
|
|
359
|
+
repo = clone(repository_url, directory, { depth: 1 }.merge(options))
|
|
247
360
|
FileUtils.rm_r File.join(repo.dir.to_s, '.git')
|
|
248
361
|
end
|
|
249
362
|
|
|
250
|
-
#
|
|
363
|
+
# Get or set a git global configuration value
|
|
364
|
+
#
|
|
365
|
+
# @example Set a value
|
|
366
|
+
# Git.global_config('user.name', 'Scott Chacon')
|
|
367
|
+
#
|
|
368
|
+
# @example Get a value
|
|
369
|
+
# Git.global_config('user.name') # => 'Scott Chacon'
|
|
370
|
+
#
|
|
371
|
+
# @example List all global config entries
|
|
372
|
+
# Git.global_config # => { 'user.name' => 'Scott Chacon', ... }
|
|
373
|
+
#
|
|
374
|
+
# @param name [String, nil] the config key to get or set; omit to list all
|
|
375
|
+
#
|
|
376
|
+
# @param value [Object, nil] the value to set; omit to get or list
|
|
377
|
+
#
|
|
378
|
+
# @return [String, Hash, Git::CommandLine::Result] the config value, all entries,
|
|
379
|
+
# or the result of the set command
|
|
380
|
+
#
|
|
381
|
+
# @deprecated Use {Git.config_get}, {Git.config_set}, or {Git.config_list} instead.
|
|
382
|
+
#
|
|
383
|
+
# - `Git.global_config('user.name')` → `Git.config_get('user.name', global: true)`
|
|
384
|
+
# - `Git.global_config('user.name', 'Bob')` → `Git.config_set('user.name', 'Bob', global: true)`
|
|
385
|
+
# - `Git.global_config` → `Git.config_list(global: true)`
|
|
251
386
|
#
|
|
252
|
-
#g.config('user.name', 'Scott Chacon') # sets value
|
|
253
|
-
#g.config('user.email', 'email@email.com') # sets value
|
|
254
|
-
#g.config('user.name') # returns 'Scott Chacon'
|
|
255
|
-
#g.config # returns whole config hash
|
|
256
387
|
def self.global_config(name = nil, value = nil)
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
388
|
+
Git::Deprecation.warn(
|
|
389
|
+
'Git.global_config is deprecated and will be removed in v6.0.0. ' \
|
|
390
|
+
'Use Git.config_get(name, global: true), Git.config_set(name, value, global: true), ' \
|
|
391
|
+
'or Git.config_list(global: true) instead.'
|
|
392
|
+
)
|
|
393
|
+
legacy_config_set_get_list(name, value, global: true)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Option keys accepted by {.ls_remote}
|
|
397
|
+
#
|
|
398
|
+
# Parser-incompatible options such as `:get_url` and `:symref` are intentionally
|
|
399
|
+
# excluded because {Git::Parsers::LsRemote.parse_output} cannot handle the
|
|
400
|
+
# non-standard output formats those flags produce.
|
|
401
|
+
#
|
|
402
|
+
# @return [Array<Symbol>]
|
|
403
|
+
#
|
|
404
|
+
# @api private
|
|
405
|
+
#
|
|
406
|
+
LS_REMOTE_ALLOWED_OPTS = %i[
|
|
407
|
+
branches b heads h tags t refs upload_pack quiet q exit_code sort server_option o timeout
|
|
408
|
+
].freeze
|
|
409
|
+
private_constant :LS_REMOTE_ALLOWED_OPTS
|
|
410
|
+
|
|
411
|
+
# Displays references available in a remote repository along with the associated commit IDs
|
|
412
|
+
#
|
|
413
|
+
# @example From a remote repository given its URL
|
|
414
|
+
# references = Git.ls_remote('https://github.com/user/repo.git')
|
|
415
|
+
#
|
|
416
|
+
# @example From the default remote of the current repository
|
|
417
|
+
# references = Git.ls_remote
|
|
418
|
+
#
|
|
419
|
+
# @example From a specific remote of the current repository
|
|
420
|
+
# references = Git.ls_remote('origin')
|
|
421
|
+
#
|
|
422
|
+
# @param repository [String, nil] the target repository location or the name of a remote
|
|
423
|
+
#
|
|
424
|
+
# Defaults to `'.'` (the current directory). Passing `nil` explicitly is
|
|
425
|
+
# deprecated and will be removed in v6.0.0; pass `'.'` or omit the argument.
|
|
426
|
+
#
|
|
427
|
+
# @param options [Hash] the options to pass to the git command
|
|
428
|
+
#
|
|
429
|
+
# @option options [Boolean, nil] :branches (nil) limit output to refs under `refs/heads/`
|
|
430
|
+
#
|
|
431
|
+
# Alias: `:b`
|
|
432
|
+
#
|
|
433
|
+
# @option options [Boolean, nil] :heads (nil) limit output to refs under `refs/heads/`
|
|
434
|
+
#
|
|
435
|
+
# Deprecated: use `:branches` instead. Kept for backward compatibility with
|
|
436
|
+
# older git versions where `--heads` is the only supported flag.
|
|
437
|
+
#
|
|
438
|
+
# Alias: `:h`
|
|
439
|
+
#
|
|
440
|
+
# @option options [Boolean, nil] :tags (nil) limit output to refs under `refs/tags/`
|
|
441
|
+
#
|
|
442
|
+
# Alias: `:t`
|
|
443
|
+
#
|
|
444
|
+
# @option options [Boolean, nil] :refs (nil) exclude peeled tags and pseudorefs
|
|
445
|
+
# like `HEAD` from the output
|
|
446
|
+
#
|
|
447
|
+
# @option options [String] :upload_pack (nil) full path to `git-upload-pack` on the
|
|
448
|
+
# remote host
|
|
449
|
+
#
|
|
450
|
+
# Useful when accessing repositories via SSH where the daemon does not use the
|
|
451
|
+
# PATH configured by the user.
|
|
452
|
+
#
|
|
453
|
+
# @option options [Boolean, nil] :quiet (nil) do not print the remote URL to stderr
|
|
454
|
+
#
|
|
455
|
+
# Alias: `:q`
|
|
456
|
+
#
|
|
457
|
+
# @option options [Boolean, nil] :exit_code (nil) exit with status `2` when no
|
|
458
|
+
# matching refs are found in the remote repository
|
|
459
|
+
#
|
|
460
|
+
# Without this option, the command exits `0` whenever it successfully
|
|
461
|
+
# communicates with the remote, even if no refs match.
|
|
462
|
+
#
|
|
463
|
+
# @option options [String] :sort (nil) sort output by the given key
|
|
464
|
+
#
|
|
465
|
+
# Prefix `-` for descending order. Supports `"version:refname"` or `"v:refname"`.
|
|
466
|
+
# See `git for-each-ref` for sort key documentation.
|
|
467
|
+
#
|
|
468
|
+
# @option options [String, Array<String>] :server_option (nil) transmit a string to
|
|
469
|
+
# the server when communicating using protocol version 2
|
|
470
|
+
#
|
|
471
|
+
# The string must not contain NUL or LF characters. Repeatable by passing an
|
|
472
|
+
# Array. Alias: `:o`
|
|
473
|
+
#
|
|
474
|
+
# @option options [Numeric] :timeout (nil) execution timeout in seconds
|
|
475
|
+
#
|
|
476
|
+
# @option options [Logger] :log (nil) a logger to use for Git operations
|
|
477
|
+
#
|
|
478
|
+
# Git commands are logged at the `:info` level. Additional logging is done at
|
|
479
|
+
# the `:debug` level.
|
|
480
|
+
#
|
|
481
|
+
# @return [Hash{String => Hash}] the available references of the target repo
|
|
482
|
+
#
|
|
483
|
+
def self.ls_remote(repository = '.', options = {})
|
|
484
|
+
repository = normalize_ls_remote_repository(repository)
|
|
485
|
+
options = options.dup
|
|
486
|
+
log = options.delete(:log)
|
|
487
|
+
unknown = options.keys - LS_REMOTE_ALLOWED_OPTS
|
|
488
|
+
raise ArgumentError, "Unknown options: #{unknown.join(', ')}" unless unknown.empty?
|
|
489
|
+
|
|
490
|
+
context = Git::ExecutionContext::Global.new(logger: log)
|
|
491
|
+
output_lines = Git::Commands::LsRemote.new(context).call(repository, **options).stdout.split("\n")
|
|
492
|
+
Git::Parsers::LsRemote.parse_output(output_lines)
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
# Normalize the repository argument for {.ls_remote}
|
|
496
|
+
#
|
|
497
|
+
# Returns the repository unchanged unless it is nil, in which case a
|
|
498
|
+
# deprecation warning is emitted and `'.'` is returned.
|
|
499
|
+
#
|
|
500
|
+
# @param repository [String, nil] the repository argument passed by the caller
|
|
501
|
+
#
|
|
502
|
+
# @return [String] the normalized repository value (`'.'` when nil was given)
|
|
503
|
+
#
|
|
504
|
+
# @api private
|
|
505
|
+
#
|
|
506
|
+
def self.normalize_ls_remote_repository(repository)
|
|
507
|
+
return repository unless repository.nil?
|
|
508
|
+
|
|
509
|
+
Git::Deprecation.warn(
|
|
510
|
+
'Passing nil as the repository to Git.ls_remote is deprecated and will ' \
|
|
511
|
+
"be removed in v6.0.0. Pass '.' explicitly or omit the argument instead."
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
'.'
|
|
515
|
+
end
|
|
516
|
+
private_class_method :normalize_ls_remote_repository
|
|
517
|
+
|
|
518
|
+
# Thread-safe cache for git versions, keyed by binary path.
|
|
519
|
+
@git_version_cache_mutex = Mutex.new
|
|
520
|
+
@git_version_cache = {}
|
|
521
|
+
|
|
522
|
+
# Return the cached git version for the given binary path
|
|
523
|
+
#
|
|
524
|
+
# If it isn't already known, compute it using the given block.
|
|
525
|
+
#
|
|
526
|
+
# @param binary_path [String] the path to the git binary
|
|
527
|
+
#
|
|
528
|
+
# @return [Git::Version] the git version
|
|
529
|
+
#
|
|
530
|
+
# @yield [] compute the git version if it is not cached
|
|
531
|
+
#
|
|
532
|
+
# @yieldreturn [Git::Version] the computed git version
|
|
533
|
+
#
|
|
534
|
+
# @api private
|
|
535
|
+
def self.cached_git_version(binary_path, &block)
|
|
536
|
+
@git_version_cache_mutex.synchronize do
|
|
537
|
+
@git_version_cache[binary_path] ||= block.call
|
|
267
538
|
end
|
|
268
539
|
end
|
|
269
540
|
|
|
270
|
-
#
|
|
541
|
+
# Clear the cached git version for all binary paths
|
|
271
542
|
#
|
|
272
|
-
# @
|
|
273
|
-
# `true`, the repository will be created in `"#{directory}/.git"`.
|
|
274
|
-
# Otherwise, the repository is created in `"#{directory}"`.
|
|
543
|
+
# @return [void]
|
|
275
544
|
#
|
|
276
|
-
#
|
|
545
|
+
# @api private
|
|
546
|
+
def self.clear_git_version_cache
|
|
547
|
+
@git_version_cache_mutex.synchronize do
|
|
548
|
+
@git_version_cache.clear
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
# Return the version of a git binary as a {Git::Version}
|
|
277
553
|
#
|
|
278
|
-
#
|
|
279
|
-
#
|
|
280
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
554
|
+
# @example Default binary
|
|
555
|
+
# Git.git_version #=> #<Git::Version 2.42.0>
|
|
281
556
|
#
|
|
282
|
-
# @
|
|
283
|
-
#
|
|
557
|
+
# @example Explicit binary path
|
|
558
|
+
# Git.git_version('/opt/homebrew/bin/git') #=> #<Git::Version 2.42.0>
|
|
284
559
|
#
|
|
285
|
-
# @
|
|
286
|
-
# `
|
|
287
|
-
# See [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
|
|
560
|
+
# @param binary_path [String, nil] path to the git binary; defaults to
|
|
561
|
+
# `Git::Config.instance.binary_path`
|
|
288
562
|
#
|
|
289
|
-
# @
|
|
290
|
-
# initial branch in the newly created repository.
|
|
563
|
+
# @return [Git::Version] the parsed git version
|
|
291
564
|
#
|
|
292
|
-
# @
|
|
293
|
-
# Git repository. The default for non-bare repository is `"#{directory}/.git"`.
|
|
565
|
+
# @raise [Git::UnexpectedResultError] if the version output cannot be parsed
|
|
294
566
|
#
|
|
295
|
-
#
|
|
296
|
-
# and converted to an absolute path using
|
|
297
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
567
|
+
# @raise [Git::FailedError] if the git binary exits with a non-zero status
|
|
298
568
|
#
|
|
299
|
-
# @
|
|
300
|
-
#
|
|
301
|
-
|
|
569
|
+
# @raise [Git::Error] if the binary is not found or fails to launch
|
|
570
|
+
#
|
|
571
|
+
def self.git_version(binary_path = nil)
|
|
572
|
+
path = binary_path || Git::Config.instance.binary_path
|
|
573
|
+
cached_git_version(path) { run_git_version(path) }
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# Return the version of the git binary
|
|
577
|
+
#
|
|
578
|
+
# @param path [String] the path to the git binary
|
|
579
|
+
#
|
|
580
|
+
# @return [Git::Version] the parsed git version
|
|
581
|
+
#
|
|
582
|
+
# @raise [Git::UnexpectedResultError] if the version output cannot be parsed
|
|
583
|
+
#
|
|
584
|
+
# @raise [Git::FailedError] if the git binary exits with a non-zero status
|
|
585
|
+
#
|
|
586
|
+
# @raise [Git::Error] if the binary is not found or fails to launch
|
|
587
|
+
#
|
|
588
|
+
# @api private
|
|
589
|
+
#
|
|
590
|
+
def self.run_git_version(path)
|
|
591
|
+
output = Git::Commands::Version.new(Git::ExecutionContext::Global.new(binary_path: path)).call.stdout
|
|
592
|
+
Git::Version.parse(output)
|
|
593
|
+
end
|
|
594
|
+
private_class_method :run_git_version
|
|
595
|
+
|
|
596
|
+
# Get or set a git config value
|
|
302
597
|
#
|
|
303
|
-
# @
|
|
304
|
-
# of the newly initialized repository
|
|
598
|
+
# @overload legacy_config_set_get_list(name, value, global:)
|
|
305
599
|
#
|
|
306
|
-
#
|
|
307
|
-
# git = Git.init
|
|
600
|
+
# Set the value of a git configuration option
|
|
308
601
|
#
|
|
309
|
-
#
|
|
310
|
-
# git = Git.init '~/code/ruby-git'
|
|
602
|
+
# @param name [String] the name of the git configuration value to set
|
|
311
603
|
#
|
|
312
|
-
#
|
|
313
|
-
# git = Git.init '~/code/ruby-git.git', bare: true
|
|
604
|
+
# @param value [String, Boolean] the value to set
|
|
314
605
|
#
|
|
315
|
-
#
|
|
316
|
-
#
|
|
606
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
607
|
+
# local repo config
|
|
317
608
|
#
|
|
318
|
-
#
|
|
609
|
+
# @return [Git::CommandLine::Result] the result of the git config command
|
|
319
610
|
#
|
|
320
|
-
|
|
321
|
-
|
|
611
|
+
# @overload legacy_config_set_get_list(name, global:)
|
|
612
|
+
#
|
|
613
|
+
# Get the value of a git configuration option
|
|
614
|
+
#
|
|
615
|
+
# @param name [String] the name of the git configuration value to get
|
|
616
|
+
#
|
|
617
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
618
|
+
# local repo config
|
|
619
|
+
#
|
|
620
|
+
# @return [String] the value of the git configuration option
|
|
621
|
+
#
|
|
622
|
+
# @overload legacy_config_set_get_list(global:)
|
|
623
|
+
#
|
|
624
|
+
# Get all git configuration options
|
|
625
|
+
#
|
|
626
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
627
|
+
# local repo config
|
|
628
|
+
#
|
|
629
|
+
# @return [Hash{String => String}] all git configuration options
|
|
630
|
+
#
|
|
631
|
+
# @raise [Git::FailedError] if the git config command fails
|
|
632
|
+
#
|
|
633
|
+
# @api private
|
|
634
|
+
#
|
|
635
|
+
def self.legacy_config_set_get_list(name, value, global:)
|
|
636
|
+
if !name.nil? && !value.nil?
|
|
637
|
+
legacy_config_set(name, value, global:)
|
|
638
|
+
elsif !name.nil?
|
|
639
|
+
legacy_config_get(name, global:)
|
|
640
|
+
else
|
|
641
|
+
legacy_config_list(global:)
|
|
642
|
+
end
|
|
322
643
|
end
|
|
644
|
+
private_class_method :legacy_config_set_get_list
|
|
323
645
|
|
|
324
|
-
#
|
|
325
|
-
# of the target repository
|
|
646
|
+
# Set the value of a git configuration option
|
|
326
647
|
#
|
|
327
|
-
#
|
|
328
|
-
# :refs
|
|
648
|
+
# @param name [String] the name of the git configuration value to set
|
|
329
649
|
#
|
|
330
|
-
# @param [String
|
|
331
|
-
#
|
|
332
|
-
|
|
333
|
-
|
|
650
|
+
# @param value [String, Boolean] the value to set
|
|
651
|
+
#
|
|
652
|
+
# @param global [Boolean] whether to use the global git configuration
|
|
653
|
+
#
|
|
654
|
+
# @api private
|
|
655
|
+
#
|
|
656
|
+
def self.legacy_config_set(name, value, global:)
|
|
657
|
+
options = global ? { global: true } : {}
|
|
658
|
+
Git::Commands::ConfigOptionSyntax::Set.new(execution_context).call(name, value, **options)
|
|
334
659
|
end
|
|
660
|
+
private_class_method :legacy_config_set
|
|
335
661
|
|
|
336
|
-
#
|
|
662
|
+
# Get the value of a git configuration option
|
|
337
663
|
#
|
|
338
|
-
#
|
|
339
|
-
# a git reference, referring to an existing working directory.
|
|
664
|
+
# @param name [String] the name of the git configuration option
|
|
340
665
|
#
|
|
341
|
-
#
|
|
342
|
-
# the repository and index are in the default places (`.git/`, `.git/index`).
|
|
666
|
+
# @param global [Boolean] whether to use the global git configuration
|
|
343
667
|
#
|
|
344
|
-
# @
|
|
345
|
-
# git = Git.open
|
|
668
|
+
# @return [String] the value of the git configuration option
|
|
346
669
|
#
|
|
347
|
-
# @
|
|
348
|
-
# git = Git.open('~/Projects/ruby-git')
|
|
670
|
+
# @api private
|
|
349
671
|
#
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
672
|
+
def self.legacy_config_get(name, global:)
|
|
673
|
+
options = global ? { global: true } : {}
|
|
674
|
+
result = Git::Commands::ConfigOptionSyntax::Get.new(execution_context).call(name, **options)
|
|
675
|
+
raise Git::FailedError, result if result.status.exitstatus != 0
|
|
676
|
+
|
|
677
|
+
result.stdout
|
|
678
|
+
end
|
|
679
|
+
private_class_method :legacy_config_get
|
|
680
|
+
|
|
681
|
+
# Get a list of all git configuration options
|
|
353
682
|
#
|
|
354
|
-
# @
|
|
355
|
-
#
|
|
683
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
684
|
+
# local repo config
|
|
356
685
|
#
|
|
357
|
-
# @
|
|
358
|
-
# for git commands.
|
|
686
|
+
# @return [Hash{String => String}] all git configuration options
|
|
359
687
|
#
|
|
360
|
-
#
|
|
361
|
-
# and converted to an absolute path using
|
|
362
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
688
|
+
# @api private
|
|
363
689
|
#
|
|
364
|
-
|
|
365
|
-
|
|
690
|
+
def self.legacy_config_list(global:)
|
|
691
|
+
options = global ? { global: true } : {}
|
|
692
|
+
output = Git::Commands::ConfigOptionSyntax::List.new(execution_context).call(**options).stdout
|
|
693
|
+
parse_config_list(output.split("\n"))
|
|
694
|
+
end
|
|
695
|
+
private_class_method :legacy_config_list
|
|
696
|
+
|
|
697
|
+
# Parse the output of `git config --list` into a hash
|
|
366
698
|
#
|
|
367
|
-
# @
|
|
368
|
-
# the repository directory. The default is `"#{working_dir}/.git"`.
|
|
699
|
+
# @param lines [Array<String>] the lines of output from `git config --list`
|
|
369
700
|
#
|
|
370
|
-
# @
|
|
371
|
-
# index file. The default is `"#{working_dir}/.git/index"`
|
|
701
|
+
# @return [Hash{String => String}] the parsed git configuration options
|
|
372
702
|
#
|
|
373
|
-
# @
|
|
374
|
-
#
|
|
375
|
-
|
|
703
|
+
# @api private
|
|
704
|
+
#
|
|
705
|
+
def self.parse_config_list(lines)
|
|
706
|
+
lines.each_with_object({}) do |line, hsh|
|
|
707
|
+
key, value = line.split('=', 2)
|
|
708
|
+
hsh[key] = value || ''
|
|
709
|
+
end
|
|
710
|
+
end
|
|
711
|
+
private_class_method :parse_config_list
|
|
712
|
+
|
|
713
|
+
# @api private
|
|
714
|
+
def self.execution_context
|
|
715
|
+
Git::ExecutionContext::Global.new
|
|
716
|
+
end
|
|
717
|
+
private_class_method :execution_context
|
|
718
|
+
|
|
719
|
+
# Scopes that require an active repository and cannot be used at the Git module level
|
|
720
|
+
#
|
|
721
|
+
# @api private
|
|
722
|
+
#
|
|
723
|
+
REPOSITORY_SPECIFIC_SCOPES = %i[local worktree blob].freeze
|
|
724
|
+
private_constant :REPOSITORY_SPECIFIC_SCOPES
|
|
725
|
+
|
|
726
|
+
# Raises +ArgumentError+ when a repository-specific scope is requested.
|
|
727
|
+
#
|
|
728
|
+
# The +:local+, +:worktree+, and +:blob+ scopes require an active git
|
|
729
|
+
# repository and are therefore not valid at the Git module level.
|
|
730
|
+
#
|
|
731
|
+
# @param options_to_check [Hash{Symbol => Object}] the scope options to check
|
|
732
|
+
#
|
|
733
|
+
# If any of the options listed in +REPOSITORY_SPECIFIC_SCOPES+ are present and
|
|
734
|
+
# truthy, an +ArgumentError+ will be raised.
|
|
735
|
+
#
|
|
736
|
+
# @option options_to_check [Object] :local truthy value requests local scope
|
|
737
|
+
#
|
|
738
|
+
# @option options_to_check [Object] :worktree truthy value requests worktree scope
|
|
739
|
+
#
|
|
740
|
+
# @option options_to_check [Object] :blob truthy value requests blob scope
|
|
741
|
+
#
|
|
742
|
+
# @raise [ArgumentError] if a repository-specific scope is requested
|
|
743
|
+
#
|
|
744
|
+
# @api private
|
|
745
|
+
#
|
|
746
|
+
def self.assert_valid_scope!(**options_to_check)
|
|
747
|
+
invalid = REPOSITORY_SPECIFIC_SCOPES.select { |s| options_to_check[s] }
|
|
748
|
+
return if invalid.empty?
|
|
749
|
+
|
|
750
|
+
raise ArgumentError, "#{invalid.join(', ')} scope requires a repository"
|
|
751
|
+
end
|
|
752
|
+
private_class_method :assert_valid_scope!
|
|
753
|
+
|
|
754
|
+
# Return the version of the git binary
|
|
755
|
+
#
|
|
756
|
+
# @example Basic usage
|
|
757
|
+
# Git.binary_version # => [2, 46, 0]
|
|
758
|
+
#
|
|
759
|
+
# @param binary_path [String, nil] path to the git binary; defaults to
|
|
760
|
+
# `Git::Config.instance.binary_path`
|
|
761
|
+
#
|
|
762
|
+
# @return [Array<Integer>] the version of the git binary
|
|
763
|
+
#
|
|
764
|
+
# @deprecated Use {Git.git_version} instead, which returns a
|
|
765
|
+
# {Git::Version} (not an Array)
|
|
376
766
|
#
|
|
377
|
-
#
|
|
378
|
-
#
|
|
767
|
+
# For the legacy array shape, call: `Git.git_version.to_a`.
|
|
768
|
+
# The optional binary_path argument is preserved:
|
|
769
|
+
# `Git.git_version(binary_path)`.
|
|
379
770
|
#
|
|
380
|
-
def self.
|
|
381
|
-
|
|
771
|
+
def self.binary_version(binary_path = nil)
|
|
772
|
+
binary_path ||= Git::Config.instance.binary_path
|
|
773
|
+
Git::Deprecation.warn(
|
|
774
|
+
'Git.binary_version is deprecated and will be removed in v6.0.0. ' \
|
|
775
|
+
'Use Git.git_version instead, which returns a Git::Version ' \
|
|
776
|
+
'(not an Array). For the legacy array shape, call: Git.git_version.to_a. ' \
|
|
777
|
+
'The optional binary_path argument is preserved: Git.git_version(binary_path).'
|
|
778
|
+
)
|
|
779
|
+
git_version(binary_path).to_a
|
|
382
780
|
end
|
|
383
781
|
end
|