git 1.19.1 → 4.4.5
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/.commitlintrc.yml +38 -0
- data/.github/copilot-instructions.md +2733 -0
- data/.github/pull_request_template.md +17 -0
- data/.github/workflows/continuous_integration.yml +92 -21
- data/.github/workflows/enforce_conventional_commits.yml +29 -0
- data/.github/workflows/experimental_continuous_integration.yml +59 -0
- data/.github/workflows/release.yml +53 -0
- data/.gitignore +5 -0
- data/.husky/commit-msg +1 -0
- data/.release-please-manifest.json +3 -0
- data/.rubocop.yml +55 -0
- data/.rubocop_todo.yml +12 -0
- data/.yardopts +4 -1
- data/AI_POLICY.md +24 -0
- data/CHANGELOG.md +501 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/CONTRIBUTING.md +323 -102
- data/GOVERNANCE.md +106 -0
- data/LICENSE +1 -1
- data/MAINTAINERS.md +17 -4
- data/README.md +575 -246
- data/Rakefile +13 -55
- data/git.gemspec +36 -30
- data/lib/git/args_builder.rb +111 -0
- data/lib/git/author.rb +9 -7
- data/lib/git/base.rb +602 -173
- data/lib/git/branch.rb +318 -38
- data/lib/git/branches.rb +21 -24
- data/lib/git/command_line.rb +330 -0
- data/lib/git/command_line_result.rb +9 -3
- data/lib/git/config.rb +10 -6
- data/lib/git/diff.rb +149 -81
- data/lib/git/diff_path_status.rb +46 -0
- data/lib/git/diff_stats.rb +59 -0
- data/lib/git/errors.rb +212 -0
- data/lib/git/escaped_path.rb +2 -2
- data/lib/git/fsck_object.rb +48 -0
- data/lib/git/fsck_result.rb +121 -0
- data/lib/git/index.rb +2 -1
- data/lib/git/lib.rb +1648 -643
- data/lib/git/log.rb +143 -106
- data/lib/git/object.rb +151 -125
- data/lib/git/path.rb +23 -16
- data/lib/git/remote.rb +5 -4
- data/lib/git/repository.rb +2 -2
- data/lib/git/stash.rb +11 -12
- data/lib/git/stashes.rb +16 -15
- data/lib/git/status.rb +104 -143
- data/lib/git/url.rb +3 -3
- data/lib/git/version.rb +3 -1
- data/lib/git/working_directory.rb +2 -0
- data/lib/git/worktree.rb +6 -5
- data/lib/git/worktrees.rb +6 -6
- data/lib/git.rb +131 -28
- data/package.json +10 -0
- data/redesign/1_architecture_existing.md +66 -0
- data/redesign/2_architecture_redesign.md +130 -0
- data/redesign/3_architecture_implementation.md +138 -0
- data/redesign/index.md +34 -0
- data/release-please-config.json +36 -0
- data/tasks/gem_tasks.rake +10 -0
- data/tasks/rubocop.rake +12 -0
- data/tasks/test.rake +13 -0
- data/tasks/test_gem.rake +12 -0
- data/tasks/yard.rake +23 -0
- metadata +114 -37
- data/.github/stale.yml +0 -25
- data/Dockerfile.changelog-rs +0 -12
- data/PULL_REQUEST_TEMPLATE.md +0 -9
- data/RELEASING.md +0 -70
- data/lib/git/base/factory.rb +0 -99
- data/lib/git/failed_error.rb +0 -53
- data/lib/git/git_execute_error.rb +0 -7
- data/lib/git/signaled_error.rb +0 -50
- /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
data/Rakefile
CHANGED
|
@@ -1,60 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
require 'English'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
require '
|
|
3
|
+
require 'rake/clean'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
desc 'Run Unit Tests'
|
|
9
|
-
task :test do
|
|
10
|
-
sh 'ruby bin/test'
|
|
11
|
-
|
|
12
|
-
# You can run individual test files (or multiple files) from the command
|
|
13
|
-
# line with:
|
|
14
|
-
#
|
|
15
|
-
# $ bin/test tests/units/test_archive.rb
|
|
16
|
-
#
|
|
17
|
-
# $ bin/test tests/units/test_archive.rb tests/units/test_object.rb
|
|
18
|
-
end
|
|
19
|
-
default_tasks << :test
|
|
20
|
-
|
|
21
|
-
unless RUBY_PLATFORM == 'java' || RUBY_ENGINE == 'truffleruby'
|
|
22
|
-
#
|
|
23
|
-
# YARD documentation for this project can NOT be built with JRuby.
|
|
24
|
-
# This project uses the redcarpet gem which can not be installed on JRuby.
|
|
25
|
-
#
|
|
26
|
-
require 'yard'
|
|
27
|
-
YARD::Rake::YardocTask.new
|
|
28
|
-
CLEAN << '.yardoc'
|
|
29
|
-
CLEAN << 'doc'
|
|
30
|
-
default_tasks << :yard
|
|
31
|
-
|
|
32
|
-
require 'yardstick/rake/verify'
|
|
33
|
-
Yardstick::Rake::Verify.new(:'yardstick:coverage') do |t|
|
|
34
|
-
t.threshold = 50
|
|
35
|
-
t.require_exact_threshold = false
|
|
36
|
-
end
|
|
37
|
-
default_tasks << :'yardstick:coverage'
|
|
5
|
+
# Load all .rake files from tasks and its subdirectories.
|
|
6
|
+
Dir.glob('tasks/**/*.rake').each { |r| load r }
|
|
38
7
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
default_tasks << :build
|
|
8
|
+
default_tasks = []
|
|
9
|
+
default_tasks << :test if Rake::Task.task_defined?(:test)
|
|
10
|
+
default_tasks << :rubocop if Rake::Task.task_defined?(:rubocop)
|
|
11
|
+
default_tasks << :yard if Rake::Task.task_defined?(:yard)
|
|
12
|
+
default_tasks << :'yardstick:coverage' if Rake::Task.task_defined?(:'yardstick:coverage')
|
|
13
|
+
# Do not include yardstick as a default task for now since there are too many
|
|
14
|
+
# warnings. Will work to get the warnings down before re-enabling it.
|
|
15
|
+
# default_tasks << :yardstick if Rake::Task.task_defined?(:yardstick)
|
|
16
|
+
default_tasks << :build if Rake::Task.task_defined?(:build)
|
|
50
17
|
|
|
51
18
|
task default: default_tasks
|
|
52
|
-
|
|
53
|
-
desc 'Build and install the git gem and run a sanity check'
|
|
54
|
-
task :'test:gem' => :install do
|
|
55
|
-
output = `ruby -e "require 'git'; g = Git.open('.'); puts g.log.size"`.chomp
|
|
56
|
-
raise 'Gem test failed' unless $CHILD_STATUS.success?
|
|
57
|
-
raise 'Expected gem test to return an integer' unless output =~ /^\d+$/
|
|
58
|
-
|
|
59
|
-
puts 'Gem Test Succeeded'
|
|
60
|
-
end
|
data/git.gemspec
CHANGED
|
@@ -1,52 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path('lib', __dir__)
|
|
2
4
|
require 'git/version'
|
|
3
5
|
|
|
4
|
-
Gem::Specification.new do |
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.author = 'Scott Chacon and others'
|
|
8
|
+
spec.email = 'schacon@gmail.com'
|
|
9
|
+
spec.homepage = 'http://github.com/ruby-git/ruby-git'
|
|
10
|
+
spec.license = 'MIT'
|
|
11
|
+
spec.name = 'git'
|
|
12
|
+
spec.summary = 'An API to create, read, and manipulate Git repositories'
|
|
13
|
+
spec.description = <<~DESCRIPTION
|
|
12
14
|
The git gem provides an API that can be used to
|
|
13
15
|
create, read, and manipulate Git repositories by wrapping system calls to the git
|
|
14
16
|
command line. The API can be used for working with Git in complex interactions
|
|
15
17
|
including branching and merging, object inspection and manipulation, history, patch
|
|
16
18
|
generation and more.
|
|
17
19
|
DESCRIPTION
|
|
18
|
-
|
|
20
|
+
spec.version = Git::VERSION
|
|
19
21
|
|
|
22
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
23
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
24
|
+
spec.metadata['changelog_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}/file/CHANGELOG.md"
|
|
25
|
+
spec.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{spec.name}/#{spec.version}"
|
|
26
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
s.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{s.name}/#{s.version}"
|
|
28
|
+
spec.require_paths = ['lib']
|
|
29
|
+
spec.required_ruby_version = '>= 3.2.0'
|
|
30
|
+
spec.requirements = ['git 2.28.0 or greater']
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
spec.add_dependency 'activesupport', '>= 5.0'
|
|
33
|
+
spec.add_dependency 'addressable', '~> 2.8'
|
|
34
|
+
spec.add_dependency 'process_executer', '~> 4.1'
|
|
35
|
+
spec.add_dependency 'rchardet', '~> 1.9'
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
spec.add_development_dependency 'create_github_release', '~> 2.1'
|
|
38
|
+
spec.add_development_dependency 'main_branch_shared_rubocop_config', '~> 0.1'
|
|
39
|
+
spec.add_development_dependency 'minitar', '~> 1.0'
|
|
40
|
+
spec.add_development_dependency 'mocha', '~> 2.7'
|
|
41
|
+
spec.add_development_dependency 'rake', '~> 13.2'
|
|
42
|
+
spec.add_development_dependency 'rubocop', '~> 1.77'
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
s.add_development_dependency 'create_github_release', '~> 0.2'
|
|
36
|
-
s.add_development_dependency 'minitar', '~> 0.9'
|
|
37
|
-
s.add_development_dependency 'mocha', '~> 2.1'
|
|
38
|
-
s.add_development_dependency 'rake', '~> 13.0'
|
|
39
|
-
s.add_development_dependency 'test-unit', '~> 3.3'
|
|
44
|
+
spec.add_development_dependency 'test-unit', '~> 3.6'
|
|
40
45
|
|
|
41
46
|
unless RUBY_PLATFORM == 'java'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
spec.add_development_dependency 'irb', '~> 1.6'
|
|
48
|
+
spec.add_development_dependency 'redcarpet', '~> 3.6'
|
|
49
|
+
spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
|
|
50
|
+
spec.add_development_dependency 'yardstick', '~> 0.9'
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
# Specify which files should be added to the gem when it is released.
|
|
48
54
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
49
|
-
|
|
55
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
50
56
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features|bin)/}) }
|
|
51
57
|
end
|
|
52
58
|
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Takes a hash of user options and a declarative map and produces
|
|
5
|
+
# an array of command-line arguments. Also validates that only
|
|
6
|
+
# supported options are provided based on the map.
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
class ArgsBuilder
|
|
10
|
+
# This hash maps an option type to a lambda that knows how to build the
|
|
11
|
+
# corresponding command-line argument. This is a scalable dispatch table.
|
|
12
|
+
ARG_BUILDERS = {
|
|
13
|
+
boolean: ->(config, value) { value ? config[:flag] : [] },
|
|
14
|
+
|
|
15
|
+
boolean_negatable: lambda do |config, value|
|
|
16
|
+
case value
|
|
17
|
+
when true then config[:flag]
|
|
18
|
+
when false then config[:flag].sub('--', '--no-')
|
|
19
|
+
else []
|
|
20
|
+
end
|
|
21
|
+
end,
|
|
22
|
+
|
|
23
|
+
valued_equals: ->(config, value) { "#{config[:flag]}=#{value}" if value },
|
|
24
|
+
|
|
25
|
+
valued_space: ->(config, value) { [config[:flag], value.to_s] if value },
|
|
26
|
+
|
|
27
|
+
repeatable_valued_space: lambda do |config, value|
|
|
28
|
+
Array(value).flat_map { |v| [config[:flag], v.to_s] }
|
|
29
|
+
end,
|
|
30
|
+
|
|
31
|
+
custom: ->(config, value) { config[:builder].call(value) },
|
|
32
|
+
|
|
33
|
+
validate_only: ->(_config, _value) { [] } # Does not build any args
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
# Main entrypoint to validate options and build arguments
|
|
37
|
+
def self.build(opts, option_map)
|
|
38
|
+
validate!(opts, option_map)
|
|
39
|
+
new(opts, option_map).build
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Public validation method that can be called independently
|
|
43
|
+
def self.validate!(opts, option_map)
|
|
44
|
+
validate_unsupported_keys!(opts, option_map)
|
|
45
|
+
validate_configured_options!(opts, option_map)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def initialize(opts, option_map)
|
|
49
|
+
@opts = opts
|
|
50
|
+
@option_map = option_map
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def build
|
|
54
|
+
@option_map.flat_map do |config|
|
|
55
|
+
type = config[:type]
|
|
56
|
+
next config[:flag] if type == :static
|
|
57
|
+
|
|
58
|
+
key = config[:keys].find { |k| @opts.key?(k) }
|
|
59
|
+
next [] unless key
|
|
60
|
+
|
|
61
|
+
build_arg_for_option(config, @opts[key])
|
|
62
|
+
end.compact
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def build_arg_for_option(config, value)
|
|
68
|
+
builder = ARG_BUILDERS[config[:type]]
|
|
69
|
+
builder&.call(config, value) || []
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private_class_method def self.validate_unsupported_keys!(opts, option_map)
|
|
73
|
+
all_valid_keys = option_map.flat_map { |config| config[:keys] }.compact
|
|
74
|
+
unsupported_keys = opts.keys - all_valid_keys
|
|
75
|
+
|
|
76
|
+
return if unsupported_keys.empty?
|
|
77
|
+
|
|
78
|
+
raise ArgumentError, "Unsupported options: #{unsupported_keys.map(&:inspect).join(', ')}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private_class_method def self.validate_configured_options!(opts, option_map)
|
|
82
|
+
option_map.each do |config|
|
|
83
|
+
next unless config[:keys] # Skip static flags
|
|
84
|
+
|
|
85
|
+
check_for_missing_required_option!(opts, config)
|
|
86
|
+
validate_option_value!(opts, config)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private_class_method def self.check_for_missing_required_option!(opts, config)
|
|
91
|
+
return unless config[:required]
|
|
92
|
+
|
|
93
|
+
key_provided = config[:keys].any? { |k| opts.key?(k) }
|
|
94
|
+
return if key_provided
|
|
95
|
+
|
|
96
|
+
raise ArgumentError, "Missing required option: #{config[:keys].first}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private_class_method def self.validate_option_value!(opts, config)
|
|
100
|
+
validator = config[:validator]
|
|
101
|
+
return unless validator
|
|
102
|
+
|
|
103
|
+
user_key = config[:keys].find { |k| opts.key?(k) }
|
|
104
|
+
return unless user_key # Don't validate if the user didn't provide the option
|
|
105
|
+
|
|
106
|
+
return if validator.call(opts[user_key])
|
|
107
|
+
|
|
108
|
+
raise ArgumentError, "Invalid value for option: #{user_key}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/git/author.rb
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Git
|
|
4
|
+
# An author in a Git commit
|
|
2
5
|
class Author
|
|
3
6
|
attr_accessor :name, :email, :date
|
|
4
|
-
|
|
7
|
+
|
|
5
8
|
def initialize(author_string)
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
return unless (m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string))
|
|
10
|
+
|
|
11
|
+
@name = m[1]
|
|
12
|
+
@email = m[2]
|
|
13
|
+
@date = Time.at(m[3].to_i)
|
|
11
14
|
end
|
|
12
|
-
|
|
13
15
|
end
|
|
14
16
|
end
|