git 4.0.0 → 4.0.1
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/.gitignore +1 -0
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +51 -0
- data/.rubocop_todo.yml +12 -0
- data/CHANGELOG.md +44 -0
- data/Rakefile +13 -1
- data/git.gemspec +35 -30
- data/lib/git/args_builder.rb +103 -0
- data/lib/git/author.rb +6 -5
- data/lib/git/base.rb +254 -165
- data/lib/git/branch.rb +14 -15
- data/lib/git/branches.rb +9 -13
- data/lib/git/command_line.rb +97 -55
- data/lib/git/config.rb +4 -6
- data/lib/git/diff.rb +75 -39
- data/lib/git/diff_path_status.rb +4 -3
- data/lib/git/diff_stats.rb +1 -1
- data/lib/git/errors.rb +8 -2
- data/lib/git/escaped_path.rb +1 -1
- data/lib/git/lib.rb +865 -557
- data/lib/git/log.rb +74 -210
- data/lib/git/object.rb +85 -66
- data/lib/git/path.rb +18 -8
- data/lib/git/remote.rb +3 -4
- data/lib/git/repository.rb +0 -2
- data/lib/git/stash.rb +13 -6
- data/lib/git/stashes.rb +5 -5
- data/lib/git/status.rb +108 -247
- data/lib/git/url.rb +3 -3
- data/lib/git/version.rb +1 -1
- data/lib/git/worktree.rb +4 -5
- data/lib/git/worktrees.rb +4 -6
- data/lib/git.rb +16 -15
- metadata +35 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 800cd24ccf9ac35997240caf75df510839ecc7fb6a7e810b518d8a68a19a9251
|
4
|
+
data.tar.gz: 50ac76f678bf832e9eea55c027d9ad6f98514880c7673b58a5602c85c34a080e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e37d72ec1ebeea3d7eb784f6779e98288be086ac86941db67c0357b8902719218302449b69a5718d68da805f3bd8b19ddf21040766528724bc416e012bcc55b
|
7
|
+
data.tar.gz: 6402c06932c7d51f1a5ba6022464589be335c22539de31e5570e4ba22d54b76a2b7055edbe5d518c0377763837495f2005e83c91bbac360d752d724238a0d9c2
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
inherit_gem:
|
4
|
+
main_branch_shared_rubocop_config: config/rubocop.yml
|
5
|
+
|
6
|
+
# Don't care about complexity offenses in the TestUnit tests This exclusions
|
7
|
+
# will be removed when we switch to RSpec.
|
8
|
+
Metrics/CyclomaticComplexity:
|
9
|
+
Exclude:
|
10
|
+
- "tests/test_helper.rb"
|
11
|
+
- "tests/units/**/*"
|
12
|
+
|
13
|
+
Metrics/ClassLength:
|
14
|
+
Exclude:
|
15
|
+
- "tests/test_helper.rb"
|
16
|
+
- "tests/units/**/*"
|
17
|
+
|
18
|
+
Metrics/AbcSize:
|
19
|
+
Exclude:
|
20
|
+
- "tests/test_helper.rb"
|
21
|
+
- "tests/units/**/*"
|
22
|
+
|
23
|
+
# Don't care so much about length of methods in tests
|
24
|
+
Metrics/MethodLength:
|
25
|
+
Exclude:
|
26
|
+
- "tests/test_helper.rb"
|
27
|
+
- "tests/units/**/*"
|
28
|
+
|
29
|
+
# Allow test data to have long lines
|
30
|
+
Layout/LineLength:
|
31
|
+
Exclude:
|
32
|
+
- "tests/test_helper.rb"
|
33
|
+
- "tests/units/**/*"
|
34
|
+
- "*.gemspec"
|
35
|
+
|
36
|
+
# Testing and gemspec DSL results in large blocks
|
37
|
+
Metrics/BlockLength:
|
38
|
+
Exclude:
|
39
|
+
- "tests/test_helper.rb"
|
40
|
+
- "tests/units/**/*"
|
41
|
+
- "*.gemspec"
|
42
|
+
|
43
|
+
# Don't force every test class to be described
|
44
|
+
Style/Documentation:
|
45
|
+
Exclude:
|
46
|
+
- "tests/units/**/*"
|
47
|
+
|
48
|
+
AllCops:
|
49
|
+
# Pin this project to Ruby 3.1 in case the shared config above is upgraded to 3.2
|
50
|
+
# or later.
|
51
|
+
TargetRubyVersion: 3.2
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2025-07-06 21:08:14 UTC using RuboCop version 1.77.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
# Configuration parameters: CountComments, CountAsOne.
|
11
|
+
Metrics/ClassLength:
|
12
|
+
Max: 1032
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,50 @@
|
|
5
5
|
|
6
6
|
# Change Log
|
7
7
|
|
8
|
+
## [4.0.1](https://github.com/ruby-git/ruby-git/compare/v4.0.0...v4.0.1) (2025-07-06)
|
9
|
+
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
* Fix Rubocop Layout/LineLength offense ([52d80ac](https://github.com/ruby-git/ruby-git/commit/52d80ac592d9139655d47af8e764eebf8577fda7))
|
14
|
+
* Fix Rubocop Lint/EmptyBlock offense ([9081f0f](https://github.com/ruby-git/ruby-git/commit/9081f0fb055e0d6cc693fd8f8bf47b2fa13efef0))
|
15
|
+
* Fix Rubocop Lint/MissingSuper offense ([e9e91a8](https://github.com/ruby-git/ruby-git/commit/e9e91a88fc338944b816ee6929cadf06ff1daab5))
|
16
|
+
* Fix Rubocop Lint/StructNewOverride offense ([141c2cf](https://github.com/ruby-git/ruby-git/commit/141c2cfd8215f5120f536f78b3c066751d74aabe))
|
17
|
+
* Fix Rubocop Lint/SuppressedException offense ([4372a20](https://github.com/ruby-git/ruby-git/commit/4372a20b0b61e862efb7558f2274769ae17aa2c9))
|
18
|
+
* Fix Rubocop Lint/UselessConstantScoping offense ([54c4a3b](https://github.com/ruby-git/ruby-git/commit/54c4a3bba206ab379a0849fbc9478db5b61e192a))
|
19
|
+
* Fix Rubocop Metrics/AbcSize offense ([256d860](https://github.com/ruby-git/ruby-git/commit/256d8602a4024d1fbe432eda8bbcb1891fb726bc))
|
20
|
+
* Fix Rubocop Metrics/BlockLength offense ([9c856ba](https://github.com/ruby-git/ruby-git/commit/9c856ba42d0955cb6c3f5848f9c3253b54fd3735))
|
21
|
+
* Fix Rubocop Metrics/ClassLength offense (exclude tests) ([d70c800](https://github.com/ruby-git/ruby-git/commit/d70c800263ff1347109688dbb5b66940c6d64f2c))
|
22
|
+
* Fix Rubocop Metrics/ClassLength offense (refactor Git::Log) ([1aae57a](https://github.com/ruby-git/ruby-git/commit/1aae57a631aa331a84c37122ffc8fa09b415c6c5))
|
23
|
+
* Fix Rubocop Metrics/ClassLength offense (refactor Git::Status) ([e3a378b](https://github.com/ruby-git/ruby-git/commit/e3a378b6384bf1d0dc80ebc5aea792f9ff5b512a))
|
24
|
+
* Fix Rubocop Metrics/CyclomaticComplexity offense ([abfcf94](https://github.com/ruby-git/ruby-git/commit/abfcf948a08578635f7e832c31deaf992e6f3fb1))
|
25
|
+
* Fix Rubocop Metrics/MethodLength offense ([e708c36](https://github.com/ruby-git/ruby-git/commit/e708c3673321bdcae13516bd63f3c5d051b3ba33))
|
26
|
+
* Fix Rubocop Metrics/ParameterLists offense ([c7946b0](https://github.com/ruby-git/ruby-git/commit/c7946b089aba648d0e56a7435f85ed337e33d116))
|
27
|
+
* Fix Rubocop Metrics/PerceivedComplexity offense ([5dd5e0c](https://github.com/ruby-git/ruby-git/commit/5dd5e0c55fd37bb4baf3cf196f752a4f6c142ca7))
|
28
|
+
* Fix Rubocop Naming/AccessorMethodName offense ([e9d9c4f](https://github.com/ruby-git/ruby-git/commit/e9d9c4f2488d2527176b87c547caecfae4040219))
|
29
|
+
* Fix Rubocop Naming/HeredocDelimiterNaming offense ([b4297a5](https://github.com/ruby-git/ruby-git/commit/b4297a54ef4a0106e9786d10230a7219dcdbf0e8))
|
30
|
+
* Fix Rubocop Naming/PredicateMethod offense ([d33f7a8](https://github.com/ruby-git/ruby-git/commit/d33f7a8969ef1bf47adbca16589021647d5d2bb9))
|
31
|
+
* Fix Rubocop Naming/PredicatePrefix offense ([57edc79](https://github.com/ruby-git/ruby-git/commit/57edc7995750b8c1f792bcae480b9082e86d14d3))
|
32
|
+
* Fix Rubocop Naming/VariableNumber offense ([3fba6fa](https://github.com/ruby-git/ruby-git/commit/3fba6fa02908c632891c67f32ef7decc388e8147))
|
33
|
+
* Fix Rubocop Style/ClassVars offense ([a2f651a](https://github.com/ruby-git/ruby-git/commit/a2f651aea60e43b9b41271f03fe6cb6c4ef12b70))
|
34
|
+
* Fix Rubocop Style/Documentation offense ([e80c27d](https://github.com/ruby-git/ruby-git/commit/e80c27dbb50b38e71db55187ce1a630682d2ef3b))
|
35
|
+
* Fix Rubocop Style/IfUnlessModifier offense ([c974832](https://github.com/ruby-git/ruby-git/commit/c97483239e64477adab4ad047c094401ea008591))
|
36
|
+
* Fix Rubocop Style/MultilineBlockChain offense ([dd4e4ec](https://github.com/ruby-git/ruby-git/commit/dd4e4ecf0932ab02fa58ebe7a4189b44828729f5))
|
37
|
+
* Fix Rubocop Style/OptionalBooleanParameter offense ([c010a86](https://github.com/ruby-git/ruby-git/commit/c010a86cfc265054dc02ab4b7d778e4ba7e5426c))
|
38
|
+
* Fix typo in status.rb ([284fae7](https://github.com/ruby-git/ruby-git/commit/284fae7d3606724325ec21b0da7794d9eae2f0bd))
|
39
|
+
* Remove duplicate methods found by rubocop ([bd691c5](https://github.com/ruby-git/ruby-git/commit/bd691c58e3312662f07f8f96a1b48a7533f9a2e1))
|
40
|
+
* Result of running rake rubocop:autocorrect ([8f1e3bb](https://github.com/ruby-git/ruby-git/commit/8f1e3bb25fb4567093e9b49af42847a918d7d0c4))
|
41
|
+
* Result of running rake rubocop:autocorrect_all ([5c75783](https://github.com/ruby-git/ruby-git/commit/5c75783c0f50fb48d59012176cef7e985f7f83e2))
|
42
|
+
|
43
|
+
|
44
|
+
### Other Changes
|
45
|
+
|
46
|
+
* Add rubocop todo file to silence known offenses until they can be fixed ([2c36f8c](https://github.com/ruby-git/ruby-git/commit/2c36f8c9eb8ff14defe8f6fff1b6eb81d277f620))
|
47
|
+
* Avoid deprecated dsa for tests keys ([1da8c28](https://github.com/ruby-git/ruby-git/commit/1da8c2894b727757a909d015fb5a4bcd00133f59))
|
48
|
+
* Fix yarddoc error caused by rubocop autocorrect ([58c4af3](https://github.com/ruby-git/ruby-git/commit/58c4af3513df3c854e49380adfe5685023275684))
|
49
|
+
* Integrate Rubocop with the project ([a04297d](https://github.com/ruby-git/ruby-git/commit/a04297d8d6568691b71402d9dbba36c45427ebc3))
|
50
|
+
* Rename Gem::Specification variable from s to spec ([4d976c4](https://github.com/ruby-git/ruby-git/commit/4d976c443c3a3cf25cc2fec7caa213ae7f090853))
|
51
|
+
|
8
52
|
## [4.0.0](https://github.com/ruby-git/ruby-git/compare/v3.1.1...v4.0.0) (2025-07-02)
|
9
53
|
|
10
54
|
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bundler/gem_tasks'
|
2
4
|
require 'English'
|
3
5
|
|
@@ -18,6 +20,16 @@ task :test do
|
|
18
20
|
end
|
19
21
|
default_tasks << :test
|
20
22
|
|
23
|
+
# Rubocop
|
24
|
+
|
25
|
+
require 'rubocop/rake_task'
|
26
|
+
|
27
|
+
RuboCop::RakeTask.new
|
28
|
+
|
29
|
+
default_tasks << :rubocop
|
30
|
+
|
31
|
+
# YARD
|
32
|
+
|
21
33
|
unless RUBY_PLATFORM == 'java' || RUBY_ENGINE == 'truffleruby'
|
22
34
|
#
|
23
35
|
# YARD documentation for this project can NOT be built with JRuby.
|
@@ -51,7 +63,7 @@ default_tasks << :build
|
|
51
63
|
task default: default_tasks
|
52
64
|
|
53
65
|
desc 'Build and install the git gem and run a sanity check'
|
54
|
-
task
|
66
|
+
task 'test:gem': :install do
|
55
67
|
output = `ruby -e "require 'git'; g = Git.open('.'); puts g.log.size"`.chomp
|
56
68
|
raise 'Gem test failed' unless $CHILD_STATUS.success?
|
57
69
|
raise 'Expected gem test to return an integer' unless output =~ /^\d+$/
|
data/git.gemspec
CHANGED
@@ -1,52 +1,57 @@
|
|
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
|
-
|
32
|
+
spec.add_dependency 'activesupport', '>= 5.0'
|
33
|
+
spec.add_dependency 'addressable', '~> 2.8'
|
34
|
+
spec.add_dependency 'process_executer', '~> 4.0'
|
35
|
+
spec.add_dependency 'rchardet', '~> 1.9'
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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'
|
34
43
|
|
35
|
-
|
36
|
-
s.add_development_dependency 'minitar', '~> 1.0'
|
37
|
-
s.add_development_dependency 'mocha', '~> 2.7'
|
38
|
-
s.add_development_dependency 'rake', '~> 13.2'
|
39
|
-
s.add_development_dependency 'test-unit', '~> 3.6'
|
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 'redcarpet', '~> 3.6'
|
48
|
+
spec.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
|
49
|
+
spec.add_development_dependency 'yardstick', '~> 0.9'
|
45
50
|
end
|
46
51
|
|
47
52
|
# Specify which files should be added to the gem when it is released.
|
48
53
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
49
|
-
|
54
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
50
55
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features|bin)/}) }
|
51
56
|
end
|
52
57
|
end
|
@@ -0,0 +1,103 @@
|
|
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
|
+
valued_equals: ->(config, value) { "#{config[:flag]}=#{value}" if value },
|
16
|
+
|
17
|
+
valued_space: ->(config, value) { [config[:flag], value.to_s] if value },
|
18
|
+
|
19
|
+
repeatable_valued_space: lambda do |config, value|
|
20
|
+
Array(value).flat_map { |v| [config[:flag], v.to_s] }
|
21
|
+
end,
|
22
|
+
|
23
|
+
custom: ->(config, value) { config[:builder].call(value) },
|
24
|
+
|
25
|
+
validate_only: ->(_config, _value) { [] } # Does not build any args
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
# Main entrypoint to validate options and build arguments
|
29
|
+
def self.build(opts, option_map)
|
30
|
+
validate!(opts, option_map)
|
31
|
+
new(opts, option_map).build
|
32
|
+
end
|
33
|
+
|
34
|
+
# Public validation method that can be called independently
|
35
|
+
def self.validate!(opts, option_map)
|
36
|
+
validate_unsupported_keys!(opts, option_map)
|
37
|
+
validate_configured_options!(opts, option_map)
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(opts, option_map)
|
41
|
+
@opts = opts
|
42
|
+
@option_map = option_map
|
43
|
+
end
|
44
|
+
|
45
|
+
def build
|
46
|
+
@option_map.flat_map do |config|
|
47
|
+
type = config[:type]
|
48
|
+
next config[:flag] if type == :static
|
49
|
+
|
50
|
+
key = config[:keys].find { |k| @opts.key?(k) }
|
51
|
+
next [] unless key
|
52
|
+
|
53
|
+
build_arg_for_option(config, @opts[key])
|
54
|
+
end.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def build_arg_for_option(config, value)
|
60
|
+
builder = ARG_BUILDERS[config[:type]]
|
61
|
+
builder&.call(config, value) || []
|
62
|
+
end
|
63
|
+
|
64
|
+
private_class_method def self.validate_unsupported_keys!(opts, option_map)
|
65
|
+
all_valid_keys = option_map.flat_map { |config| config[:keys] }.compact
|
66
|
+
unsupported_keys = opts.keys - all_valid_keys
|
67
|
+
|
68
|
+
return if unsupported_keys.empty?
|
69
|
+
|
70
|
+
raise ArgumentError, "Unsupported options: #{unsupported_keys.map(&:inspect).join(', ')}"
|
71
|
+
end
|
72
|
+
|
73
|
+
private_class_method def self.validate_configured_options!(opts, option_map)
|
74
|
+
option_map.each do |config|
|
75
|
+
next unless config[:keys] # Skip static flags
|
76
|
+
|
77
|
+
check_for_missing_required_option!(opts, config)
|
78
|
+
validate_option_value!(opts, config)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private_class_method def self.check_for_missing_required_option!(opts, config)
|
83
|
+
return unless config[:required]
|
84
|
+
|
85
|
+
key_provided = config[:keys].any? { |k| opts.key?(k) }
|
86
|
+
return if key_provided
|
87
|
+
|
88
|
+
raise ArgumentError, "Missing required option: #{config[:keys].first}"
|
89
|
+
end
|
90
|
+
|
91
|
+
private_class_method def self.validate_option_value!(opts, config)
|
92
|
+
validator = config[:validator]
|
93
|
+
return unless validator
|
94
|
+
|
95
|
+
user_key = config[:keys].find { |k| opts.key?(k) }
|
96
|
+
return unless user_key # Don't validate if the user didn't provide the option
|
97
|
+
|
98
|
+
return if validator.call(opts[user_key])
|
99
|
+
|
100
|
+
raise ArgumentError, "Invalid value for option: #{user_key}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/git/author.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Git
|
4
|
+
# An author in a Git commit
|
4
5
|
class Author
|
5
6
|
attr_accessor :name, :email, :date
|
6
7
|
|
7
8
|
def initialize(author_string)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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)
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|