git 5.0.0.beta.1 → 5.0.0.beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +6 -0
- data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +188 -0
- data/.github/skills/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +22 -0
- data/.github/skills/extract-facade-from-base-lib/SKILL.md +28 -14
- data/.github/skills/facade-implementation/SKILL.md +14 -0
- data/.github/skills/facade-test-conventions/SKILL.md +14 -0
- data/.rubocop.yml +5 -0
- data/README.md +90 -22
- data/UPGRADING.md +141 -0
- data/git.gemspec +5 -0
- data/lib/git/branch.rb +7 -18
- data/lib/git/branches.rb +2 -10
- data/lib/git/command_line/base.rb +10 -0
- data/lib/git/command_line/capturing.rb +5 -3
- data/lib/git/command_line/streaming.rb +5 -3
- data/lib/git/command_line.rb +3 -3
- data/lib/git/commands/base.rb +7 -6
- data/lib/git/commands/cat_file/batch.rb +6 -1
- data/lib/git/commands/cat_file/raw.rb +7 -1
- data/lib/git/commands/config_option_syntax/get_urlmatch.rb +5 -0
- data/lib/git/commands/show_ref/exclude_existing.rb +1 -1
- data/lib/git/commands/update_ref/batch.rb +1 -1
- data/lib/git/commands/version.rb +5 -0
- data/lib/git/commands.rb +5 -7
- data/lib/git/config.rb +17 -0
- data/lib/git/config_entry_info.rb +106 -0
- data/lib/git/configuring.rb +665 -0
- data/lib/git/deprecation.rb +9 -0
- data/lib/git/diff.rb +4 -8
- data/lib/git/diff_path_status.rb +2 -13
- data/lib/git/diff_stats.rb +1 -9
- data/lib/git/execution_context/global.rb +3 -28
- data/lib/git/execution_context/repository.rb +30 -41
- data/lib/git/execution_context.rb +43 -24
- data/lib/git/log.rb +3 -9
- data/lib/git/object.rb +14 -21
- data/lib/git/parsers/config_entry.rb +110 -0
- data/lib/git/parsers/ls_remote.rb +79 -0
- data/lib/git/remote.rb +7 -20
- data/lib/git/repository/branching.rb +183 -12
- data/lib/git/repository/committing.rb +64 -68
- data/lib/git/repository/context_helpers.rb +264 -0
- data/lib/git/repository/factories.rb +682 -0
- data/lib/git/repository/inspecting.rb +99 -0
- data/lib/git/repository/maintenance.rb +65 -0
- data/lib/git/repository/merging.rb +63 -1
- data/lib/git/repository/object_operations.rb +133 -35
- data/lib/git/repository/path_resolver.rb +1 -1
- data/lib/git/repository/remote_operations.rb +166 -21
- data/lib/git/repository/staging.rb +187 -23
- data/lib/git/repository/stashing.rb +39 -3
- data/lib/git/repository/status_operations.rb +21 -0
- data/lib/git/repository.rb +288 -128
- data/lib/git/stash.rb +2 -9
- data/lib/git/stashes.rb +2 -7
- data/lib/git/status.rb +12 -23
- data/lib/git/version.rb +2 -2
- data/lib/git/worktree.rb +2 -15
- data/lib/git/worktrees.rb +2 -15
- data/lib/git.rb +182 -77
- data/redesign/3_architecture_implementation.md +170 -112
- data/redesign/Phase 4 - Step A.md +366 -0
- data/redesign/beta_release.md +107 -0
- data/redesign/c1c2_audit.md +566 -0
- data/redesign/c1c2_bucket6_lib_orphans.md +626 -0
- data/redesign/config_design.rb +501 -0
- metadata +19 -6
- data/lib/git/base.rb +0 -1204
- data/lib/git/lib.rb +0 -2855
- data/lib/git/repository/configuring.rb +0 -156
data/lib/git/worktrees.rb
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'git/base'
|
|
4
|
-
|
|
5
3
|
module Git
|
|
6
4
|
# Collection of all Git worktrees in a repository
|
|
7
5
|
#
|
|
8
6
|
# Wraps every linked and main worktree and provides enumeration and
|
|
9
7
|
# path-based lookup.
|
|
10
8
|
#
|
|
11
|
-
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy
|
|
12
|
-
# form) as the `base` argument. The `is_a?(Git::Base)` guard routes git
|
|
13
|
-
# operations through the facade repository and will be removed when
|
|
14
|
-
# {Git::Base} is deleted in Phase 4.
|
|
15
|
-
#
|
|
16
9
|
# @example Enumerate all worktrees
|
|
17
10
|
# worktrees = repo.worktrees
|
|
18
11
|
# worktrees.each { |wt| puts wt.dir }
|
|
@@ -24,7 +17,7 @@ module Git
|
|
|
24
17
|
|
|
25
18
|
# Creates a new Worktrees collection populated from the given repository
|
|
26
19
|
#
|
|
27
|
-
# @param base [Git::
|
|
20
|
+
# @param base [Git::Repository] the repository to enumerate
|
|
28
21
|
# worktrees from
|
|
29
22
|
#
|
|
30
23
|
# @return [void]
|
|
@@ -130,18 +123,12 @@ module Git
|
|
|
130
123
|
|
|
131
124
|
private
|
|
132
125
|
|
|
133
|
-
# Resolves the {Git::Repository} for this collection of worktrees
|
|
134
|
-
#
|
|
135
|
-
# Accepts either a {Git::Repository} (new form) or a {Git::Base} (legacy).
|
|
136
|
-
# The `is_a?(Git::Base)` guard will be removed when {Git::Base} is deleted
|
|
137
|
-
# in Phase 4.
|
|
138
|
-
#
|
|
139
126
|
# @return [Git::Repository] the repository used to enumerate worktrees
|
|
140
127
|
#
|
|
141
128
|
# @api private
|
|
142
129
|
#
|
|
143
130
|
def worktree_repository
|
|
144
|
-
@base
|
|
131
|
+
@base
|
|
145
132
|
end
|
|
146
133
|
end
|
|
147
134
|
end
|
data/lib/git.rb
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
require 'active_support'
|
|
4
4
|
require 'active_support/deprecation'
|
|
5
5
|
|
|
6
|
+
require 'git/deprecation'
|
|
6
7
|
require 'git/version'
|
|
7
8
|
|
|
8
9
|
module Git
|
|
9
|
-
Deprecation = ActiveSupport::Deprecation.new('5.0.0', 'Git')
|
|
10
|
-
|
|
11
10
|
# Minimum git version required by this gem
|
|
12
11
|
#
|
|
13
12
|
# Commands and features may require newer versions, but this is the absolute
|
|
@@ -26,8 +25,11 @@ require 'git/branch_info'
|
|
|
26
25
|
require 'git/branches'
|
|
27
26
|
require 'git/command_line_result'
|
|
28
27
|
require 'git/command_line'
|
|
29
|
-
require '
|
|
28
|
+
require 'process_executer'
|
|
30
29
|
require 'git/config'
|
|
30
|
+
require 'git/config_entry_info'
|
|
31
|
+
require 'git/parsers/config_entry'
|
|
32
|
+
require 'git/configuring'
|
|
31
33
|
require 'git/diff'
|
|
32
34
|
require 'git/diff_file_numstat_info'
|
|
33
35
|
require 'git/diff_file_patch_info'
|
|
@@ -40,16 +42,17 @@ require 'git/encoding_utils'
|
|
|
40
42
|
require 'git/errors'
|
|
41
43
|
require 'git/escaped_path'
|
|
42
44
|
require 'git/execution_context'
|
|
45
|
+
require 'git/execution_context/global'
|
|
43
46
|
require 'git/file_ref'
|
|
44
47
|
require 'git/fsck_object'
|
|
45
48
|
require 'git/fsck_result'
|
|
49
|
+
require 'git/parsers/ls_remote'
|
|
46
50
|
require 'git/version_constraint'
|
|
47
|
-
require 'git/
|
|
51
|
+
require 'git/commands'
|
|
48
52
|
require 'git/log'
|
|
49
53
|
require 'git/object'
|
|
50
54
|
require 'git/remote'
|
|
51
55
|
require 'git/repository'
|
|
52
|
-
require 'git/base'
|
|
53
56
|
require 'git/status'
|
|
54
57
|
require 'git/stash'
|
|
55
58
|
require 'git/stash_info'
|
|
@@ -69,34 +72,57 @@ require 'git/worktrees'
|
|
|
69
72
|
# @author Scott Chacon (mailto:schacon@gmail.com)
|
|
70
73
|
#
|
|
71
74
|
module Git
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
#
|
|
75
|
-
#
|
|
75
|
+
extend Git::Configuring
|
|
76
|
+
|
|
77
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
78
|
+
# Use `Git.config_get(name)`, `Git.config_set(name, value)`, or `Git.config_list` instead.
|
|
76
79
|
def config(name = nil, value = nil)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
# return value
|
|
83
|
-
lib.config_get(name)
|
|
84
|
-
else
|
|
85
|
-
# return hash
|
|
86
|
-
lib.config_list
|
|
87
|
-
end
|
|
80
|
+
Git::Deprecation.warn(
|
|
81
|
+
'Git#config is deprecated and will be removed in v6.0.0. ' \
|
|
82
|
+
'Use Git.config_get(name), Git.config_set(name, value), or Git.config_list instead.'
|
|
83
|
+
)
|
|
84
|
+
Git.__send__(:run_config_utility, name, value, global: false)
|
|
88
85
|
end
|
|
89
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
|
|
93
|
+
#
|
|
94
|
+
# @yieldparam config [Git::Config] the singleton config object
|
|
95
|
+
#
|
|
96
|
+
# @yieldreturn [void]
|
|
97
|
+
#
|
|
98
|
+
# @return [void]
|
|
99
|
+
#
|
|
90
100
|
def self.configure
|
|
91
|
-
yield
|
|
101
|
+
yield Git::Config.instance
|
|
102
|
+
nil
|
|
92
103
|
end
|
|
93
104
|
|
|
105
|
+
# Returns the process-wide {Git::Config} singleton
|
|
106
|
+
#
|
|
107
|
+
# @example Read the configured binary path
|
|
108
|
+
# Git.config.binary_path #=> "git"
|
|
109
|
+
#
|
|
110
|
+
# @return [Git::Config] the singleton config object
|
|
111
|
+
#
|
|
94
112
|
def self.config
|
|
95
|
-
|
|
113
|
+
Git::Config.instance
|
|
96
114
|
end
|
|
97
115
|
|
|
116
|
+
# @deprecated Mixing in the `Git` module is deprecated and will be removed in v6.0.0.
|
|
117
|
+
# Use `Git.config_get(name, global: true)`, `Git.config_set(name, value, global: true)`, or
|
|
118
|
+
# `Git.config_list(global: true)` instead.
|
|
98
119
|
def global_config(name = nil, value = nil)
|
|
99
|
-
|
|
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)
|
|
100
126
|
end
|
|
101
127
|
|
|
102
128
|
# Open a bare repository
|
|
@@ -130,11 +156,11 @@ module Git
|
|
|
130
156
|
# are logged at the `:info` level. Additional logging is done at the `:debug`
|
|
131
157
|
# level.
|
|
132
158
|
#
|
|
133
|
-
# @return [Git::
|
|
159
|
+
# @return [Git::Repository] an object that can execute git commands in the context
|
|
134
160
|
# of the bare repository.
|
|
135
161
|
#
|
|
136
162
|
def self.bare(git_dir, options = {})
|
|
137
|
-
|
|
163
|
+
Git::Repository.bare(git_dir, options)
|
|
138
164
|
end
|
|
139
165
|
|
|
140
166
|
# Clone a repository into an empty or newly created directory
|
|
@@ -248,11 +274,11 @@ module Git
|
|
|
248
274
|
# git_ssh: 'ssh -i /path/to/private_key'
|
|
249
275
|
# )
|
|
250
276
|
#
|
|
251
|
-
# @return [Git::
|
|
277
|
+
# @return [Git::Repository] an object that can execute git commands in the context
|
|
252
278
|
# of the cloned local working copy or cloned repository.
|
|
253
279
|
#
|
|
254
280
|
def self.clone(repository_url, directory = nil, options = {})
|
|
255
|
-
|
|
281
|
+
Git::Repository.clone(repository_url, directory, options)
|
|
256
282
|
end
|
|
257
283
|
|
|
258
284
|
# Returns the name of the default branch of the given repository
|
|
@@ -293,7 +319,9 @@ module Git
|
|
|
293
319
|
# @return [String] the name of the default branch
|
|
294
320
|
#
|
|
295
321
|
def self.default_branch(repository, options = {})
|
|
296
|
-
|
|
322
|
+
context = Git::ExecutionContext::Global.new(logger: options[:log])
|
|
323
|
+
output = Git::Commands::LsRemote.new(context).call(repository, 'HEAD', symref: true).stdout
|
|
324
|
+
Git::Parsers::LsRemote.parse_default_branch(output)
|
|
297
325
|
end
|
|
298
326
|
|
|
299
327
|
# Export the current HEAD (or a branch, if <tt>options[:branch]</tt>
|
|
@@ -317,17 +345,7 @@ module Git
|
|
|
317
345
|
# g.config('user.name') # returns 'Scott Chacon'
|
|
318
346
|
# g.config # returns whole config hash
|
|
319
347
|
def self.global_config(name = nil, value = nil)
|
|
320
|
-
|
|
321
|
-
if name && value
|
|
322
|
-
# set value
|
|
323
|
-
lib.global_config_set(name, value)
|
|
324
|
-
elsif name
|
|
325
|
-
# return value
|
|
326
|
-
lib.global_config_get(name)
|
|
327
|
-
else
|
|
328
|
-
# return hash
|
|
329
|
-
lib.global_config_list
|
|
330
|
-
end
|
|
348
|
+
run_config_utility(name, value, global: true)
|
|
331
349
|
end
|
|
332
350
|
|
|
333
351
|
# Create an empty Git repository or reinitialize an existing Git repository
|
|
@@ -367,11 +385,15 @@ module Git
|
|
|
367
385
|
# - If nil, disables SSH for this instance.
|
|
368
386
|
# - If a non-empty string, uses that value for this instance.
|
|
369
387
|
#
|
|
388
|
+
# @option options [String, :use_global_config] :binary_path path to the git
|
|
389
|
+
# binary; defaults to `Git::Config.instance.binary_path` when not specified.
|
|
390
|
+
# Raises `ArgumentError` if set to `nil`.
|
|
391
|
+
#
|
|
370
392
|
# @option options [Logger] :log A logger to use for Git operations. Git
|
|
371
393
|
# commands are logged at the `:info` level. Additional logging is done
|
|
372
394
|
# at the `:debug` level.
|
|
373
395
|
#
|
|
374
|
-
# @return [Git::
|
|
396
|
+
# @return [Git::Repository] an object that can execute git commands in the context
|
|
375
397
|
# of the newly initialized repository
|
|
376
398
|
#
|
|
377
399
|
# @example Initialize a repository in the current directory
|
|
@@ -389,31 +411,23 @@ module Git
|
|
|
389
411
|
# @see https://git-scm.com/docs/git-init git init
|
|
390
412
|
#
|
|
391
413
|
def self.init(directory = '.', options = {})
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
options = options.dup
|
|
395
|
-
options[:repository] ||= options.delete(:separate_git_dir)
|
|
396
|
-
init_opts = options.slice(:bare, :initial_branch)
|
|
397
|
-
init_opts[:separate_git_dir] = options[:repository] if options.key?(:repository)
|
|
398
|
-
Git::Commands::Init.new(Git::Lib.new(nil, options[:log])).call(directory, **init_opts)
|
|
399
|
-
|
|
400
|
-
open_initialized_repository(directory, options)
|
|
414
|
+
Git::Repository.init(directory, options)
|
|
401
415
|
end
|
|
402
416
|
|
|
403
|
-
#
|
|
417
|
+
# Option keys accepted by {.ls_remote}
|
|
418
|
+
#
|
|
419
|
+
# Parser-incompatible options such as `:get_url` and `:symref` are intentionally
|
|
420
|
+
# excluded because {Git::Parsers::LsRemote.parse_output} cannot handle the
|
|
421
|
+
# non-standard output formats those flags produce.
|
|
422
|
+
#
|
|
423
|
+
# @return [Array<Symbol>]
|
|
404
424
|
#
|
|
405
|
-
# @param directory [String] the directory containing the repository
|
|
406
|
-
# @param options [Hash] the options hash
|
|
407
|
-
# @return [Git::Base] the opened repository
|
|
408
425
|
# @api private
|
|
409
426
|
#
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
Git.open(directory, options.slice(:log, :git_ssh, :index, :repository).compact)
|
|
415
|
-
end
|
|
416
|
-
end
|
|
427
|
+
LS_REMOTE_ALLOWED_OPTS = %i[
|
|
428
|
+
branches b heads h tags t refs upload_pack quiet q exit_code sort server_option o timeout
|
|
429
|
+
].freeze
|
|
430
|
+
private_constant :LS_REMOTE_ALLOWED_OPTS
|
|
417
431
|
|
|
418
432
|
# returns a Hash containing information about the references
|
|
419
433
|
# of the target repository
|
|
@@ -424,7 +438,15 @@ module Git
|
|
|
424
438
|
# @param [String|NilClass] location the target repository location or nil for '.'
|
|
425
439
|
# @return [{String=>Hash}] the available references of the target repo.
|
|
426
440
|
def self.ls_remote(location = nil, options = {})
|
|
427
|
-
|
|
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)
|
|
428
450
|
end
|
|
429
451
|
|
|
430
452
|
# Open a an existing Git working directory
|
|
@@ -474,17 +496,41 @@ module Git
|
|
|
474
496
|
# commands are logged at the `:info` level. Additional logging is done
|
|
475
497
|
# at the `:debug` level.
|
|
476
498
|
#
|
|
477
|
-
# @return [Git::
|
|
499
|
+
# @return [Git::Repository] an object that can execute git commands in the context
|
|
478
500
|
# of the opened working copy
|
|
479
501
|
#
|
|
480
502
|
def self.open(working_dir, options = {})
|
|
481
|
-
|
|
503
|
+
Git::Repository.open(working_dir, options)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
# Thread-safe cache for git versions, keyed by binary path.
|
|
507
|
+
@git_version_cache_mutex = Mutex.new
|
|
508
|
+
@git_version_cache = {}
|
|
509
|
+
|
|
510
|
+
# @api private
|
|
511
|
+
def self.cached_git_version(binary_path, &block)
|
|
512
|
+
@git_version_cache_mutex.synchronize do
|
|
513
|
+
@git_version_cache[binary_path] ||= block.call
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
# @api private
|
|
518
|
+
def self.clear_git_version_cache
|
|
519
|
+
@git_version_cache_mutex.synchronize do
|
|
520
|
+
@git_version_cache.clear
|
|
521
|
+
end
|
|
482
522
|
end
|
|
483
523
|
|
|
484
524
|
# Return the version of a git binary as a {Git::Version}
|
|
485
525
|
#
|
|
526
|
+
# @example Default binary
|
|
527
|
+
# Git.git_version #=> #<Git::Version 2.42.0>
|
|
528
|
+
#
|
|
529
|
+
# @example Explicit binary path
|
|
530
|
+
# Git.git_version('/opt/homebrew/bin/git') #=> #<Git::Version 2.42.0>
|
|
531
|
+
#
|
|
486
532
|
# @param binary_path [String, nil] path to the git binary; defaults to
|
|
487
|
-
# `Git::
|
|
533
|
+
# `Git::Config.instance.binary_path`
|
|
488
534
|
#
|
|
489
535
|
# @return [Git::Version] the parsed git version
|
|
490
536
|
#
|
|
@@ -494,15 +540,9 @@ module Git
|
|
|
494
540
|
#
|
|
495
541
|
# @raise [Git::Error] if the binary is not found or fails to launch
|
|
496
542
|
#
|
|
497
|
-
# @example Default binary
|
|
498
|
-
# Git.git_version #=> #<Git::Version 2.42.0>
|
|
499
|
-
#
|
|
500
|
-
# @example Explicit binary path
|
|
501
|
-
# Git.git_version('/opt/homebrew/bin/git') #=> #<Git::Version 2.42.0>
|
|
502
|
-
#
|
|
503
543
|
def self.git_version(binary_path = nil)
|
|
504
|
-
path = binary_path || Git::
|
|
505
|
-
|
|
544
|
+
path = binary_path || Git::Config.instance.binary_path
|
|
545
|
+
cached_git_version(path) { run_git_version(path) }
|
|
506
546
|
end
|
|
507
547
|
|
|
508
548
|
# @api private
|
|
@@ -512,18 +552,83 @@ module Git
|
|
|
512
552
|
end
|
|
513
553
|
private_class_method :run_git_version
|
|
514
554
|
|
|
555
|
+
# @api private
|
|
556
|
+
def self.run_config_utility(name, value, global:)
|
|
557
|
+
context = Git::ExecutionContext::Global.new
|
|
558
|
+
options = global ? { global: true } : {}
|
|
559
|
+
|
|
560
|
+
return Git::Commands::ConfigOptionSyntax::Set.new(context).call(name, value, **options) if !name.nil? && !value.nil?
|
|
561
|
+
return run_config_get(context, name, options) if name
|
|
562
|
+
|
|
563
|
+
output = Git::Commands::ConfigOptionSyntax::List.new(context).call(**options).stdout
|
|
564
|
+
parse_config_list(output.split("\n"))
|
|
565
|
+
end
|
|
566
|
+
private_class_method :run_config_utility
|
|
567
|
+
|
|
568
|
+
def self.run_config_get(context, name, options)
|
|
569
|
+
result = Git::Commands::ConfigOptionSyntax::Get.new(context).call(name, **options)
|
|
570
|
+
raise Git::FailedError, result if result.status.exitstatus != 0
|
|
571
|
+
|
|
572
|
+
result.stdout
|
|
573
|
+
end
|
|
574
|
+
private_class_method :run_config_get
|
|
575
|
+
|
|
576
|
+
# @api private
|
|
577
|
+
def self.parse_config_list(lines)
|
|
578
|
+
lines.each_with_object({}) do |line, hsh|
|
|
579
|
+
key, value = line.split('=', 2)
|
|
580
|
+
hsh[key] = value || ''
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
private_class_method :parse_config_list
|
|
584
|
+
|
|
585
|
+
# @api private
|
|
586
|
+
def self.execution_context
|
|
587
|
+
Git::ExecutionContext::Global.new
|
|
588
|
+
end
|
|
589
|
+
private_class_method :execution_context
|
|
590
|
+
|
|
591
|
+
# Scopes that require an active repository and cannot be used at the Git module level
|
|
592
|
+
#
|
|
593
|
+
# @api private
|
|
594
|
+
#
|
|
595
|
+
REPOSITORY_SPECIFIC_SCOPES = %i[local worktree blob].freeze
|
|
596
|
+
private_constant :REPOSITORY_SPECIFIC_SCOPES
|
|
597
|
+
|
|
598
|
+
# Raises +ArgumentError+ when a repository-specific scope is requested.
|
|
599
|
+
#
|
|
600
|
+
# The +:local+, +:worktree+, and +:blob+ scopes require an active git
|
|
601
|
+
# repository and are therefore not valid at the Git module level.
|
|
602
|
+
#
|
|
603
|
+
# @api private
|
|
604
|
+
#
|
|
605
|
+
def self.assert_valid_scope!(**opts)
|
|
606
|
+
invalid = REPOSITORY_SPECIFIC_SCOPES.select { |s| opts[s] }
|
|
607
|
+
return if invalid.empty?
|
|
608
|
+
|
|
609
|
+
raise ArgumentError, "#{invalid.join(', ')} scope requires a repository"
|
|
610
|
+
end
|
|
611
|
+
private_class_method :assert_valid_scope!
|
|
612
|
+
|
|
515
613
|
# Return the version of the git binary
|
|
516
614
|
#
|
|
517
|
-
# @example
|
|
518
|
-
#
|
|
615
|
+
# @example Basic usage
|
|
616
|
+
# Git.binary_version # => [2, 46, 0]
|
|
617
|
+
#
|
|
618
|
+
# @param binary_path [String, nil] path to the git binary; defaults to
|
|
619
|
+
# `Git::Config.instance.binary_path`
|
|
519
620
|
#
|
|
520
621
|
# @return [Array<Integer>] the version of the git binary
|
|
521
622
|
#
|
|
522
|
-
# @deprecated Use {Git.git_version} instead, which returns a
|
|
623
|
+
# @deprecated Use {Git.git_version} instead, which returns a
|
|
624
|
+
# {Git::Version} (not an Array)
|
|
625
|
+
#
|
|
523
626
|
# For the legacy array shape, call: `Git.git_version.to_a`.
|
|
524
|
-
# The optional binary_path argument is preserved:
|
|
627
|
+
# The optional binary_path argument is preserved:
|
|
628
|
+
# `Git.git_version(binary_path)`.
|
|
525
629
|
#
|
|
526
|
-
def self.binary_version(binary_path =
|
|
630
|
+
def self.binary_version(binary_path = nil)
|
|
631
|
+
binary_path ||= Git::Config.instance.binary_path
|
|
527
632
|
Git::Deprecation.warn(
|
|
528
633
|
'Git.binary_version is deprecated and will be removed in 6.0. ' \
|
|
529
634
|
'Use Git.git_version instead, which returns a Git::Version ' \
|