git 5.0.0.beta.3 → 5.0.0.beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.dockerignore +27 -0
- data/.github/copilot-instructions.md +3 -8
- data/.github/hooks/bin-setup-on-worktree.json +11 -0
- data/.github/hooks/run-bin-setup-once.sh +14 -0
- data/.github/skills/breaking-change-analysis/SKILL.md +6 -9
- data/.github/skills/ci-cd-troubleshooting/SKILL.md +2 -2
- data/.github/skills/command-implementation/REFERENCE.md +34 -33
- data/.github/skills/command-implementation/SKILL.md +5 -4
- data/.github/skills/command-test-conventions/SKILL.md +13 -9
- data/.github/skills/command-yard-documentation/SKILL.md +14 -6
- data/.github/skills/development-workflow/SKILL.md +20 -14
- data/.github/skills/facade-implementation/REFERENCE.md +19 -22
- data/.github/skills/facade-implementation/SKILL.md +0 -5
- data/.github/skills/facade-test-conventions/SKILL.md +4 -7
- data/.github/skills/facade-yard-documentation/SKILL.md +8 -2
- data/.github/skills/make-skill-template/SKILL.md +53 -3
- data/.github/skills/pr-readiness-review/SKILL.md +22 -2
- data/.github/skills/project-context/SKILL.md +16 -23
- data/.github/skills/pull-request-review/SKILL.md +2 -2
- data/.github/skills/rebase/SKILL.md +148 -0
- data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +1 -1
- data/.github/skills/resolve-feedback/SKILL.md +288 -0
- data/.github/skills/review-arguments-dsl/CHECKLIST.md +3 -3
- data/.github/skills/reviewing-skills/SKILL.md +28 -3
- data/.github/skills/test-debugging/SKILL.md +20 -19
- data/.github/skills/yard-documentation/SKILL.md +671 -483
- data/.github/skills/yard-documentation/element-rules.md +162 -0
- data/.github/skills-deprecated/README.md +21 -0
- data/.github/{skills → skills-deprecated}/extract-command-from-lib/SKILL.md +9 -9
- data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/SKILL.md +12 -12
- data/.github/workflows/continuous_integration.yml +3 -2
- data/.rubocop.yml +7 -39
- data/.yard-lint.yml +75 -0
- data/CONTRIBUTING.md +186 -174
- data/Gemfile +17 -0
- data/README.md +47 -12
- data/Rakefile +3 -21
- data/UPGRADING.md +219 -70
- data/docker/test/Dockerfile +32 -0
- data/docker/test/docker-compose.yml +0 -0
- data/git.gemspec +3 -4
- data/lib/git/author.rb +20 -1
- data/lib/git/branch.rb +26 -6
- data/lib/git/branch_delete_failure.rb +3 -0
- data/lib/git/branch_delete_result.rb +6 -3
- data/lib/git/branch_info.rb +6 -6
- data/lib/git/command_line/base.rb +6 -13
- data/lib/git/command_line/capturing.rb +67 -10
- data/lib/git/command_line/result.rb +0 -8
- data/lib/git/command_line/streaming.rb +45 -5
- data/lib/git/command_line.rb +4 -3
- data/lib/git/commands/add.rb +61 -53
- data/lib/git/commands/am/abort.rb +2 -2
- data/lib/git/commands/am/apply.rb +109 -98
- data/lib/git/commands/am/continue.rb +2 -2
- data/lib/git/commands/am/quit.rb +2 -2
- data/lib/git/commands/am/retry.rb +4 -2
- data/lib/git/commands/am/show_current_patch.rb +1 -1
- data/lib/git/commands/am/skip.rb +2 -2
- data/lib/git/commands/am.rb +2 -2
- data/lib/git/commands/apply.rb +7 -2
- data/lib/git/commands/archive/list_formats.rb +3 -3
- data/lib/git/commands/archive.rb +7 -2
- data/lib/git/commands/arguments.rb +1370 -359
- data/lib/git/commands/base.rb +111 -13
- data/lib/git/commands/branch/copy.rb +29 -21
- data/lib/git/commands/branch/create.rb +72 -68
- data/lib/git/commands/branch/delete.rb +25 -17
- data/lib/git/commands/branch/list.rb +76 -60
- data/lib/git/commands/branch/move.rb +29 -21
- data/lib/git/commands/branch/set_upstream.rb +8 -8
- data/lib/git/commands/branch/show_current.rb +3 -3
- data/lib/git/commands/branch/unset_upstream.rb +4 -8
- data/lib/git/commands/branch.rb +2 -2
- data/lib/git/commands/cat_file/batch.rb +36 -20
- data/lib/git/commands/cat_file/filtered.rb +12 -12
- data/lib/git/commands/cat_file/raw.rb +13 -13
- data/lib/git/commands/cat_file.rb +4 -4
- data/lib/git/commands/checkout/branch.rb +7 -5
- data/lib/git/commands/checkout/files.rb +5 -4
- data/lib/git/commands/checkout.rb +4 -4
- data/lib/git/commands/checkout_index.rb +5 -4
- data/lib/git/commands/clean.rb +6 -4
- data/lib/git/commands/clone.rb +5 -4
- data/lib/git/commands/commit.rb +5 -4
- data/lib/git/commands/commit_tree.rb +5 -4
- data/lib/git/commands/config_option_syntax/add.rb +7 -4
- data/lib/git/commands/config_option_syntax/get.rb +9 -5
- data/lib/git/commands/config_option_syntax/get_all.rb +7 -4
- data/lib/git/commands/config_option_syntax/get_color.rb +8 -4
- data/lib/git/commands/config_option_syntax/get_color_bool.rb +7 -4
- data/lib/git/commands/config_option_syntax/get_regexp.rb +8 -4
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +8 -4
- data/lib/git/commands/config_option_syntax/list.rb +8 -4
- data/lib/git/commands/config_option_syntax/remove_section.rb +7 -2
- data/lib/git/commands/config_option_syntax/rename_section.rb +7 -2
- data/lib/git/commands/config_option_syntax/replace_all.rb +7 -2
- data/lib/git/commands/config_option_syntax/set.rb +7 -2
- data/lib/git/commands/config_option_syntax/unset.rb +7 -4
- data/lib/git/commands/config_option_syntax/unset_all.rb +7 -2
- data/lib/git/commands/describe.rb +5 -4
- data/lib/git/commands/diff.rb +13 -12
- data/lib/git/commands/diff_files.rb +7 -6
- data/lib/git/commands/diff_index.rb +10 -7
- data/lib/git/commands/fetch.rb +6 -4
- data/lib/git/commands/fsck.rb +6 -4
- data/lib/git/commands/gc.rb +6 -4
- data/lib/git/commands/grep.rb +6 -5
- data/lib/git/commands/init.rb +6 -4
- data/lib/git/commands/log.rb +287 -285
- data/lib/git/commands/ls_files.rb +69 -65
- data/lib/git/commands/ls_remote.rb +62 -56
- data/lib/git/commands/ls_tree.rb +50 -46
- data/lib/git/commands/maintenance/register.rb +25 -23
- data/lib/git/commands/maintenance/run.rb +7 -2
- data/lib/git/commands/maintenance/start.rb +7 -2
- data/lib/git/commands/maintenance/stop.rb +7 -2
- data/lib/git/commands/maintenance/unregister.rb +7 -2
- data/lib/git/commands/merge/abort.rb +2 -2
- data/lib/git/commands/merge/continue.rb +2 -2
- data/lib/git/commands/merge/quit.rb +2 -2
- data/lib/git/commands/merge/start.rb +7 -2
- data/lib/git/commands/merge.rb +2 -2
- data/lib/git/commands/merge_base.rb +7 -2
- data/lib/git/commands/mv.rb +7 -2
- data/lib/git/commands/name_rev.rb +7 -2
- data/lib/git/commands/pull.rb +7 -2
- data/lib/git/commands/push.rb +7 -2
- data/lib/git/commands/read_tree.rb +7 -2
- data/lib/git/commands/remote/add.rb +7 -2
- data/lib/git/commands/remote/get_url.rb +4 -2
- data/lib/git/commands/remote/list.rb +4 -2
- data/lib/git/commands/remote/prune.rb +4 -2
- data/lib/git/commands/remote/remove.rb +4 -2
- data/lib/git/commands/remote/rename.rb +4 -2
- data/lib/git/commands/remote/set_branches.rb +9 -2
- data/lib/git/commands/remote/set_head.rb +12 -5
- data/lib/git/commands/remote/set_url.rb +9 -2
- data/lib/git/commands/remote/set_url_add.rb +11 -2
- data/lib/git/commands/remote/set_url_delete.rb +9 -2
- data/lib/git/commands/remote/show.rb +18 -12
- data/lib/git/commands/remote/update.rb +19 -12
- data/lib/git/commands/remote.rb +2 -2
- data/lib/git/commands/repack.rb +67 -63
- data/lib/git/commands/reset.rb +51 -44
- data/lib/git/commands/rev_parse.rb +135 -128
- data/lib/git/commands/revert/abort.rb +2 -2
- data/lib/git/commands/revert/continue.rb +7 -2
- data/lib/git/commands/revert/quit.rb +2 -2
- data/lib/git/commands/revert/skip.rb +2 -2
- data/lib/git/commands/revert/start.rb +7 -2
- data/lib/git/commands/revert.rb +2 -2
- data/lib/git/commands/rm.rb +35 -36
- data/lib/git/commands/show.rb +1 -1
- data/lib/git/commands/show_ref/exclude_existing.rb +3 -4
- data/lib/git/commands/show_ref/exists.rb +15 -13
- data/lib/git/commands/show_ref/list.rb +39 -35
- data/lib/git/commands/show_ref/verify.rb +29 -27
- data/lib/git/commands/show_ref.rb +4 -4
- data/lib/git/commands/stash/apply.rb +31 -25
- data/lib/git/commands/stash/branch.rb +10 -8
- data/lib/git/commands/stash/clear.rb +7 -5
- data/lib/git/commands/stash/create.rb +10 -8
- data/lib/git/commands/stash/drop.rb +15 -9
- data/lib/git/commands/stash/list.rb +9 -5
- data/lib/git/commands/stash/pop.rb +21 -12
- data/lib/git/commands/stash/push.rb +20 -11
- data/lib/git/commands/stash/show.rb +21 -12
- data/lib/git/commands/stash/store.rb +19 -10
- data/lib/git/commands/stash.rb +2 -2
- data/lib/git/commands/status.rb +7 -2
- data/lib/git/commands/symbolic_ref/delete.rb +18 -14
- data/lib/git/commands/symbolic_ref/read.rb +24 -20
- data/lib/git/commands/symbolic_ref/update.rb +20 -17
- data/lib/git/commands/symbolic_ref.rb +4 -4
- data/lib/git/commands/tag/create.rb +45 -42
- data/lib/git/commands/tag/delete.rb +5 -3
- data/lib/git/commands/tag/list.rb +47 -44
- data/lib/git/commands/tag/verify.rb +12 -12
- data/lib/git/commands/tag.rb +2 -2
- data/lib/git/commands/update_ref/batch.rb +6 -1
- data/lib/git/commands/update_ref/delete.rb +19 -21
- data/lib/git/commands/update_ref/update.rb +22 -25
- data/lib/git/commands/update_ref.rb +4 -4
- data/lib/git/commands/version.rb +14 -11
- data/lib/git/commands/worktree/add.rb +50 -51
- data/lib/git/commands/worktree/list.rb +17 -17
- data/lib/git/commands/worktree/lock.rb +12 -12
- data/lib/git/commands/worktree/move.rb +16 -16
- data/lib/git/commands/worktree/prune.rb +2 -2
- data/lib/git/commands/worktree/remove.rb +2 -2
- data/lib/git/commands/worktree/repair.rb +2 -2
- data/lib/git/commands/worktree/unlock.rb +2 -2
- data/lib/git/commands/write_tree.rb +2 -2
- data/lib/git/commands.rb +4 -3
- data/lib/git/config.rb +47 -1
- data/lib/git/configuring.rb +89 -15
- data/lib/git/detached_head_info.rb +4 -1
- data/lib/git/diff.rb +2 -5
- data/lib/git/diff_file_numstat_info.rb +3 -1
- data/lib/git/diff_file_patch_info.rb +3 -1
- data/lib/git/diff_file_raw_info.rb +3 -1
- data/lib/git/diff_info.rb +8 -15
- data/lib/git/diff_path_status.rb +16 -3
- data/lib/git/diff_result.rb +3 -1
- data/lib/git/diff_stats.rb +15 -0
- data/lib/git/dirstat_info.rb +24 -8
- data/lib/git/encoding_utils.rb +32 -1
- data/lib/git/errors.rb +19 -9
- data/lib/git/escaped_path.rb +55 -3
- data/lib/git/execution_context/repository.rb +15 -0
- data/lib/git/execution_context.rb +76 -74
- data/lib/git/file_ref.rb +6 -3
- data/lib/git/fsck_object.rb +8 -0
- data/lib/git/fsck_result.rb +26 -15
- data/lib/git/log.rb +152 -5
- data/lib/git/object.rb +284 -8
- data/lib/git/parsers/branch.rb +18 -0
- data/lib/git/parsers/cat_file.rb +2 -2
- data/lib/git/parsers/diff.rb +213 -5
- data/lib/git/parsers/fsck.rb +11 -0
- data/lib/git/parsers/ls_remote.rb +1 -1
- data/lib/git/parsers/stash.rb +51 -0
- data/lib/git/parsers/tag.rb +38 -0
- data/lib/git/remote.rb +34 -2
- data/lib/git/repository/branching.rb +23 -21
- data/lib/git/repository/committing.rb +46 -6
- data/lib/git/repository/context_helpers.rb +45 -16
- data/lib/git/repository/diffing.rb +32 -23
- data/lib/git/repository/factories.rb +153 -28
- data/lib/git/repository/inspecting.rb +1 -1
- data/lib/git/repository/logging.rb +169 -30
- data/lib/git/repository/maintenance.rb +1 -1
- data/lib/git/repository/merging.rb +3 -3
- data/lib/git/repository/object_operations.rb +108 -14
- data/lib/git/repository/remote_operations.rb +150 -171
- data/lib/git/repository/shared_private.rb +7 -5
- data/lib/git/repository/staging.rb +36 -12
- data/lib/git/repository/stashing.rb +16 -16
- data/lib/git/repository/status_operations.rb +1 -1
- data/lib/git/repository/worktree_operations.rb +1 -1
- data/lib/git/repository.rb +123 -63
- data/lib/git/stash.rb +16 -21
- data/lib/git/stash_info.rb +4 -4
- data/lib/git/stashes.rb +20 -26
- data/lib/git/status.rb +21 -7
- data/lib/git/tag_delete_failure.rb +3 -0
- data/lib/git/tag_delete_result.rb +6 -3
- data/lib/git/tag_info.rb +1 -0
- data/lib/git/url.rb +12 -5
- data/lib/git/version.rb +6 -4
- data/lib/git/version_constraint.rb +4 -0
- data/lib/git.rb +398 -314
- data/redesign/3_architecture_implementation.md +59 -29
- data/redesign/Phase 4 - Step B.md +921 -0
- data/redesign/Phase 4 - Step C.md +833 -0
- data/redesign/c1a-public-api-scope.tsv +256 -0
- data/redesign/phase-4-step-b-test-audit.tsv +485 -0
- data/tasks/yard.rake +24 -17
- metadata +24 -57
- data/commitlint.test +0 -4
- data/lib/git/args_builder.rb +0 -103
- data/lib/git/command_line_result.rb +0 -8
- data/lib/git/deprecation.rb +0 -9
- data/tasks/test.rake +0 -25
- /data/.github/{skills → skills-deprecated}/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -0
- /data/.github/{skills → skills-deprecated}/review-backward-compatibility/SKILL.md +0 -0
data/lib/git.rb
CHANGED
|
@@ -1,29 +1,54 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'active_support'
|
|
4
3
|
require 'active_support/deprecation'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
9
|
module Git
|
|
10
|
-
#
|
|
10
|
+
# The deprecation instance used to emit deprecation warnings for the Git gem
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
|
|
12
|
+
# @api public
|
|
13
|
+
Deprecation = ActiveSupport::Deprecation.new('6.0.0', 'Git')
|
|
14
|
+
|
|
15
|
+
# Configure a deprecation instance from a GIT_DEPRECATION_BEHAVIOR value
|
|
14
16
|
#
|
|
15
|
-
# @
|
|
17
|
+
# @param deprecation [ActiveSupport::Deprecation] the deprecation instance to configure
|
|
16
18
|
#
|
|
17
|
-
# @
|
|
19
|
+
# @param behavior [String, nil] the desired behavior name (e.g. `'silence'`); when
|
|
20
|
+
# `nil` the deprecation instance is left unchanged
|
|
18
21
|
#
|
|
19
|
-
|
|
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))
|
|
20
46
|
end
|
|
21
47
|
|
|
22
48
|
require 'git/author'
|
|
23
49
|
require 'git/branch'
|
|
24
50
|
require 'git/branch_info'
|
|
25
51
|
require 'git/branches'
|
|
26
|
-
require 'git/command_line_result'
|
|
27
52
|
require 'git/command_line'
|
|
28
53
|
require 'process_executer'
|
|
29
54
|
require 'git/config'
|
|
@@ -61,6 +86,7 @@ require 'git/tag_delete_failure'
|
|
|
61
86
|
require 'git/tag_delete_result'
|
|
62
87
|
require 'git/tag_info'
|
|
63
88
|
require 'git/url'
|
|
89
|
+
require 'git/version'
|
|
64
90
|
require 'git/worktree'
|
|
65
91
|
require 'git/worktrees'
|
|
66
92
|
|
|
@@ -69,19 +95,77 @@ require 'git/worktrees'
|
|
|
69
95
|
# open a bare repository, initialize a new repo or clone an
|
|
70
96
|
# existing remote repository.
|
|
71
97
|
#
|
|
72
|
-
# @author Scott Chacon (mailto:schacon@gmail.com)
|
|
73
|
-
#
|
|
74
98
|
module Git
|
|
75
99
|
extend Git::Configuring
|
|
100
|
+
extend Git::Repository::Factories
|
|
101
|
+
|
|
102
|
+
# Minimum git version required by this gem
|
|
103
|
+
#
|
|
104
|
+
# Commands and features may require newer versions, but this is the absolute
|
|
105
|
+
# minimum supported version for the gem as a whole.
|
|
106
|
+
#
|
|
107
|
+
# @return [Git::Version]
|
|
108
|
+
#
|
|
109
|
+
# @api public
|
|
110
|
+
#
|
|
111
|
+
MINIMUM_GIT_VERSION = Version.parse('2.28.0')
|
|
76
112
|
|
|
113
|
+
# Intercept the first lookup of the deprecated `Git::CommandLineResult` constant
|
|
114
|
+
#
|
|
115
|
+
# When `name` is `:CommandLineResult`, caches and returns {Git::CommandLine::Result}
|
|
116
|
+
# after emitting a deprecation warning. Calls `super` for any other unknown constant,
|
|
117
|
+
# preserving normal Ruby `NameError` behavior.
|
|
118
|
+
#
|
|
119
|
+
# @param name [Symbol] the name of the missing constant
|
|
120
|
+
#
|
|
121
|
+
# @return [Class] the resolved constant value
|
|
122
|
+
#
|
|
123
|
+
# @api private
|
|
124
|
+
def self.const_missing(name)
|
|
125
|
+
return super unless name == :CommandLineResult
|
|
126
|
+
|
|
127
|
+
# Cache the constant first so subsequent accesses are zero-cost even if
|
|
128
|
+
# the deprecation behavior raises (e.g. in the test suite).
|
|
129
|
+
const_set(:CommandLineResult, Git::CommandLine::Result)
|
|
130
|
+
Git::Deprecation.warn(
|
|
131
|
+
'Git::CommandLineResult is deprecated and will be removed in v6.0.0. ' \
|
|
132
|
+
'Use Git::CommandLine::Result instead.'
|
|
133
|
+
)
|
|
134
|
+
Git::CommandLine::Result
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Gets or sets local git configuration options
|
|
138
|
+
#
|
|
139
|
+
# @overload config(name, value)
|
|
140
|
+
# Set the value for the git named configuration option
|
|
141
|
+
#
|
|
142
|
+
# @param name [String] the name of the git configuration option
|
|
143
|
+
#
|
|
144
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
145
|
+
#
|
|
146
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
147
|
+
#
|
|
148
|
+
# @overload config(name)
|
|
149
|
+
# Get the value for the git named configuration option
|
|
150
|
+
#
|
|
151
|
+
# @param name [String] the name of the git configuration option
|
|
152
|
+
#
|
|
153
|
+
# @return [String] the value of the git configuration option
|
|
154
|
+
#
|
|
155
|
+
# @overload config()
|
|
156
|
+
# List all git configuration options
|
|
157
|
+
#
|
|
158
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
159
|
+
#
|
|
77
160
|
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
78
161
|
# Use `Git.config_get(name)`, `Git.config_set(name, value)`, or `Git.config_list` instead.
|
|
162
|
+
#
|
|
79
163
|
def config(name = nil, value = nil)
|
|
80
164
|
Git::Deprecation.warn(
|
|
81
165
|
'Git#config is deprecated and will be removed in v6.0.0. ' \
|
|
82
166
|
'Use Git.config_get(name), Git.config_set(name, value), or Git.config_list instead.'
|
|
83
167
|
)
|
|
84
|
-
Git.__send__(:
|
|
168
|
+
Git.__send__(:legacy_config_set_get_list, name, value, global: false)
|
|
85
169
|
end
|
|
86
170
|
|
|
87
171
|
# Configures the gem by yielding {Git::Config.instance} to the block
|
|
@@ -89,14 +173,14 @@ module Git
|
|
|
89
173
|
# @example Set the global git binary path
|
|
90
174
|
# Git.configure { |c| c.binary_path = '/usr/local/bin/git' }
|
|
91
175
|
#
|
|
176
|
+
# @return [void]
|
|
177
|
+
#
|
|
92
178
|
# @yield [config] yields the singleton config object
|
|
93
179
|
#
|
|
94
180
|
# @yieldparam config [Git::Config] the singleton config object
|
|
95
181
|
#
|
|
96
182
|
# @yieldreturn [void]
|
|
97
183
|
#
|
|
98
|
-
# @return [void]
|
|
99
|
-
#
|
|
100
184
|
def self.configure
|
|
101
185
|
yield Git::Config.instance
|
|
102
186
|
nil
|
|
@@ -113,172 +197,39 @@ module Git
|
|
|
113
197
|
Git::Config.instance
|
|
114
198
|
end
|
|
115
199
|
|
|
116
|
-
#
|
|
117
|
-
# Use `Git.config_get(name, global: true)`, `Git.config_set(name, value, global: true)`, or
|
|
118
|
-
# `Git.config_list(global: true)` instead.
|
|
119
|
-
def global_config(name = nil, value = nil)
|
|
120
|
-
Git::Deprecation.warn(
|
|
121
|
-
'Git#global_config is deprecated and will be removed in v6.0.0. ' \
|
|
122
|
-
'Use Git.config_get(name, global: true), Git.config_set(name, value, global: true), ' \
|
|
123
|
-
'or Git.config_list(global: true) instead.'
|
|
124
|
-
)
|
|
125
|
-
Git.global_config(name, value)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
# Open a bare repository
|
|
129
|
-
#
|
|
130
|
-
# Opens a bare repository located in the `git_dir` directory.
|
|
131
|
-
# Since there is no working copy, you can not checkout or commit
|
|
132
|
-
# but you can do most read operations.
|
|
133
|
-
#
|
|
134
|
-
# @see https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository
|
|
135
|
-
# What is a bare repository?
|
|
136
|
-
#
|
|
137
|
-
# @example Open a bare repository and retrieve the first commit SHA
|
|
138
|
-
# repository = Git.bare('ruby-git.git')
|
|
139
|
-
# puts repository.log[0].sha #=> "64c6fa011d3287bab9158049c85f3e85718854a0"
|
|
140
|
-
#
|
|
141
|
-
# @param [Pathname] git_dir The path to the bare repository directory
|
|
142
|
-
# containing an initialized Git repository. If a relative path is given, it
|
|
143
|
-
# is converted to an absolute path using
|
|
144
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
145
|
-
#
|
|
146
|
-
# @param [Hash] options The options for this command (see list of valid
|
|
147
|
-
# options below)
|
|
148
|
-
#
|
|
149
|
-
# @option options [String, nil] :git_ssh An optional custom SSH command
|
|
150
|
-
#
|
|
151
|
-
# - If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
|
|
152
|
-
# - If nil, disables SSH for this instance.
|
|
153
|
-
# - If a non-empty string, uses that value for this instance.
|
|
154
|
-
#
|
|
155
|
-
# @option options [Logger] :log A logger to use for Git operations. Git commands
|
|
156
|
-
# are logged at the `:info` level. Additional logging is done at the `:debug`
|
|
157
|
-
# level.
|
|
158
|
-
#
|
|
159
|
-
# @return [Git::Repository] an object that can execute git commands in the context
|
|
160
|
-
# of the bare repository.
|
|
161
|
-
#
|
|
162
|
-
def self.bare(git_dir, options = {})
|
|
163
|
-
Git::Repository.bare(git_dir, options)
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# Clone a repository into an empty or newly created directory
|
|
167
|
-
#
|
|
168
|
-
# @see https://git-scm.com/docs/git-clone git clone
|
|
169
|
-
# @see https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a GIT URLs
|
|
200
|
+
# Gets or sets global git configuration options
|
|
170
201
|
#
|
|
171
|
-
# @
|
|
172
|
-
#
|
|
173
|
-
# for more information.
|
|
174
|
-
#
|
|
175
|
-
# @param directory [Pathname, nil] The directory to clone into
|
|
176
|
-
#
|
|
177
|
-
# If `directory` is a relative path it is relative to the `:chdir` option if
|
|
178
|
-
# given. If `:chdir` is not given, `directory` is relative to the current
|
|
179
|
-
# working directory.
|
|
180
|
-
#
|
|
181
|
-
# If `nil`, `directory` will be set to the basename of the last component of
|
|
182
|
-
# the path from the `repository_url`. For example, for the URL:
|
|
183
|
-
# `https://github.com/org/repo.git`, `directory` will be set to `repo`.
|
|
184
|
-
#
|
|
185
|
-
# If the last component of the path is `.git`, the next-to-last component of
|
|
186
|
-
# the path is used. For example, for the URL `/Users/me/foo/.git`, `directory`
|
|
187
|
-
# will be set to `foo`.
|
|
188
|
-
#
|
|
189
|
-
# @param [Hash] options The options for this command (see list of valid
|
|
190
|
-
# options below)
|
|
191
|
-
#
|
|
192
|
-
# @option options [Boolean] :bare Make a bare Git repository. See
|
|
193
|
-
# [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
|
|
194
|
-
#
|
|
195
|
-
# @option options [String] :branch The name of a branch or tag to checkout
|
|
196
|
-
# instead of the default branch.
|
|
202
|
+
# @overload global_config(name, value)
|
|
203
|
+
# Set the value for the git named configuration option
|
|
197
204
|
#
|
|
198
|
-
#
|
|
199
|
-
# set on the newly created repository.
|
|
205
|
+
# @param name [String] the name of the git configuration option
|
|
200
206
|
#
|
|
201
|
-
#
|
|
202
|
-
# truncated to the specified number of commits.
|
|
203
|
-
#
|
|
204
|
-
# @option options [String] :filter Request that the server send a partial
|
|
205
|
-
# clone according to the given filter
|
|
206
|
-
#
|
|
207
|
-
# @option options [Boolean, nil] :single_branch Control whether the clone
|
|
208
|
-
# limits fetch refspecs to a single branch.
|
|
209
|
-
# - If nil (default), no flag is passed and the Git default is used.
|
|
210
|
-
# - If true, `--single-branch` is passed to limit the refspec to the
|
|
211
|
-
# checkout branch.
|
|
212
|
-
# - If false, `--no-single-branch` is passed to broaden the refspec (useful
|
|
213
|
-
# for shallow clones that should include all branches).
|
|
214
|
-
#
|
|
215
|
-
# @option options [String, nil] :git_ssh An optional custom SSH command
|
|
216
|
-
#
|
|
217
|
-
# - If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
|
|
218
|
-
# - If nil, disables SSH for this instance.
|
|
219
|
-
# - If a non-empty string, uses that value for this instance.
|
|
220
|
-
#
|
|
221
|
-
# @option options [Logger] :log A logger to use for Git operations. Git
|
|
222
|
-
# commands are logged at the `:info` level. Additional logging is done
|
|
223
|
-
# at the `:debug` level.
|
|
207
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
224
208
|
#
|
|
225
|
-
#
|
|
209
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
226
210
|
#
|
|
227
|
-
# @
|
|
228
|
-
# the
|
|
211
|
+
# @overload global_config(name)
|
|
212
|
+
# Get the value for the git named configuration option
|
|
229
213
|
#
|
|
230
|
-
#
|
|
214
|
+
# @param name [String] the name of the git configuration option
|
|
231
215
|
#
|
|
232
|
-
#
|
|
233
|
-
# is resolved relative to `:chdir`, just as if you had `cd`'d into it before
|
|
234
|
-
# running `git clone`. The returned path is the join of `:chdir` and the
|
|
235
|
-
# cloned directory path.
|
|
216
|
+
# @return [String] the value of the git configuration option
|
|
236
217
|
#
|
|
237
|
-
# @
|
|
218
|
+
# @overload global_config()
|
|
219
|
+
# List all git configuration options
|
|
238
220
|
#
|
|
239
|
-
#
|
|
240
|
-
# all submodules within, using their default settings.
|
|
221
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
241
222
|
#
|
|
242
|
-
# @
|
|
243
|
-
#
|
|
244
|
-
#
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', chdir: '/path/to/projects')
|
|
253
|
-
# # clones into /path/to/projects/ruby-git
|
|
254
|
-
#
|
|
255
|
-
# @example Create a bare repository in the directory `ruby-git.git`
|
|
256
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true)
|
|
257
|
-
#
|
|
258
|
-
# @example Clone a repository and set a single config option
|
|
259
|
-
# git = Git.clone(
|
|
260
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
261
|
-
# config: 'submodule.recurse=true'
|
|
262
|
-
# )
|
|
263
|
-
#
|
|
264
|
-
# @example Clone a repository and set multiple config options
|
|
265
|
-
# git = Git.clone(
|
|
266
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
267
|
-
# config: ['user.name=John Doe', 'user.email=john@doe.com']
|
|
268
|
-
# )
|
|
269
|
-
#
|
|
270
|
-
# @example Clone using a specific SSH key
|
|
271
|
-
# git = Git.clone(
|
|
272
|
-
# 'git@github.com:ruby-git/ruby-git.git',
|
|
273
|
-
# 'local-dir',
|
|
274
|
-
# git_ssh: 'ssh -i /path/to/private_key'
|
|
275
|
-
# )
|
|
276
|
-
#
|
|
277
|
-
# @return [Git::Repository] an object that can execute git commands in the context
|
|
278
|
-
# of the cloned local working copy or cloned repository.
|
|
279
|
-
#
|
|
280
|
-
def self.clone(repository_url, directory = nil, options = {})
|
|
281
|
-
Git::Repository.clone(repository_url, directory, options)
|
|
223
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
224
|
+
# Use `Git.config_get(name, global: true)`, `Git.config_set(name, value, global: true)`, or
|
|
225
|
+
# `Git.config_list(global: true)` instead.
|
|
226
|
+
def global_config(name = nil, value = nil)
|
|
227
|
+
Git::Deprecation.warn(
|
|
228
|
+
'Git#global_config is deprecated and will be removed in v6.0.0. ' \
|
|
229
|
+
'Use Git.config_get(name, global: true), Git.config_set(name, value, global: true), ' \
|
|
230
|
+
'or Git.config_list(global: true) instead.'
|
|
231
|
+
)
|
|
232
|
+
Git.__send__(:legacy_config_set_get_list, name, value, global: true)
|
|
282
233
|
end
|
|
283
234
|
|
|
284
235
|
# Returns the name of the default branch of the given repository
|
|
@@ -301,15 +252,16 @@ module Git
|
|
|
301
252
|
# @example with the logging option
|
|
302
253
|
# logger = Logger.new(STDOUT, level: Logger::INFO)
|
|
303
254
|
# Git.default_branch('.', log: logger) # => 'master'
|
|
304
|
-
#
|
|
305
|
-
#
|
|
255
|
+
# # Logs the executed git command to STDOUT, for example:
|
|
256
|
+
# # I, [2022-04-13T16:01:33.221596 #18415] INFO -- : git '-c' 'core.quotePath=true'
|
|
257
|
+
# # '-c' 'color.ui=false' ls-remote '--symref' '--' '.' 'HEAD' 2>&1
|
|
306
258
|
#
|
|
307
259
|
# @param repository [URI, Pathname, String] The (possibly remote) repository to get the default branch name for
|
|
308
260
|
#
|
|
309
261
|
# See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
|
|
310
262
|
# for more information.
|
|
311
263
|
#
|
|
312
|
-
# @param [Hash]
|
|
264
|
+
# @param options [Hash] The options for this command (see list of valid
|
|
313
265
|
# options below)
|
|
314
266
|
#
|
|
315
267
|
# @option options [Logger] :log A logger to use for Git operations. Git
|
|
@@ -324,94 +276,64 @@ module Git
|
|
|
324
276
|
Git::Parsers::LsRemote.parse_default_branch(output)
|
|
325
277
|
end
|
|
326
278
|
|
|
327
|
-
#
|
|
328
|
-
# is specified) into the +name+ directory, then remove all traces of git from the
|
|
329
|
-
# directory.
|
|
330
|
-
#
|
|
331
|
-
# See +clone+ for options. Does not obey the <tt>:remote</tt> option,
|
|
332
|
-
# since the .git info will be deleted anyway; always uses the default
|
|
333
|
-
# remote, 'origin.'
|
|
334
|
-
def self.export(repository, name, options = {})
|
|
335
|
-
options.delete(:remote)
|
|
336
|
-
repo = clone(repository, name, { depth: 1 }.merge(options))
|
|
337
|
-
repo.checkout("origin/#{options[:branch]}") if options[:branch]
|
|
338
|
-
FileUtils.rm_r File.join(repo.dir.to_s, '.git')
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
# Same as g.config, but forces it to be at the global level
|
|
342
|
-
#
|
|
343
|
-
# g.config('user.name', 'Scott Chacon') # sets value
|
|
344
|
-
# g.config('user.email', 'email@email.com') # sets value
|
|
345
|
-
# g.config('user.name') # returns 'Scott Chacon'
|
|
346
|
-
# g.config # returns whole config hash
|
|
347
|
-
def self.global_config(name = nil, value = nil)
|
|
348
|
-
run_config_utility(name, value, global: true)
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
# Create an empty Git repository or reinitialize an existing Git repository
|
|
352
|
-
#
|
|
353
|
-
# @param [Pathname] directory If the `:bare` option is NOT given or is not
|
|
354
|
-
# `true`, the repository will be created in `"#{directory}/.git"`.
|
|
355
|
-
# Otherwise, the repository is created in `"#{directory}"`.
|
|
279
|
+
# Clone a repository into `directory` then remove its `.git` directory
|
|
356
280
|
#
|
|
357
|
-
#
|
|
281
|
+
# Exports the current HEAD (or the specific branch given in <tt>options[:branch]</tt>)
|
|
282
|
+
# into the given `directory`. It then removes all traces of git from the directory.
|
|
358
283
|
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
361
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
284
|
+
# Takes the same options as {Git.clone} except that `:remote` is silently ignored
|
|
285
|
+
# and `:depth` defaults to 1.
|
|
362
286
|
#
|
|
363
|
-
# @param [
|
|
364
|
-
# options below)
|
|
365
|
-
#
|
|
366
|
-
# @option options [Boolean] :bare Instead of creating a repository at
|
|
367
|
-
# `"#{directory}/.git"`, create a bare repository at `"#{directory}"`.
|
|
368
|
-
# See [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
|
|
287
|
+
# @param repository_url [String, URI, Pathname] the repository to export from
|
|
369
288
|
#
|
|
370
|
-
# @
|
|
371
|
-
#
|
|
289
|
+
# @param directory [String, Pathname, nil] the directory to export into; defaults to the
|
|
290
|
+
# repository basename
|
|
372
291
|
#
|
|
373
|
-
# @
|
|
374
|
-
#
|
|
292
|
+
# @param options [Hash] options forwarded to {Git.clone} (`:remote` is ignored;
|
|
293
|
+
# `:depth` defaults to 1)
|
|
375
294
|
#
|
|
376
|
-
#
|
|
377
|
-
# and converted to an absolute path using
|
|
378
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
295
|
+
# @option options [String] :branch the branch or tag to export instead of HEAD
|
|
379
296
|
#
|
|
380
|
-
# @
|
|
381
|
-
#
|
|
382
|
-
# @option options [String, nil] :git_ssh An optional custom SSH command
|
|
297
|
+
# @return [void]
|
|
383
298
|
#
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
299
|
+
def self.export(repository_url, directory = nil, options = {})
|
|
300
|
+
options.delete(:remote)
|
|
301
|
+
repo = clone(repository_url, directory, { depth: 1 }.merge(options))
|
|
302
|
+
repo.checkout("origin/#{options[:branch]}") if options[:branch]
|
|
303
|
+
FileUtils.rm_r File.join(repo.dir.to_s, '.git')
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Get or set a git global configuration value
|
|
387
307
|
#
|
|
388
|
-
# @
|
|
389
|
-
#
|
|
390
|
-
# Raises `ArgumentError` if set to `nil`.
|
|
308
|
+
# @example Set a value
|
|
309
|
+
# Git.global_config('user.name', 'Scott Chacon')
|
|
391
310
|
#
|
|
392
|
-
# @
|
|
393
|
-
#
|
|
394
|
-
# at the `:debug` level.
|
|
311
|
+
# @example Get a value
|
|
312
|
+
# Git.global_config('user.name') # => 'Scott Chacon'
|
|
395
313
|
#
|
|
396
|
-
# @
|
|
397
|
-
#
|
|
314
|
+
# @example List all global config entries
|
|
315
|
+
# Git.global_config # => { 'user.name' => 'Scott Chacon', ... }
|
|
398
316
|
#
|
|
399
|
-
# @
|
|
400
|
-
# git = Git.init
|
|
317
|
+
# @param name [String, nil] the config key to get or set; omit to list all
|
|
401
318
|
#
|
|
402
|
-
# @
|
|
403
|
-
# git = Git.init '~/code/ruby-git'
|
|
319
|
+
# @param value [Object, nil] the value to set; omit to get or list
|
|
404
320
|
#
|
|
405
|
-
# @
|
|
406
|
-
#
|
|
321
|
+
# @return [String, Hash, Git::CommandLine::Result] the config value, all entries,
|
|
322
|
+
# or the result of the set command
|
|
407
323
|
#
|
|
408
|
-
# @
|
|
409
|
-
# git = Git.init '~/code/ruby-git', repository: '~/code/ruby-git.git'
|
|
324
|
+
# @deprecated Use {Git.config_get}, {Git.config_set}, or {Git.config_list} instead.
|
|
410
325
|
#
|
|
411
|
-
#
|
|
326
|
+
# - `Git.global_config('user.name')` → `Git.config_get('user.name', global: true)`
|
|
327
|
+
# - `Git.global_config('user.name', 'Bob')` → `Git.config_set('user.name', 'Bob', global: true)`
|
|
328
|
+
# - `Git.global_config` → `Git.config_list(global: true)`
|
|
412
329
|
#
|
|
413
|
-
def self.
|
|
414
|
-
Git::
|
|
330
|
+
def self.global_config(name = nil, value = nil)
|
|
331
|
+
Git::Deprecation.warn(
|
|
332
|
+
'Git.global_config is deprecated and will be removed in v6.0.0. ' \
|
|
333
|
+
'Use Git.config_get(name, global: true), Git.config_set(name, value, global: true), ' \
|
|
334
|
+
'or Git.config_list(global: true) instead.'
|
|
335
|
+
)
|
|
336
|
+
legacy_config_set_get_list(name, value, global: true)
|
|
415
337
|
end
|
|
416
338
|
|
|
417
339
|
# Option keys accepted by {.ls_remote}
|
|
@@ -429,84 +351,129 @@ module Git
|
|
|
429
351
|
].freeze
|
|
430
352
|
private_constant :LS_REMOTE_ALLOWED_OPTS
|
|
431
353
|
|
|
432
|
-
#
|
|
433
|
-
# of the target repository
|
|
354
|
+
# Displays references available in a remote repository along with the associated commit IDs
|
|
434
355
|
#
|
|
435
|
-
#
|
|
436
|
-
#
|
|
356
|
+
# @example From a remote repository given its URL
|
|
357
|
+
# references = Git.ls_remote('https://github.com/user/repo.git')
|
|
437
358
|
#
|
|
438
|
-
# @
|
|
439
|
-
#
|
|
440
|
-
def self.ls_remote(location = nil, options = {})
|
|
441
|
-
options = options.dup
|
|
442
|
-
log = options.delete(:log)
|
|
443
|
-
unknown = options.keys - LS_REMOTE_ALLOWED_OPTS
|
|
444
|
-
raise ArgumentError, "Unknown options: #{unknown.join(', ')}" unless unknown.empty?
|
|
445
|
-
|
|
446
|
-
context = Git::ExecutionContext::Global.new(logger: log)
|
|
447
|
-
repository = location || '.'
|
|
448
|
-
output_lines = Git::Commands::LsRemote.new(context).call(repository, **options).stdout.split("\n")
|
|
449
|
-
Git::Parsers::LsRemote.parse_output(output_lines)
|
|
450
|
-
end
|
|
451
|
-
|
|
452
|
-
# Open a an existing Git working directory
|
|
359
|
+
# @example From the default remote of the current repository
|
|
360
|
+
# references = Git.ls_remote
|
|
453
361
|
#
|
|
454
|
-
#
|
|
455
|
-
#
|
|
362
|
+
# @example From a specific remote of the current repository
|
|
363
|
+
# references = Git.ls_remote('origin')
|
|
456
364
|
#
|
|
457
|
-
#
|
|
458
|
-
# the repository and index are in the default places (`.git/`, `.git/index`).
|
|
365
|
+
# @param repository [String, nil] the target repository location or the name of a remote
|
|
459
366
|
#
|
|
460
|
-
#
|
|
461
|
-
#
|
|
367
|
+
# Defaults to `'.'` (the current directory). Passing `nil` explicitly is
|
|
368
|
+
# deprecated and will be removed in v6.0.0; pass `'.'` or omit the argument.
|
|
462
369
|
#
|
|
463
|
-
# @
|
|
464
|
-
# git = Git.open('~/Projects/ruby-git')
|
|
370
|
+
# @param options [Hash] the options to pass to the git command
|
|
465
371
|
#
|
|
466
|
-
# @
|
|
467
|
-
# logger = Logger.new(STDOUT)
|
|
468
|
-
# git = Git.open('~/Projects/ruby-git', log: logger)
|
|
372
|
+
# @option options [Boolean, nil] :branches (nil) limit output to refs under `refs/heads/`
|
|
469
373
|
#
|
|
470
|
-
#
|
|
471
|
-
# git = Git.open('~/Projects/ruby-git', repository: '~/Project/ruby-git.git')
|
|
374
|
+
# Alias: `:b`
|
|
472
375
|
#
|
|
473
|
-
# @
|
|
474
|
-
# for git commands.
|
|
376
|
+
# @option options [Boolean, nil] :heads (nil) limit output to refs under `refs/heads/`
|
|
475
377
|
#
|
|
476
|
-
#
|
|
477
|
-
#
|
|
478
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
378
|
+
# Deprecated: use `:branches` instead. Kept for backward compatibility with
|
|
379
|
+
# older git versions where `--heads` is the only supported flag.
|
|
479
380
|
#
|
|
480
|
-
#
|
|
481
|
-
# options below)
|
|
381
|
+
# Alias: `:h`
|
|
482
382
|
#
|
|
483
|
-
# @option options [
|
|
484
|
-
# the repository directory. The default is `"#{working_dir}/.git"`.
|
|
383
|
+
# @option options [Boolean, nil] :tags (nil) limit output to refs under `refs/tags/`
|
|
485
384
|
#
|
|
486
|
-
#
|
|
487
|
-
# index file. The default is `"#{working_dir}/.git/index"`
|
|
385
|
+
# Alias: `:t`
|
|
488
386
|
#
|
|
489
|
-
# @option options [
|
|
387
|
+
# @option options [Boolean, nil] :refs (nil) exclude peeled tags and pseudorefs
|
|
388
|
+
# like `HEAD` from the output
|
|
490
389
|
#
|
|
491
|
-
#
|
|
492
|
-
#
|
|
493
|
-
# - If a non-empty string, uses that value for this instance.
|
|
390
|
+
# @option options [String] :upload_pack (nil) full path to `git-upload-pack` on the
|
|
391
|
+
# remote host
|
|
494
392
|
#
|
|
495
|
-
#
|
|
496
|
-
#
|
|
497
|
-
#
|
|
393
|
+
# Useful when accessing repositories via SSH where the daemon does not use the
|
|
394
|
+
# PATH configured by the user.
|
|
395
|
+
#
|
|
396
|
+
# @option options [Boolean, nil] :quiet (nil) do not print the remote URL to stderr
|
|
397
|
+
#
|
|
398
|
+
# Alias: `:q`
|
|
399
|
+
#
|
|
400
|
+
# @option options [Boolean, nil] :exit_code (nil) exit with status `2` when no
|
|
401
|
+
# matching refs are found in the remote repository
|
|
402
|
+
#
|
|
403
|
+
# Without this option, the command exits `0` whenever it successfully
|
|
404
|
+
# communicates with the remote, even if no refs match.
|
|
405
|
+
#
|
|
406
|
+
# @option options [String] :sort (nil) sort output by the given key
|
|
407
|
+
#
|
|
408
|
+
# Prefix `-` for descending order. Supports `"version:refname"` or `"v:refname"`.
|
|
409
|
+
# See `git for-each-ref` for sort key documentation.
|
|
410
|
+
#
|
|
411
|
+
# @option options [String, Array<String>] :server_option (nil) transmit a string to
|
|
412
|
+
# the server when communicating using protocol version 2
|
|
498
413
|
#
|
|
499
|
-
#
|
|
500
|
-
#
|
|
414
|
+
# The string must not contain NUL or LF characters. Repeatable by passing an
|
|
415
|
+
# Array. Alias: `:o`
|
|
501
416
|
#
|
|
502
|
-
|
|
503
|
-
|
|
417
|
+
# @option options [Numeric] :timeout (nil) execution timeout in seconds
|
|
418
|
+
#
|
|
419
|
+
# @option options [Logger] :log (nil) a logger to use for Git operations
|
|
420
|
+
#
|
|
421
|
+
# Git commands are logged at the `:info` level. Additional logging is done at
|
|
422
|
+
# the `:debug` level.
|
|
423
|
+
#
|
|
424
|
+
# @return [Hash{String => Hash}] the available references of the target repo
|
|
425
|
+
#
|
|
426
|
+
def self.ls_remote(repository = '.', options = {})
|
|
427
|
+
repository = normalize_ls_remote_repository(repository)
|
|
428
|
+
options = options.dup
|
|
429
|
+
log = options.delete(:log)
|
|
430
|
+
unknown = options.keys - LS_REMOTE_ALLOWED_OPTS
|
|
431
|
+
raise ArgumentError, "Unknown options: #{unknown.join(', ')}" unless unknown.empty?
|
|
432
|
+
|
|
433
|
+
context = Git::ExecutionContext::Global.new(logger: log)
|
|
434
|
+
output_lines = Git::Commands::LsRemote.new(context).call(repository, **options).stdout.split("\n")
|
|
435
|
+
Git::Parsers::LsRemote.parse_output(output_lines)
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
# Normalize the repository argument for {.ls_remote}
|
|
439
|
+
#
|
|
440
|
+
# Returns the repository unchanged unless it is nil, in which case a
|
|
441
|
+
# deprecation warning is emitted and `'.'` is returned.
|
|
442
|
+
#
|
|
443
|
+
# @param repository [String, nil] the repository argument passed by the caller
|
|
444
|
+
#
|
|
445
|
+
# @return [String] the normalized repository value (`'.'` when nil was given)
|
|
446
|
+
#
|
|
447
|
+
# @api private
|
|
448
|
+
#
|
|
449
|
+
def self.normalize_ls_remote_repository(repository)
|
|
450
|
+
return repository unless repository.nil?
|
|
451
|
+
|
|
452
|
+
Git::Deprecation.warn(
|
|
453
|
+
'Passing nil as the repository to Git.ls_remote is deprecated and will ' \
|
|
454
|
+
"be removed in v6.0.0. Pass '.' explicitly or omit the argument instead."
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
'.'
|
|
504
458
|
end
|
|
459
|
+
private_class_method :normalize_ls_remote_repository
|
|
505
460
|
|
|
506
461
|
# Thread-safe cache for git versions, keyed by binary path.
|
|
507
462
|
@git_version_cache_mutex = Mutex.new
|
|
508
463
|
@git_version_cache = {}
|
|
509
464
|
|
|
465
|
+
# Return the cached git version for the given binary path
|
|
466
|
+
#
|
|
467
|
+
# If it isn't already known, compute it using the given block.
|
|
468
|
+
#
|
|
469
|
+
# @param binary_path [String] the path to the git binary
|
|
470
|
+
#
|
|
471
|
+
# @return [Git::Version] the git version
|
|
472
|
+
#
|
|
473
|
+
# @yield [] compute the git version if it is not cached
|
|
474
|
+
#
|
|
475
|
+
# @yieldreturn [Git::Version] the computed git version
|
|
476
|
+
#
|
|
510
477
|
# @api private
|
|
511
478
|
def self.cached_git_version(binary_path, &block)
|
|
512
479
|
@git_version_cache_mutex.synchronize do
|
|
@@ -514,6 +481,10 @@ module Git
|
|
|
514
481
|
end
|
|
515
482
|
end
|
|
516
483
|
|
|
484
|
+
# Clear the cached git version for all binary paths
|
|
485
|
+
#
|
|
486
|
+
# @return [void]
|
|
487
|
+
#
|
|
517
488
|
# @api private
|
|
518
489
|
def self.clear_git_version_cache
|
|
519
490
|
@git_version_cache_mutex.synchronize do
|
|
@@ -545,35 +516,135 @@ module Git
|
|
|
545
516
|
cached_git_version(path) { run_git_version(path) }
|
|
546
517
|
end
|
|
547
518
|
|
|
519
|
+
# Return the version of the git binary
|
|
520
|
+
#
|
|
521
|
+
# @param path [String] the path to the git binary
|
|
522
|
+
#
|
|
523
|
+
# @return [Git::Version] the parsed git version
|
|
524
|
+
#
|
|
525
|
+
# @raise [Git::UnexpectedResultError] if the version output cannot be parsed
|
|
526
|
+
#
|
|
527
|
+
# @raise [Git::FailedError] if the git binary exits with a non-zero status
|
|
528
|
+
#
|
|
529
|
+
# @raise [Git::Error] if the binary is not found or fails to launch
|
|
530
|
+
#
|
|
548
531
|
# @api private
|
|
532
|
+
#
|
|
549
533
|
def self.run_git_version(path)
|
|
550
534
|
output = Git::Commands::Version.new(Git::ExecutionContext::Global.new(binary_path: path)).call.stdout
|
|
551
535
|
Git::Version.parse(output)
|
|
552
536
|
end
|
|
553
537
|
private_class_method :run_git_version
|
|
554
538
|
|
|
539
|
+
# Get or set a git config value
|
|
540
|
+
#
|
|
541
|
+
# @overload legacy_config_set_get_list(name, value, global:)
|
|
542
|
+
#
|
|
543
|
+
# Set the value of a git configuration option
|
|
544
|
+
#
|
|
545
|
+
# @param name [String] the name of the git configuration value to set
|
|
546
|
+
#
|
|
547
|
+
# @param value [String, Boolean] the value to set
|
|
548
|
+
#
|
|
549
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
550
|
+
# local repo config
|
|
551
|
+
#
|
|
552
|
+
# @return [Git::CommandLine::Result] the result of the git config command
|
|
553
|
+
#
|
|
554
|
+
# @overload legacy_config_set_get_list(name, global:)
|
|
555
|
+
#
|
|
556
|
+
# Get the value of a git configuration option
|
|
557
|
+
#
|
|
558
|
+
# @param name [String] the name of the git configuration value to get
|
|
559
|
+
#
|
|
560
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
561
|
+
# local repo config
|
|
562
|
+
#
|
|
563
|
+
# @return [String] the value of the git configuration option
|
|
564
|
+
#
|
|
565
|
+
# @overload legacy_config_set_get_list(global:)
|
|
566
|
+
#
|
|
567
|
+
# Get all git configuration options
|
|
568
|
+
#
|
|
569
|
+
# @param global [Boolean] true to use the global git configuration, false for the
|
|
570
|
+
# local repo config
|
|
571
|
+
#
|
|
572
|
+
# @return [Hash{String => String}] all git configuration options
|
|
573
|
+
#
|
|
574
|
+
# @raise [Git::FailedError] if the git config command fails
|
|
575
|
+
#
|
|
555
576
|
# @api private
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
577
|
+
#
|
|
578
|
+
def self.legacy_config_set_get_list(name, value, global:)
|
|
579
|
+
if !name.nil? && !value.nil?
|
|
580
|
+
legacy_config_set(name, value, global:)
|
|
581
|
+
elsif !name.nil?
|
|
582
|
+
legacy_config_get(name, global:)
|
|
583
|
+
else
|
|
584
|
+
legacy_config_list(global:)
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
private_class_method :legacy_config_set_get_list
|
|
562
588
|
|
|
563
|
-
|
|
564
|
-
|
|
589
|
+
# Set the value of a git configuration option
|
|
590
|
+
#
|
|
591
|
+
# @param name [String] the name of the git configuration value to set
|
|
592
|
+
#
|
|
593
|
+
# @param value [String, Boolean] the value to set
|
|
594
|
+
#
|
|
595
|
+
# @param global [Boolean] whether to use the global git configuration
|
|
596
|
+
#
|
|
597
|
+
# @api private
|
|
598
|
+
#
|
|
599
|
+
def self.legacy_config_set(name, value, global:)
|
|
600
|
+
options = global ? { global: true } : {}
|
|
601
|
+
Git::Commands::ConfigOptionSyntax::Set.new(execution_context).call(name, value, **options)
|
|
565
602
|
end
|
|
566
|
-
private_class_method :
|
|
603
|
+
private_class_method :legacy_config_set
|
|
567
604
|
|
|
568
|
-
|
|
569
|
-
|
|
605
|
+
# Get the value of a git configuration option
|
|
606
|
+
#
|
|
607
|
+
# @param name [String] the name of the git configuration option
|
|
608
|
+
#
|
|
609
|
+
# @param global [Boolean] whether to use the global git configuration
|
|
610
|
+
#
|
|
611
|
+
# @return [String] the value of the git configuration option
|
|
612
|
+
#
|
|
613
|
+
# @api private
|
|
614
|
+
#
|
|
615
|
+
def self.legacy_config_get(name, global:)
|
|
616
|
+
options = global ? { global: true } : {}
|
|
617
|
+
result = Git::Commands::ConfigOptionSyntax::Get.new(execution_context).call(name, **options)
|
|
570
618
|
raise Git::FailedError, result if result.status.exitstatus != 0
|
|
571
619
|
|
|
572
620
|
result.stdout
|
|
573
621
|
end
|
|
574
|
-
private_class_method :
|
|
622
|
+
private_class_method :legacy_config_get
|
|
575
623
|
|
|
624
|
+
# Get a list of 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
|
+
#
|
|
576
631
|
# @api private
|
|
632
|
+
#
|
|
633
|
+
def self.legacy_config_list(global:)
|
|
634
|
+
options = global ? { global: true } : {}
|
|
635
|
+
output = Git::Commands::ConfigOptionSyntax::List.new(execution_context).call(**options).stdout
|
|
636
|
+
parse_config_list(output.split("\n"))
|
|
637
|
+
end
|
|
638
|
+
private_class_method :legacy_config_list
|
|
639
|
+
|
|
640
|
+
# Parse the output of `git config --list` into a hash
|
|
641
|
+
#
|
|
642
|
+
# @param lines [Array<String>] the lines of output from `git config --list`
|
|
643
|
+
#
|
|
644
|
+
# @return [Hash{String => String}] the parsed git configuration options
|
|
645
|
+
#
|
|
646
|
+
# @api private
|
|
647
|
+
#
|
|
577
648
|
def self.parse_config_list(lines)
|
|
578
649
|
lines.each_with_object({}) do |line, hsh|
|
|
579
650
|
key, value = line.split('=', 2)
|
|
@@ -600,10 +671,23 @@ module Git
|
|
|
600
671
|
# The +:local+, +:worktree+, and +:blob+ scopes require an active git
|
|
601
672
|
# repository and are therefore not valid at the Git module level.
|
|
602
673
|
#
|
|
674
|
+
# @param options_to_check [Hash{Symbol => Object}] the scope options to check
|
|
675
|
+
#
|
|
676
|
+
# If any of the options listed in +REPOSITORY_SPECIFIC_SCOPES+ are present and
|
|
677
|
+
# truthy, an +ArgumentError+ will be raised.
|
|
678
|
+
#
|
|
679
|
+
# @option options_to_check [Object] :local truthy value requests local scope
|
|
680
|
+
#
|
|
681
|
+
# @option options_to_check [Object] :worktree truthy value requests worktree scope
|
|
682
|
+
#
|
|
683
|
+
# @option options_to_check [Object] :blob truthy value requests blob scope
|
|
684
|
+
#
|
|
685
|
+
# @raise [ArgumentError] if a repository-specific scope is requested
|
|
686
|
+
#
|
|
603
687
|
# @api private
|
|
604
688
|
#
|
|
605
|
-
def self.assert_valid_scope!(**
|
|
606
|
-
invalid = REPOSITORY_SPECIFIC_SCOPES.select { |s|
|
|
689
|
+
def self.assert_valid_scope!(**options_to_check)
|
|
690
|
+
invalid = REPOSITORY_SPECIFIC_SCOPES.select { |s| options_to_check[s] }
|
|
607
691
|
return if invalid.empty?
|
|
608
692
|
|
|
609
693
|
raise ArgumentError, "#{invalid.join(', ')} scope requires a repository"
|