git 5.0.0.beta.2 → 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 +86 -23
- 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 +287 -6
- 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 +25 -13
- 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 +400 -314
- data/redesign/3_architecture_implementation.md +81 -30
- data/redesign/Phase 4 - Step A.md +6 -0
- 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 -58
- 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/lib/git/repository/configuring.rb +0 -351
- 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,214 +95,141 @@ 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
|
|
76
101
|
|
|
77
|
-
#
|
|
78
|
-
# Use `Git.open(Dir.pwd).config(...)` instead.
|
|
79
|
-
def config(name = nil, value = nil)
|
|
80
|
-
Git::Deprecation.warn(
|
|
81
|
-
'Git#config is deprecated and will be removed in v6.0.0. ' \
|
|
82
|
-
'Use Git.open(Dir.pwd).config(...) instead.'
|
|
83
|
-
)
|
|
84
|
-
Git.__send__(:run_config_utility, name, value, global: false)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Configures the gem by yielding {Git::Config.instance} to the block
|
|
88
|
-
#
|
|
89
|
-
# @example Set the global git binary path
|
|
90
|
-
# Git.configure { |c| c.binary_path = '/usr/local/bin/git' }
|
|
91
|
-
#
|
|
92
|
-
# @yield [config] yields the singleton config object
|
|
102
|
+
# Minimum git version required by this gem
|
|
93
103
|
#
|
|
94
|
-
#
|
|
104
|
+
# Commands and features may require newer versions, but this is the absolute
|
|
105
|
+
# minimum supported version for the gem as a whole.
|
|
95
106
|
#
|
|
96
|
-
# @
|
|
107
|
+
# @return [Git::Version]
|
|
97
108
|
#
|
|
98
|
-
# @
|
|
109
|
+
# @api public
|
|
99
110
|
#
|
|
100
|
-
|
|
101
|
-
yield Git::Config.instance
|
|
102
|
-
nil
|
|
103
|
-
end
|
|
111
|
+
MINIMUM_GIT_VERSION = Version.parse('2.28.0')
|
|
104
112
|
|
|
105
|
-
#
|
|
113
|
+
# Intercept the first lookup of the deprecated `Git::CommandLineResult` constant
|
|
106
114
|
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
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.
|
|
109
118
|
#
|
|
110
|
-
# @
|
|
119
|
+
# @param name [Symbol] the name of the missing constant
|
|
111
120
|
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
# @return [Class] the resolved constant value
|
|
122
|
+
#
|
|
123
|
+
# @api private
|
|
124
|
+
def self.const_missing(name)
|
|
125
|
+
return super unless name == :CommandLineResult
|
|
115
126
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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)
|
|
119
130
|
Git::Deprecation.warn(
|
|
120
|
-
'Git
|
|
121
|
-
'Use Git
|
|
131
|
+
'Git::CommandLineResult is deprecated and will be removed in v6.0.0. ' \
|
|
132
|
+
'Use Git::CommandLine::Result instead.'
|
|
122
133
|
)
|
|
123
|
-
Git
|
|
134
|
+
Git::CommandLine::Result
|
|
124
135
|
end
|
|
125
136
|
|
|
126
|
-
#
|
|
137
|
+
# Gets or sets local git configuration options
|
|
127
138
|
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
# but you can do most read operations.
|
|
139
|
+
# @overload config(name, value)
|
|
140
|
+
# Set the value for the git named configuration option
|
|
131
141
|
#
|
|
132
|
-
#
|
|
133
|
-
# What is a bare repository?
|
|
142
|
+
# @param name [String] the name of the git configuration option
|
|
134
143
|
#
|
|
135
|
-
#
|
|
136
|
-
# repository = Git.bare('ruby-git.git')
|
|
137
|
-
# puts repository.log[0].sha #=> "64c6fa011d3287bab9158049c85f3e85718854a0"
|
|
144
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
138
145
|
#
|
|
139
|
-
#
|
|
140
|
-
# containing an initialized Git repository. If a relative path is given, it
|
|
141
|
-
# is converted to an absolute path using
|
|
142
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
146
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
143
147
|
#
|
|
144
|
-
# @
|
|
145
|
-
#
|
|
148
|
+
# @overload config(name)
|
|
149
|
+
# Get the value for the git named configuration option
|
|
146
150
|
#
|
|
147
|
-
#
|
|
151
|
+
# @param name [String] the name of the git configuration option
|
|
148
152
|
#
|
|
149
|
-
#
|
|
150
|
-
# - If nil, disables SSH for this instance.
|
|
151
|
-
# - If a non-empty string, uses that value for this instance.
|
|
153
|
+
# @return [String] the value of the git configuration option
|
|
152
154
|
#
|
|
153
|
-
# @
|
|
154
|
-
#
|
|
155
|
-
# level.
|
|
155
|
+
# @overload config()
|
|
156
|
+
# List all git configuration options
|
|
156
157
|
#
|
|
157
|
-
#
|
|
158
|
-
#
|
|
158
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
159
|
+
#
|
|
160
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
161
|
+
# Use `Git.config_get(name)`, `Git.config_set(name, value)`, or `Git.config_list` instead.
|
|
159
162
|
#
|
|
160
|
-
def
|
|
161
|
-
Git::
|
|
163
|
+
def config(name = nil, value = nil)
|
|
164
|
+
Git::Deprecation.warn(
|
|
165
|
+
'Git#config is deprecated and will be removed in v6.0.0. ' \
|
|
166
|
+
'Use Git.config_get(name), Git.config_set(name, value), or Git.config_list instead.'
|
|
167
|
+
)
|
|
168
|
+
Git.__send__(:legacy_config_set_get_list, name, value, global: false)
|
|
162
169
|
end
|
|
163
170
|
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
# @see https://git-scm.com/docs/git-clone git clone
|
|
167
|
-
# @see https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a GIT URLs
|
|
168
|
-
#
|
|
169
|
-
# @param repository_url [URI, Pathname] The (possibly remote) repository url to clone
|
|
170
|
-
# from. See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
|
|
171
|
-
# for more information.
|
|
172
|
-
#
|
|
173
|
-
# @param directory [Pathname, nil] The directory to clone into
|
|
174
|
-
#
|
|
175
|
-
# If `directory` is a relative path it is relative to the `:chdir` option if
|
|
176
|
-
# given. If `:chdir` is not given, `directory` is relative to the current
|
|
177
|
-
# working directory.
|
|
178
|
-
#
|
|
179
|
-
# If `nil`, `directory` will be set to the basename of the last component of
|
|
180
|
-
# the path from the `repository_url`. For example, for the URL:
|
|
181
|
-
# `https://github.com/org/repo.git`, `directory` will be set to `repo`.
|
|
182
|
-
#
|
|
183
|
-
# If the last component of the path is `.git`, the next-to-last component of
|
|
184
|
-
# the path is used. For example, for the URL `/Users/me/foo/.git`, `directory`
|
|
185
|
-
# will be set to `foo`.
|
|
186
|
-
#
|
|
187
|
-
# @param [Hash] options The options for this command (see list of valid
|
|
188
|
-
# options below)
|
|
189
|
-
#
|
|
190
|
-
# @option options [Boolean] :bare Make a bare Git repository. See
|
|
191
|
-
# [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
|
|
192
|
-
#
|
|
193
|
-
# @option options [String] :branch The name of a branch or tag to checkout
|
|
194
|
-
# instead of the default branch.
|
|
195
|
-
#
|
|
196
|
-
# @option options [Array, String] :config A list of configuration options to
|
|
197
|
-
# set on the newly created repository.
|
|
198
|
-
#
|
|
199
|
-
# @option options [Integer] :depth Create a shallow clone with a history
|
|
200
|
-
# truncated to the specified number of commits.
|
|
201
|
-
#
|
|
202
|
-
# @option options [String] :filter Request that the server send a partial
|
|
203
|
-
# clone according to the given filter
|
|
204
|
-
#
|
|
205
|
-
# @option options [Boolean, nil] :single_branch Control whether the clone
|
|
206
|
-
# limits fetch refspecs to a single branch.
|
|
207
|
-
# - If nil (default), no flag is passed and the Git default is used.
|
|
208
|
-
# - If true, `--single-branch` is passed to limit the refspec to the
|
|
209
|
-
# checkout branch.
|
|
210
|
-
# - If false, `--no-single-branch` is passed to broaden the refspec (useful
|
|
211
|
-
# for shallow clones that should include all branches).
|
|
171
|
+
# Configures the gem by yielding {Git::Config.instance} to the block
|
|
212
172
|
#
|
|
213
|
-
# @
|
|
173
|
+
# @example Set the global git binary path
|
|
174
|
+
# Git.configure { |c| c.binary_path = '/usr/local/bin/git' }
|
|
214
175
|
#
|
|
215
|
-
#
|
|
216
|
-
# - If nil, disables SSH for this instance.
|
|
217
|
-
# - If a non-empty string, uses that value for this instance.
|
|
176
|
+
# @return [void]
|
|
218
177
|
#
|
|
219
|
-
# @
|
|
220
|
-
# commands are logged at the `:info` level. Additional logging is done
|
|
221
|
-
# at the `:debug` level.
|
|
178
|
+
# @yield [config] yields the singleton config object
|
|
222
179
|
#
|
|
223
|
-
# @
|
|
180
|
+
# @yieldparam config [Git::Config] the singleton config object
|
|
224
181
|
#
|
|
225
|
-
# @
|
|
226
|
-
# the upstream repository.
|
|
182
|
+
# @yieldreturn [void]
|
|
227
183
|
#
|
|
228
|
-
|
|
184
|
+
def self.configure
|
|
185
|
+
yield Git::Config.instance
|
|
186
|
+
nil
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Returns the process-wide {Git::Config} singleton
|
|
229
190
|
#
|
|
230
|
-
#
|
|
231
|
-
#
|
|
232
|
-
# running `git clone`. The returned path is the join of `:chdir` and the
|
|
233
|
-
# cloned directory path.
|
|
191
|
+
# @example Read the configured binary path
|
|
192
|
+
# Git.config.binary_path #=> "git"
|
|
234
193
|
#
|
|
235
|
-
# @
|
|
194
|
+
# @return [Git::Config] the singleton config object
|
|
236
195
|
#
|
|
237
|
-
|
|
238
|
-
|
|
196
|
+
def self.config
|
|
197
|
+
Git::Config.instance
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Gets or sets global git configuration options
|
|
239
201
|
#
|
|
240
|
-
# @
|
|
241
|
-
# git
|
|
202
|
+
# @overload global_config(name, value)
|
|
203
|
+
# Set the value for the git named configuration option
|
|
242
204
|
#
|
|
243
|
-
#
|
|
244
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', branch: 'development')
|
|
205
|
+
# @param name [String] the name of the git configuration option
|
|
245
206
|
#
|
|
246
|
-
#
|
|
247
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', 'my-ruby-git')
|
|
207
|
+
# @param value [String, Boolean] the value to set for the git configuration option
|
|
248
208
|
#
|
|
249
|
-
#
|
|
250
|
-
# git = Git.clone('https://github.com/ruby-git/ruby-git.git', chdir: '/path/to/projects')
|
|
251
|
-
# # clones into /path/to/projects/ruby-git
|
|
209
|
+
# @return [Git::CommandLine::Result] the result of the git configuration command
|
|
252
210
|
#
|
|
253
|
-
# @
|
|
254
|
-
#
|
|
211
|
+
# @overload global_config(name)
|
|
212
|
+
# Get the value for the git named configuration option
|
|
255
213
|
#
|
|
256
|
-
#
|
|
257
|
-
# git = Git.clone(
|
|
258
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
259
|
-
# config: 'submodule.recurse=true'
|
|
260
|
-
# )
|
|
214
|
+
# @param name [String] the name of the git configuration option
|
|
261
215
|
#
|
|
262
|
-
#
|
|
263
|
-
# git = Git.clone(
|
|
264
|
-
# 'https://github.com/ruby-git/ruby-git.git',
|
|
265
|
-
# config: ['user.name=John Doe', 'user.email=john@doe.com']
|
|
266
|
-
# )
|
|
216
|
+
# @return [String] the value of the git configuration option
|
|
267
217
|
#
|
|
268
|
-
# @
|
|
269
|
-
# git
|
|
270
|
-
# 'git@github.com:ruby-git/ruby-git.git',
|
|
271
|
-
# 'local-dir',
|
|
272
|
-
# git_ssh: 'ssh -i /path/to/private_key'
|
|
273
|
-
# )
|
|
218
|
+
# @overload global_config()
|
|
219
|
+
# List all git configuration options
|
|
274
220
|
#
|
|
275
|
-
#
|
|
276
|
-
# of the cloned local working copy or cloned repository.
|
|
221
|
+
# @return [Hash{String => String}] a hash of all git configuration options
|
|
277
222
|
#
|
|
278
|
-
|
|
279
|
-
|
|
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)
|
|
280
233
|
end
|
|
281
234
|
|
|
282
235
|
# Returns the name of the default branch of the given repository
|
|
@@ -299,15 +252,16 @@ module Git
|
|
|
299
252
|
# @example with the logging option
|
|
300
253
|
# logger = Logger.new(STDOUT, level: Logger::INFO)
|
|
301
254
|
# Git.default_branch('.', log: logger) # => 'master'
|
|
302
|
-
#
|
|
303
|
-
#
|
|
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
|
|
304
258
|
#
|
|
305
259
|
# @param repository [URI, Pathname, String] The (possibly remote) repository to get the default branch name for
|
|
306
260
|
#
|
|
307
261
|
# See [GIT URLS](https://git-scm.com/docs/git-clone#_git_urls_a_id_urls_a)
|
|
308
262
|
# for more information.
|
|
309
263
|
#
|
|
310
|
-
# @param [Hash]
|
|
264
|
+
# @param options [Hash] The options for this command (see list of valid
|
|
311
265
|
# options below)
|
|
312
266
|
#
|
|
313
267
|
# @option options [Logger] :log A logger to use for Git operations. Git
|
|
@@ -322,94 +276,64 @@ module Git
|
|
|
322
276
|
Git::Parsers::LsRemote.parse_default_branch(output)
|
|
323
277
|
end
|
|
324
278
|
|
|
325
|
-
#
|
|
326
|
-
# is specified) into the +name+ directory, then remove all traces of git from the
|
|
327
|
-
# directory.
|
|
328
|
-
#
|
|
329
|
-
# See +clone+ for options. Does not obey the <tt>:remote</tt> option,
|
|
330
|
-
# since the .git info will be deleted anyway; always uses the default
|
|
331
|
-
# remote, 'origin.'
|
|
332
|
-
def self.export(repository, name, options = {})
|
|
333
|
-
options.delete(:remote)
|
|
334
|
-
repo = clone(repository, name, { depth: 1 }.merge(options))
|
|
335
|
-
repo.checkout("origin/#{options[:branch]}") if options[:branch]
|
|
336
|
-
FileUtils.rm_r File.join(repo.dir.to_s, '.git')
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
# Same as g.config, but forces it to be at the global level
|
|
340
|
-
#
|
|
341
|
-
# g.config('user.name', 'Scott Chacon') # sets value
|
|
342
|
-
# g.config('user.email', 'email@email.com') # sets value
|
|
343
|
-
# g.config('user.name') # returns 'Scott Chacon'
|
|
344
|
-
# g.config # returns whole config hash
|
|
345
|
-
def self.global_config(name = nil, value = nil)
|
|
346
|
-
run_config_utility(name, value, global: true)
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
# Create an empty Git repository or reinitialize an existing Git repository
|
|
279
|
+
# Clone a repository into `directory` then remove its `.git` directory
|
|
350
280
|
#
|
|
351
|
-
#
|
|
352
|
-
#
|
|
353
|
-
# Otherwise, the repository is created in `"#{directory}"`.
|
|
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.
|
|
354
283
|
#
|
|
355
|
-
#
|
|
284
|
+
# Takes the same options as {Git.clone} except that `:remote` is silently ignored
|
|
285
|
+
# and `:depth` defaults to 1.
|
|
356
286
|
#
|
|
357
|
-
#
|
|
358
|
-
# and converted to an absolute path using
|
|
359
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
287
|
+
# @param repository_url [String, URI, Pathname] the repository to export from
|
|
360
288
|
#
|
|
361
|
-
# @param [
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
# @option options [Boolean] :bare Instead of creating a repository at
|
|
365
|
-
# `"#{directory}/.git"`, create a bare repository at `"#{directory}"`.
|
|
366
|
-
# See [what is a bare repository?](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbarerepositoryabarerepository).
|
|
367
|
-
#
|
|
368
|
-
# @option options [String] :initial_branch Use the specified name for the
|
|
369
|
-
# initial branch in the newly created repository.
|
|
370
|
-
#
|
|
371
|
-
# @option options [Pathname] :repository the path to put the newly initialized
|
|
372
|
-
# Git repository. The default for non-bare repository is `"#{directory}/.git"`.
|
|
289
|
+
# @param directory [String, Pathname, nil] the directory to export into; defaults to the
|
|
290
|
+
# repository basename
|
|
373
291
|
#
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
# [File.expand_path](https://www.rubydoc.info/stdlib/core/File.expand_path).
|
|
292
|
+
# @param options [Hash] options forwarded to {Git.clone} (`:remote` is ignored;
|
|
293
|
+
# `:depth` defaults to 1)
|
|
377
294
|
#
|
|
378
|
-
# @option options [
|
|
295
|
+
# @option options [String] :branch the branch or tag to export instead of HEAD
|
|
379
296
|
#
|
|
380
|
-
# @
|
|
297
|
+
# @return [void]
|
|
381
298
|
#
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
|
385
307
|
#
|
|
386
|
-
# @
|
|
387
|
-
#
|
|
388
|
-
# Raises `ArgumentError` if set to `nil`.
|
|
308
|
+
# @example Set a value
|
|
309
|
+
# Git.global_config('user.name', 'Scott Chacon')
|
|
389
310
|
#
|
|
390
|
-
# @
|
|
391
|
-
#
|
|
392
|
-
# at the `:debug` level.
|
|
311
|
+
# @example Get a value
|
|
312
|
+
# Git.global_config('user.name') # => 'Scott Chacon'
|
|
393
313
|
#
|
|
394
|
-
# @
|
|
395
|
-
#
|
|
314
|
+
# @example List all global config entries
|
|
315
|
+
# Git.global_config # => { 'user.name' => 'Scott Chacon', ... }
|
|
396
316
|
#
|
|
397
|
-
# @
|
|
398
|
-
# git = Git.init
|
|
317
|
+
# @param name [String, nil] the config key to get or set; omit to list all
|
|
399
318
|
#
|
|
400
|
-
# @
|
|
401
|
-
# git = Git.init '~/code/ruby-git'
|
|
319
|
+
# @param value [Object, nil] the value to set; omit to get or list
|
|
402
320
|
#
|
|
403
|
-
# @
|
|
404
|
-
#
|
|
321
|
+
# @return [String, Hash, Git::CommandLine::Result] the config value, all entries,
|
|
322
|
+
# or the result of the set command
|
|
405
323
|
#
|
|
406
|
-
# @
|
|
407
|
-
# 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.
|
|
408
325
|
#
|
|
409
|
-
#
|
|
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)`
|
|
410
329
|
#
|
|
411
|
-
def self.
|
|
412
|
-
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)
|
|
413
337
|
end
|
|
414
338
|
|
|
415
339
|
# Option keys accepted by {.ls_remote}
|
|
@@ -427,84 +351,129 @@ module Git
|
|
|
427
351
|
].freeze
|
|
428
352
|
private_constant :LS_REMOTE_ALLOWED_OPTS
|
|
429
353
|
|
|
430
|
-
#
|
|
431
|
-
# of the target repository
|
|
354
|
+
# Displays references available in a remote repository along with the associated commit IDs
|
|
432
355
|
#
|
|
433
|
-
#
|
|
434
|
-
#
|
|
356
|
+
# @example From a remote repository given its URL
|
|
357
|
+
# references = Git.ls_remote('https://github.com/user/repo.git')
|
|
435
358
|
#
|
|
436
|
-
# @
|
|
437
|
-
#
|
|
438
|
-
def self.ls_remote(location = nil, options = {})
|
|
439
|
-
options = options.dup
|
|
440
|
-
log = options.delete(:log)
|
|
441
|
-
unknown = options.keys - LS_REMOTE_ALLOWED_OPTS
|
|
442
|
-
raise ArgumentError, "Unknown options: #{unknown.join(', ')}" unless unknown.empty?
|
|
443
|
-
|
|
444
|
-
context = Git::ExecutionContext::Global.new(logger: log)
|
|
445
|
-
repository = location || '.'
|
|
446
|
-
output_lines = Git::Commands::LsRemote.new(context).call(repository, **options).stdout.split("\n")
|
|
447
|
-
Git::Parsers::LsRemote.parse_output(output_lines)
|
|
448
|
-
end
|
|
449
|
-
|
|
450
|
-
# Open a an existing Git working directory
|
|
359
|
+
# @example From the default remote of the current repository
|
|
360
|
+
# references = Git.ls_remote
|
|
451
361
|
#
|
|
452
|
-
#
|
|
453
|
-
#
|
|
362
|
+
# @example From a specific remote of the current repository
|
|
363
|
+
# references = Git.ls_remote('origin')
|
|
454
364
|
#
|
|
455
|
-
#
|
|
456
|
-
# 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
|
|
457
366
|
#
|
|
458
|
-
#
|
|
459
|
-
#
|
|
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.
|
|
460
369
|
#
|
|
461
|
-
# @
|
|
462
|
-
# git = Git.open('~/Projects/ruby-git')
|
|
370
|
+
# @param options [Hash] the options to pass to the git command
|
|
463
371
|
#
|
|
464
|
-
# @
|
|
465
|
-
# logger = Logger.new(STDOUT)
|
|
466
|
-
# git = Git.open('~/Projects/ruby-git', log: logger)
|
|
372
|
+
# @option options [Boolean, nil] :branches (nil) limit output to refs under `refs/heads/`
|
|
467
373
|
#
|
|
468
|
-
#
|
|
469
|
-
# git = Git.open('~/Projects/ruby-git', repository: '~/Project/ruby-git.git')
|
|
374
|
+
# Alias: `:b`
|
|
470
375
|
#
|
|
471
|
-
# @
|
|
472
|
-
# for git commands.
|
|
376
|
+
# @option options [Boolean, nil] :heads (nil) limit output to refs under `refs/heads/`
|
|
473
377
|
#
|
|
474
|
-
#
|
|
475
|
-
#
|
|
476
|
-
# [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.
|
|
477
380
|
#
|
|
478
|
-
#
|
|
479
|
-
# options below)
|
|
381
|
+
# Alias: `:h`
|
|
480
382
|
#
|
|
481
|
-
# @option options [
|
|
482
|
-
# the repository directory. The default is `"#{working_dir}/.git"`.
|
|
383
|
+
# @option options [Boolean, nil] :tags (nil) limit output to refs under `refs/tags/`
|
|
483
384
|
#
|
|
484
|
-
#
|
|
485
|
-
# index file. The default is `"#{working_dir}/.git/index"`
|
|
385
|
+
# Alias: `:t`
|
|
486
386
|
#
|
|
487
|
-
# @option options [
|
|
387
|
+
# @option options [Boolean, nil] :refs (nil) exclude peeled tags and pseudorefs
|
|
388
|
+
# like `HEAD` from the output
|
|
488
389
|
#
|
|
489
|
-
#
|
|
490
|
-
#
|
|
491
|
-
# - 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
|
|
492
392
|
#
|
|
493
|
-
#
|
|
494
|
-
#
|
|
495
|
-
#
|
|
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
|
|
413
|
+
#
|
|
414
|
+
# The string must not contain NUL or LF characters. Repeatable by passing an
|
|
415
|
+
# Array. Alias: `:o`
|
|
416
|
+
#
|
|
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.
|
|
496
423
|
#
|
|
497
|
-
# @return [
|
|
498
|
-
# of the opened working copy
|
|
424
|
+
# @return [Hash{String => Hash}] the available references of the target repo
|
|
499
425
|
#
|
|
500
|
-
def self.
|
|
501
|
-
|
|
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
|
+
'.'
|
|
502
458
|
end
|
|
459
|
+
private_class_method :normalize_ls_remote_repository
|
|
503
460
|
|
|
504
461
|
# Thread-safe cache for git versions, keyed by binary path.
|
|
505
462
|
@git_version_cache_mutex = Mutex.new
|
|
506
463
|
@git_version_cache = {}
|
|
507
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
|
+
#
|
|
508
477
|
# @api private
|
|
509
478
|
def self.cached_git_version(binary_path, &block)
|
|
510
479
|
@git_version_cache_mutex.synchronize do
|
|
@@ -512,6 +481,10 @@ module Git
|
|
|
512
481
|
end
|
|
513
482
|
end
|
|
514
483
|
|
|
484
|
+
# Clear the cached git version for all binary paths
|
|
485
|
+
#
|
|
486
|
+
# @return [void]
|
|
487
|
+
#
|
|
515
488
|
# @api private
|
|
516
489
|
def self.clear_git_version_cache
|
|
517
490
|
@git_version_cache_mutex.synchronize do
|
|
@@ -543,35 +516,135 @@ module Git
|
|
|
543
516
|
cached_git_version(path) { run_git_version(path) }
|
|
544
517
|
end
|
|
545
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
|
+
#
|
|
546
531
|
# @api private
|
|
532
|
+
#
|
|
547
533
|
def self.run_git_version(path)
|
|
548
534
|
output = Git::Commands::Version.new(Git::ExecutionContext::Global.new(binary_path: path)).call.stdout
|
|
549
535
|
Git::Version.parse(output)
|
|
550
536
|
end
|
|
551
537
|
private_class_method :run_git_version
|
|
552
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
|
+
#
|
|
553
576
|
# @api private
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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
|
|
560
588
|
|
|
561
|
-
|
|
562
|
-
|
|
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)
|
|
563
602
|
end
|
|
564
|
-
private_class_method :
|
|
603
|
+
private_class_method :legacy_config_set
|
|
565
604
|
|
|
566
|
-
|
|
567
|
-
|
|
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)
|
|
568
618
|
raise Git::FailedError, result if result.status.exitstatus != 0
|
|
569
619
|
|
|
570
620
|
result.stdout
|
|
571
621
|
end
|
|
572
|
-
private_class_method :
|
|
622
|
+
private_class_method :legacy_config_get
|
|
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
|
+
#
|
|
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
|
|
573
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
|
+
#
|
|
574
646
|
# @api private
|
|
647
|
+
#
|
|
575
648
|
def self.parse_config_list(lines)
|
|
576
649
|
lines.each_with_object({}) do |line, hsh|
|
|
577
650
|
key, value = line.split('=', 2)
|
|
@@ -598,10 +671,23 @@ module Git
|
|
|
598
671
|
# The +:local+, +:worktree+, and +:blob+ scopes require an active git
|
|
599
672
|
# repository and are therefore not valid at the Git module level.
|
|
600
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
|
+
#
|
|
601
687
|
# @api private
|
|
602
688
|
#
|
|
603
|
-
def self.assert_valid_scope!(**
|
|
604
|
-
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] }
|
|
605
691
|
return if invalid.empty?
|
|
606
692
|
|
|
607
693
|
raise ArgumentError, "#{invalid.join(', ')} scope requires a repository"
|