git 1.19.1 → 2.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f12803468275850ae680a4df2719890e8f84de95258f30dc898f817c7155d44
4
- data.tar.gz: d24540a708538775d2ff1af495f04e7f42a297aaf790d0fe7b65ad71fe402550
3
+ metadata.gz: bf201a54a634864ee66f8e43866215d0c133fba4d2169ac1e0da3e5aa7bb1a2f
4
+ data.tar.gz: 38e2e3d0f2429fe458bca0218a49bd7d09707acd7d76da40cc8f9d7ce6fcfd74
5
5
  SHA512:
6
- metadata.gz: 15a09f75d84fb1ff7547403eb36c7342bee11fc1a23cf86e5eae224a2494da0e0bc60bf288c04924c87bdf6736f156f4d98f0468cf815d03b3291509ab234e8d
7
- data.tar.gz: 7fe2633018ec2e38805b987271cc033d023b1a32b429cf2f75e88d1ac1c86c913689fc46806ea49c38fce66005215b05fc700ca3adc925afd0b3dcd3fefdc091
6
+ metadata.gz: 03cb58e9fc52d517d1a95584dae5c99d15532446442bac8aa6383a81770d7cc439643cd8bea04e5ae93dda8e481936ed3deebe86166fef2c4b9cd0ca3cdc8580
7
+ data.tar.gz: 2ca4de81d5a9359dc8f80d1a4ca218dafc472f5b9cb5a5b7f01c6633adbeaf8361c34e9f741147ae1948593779af9770508be35a3ef3590991e6830990a6355f
@@ -2,35 +2,39 @@ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches: [master,v1]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [master,v1]
8
8
  workflow_dispatch:
9
9
 
10
10
  jobs:
11
- continuous_integration_build:
12
- continue-on-error: true
11
+ build:
12
+ name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
13
+ runs-on: ${{ matrix.operating-system }}
14
+ continue-on-error: ${{ matrix.experimental == 'Yes' }}
15
+ env: { JAVA_OPTS: -Djdk.io.File.enableADS=true }
16
+
13
17
  strategy:
14
18
  fail-fast: false
15
19
  matrix:
16
- ruby: [2.7, 3.0, 3.1, 3.2]
20
+ # Only the latest versions of JRuby and TruffleRuby are tested
21
+ ruby: ["3.0", "3.1", "3.2", "3.3", "truffleruby-23.1.1", "jruby-9.4.5.0"]
17
22
  operating-system: [ubuntu-latest]
23
+ experimental: [No]
18
24
  include:
19
- - ruby: head
25
+ - # Building against head version of Ruby is considered experimental
26
+ ruby: head
20
27
  operating-system: ubuntu-latest
21
- - ruby: truffleruby-head
22
- operating-system: ubuntu-latest
23
- - ruby: 2.7
24
- operating-system: windows-latest
25
- - ruby: jruby-head
26
- operating-system: windows-latest
28
+ experimental: Yes
27
29
 
28
- name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
29
-
30
- runs-on: ${{ matrix.operating-system }}
30
+ - # Only test with minimal Ruby version on Windows
31
+ ruby: 3.0
32
+ operating-system: windows-latest
31
33
 
32
- env:
33
- JAVA_OPTS: -Djdk.io.File.enableADS=true
34
+ - # Since JRuby on Windows is known to not work, consider this experimental
35
+ ruby: jruby-9.4.5.0
36
+ operating-system: windows-latest
37
+ experimental: Yes
34
38
 
35
39
  steps:
36
40
  - name: Checkout Code
data/CHANGELOG.md CHANGED
@@ -5,6 +5,16 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## v2.0.0.pre1 (2024-01-15)
9
+
10
+ [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.19.1..v2.0.0.pre1)
11
+
12
+ Changes since v1.19.1:
13
+
14
+ * 7585c39 Change how the git CLI subprocess is executed (#684)
15
+ * f93e042 Update instructions for releasing a new version of the git gem (#686)
16
+ * f48930d Update minimum required version of Ruby and Git (#685)
17
+
8
18
  ## v1.19.1 (2024-01-13)
9
19
 
10
20
  [Full Changelog](https://github.com/ruby-git/ruby-git/compare/v1.19.0..v1.19.1)
data/README.md CHANGED
@@ -17,6 +17,14 @@ command line. The API can be used for working with Git in complex interactions
17
17
  including branching and merging, object inspection and manipulation, history, patch
18
18
  generation and more.
19
19
 
20
+ Get started by obtaining a repository object by:
21
+
22
+ * opening an existing working copy with [Git.open](https://rubydoc.info/gems/git/Git#open-class_method)
23
+ * initializing a new repository with [Git.init](https://rubydoc.info/gems/git/Git#init-class_method)
24
+ * cloning a repository with [Git.clone](https://rubydoc.info/gems/git/Git#clone-class_method)
25
+
26
+ Methods that can be called on a repository object are documented in [Git::Base](https://rubydoc.info/gems/git/Git/Base)
27
+
20
28
  ## v2.0.0 pre-release
21
29
 
22
30
  git 2.0.0 is available as a pre-release version for testing! Please give it a try.
@@ -32,7 +40,7 @@ The changes coming in this major release include:
32
40
  * Update the required Git command line version to at least 2.28
33
41
  * Update how CLI commands are called to use the [process_executer](https://github.com/main-branch/process_executer)
34
42
  gem which is built on top of [Kernel.spawn](https://ruby-doc.org/3.3.0/Kernel.html#method-i-spawn).
35
- See [PR #617](https://github.com/ruby-git/ruby-git/pull/617) for more details
43
+ See [PR #684](https://github.com/ruby-git/ruby-git/pull/684) for more details
36
44
  on the motivation for this implementation.
37
45
 
38
46
  The tentative plan is to release `2.0.0` near the end of March 2024 depending on
@@ -41,36 +49,19 @@ the feedback received during the pre-release period.
41
49
  The `master` branch will be used for `2.x` development. If needed, fixes for `1.x`
42
50
  version will be done on the `v1` branch.
43
51
 
44
- ## Homepage
45
-
46
- The project source code is at:
47
-
48
- http://github.com/ruby-git/ruby-git
49
-
50
- ## Documentation
51
-
52
- Detailed documentation can be found at:
53
-
54
- https://rubydoc.info/gems/git/Git.html
55
-
56
- Get started by obtaining a repository object by:
57
-
58
- * opening an existing working copy with [Git.open](https://rubydoc.info/gems/git/Git#open-class_method)
59
- * initializing a new repository with [Git.init](https://rubydoc.info/gems/git/Git#init-class_method)
60
- * cloning a repository with [Git.clone](https://rubydoc.info/gems/git/Git#clone-class_method)
61
-
62
- Methods that can be called on a repository object are documented in [Git::Base](https://rubydoc.info/gems/git/Git/Base)
63
-
64
52
  ## Install
65
53
 
66
- You can install Ruby/Git like this:
54
+ Install the gem and add to the application's Gemfile by executing:
67
55
 
68
- ```
69
- sudo gem install git
56
+ ```shell
57
+ bundle add git
70
58
  ```
71
59
 
72
- ## Code Status
60
+ If bundler is not being used to manage dependencies, install the gem by executing:
73
61
 
62
+ ```shell
63
+ gem install git
64
+ ```
74
65
 
75
66
  ## Major Objects
76
67
 
@@ -103,12 +94,6 @@ Pass the `--all` option to `git log` as follows:
103
94
 
104
95
  Here are a bunch of examples of how to use the Ruby/Git package.
105
96
 
106
- Ruby < 1.9 will require rubygems to be loaded.
107
-
108
- ```ruby
109
- require 'rubygems'
110
- ```
111
-
112
97
  Require the 'git' gem.
113
98
  ```ruby
114
99
  require 'git'
@@ -422,6 +407,14 @@ g.with_temp_working(dir) do
422
407
  end
423
408
  ```
424
409
 
410
+ ## Ruby version support policy
411
+
412
+ This gem will be expected to function correctly on:
413
+
414
+ * All non-EOL versions of the MRI Ruby on Mac, Linux, and Windows
415
+ * The latest version of JRuby on Linux and Windows
416
+ * The latest version of Truffle Ruby on Linus
417
+
425
418
  ## License
426
419
 
427
420
  licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further details.
data/RELEASING.md CHANGED
@@ -7,64 +7,79 @@
7
7
 
8
8
  Releasing a new version of the `git` gem requires these steps:
9
9
 
10
- - [How to release a new git.gem](#how-to-release-a-new-gitgem)
11
- - [Install Prerequisites](#install-prerequisites)
12
- - [Prepare the Release](#prepare-the-release)
13
- - [Review and Merge the Release](#review-and-merge-the-release)
14
- - [Build and Release the Gem](#build-and-release-the-gem)
15
-
16
- These instructions use an example where:
17
-
18
- - The default branch is `master`
19
- - The current release version is `1.5.0`
20
- - You want to create a new *minor* release, `1.6.0`
10
+ * [Install Prerequisites](#install-prerequisites)
11
+ * [Determine the SemVer release type](#determine-the-semver-release-type)
12
+ * [Create the release](#create-the-release)
13
+ * [Review the CHANGELOG and release PR](#review-the-changelog-and-release-pr)
14
+ * [Manually merge the release PR](#manually-merge-the-release-pr)
15
+ * [Publish the git gem to RubyGems.org](#publish-the-git-gem-to-rubygemsorg)
21
16
 
22
17
  ## Install Prerequisites
23
18
 
24
19
  The following tools need to be installed in order to create the release:
25
20
 
26
- - [git](https://git-scm.com) is used to interact with the local and remote repositories
27
- - [gh](https://cli.github.com) is used to create the release and PR in GitHub
28
- - [Docker](https://www.docker.com) is used to run the script to create the release notes
21
+ * [create_githhub_release](https://github.com/main-branch/create_github_release) is used to create the release
22
+ * [git](https://git-scm.com) is used by `create-github-release` to interact with the local and remote repositories
23
+ * [gh](https://cli.github.com) is used by `create-github-release` to create the release and PR in GitHub
29
24
 
30
- On a Mac, these tools can be installed using [brew](https://brew.sh):
25
+ On a Mac, these tools can be installed using [gem](https://guides.rubygems.org/rubygems-basics/) and [brew](https://brew.sh):
31
26
 
32
27
  ```shell
28
+ $ gem install create_github_release
29
+ ...
33
30
  $ brew install git
34
31
  ...
35
32
  $ brew install gh
36
33
  ...
37
- $ brew install --cask docker
38
- ...
39
34
  $
40
35
  ```
41
36
 
42
- ## Prepare the Release
37
+ ## Determine the SemVer release type
43
38
 
44
- Bump the version, create release notes, tag the release and create a GitHub release and PR which can be used to review the release.
39
+ Determine the SemVer version increment that should be applied for the new release:
45
40
 
46
- Steps:
41
+ * `major`: when the release includes incompatible API or functional changes.
42
+ * `minor`: when the release adds functionality in a backward-compatible manner
43
+ * `patch`: when the release includes small user-facing changes that are
44
+ backward-compatible and do not introduce new functionality.
47
45
 
48
- - Check out the code with `git clone https://github.com/ruby-git/ruby-git ruby-git-v1.6.0 && cd ruby-git-v1.6.0`
49
- - Install development dependencies using bundle `bundle install`
50
- - Based upon the nature of the changes, decide on the type of release: `major`, `minor`, or `patch` (in this example we will use `minor`)
51
- - Run the release script `bundle exec create-github-release minor`
46
+ ## Create the release
52
47
 
53
- ## Review and Merge the Release
48
+ Create the release using the `create-github-release` command. If the release type
49
+ is `major`, the command is:
54
50
 
55
- Have the release PR approved and merge the changes into the `master` branch.
51
+ ```shell
52
+ create-github-release major
53
+ ```
56
54
 
57
- **IMPORTANT** DO NOT merge to the `master` branch using the GitHub UI. Instead use the instructions below.
55
+ Follow the directions given by the `create-github-release` command to finish the
56
+ release. Where the instructions given by the command differ than the instructions
57
+ below, follow the instructions given by the command.
58
58
 
59
- Steps:
59
+ ## Review the CHANGELOG and release PR
60
60
 
61
- - Get the release PR reviewed and approved in GitHub
62
- - Merge the changes with the command `git checkout master && git merge --ff-only v1.6.0 && git push`
61
+ The `create-github-release` command will output a link to the CHANGELOG and the PR
62
+ it created for the release. Review the CHANGELOG and have someone review and approve
63
+ the release PR.
63
64
 
64
- ## Build and Release the Gem
65
+ ## Manually merge the release PR
65
66
 
66
- Build the gem and publish it to [rubygems.org](https://rubygems.org/gems/git)
67
+ It is important to manually merge the PR so a separate merge commit can be avoided.
68
+ Use the commands output by the `create-github-release` which will looks like this
69
+ if you are creating a 2.0.0 release:
67
70
 
68
- Steps:
71
+ ```shell
72
+ git checkout master
73
+ git merge --ff-only release-v2.0.0
74
+ git push
75
+ ```
76
+
77
+ This will automatically close the release PR.
78
+
79
+ ## Publish the git gem to RubyGems.org
69
80
 
70
- - Build and release the gem using rake `bundle exec rake release`
81
+ Finally, publish the git gem to RubyGems.org using the following command:
82
+
83
+ ```shell
84
+ rake release:rubygem_push
85
+ ```
data/git.gemspec CHANGED
@@ -24,22 +24,20 @@ Gem::Specification.new do |s|
24
24
  s.metadata['documentation_uri'] = "https://rubydoc.info/gems/#{s.name}/#{s.version}"
25
25
 
26
26
  s.require_paths = ['lib']
27
- s.required_ruby_version = '>= 2.3'
28
- s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to?(:required_rubygems_version=)
29
- s.requirements = ['git 1.6.0.0, or greater']
27
+ s.required_ruby_version = '>= 3.0.0'
28
+ s.requirements = ['git 2.28.0 or greater']
30
29
 
31
30
  s.add_runtime_dependency 'addressable', '~> 2.8'
31
+ s.add_runtime_dependency 'process_executer', '~> 0.7'
32
32
  s.add_runtime_dependency 'rchardet', '~> 1.8'
33
33
 
34
- s.add_development_dependency 'bump', '~> 0.10'
35
- s.add_development_dependency 'create_github_release', '~> 0.2'
36
34
  s.add_development_dependency 'minitar', '~> 0.9'
37
35
  s.add_development_dependency 'mocha', '~> 2.1'
38
- s.add_development_dependency 'rake', '~> 13.0'
39
- s.add_development_dependency 'test-unit', '~> 3.3'
36
+ s.add_development_dependency 'rake', '~> 13.1'
37
+ s.add_development_dependency 'test-unit', '~> 3.6'
40
38
 
41
39
  unless RUBY_PLATFORM == 'java'
42
- s.add_development_dependency 'redcarpet', '~> 3.5'
40
+ s.add_development_dependency 'redcarpet', '~> 3.6'
43
41
  s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
44
42
  s.add_development_dependency 'yardstick', '~> 0.9'
45
43
  end
@@ -0,0 +1,342 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'git/base'
4
+ require 'git/command_line_result'
5
+ require 'git/failed_error'
6
+ require 'git/signaled_error'
7
+ require 'stringio'
8
+
9
+ module Git
10
+ # Runs a git command and returns the result
11
+ #
12
+ # @api public
13
+ #
14
+ class CommandLine
15
+ # Create a Git::CommandLine object
16
+ #
17
+ # @example
18
+ # env = { 'GIT_DIR' => '/path/to/git/dir' }
19
+ # binary_path = '/usr/bin/git'
20
+ # global_opts = %w[--git-dir /path/to/git/dir]
21
+ # logger = Logger.new(STDOUT)
22
+ # cli = CommandLine.new(env, binary_path, global_opts, logger)
23
+ # cli.run('version') #=> #<Git::CommandLineResult:0x00007f9b0c0b0e00
24
+ #
25
+ # @param env [Hash<String, String>] environment variables to set
26
+ # @param global_opts [Array<String>] global options to pass to git
27
+ # @param logger [Logger] the logger to use
28
+ #
29
+ def initialize(env, binary_path, global_opts, logger)
30
+ @env = env
31
+ @binary_path = binary_path
32
+ @global_opts = global_opts
33
+ @logger = logger
34
+ end
35
+
36
+ # @attribute [r] env
37
+ #
38
+ # Variables to set (or unset) in the git command's environment
39
+ #
40
+ # @example
41
+ # env = { 'GIT_DIR' => '/path/to/git/dir' }
42
+ # command_line = Git::CommandLine.new(env, '/usr/bin/git', [], Logger.new(STDOUT))
43
+ # command_line.env #=> { 'GIT_DIR' => '/path/to/git/dir' }
44
+ #
45
+ # @return [Hash<String, String>]
46
+ #
47
+ # @see https://ruby-doc.org/3.2.1/Process.html#method-c-spawn Process.spawn
48
+ # for details on how to set environment variables using the `env` parameter
49
+ #
50
+ attr_reader :env
51
+
52
+ # @attribute [r] binary_path
53
+ #
54
+ # The path to the command line binary to run
55
+ #
56
+ # @example
57
+ # binary_path = '/usr/bin/git'
58
+ # command_line = Git::CommandLine.new({}, binary_path, ['version'], Logger.new(STDOUT))
59
+ # command_line.binary_path #=> '/usr/bin/git'
60
+ #
61
+ # @return [String]
62
+ #
63
+ attr_reader :binary_path
64
+
65
+ # @attribute [r] global_opts
66
+ #
67
+ # The global options to pass to git
68
+ #
69
+ # These are options that are passed to git before the command name and
70
+ # arguments. For example, in `git --git-dir /path/to/git/dir version`, the
71
+ # global options are %w[--git-dir /path/to/git/dir].
72
+ #
73
+ # @example
74
+ # env = {}
75
+ # global_opts = %w[--git-dir /path/to/git/dir]
76
+ # logger = Logger.new(nil)
77
+ # cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
78
+ # cli.global_opts #=> %w[--git-dir /path/to/git/dir]
79
+ #
80
+ # @return [Array<String>]
81
+ #
82
+ attr_reader :global_opts
83
+
84
+ # @attribute [r] logger
85
+ #
86
+ # The logger to use for logging git commands and results
87
+ #
88
+ # @example
89
+ # env = {}
90
+ # global_opts = %w[]
91
+ # logger = Logger.new(STDOUT)
92
+ # cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
93
+ # cli.logger == logger #=> true
94
+ #
95
+ # @return [Logger]
96
+ #
97
+ attr_reader :logger
98
+
99
+ # Execute a git command, wait for it to finish, and return the result
100
+ #
101
+ # NORMALIZATION
102
+ #
103
+ # The command output is returned as a Unicde string containing the binary output
104
+ # from the command. If the binary output is not valid UTF-8, the output will
105
+ # cause problems because the encoding will be invalid.
106
+ #
107
+ # Normalization is a process that trys to convert the binary output to a valid
108
+ # UTF-8 string. It uses the `rchardet` gem to detect the encoding of the binary
109
+ # output and then converts it to UTF-8.
110
+ #
111
+ # Normalization is not enabled by default. Pass `normalize: true` to Git::CommandLine#run
112
+ # to enable it. Normalization will only be performed on stdout and only if the `out:`` option
113
+ # is nil or is a StringIO object. If the out: option is set to a file or other IO object,
114
+ # the normalize option will be ignored.
115
+ #
116
+ # @example Run a command and return the output
117
+ #
118
+ # cli.run('version') #=> "git version 2.39.1\n"
119
+ #
120
+ # @example The args array should be splatted into the parameter list
121
+ # args = %w[log -n 1 --oneline]
122
+ # cli.run(*args) #=> "f5baa11 beginning of Ruby/Git project\n"
123
+ #
124
+ # @example Run a command and return the chomped output
125
+ # cli.run('version', chomp: true) #=> "git version 2.39.1"
126
+ #
127
+ # @example Run a command and without normalizing the output
128
+ # cli.run('version', normalize: false) #=> "git version 2.39.1\n"
129
+ #
130
+ # @example Capture stdout in a temporary file
131
+ # require 'tempfile'
132
+ # tempfile = Tempfile.create('git') do |file|
133
+ # cli.run('version', out: file)
134
+ # file.rewind
135
+ # file.read #=> "git version 2.39.1\n"
136
+ # end
137
+ #
138
+ # @example Capture stderr in a StringIO object
139
+ # require 'stringio'
140
+ # stderr = StringIO.new
141
+ # begin
142
+ # cli.run('log', 'nonexistent-branch', err: stderr)
143
+ # rescue Git::FailedError => e
144
+ # stderr.string #=> "unknown revision or path not in the working tree.\n"
145
+ # end
146
+ #
147
+ # @param args [Array<String>] the command line arguements to pass to git
148
+ #
149
+ # This array should be splatted into the parameter list.
150
+ #
151
+ # @param out [#write, nil] the object to write stdout to or nil to ignore stdout
152
+ #
153
+ # If this is a 'StringIO' object, then `stdout_writer.string` will be returned.
154
+ #
155
+ # In general, only specify a `stdout_writer` object when you want to redirect
156
+ # stdout to a file or some other object that responds to `#write`. The default
157
+ # behavior will return the output of the command.
158
+ #
159
+ # @param err [#write] the object to write stderr to or nil to ignore stderr
160
+ #
161
+ # If this is a 'StringIO' object and `merged_output` is `true`, then
162
+ # `stderr_writer.string` will be merged into the output returned by this method.
163
+ #
164
+ # @param normalize [Boolean] whether to normalize the output to a valid encoding
165
+ # @param chomp [Boolean] whether to chomp the output
166
+ # @param merge [Boolean] whether to merge stdout and stderr in the string returned
167
+ # @param chdir [String] the directory to run the command in
168
+ #
169
+ # @return [Git::CommandLineResult] the output of the command
170
+ #
171
+ # This result of running the command.
172
+ #
173
+ # @raise [ArgumentError] if `args` is not an array of strings
174
+ # @raise [Git::SignaledError] if the command was terminated because of an uncaught signal
175
+ # @raise [Git::FailedError] if the command returned a non-zero exitstatus
176
+ #
177
+ def run(*args, out:, err:, normalize:, chomp:, merge:, chdir: nil)
178
+ git_cmd = build_git_cmd(args)
179
+ out ||= StringIO.new
180
+ err ||= (merge ? out : StringIO.new)
181
+ status = execute(git_cmd, out, err, chdir: (chdir || :not_set))
182
+
183
+ process_result(git_cmd, status, out, err, normalize, chomp)
184
+ end
185
+
186
+ private
187
+
188
+ # Build the git command line from the available sources to send to `Process.spawn`
189
+ # @return [Array<String>]
190
+ # @api private
191
+ #
192
+ def build_git_cmd(args)
193
+ raise ArgumentError.new('The args array can not contain an array') if args.any? { |a| a.is_a?(Array) }
194
+
195
+ [binary_path, *global_opts, *args].map { |e| e.to_s }
196
+ end
197
+
198
+ # Determine the output to return in the `CommandLineResult`
199
+ #
200
+ # If the writer can return the output by calling `#string` (such as a StringIO),
201
+ # then return the result of normalizing the encoding and chomping the output
202
+ # as requested.
203
+ #
204
+ # If the writer does not support `#string`, then return nil. The output is
205
+ # assumed to be collected by the writer itself such as when the writer
206
+ # is a file instead of a StringIO.
207
+ #
208
+ # @param writer [#string] the writer to post-process
209
+ #
210
+ # @return [String, nil]
211
+ #
212
+ # @api private
213
+ #
214
+ def post_process(writer, normalize, chomp)
215
+ if writer.respond_to?(:string)
216
+ output = writer.string.dup
217
+ output = output.lines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join if normalize
218
+ output.chomp! if chomp
219
+ output
220
+ else
221
+ nil
222
+ end
223
+ end
224
+
225
+ # Post-process all writers and return an array of the results
226
+ #
227
+ # @param writers [Array<#write>] the writers to post-process
228
+ # @param normalize [Boolean] whether to normalize the output of each writer
229
+ # @param chomp [Boolean] whether to chomp the output of each writer
230
+ #
231
+ # @return [Array<String, nil>] the output of each writer that supports `#string`
232
+ #
233
+ # @api private
234
+ #
235
+ def post_process_all(writers, normalize, chomp)
236
+ Array.new.tap do |result|
237
+ writers.each { |writer| result << post_process(writer, normalize, chomp) }
238
+ end
239
+ end
240
+
241
+ # Raise an error when there was exception while collecting the subprocess output
242
+ #
243
+ # @param git_cmd [Array<String>] the git command that was executed
244
+ # @param pipe_name [Symbol] the name of the pipe that raised the exception
245
+ # @param pipe [ProcessExecuter::MonitoredPipe] the pipe that raised the exception
246
+ #
247
+ # @raise [Git::GitExecuteError]
248
+ #
249
+ # @return [void] this method always raises an error
250
+ #
251
+ # @api private
252
+ #
253
+ def raise_pipe_error(git_cmd, pipe_name, pipe)
254
+ raise Git::GitExecuteError.new("Pipe Exception for #{git_cmd}: #{pipe_name}"), cause: pipe.exception
255
+ end
256
+
257
+ # Execute the git command and collect the output
258
+ #
259
+ # @param cmd [Array<String>] the git command to execute
260
+ # @param chdir [String] the directory to run the command in
261
+ #
262
+ # @raise [Git::GitExecuteError] if an exception was raised while collecting subprocess output
263
+ #
264
+ # @return [Process::Status] the status of the completed subprocess
265
+ #
266
+ # @api private
267
+ #
268
+ def spawn(cmd, out_writers, err_writers, chdir:)
269
+ out_pipe = ProcessExecuter::MonitoredPipe.new(*out_writers, chunk_size: 10_000)
270
+ err_pipe = ProcessExecuter::MonitoredPipe.new(*err_writers, chunk_size: 10_000)
271
+ ProcessExecuter.spawn(env, *cmd, out: out_pipe, err: err_pipe, chdir: chdir)
272
+ ensure
273
+ out_pipe.close
274
+ err_pipe.close
275
+ raise_pipe_error(cmd, :stdout, out_pipe) if out_pipe.exception
276
+ raise_pipe_error(cmd, :stderr, err_pipe) if err_pipe.exception
277
+ end
278
+
279
+ # The writers that will be used to collect stdout and stderr
280
+ #
281
+ # Additional writers could be added here if you wanted to tee output
282
+ # or send output to the terminal.
283
+ #
284
+ # @param out [#write] the object to write stdout to
285
+ # @param err [#write] the object to write stderr to
286
+ #
287
+ # @return [Array<Array<#write>, Array<#write>>] the writers for stdout and stderr
288
+ #
289
+ # @api private
290
+ #
291
+ def writers(out, err)
292
+ out_writers = [out]
293
+ err_writers = [err]
294
+ [out_writers, err_writers]
295
+ end
296
+
297
+ # Process the result of the command and return a Git::CommandLineResult
298
+ #
299
+ # Post process output, log the command and result, and raise an error if the
300
+ # command failed.
301
+ #
302
+ # @param git_cmd [Array<String>] the git command that was executed
303
+ # @param status [Process::Status] the status of the completed subprocess
304
+ # @param out [#write] the object that stdout was written to
305
+ # @param err [#write] the object that stderr was written to
306
+ # @param normalize [Boolean] whether to normalize the output of each writer
307
+ # @param chomp [Boolean] whether to chomp the output of each writer
308
+ #
309
+ # @return [Git::CommandLineResult] the result of the command to return to the caller
310
+ #
311
+ # @raise [Git::FailedError] if the command failed
312
+ # @raise [Git::SignaledError] if the command was signaled
313
+ #
314
+ # @api private
315
+ #
316
+ def process_result(git_cmd, status, out, err, normalize, chomp)
317
+ out_str, err_str = post_process_all([out, err], normalize, chomp)
318
+ logger.info { "#{git_cmd} exited with status #{status}" }
319
+ logger.debug { "stdout:\n#{out_str.inspect}\nstderr:\n#{err_str.inspect}" }
320
+ Git::CommandLineResult.new(git_cmd, status, out_str, err_str).tap do |result|
321
+ raise Git::SignaledError.new(result) if status.signaled?
322
+ raise Git::FailedError.new(result) unless status.success?
323
+ end
324
+ end
325
+
326
+ # Execute the git command and write the command output to out and err
327
+ #
328
+ # @param git_cmd [Array<String>] the git command to execute
329
+ # @param out [#write] the object to write stdout to
330
+ # @param err [#write] the object to write stderr to
331
+ # @param chdir [String] the directory to run the command in
332
+ #
333
+ # @return [Git::CommandLineResult] the result of the command to return to the caller
334
+ #
335
+ # @api private
336
+ #
337
+ def execute(git_cmd, out, err, chdir:)
338
+ out_writers, err_writers = writers(out, err)
339
+ spawn(git_cmd, out_writers, err_writers, chdir: chdir)
340
+ end
341
+ end
342
+ end
@@ -14,20 +14,18 @@ module Git
14
14
  class FailedError < Git::GitExecuteError
15
15
  # Create a FailedError object
16
16
  #
17
- # Since this gem redirects stderr to stdout, the stdout of the process is used.
18
- #
19
17
  # @example
20
18
  # `exit 1` # set $? appropriately for this example
21
19
  # result = Git::CommandLineResult.new(%w[git status], $?, 'stdout', 'stderr')
22
20
  # error = Git::FailedError.new(result)
23
21
  # error.message #=>
24
- # "[\"git\", \"status\"]\nstatus: pid 89784 exit 1\noutput: \"stdout\""
22
+ # "[\"git\", \"status\"]\nstatus: pid 89784 exit 1\nstderr: \"stderr\""
25
23
  #
26
24
  # @param result [Git::CommandLineResult] the result of the git command including
27
25
  # the git command, status, stdout, and stderr
28
26
  #
29
27
  def initialize(result)
30
- super("#{result.git_cmd}\nstatus: #{result.status}\noutput: #{result.stdout.inspect}")
28
+ super("#{result.git_cmd}\nstatus: #{result.status}\nstderr: #{result.stderr.inspect}")
31
29
  @result = result
32
30
  end
33
31
 
data/lib/git/lib.rb CHANGED
@@ -1,14 +1,15 @@
1
1
  require 'git/failed_error'
2
+ require 'git/command_line'
2
3
  require 'logger'
4
+ require 'pp'
5
+ require 'process_executer'
6
+ require 'stringio'
3
7
  require 'tempfile'
4
8
  require 'zlib'
5
9
  require 'open3'
6
10
 
7
11
  module Git
8
12
  class Lib
9
-
10
- @@semaphore = Mutex.new
11
-
12
13
  # The path to the Git working copy. The default is '"./.git"'.
13
14
  #
14
15
  # @return [Pathname] the path to the Git working copy.
@@ -337,7 +338,19 @@ module Git
337
338
  end
338
339
 
339
340
  def object_contents(sha, &block)
340
- command('cat-file', '-p', sha, &block)
341
+ if block_given?
342
+ Tempfile.create do |file|
343
+ # If a block is given, write the output from the process to a temporary
344
+ # file and then yield the file to the block
345
+ #
346
+ command('cat-file', "-p", sha, out: file, err: file)
347
+ file.rewind
348
+ yield file
349
+ end
350
+ else
351
+ # If a block is not given, return stdout
352
+ command('cat-file', '-p', sha)
353
+ end
341
354
  end
342
355
 
343
356
  def ls_tree(sha)
@@ -474,11 +487,15 @@ module Git
474
487
  grep_opts.push('--', *opts[:path_limiter]) if opts[:path_limiter].is_a?(Array)
475
488
 
476
489
  hsh = {}
477
- command_lines('grep', *grep_opts).each do |line|
478
- if m = /(.*?)\:(\d+)\:(.*)/.match(line)
479
- hsh[m[1]] ||= []
480
- hsh[m[1]] << [m[2].to_i, m[3]]
490
+ begin
491
+ command_lines('grep', *grep_opts).each do |line|
492
+ if m = /(.*?)\:(\d+)\:(.*)/.match(line)
493
+ hsh[m[1]] ||= []
494
+ hsh[m[1]] << [m[2].to_i, m[3]]
495
+ end
481
496
  end
497
+ rescue Git::FailedError => e
498
+ raise unless e.result.status.exitstatus == 1 && e.result.stderr == ''
482
499
  end
483
500
  hsh
484
501
  end
@@ -865,16 +882,17 @@ module Git
865
882
 
866
883
  def conflicts # :yields: file, your, their
867
884
  self.unmerged.each do |f|
868
- your_tempfile = Tempfile.new("YOUR-#{File.basename(f)}")
869
- your = your_tempfile.path
870
- your_tempfile.close # free up file for git command process
871
- command('show', ":2:#{f}", redirect: "> #{escape your}")
872
-
873
- their_tempfile = Tempfile.new("THEIR-#{File.basename(f)}")
874
- their = their_tempfile.path
875
- their_tempfile.close # free up file for git command process
876
- command('show', ":3:#{f}", redirect: "> #{escape their}")
877
- yield(f, your, their)
885
+ Tempfile.create("YOUR-#{File.basename(f)}") do |your|
886
+ command('show', ":2:#{f}", out: your)
887
+ your.close
888
+
889
+ Tempfile.create("THEIR-#{File.basename(f)}") do |their|
890
+ command('show', ":3:#{f}", out: their)
891
+ their.close
892
+
893
+ yield(f, your.path, their.path)
894
+ end
895
+ end
878
896
  end
879
897
  end
880
898
 
@@ -948,7 +966,7 @@ module Git
948
966
  arr_opts << remote if remote
949
967
  arr_opts << opts[:ref] if opts[:ref]
950
968
 
951
- command('fetch', *arr_opts)
969
+ command('fetch', *arr_opts, merge: true)
952
970
  end
953
971
 
954
972
  def push(remote = nil, branch = nil, opts = nil)
@@ -1001,7 +1019,13 @@ module Git
1001
1019
  head = File.join(@git_dir, 'refs', 'tags', tag_name)
1002
1020
  return File.read(head).chomp if File.exist?(head)
1003
1021
 
1004
- command('show-ref', '--tags', '-s', tag_name)
1022
+ begin
1023
+ command('show-ref', '--tags', '-s', tag_name)
1024
+ rescue Git::FailedError => e
1025
+ raise unless e.result.status.exitstatus == 1 && e.result.stderr == ''
1026
+
1027
+ ''
1028
+ end
1005
1029
  end
1006
1030
 
1007
1031
  def repack
@@ -1026,15 +1050,12 @@ module Git
1026
1050
 
1027
1051
  def commit_tree(tree, opts = {})
1028
1052
  opts[:message] ||= "commit tree #{tree}"
1029
- t = Tempfile.new('commit-message')
1030
- t.write(opts[:message])
1031
- t.close
1032
-
1033
1053
  arr_opts = []
1034
1054
  arr_opts << tree
1035
1055
  arr_opts << '-p' << opts[:parent] if opts[:parent]
1036
- arr_opts += Array(opts[:parents]).map { |p| ['-p', p] }.flatten if opts[:parents]
1037
- command('commit-tree', *arr_opts, redirect: "< #{escape t.path}")
1056
+ Array(opts[:parents]).each { |p| arr_opts << '-p' << p } if opts[:parents]
1057
+ arr_opts << '-m' << opts[:message]
1058
+ command('commit-tree', *arr_opts)
1038
1059
  end
1039
1060
 
1040
1061
  def update_ref(ref, commit)
@@ -1080,7 +1101,11 @@ module Git
1080
1101
  arr_opts << "--remote=#{opts[:remote]}" if opts[:remote]
1081
1102
  arr_opts << sha
1082
1103
  arr_opts << '--' << opts[:path] if opts[:path]
1083
- command('archive', *arr_opts, redirect: " > #{escape file}")
1104
+
1105
+ f = File.open(file, 'wb')
1106
+ command('archive', *arr_opts, out: f)
1107
+ f.close
1108
+
1084
1109
  if opts[:add_gzip]
1085
1110
  file_content = File.read(file)
1086
1111
  Zlib::GzipWriter.open(file) do |gz|
@@ -1115,7 +1140,7 @@ module Git
1115
1140
  end
1116
1141
 
1117
1142
  def required_command_version
1118
- [1, 6]
1143
+ [2, 28]
1119
1144
  end
1120
1145
 
1121
1146
  def meets_required_version?
@@ -1133,11 +1158,6 @@ module Git
1133
1158
 
1134
1159
  private
1135
1160
 
1136
- # Systen ENV variables involved in the git commands.
1137
- #
1138
- # @return [<String>] the names of the EVN variables involved in the git commands
1139
- ENV_VARIABLE_NAMES = ['GIT_DIR', 'GIT_WORK_TREE', 'GIT_INDEX_FILE', 'GIT_SSH']
1140
-
1141
1161
  def command_lines(cmd, *opts, chdir: nil)
1142
1162
  cmd_op = command(cmd, *opts, chdir: chdir)
1143
1163
  if cmd_op.encoding.name != "UTF-8"
@@ -1148,84 +1168,32 @@ module Git
1148
1168
  op.split("\n")
1149
1169
  end
1150
1170
 
1151
- # Takes the current git's system ENV variables and store them.
1152
- def store_git_system_env_variables
1153
- @git_system_env_variables = {}
1154
- ENV_VARIABLE_NAMES.each do |env_variable_name|
1155
- @git_system_env_variables[env_variable_name] = ENV[env_variable_name]
1156
- end
1171
+ def env_overrides
1172
+ {
1173
+ 'GIT_DIR' => @git_dir,
1174
+ 'GIT_WORK_TREE' => @git_work_dir,
1175
+ 'GIT_INDEX_FILE' => @git_index_file,
1176
+ 'GIT_SSH' => Git::Base.config.git_ssh
1177
+ }
1157
1178
  end
1158
1179
 
1159
- # Takes the previously stored git's ENV variables and set them again on ENV.
1160
- def restore_git_system_env_variables
1161
- ENV_VARIABLE_NAMES.each do |env_variable_name|
1162
- ENV[env_variable_name] = @git_system_env_variables[env_variable_name]
1180
+ def global_opts
1181
+ Array.new.tap do |global_opts|
1182
+ global_opts << "--git-dir=#{@git_dir}" if !@git_dir.nil?
1183
+ global_opts << "--work-tree=#{@git_work_dir}" if !@git_work_dir.nil?
1184
+ global_opts << '-c' << 'core.quotePath=true'
1185
+ global_opts << '-c' << 'color.ui=false'
1163
1186
  end
1164
1187
  end
1165
1188
 
1166
- # Sets git's ENV variables to the custom values for the current instance.
1167
- def set_custom_git_env_variables
1168
- ENV['GIT_DIR'] = @git_dir
1169
- ENV['GIT_WORK_TREE'] = @git_work_dir
1170
- ENV['GIT_INDEX_FILE'] = @git_index_file
1171
- ENV['GIT_SSH'] = Git::Base.config.git_ssh
1189
+ def command_line
1190
+ @command_line ||=
1191
+ Git::CommandLine.new(env_overrides, Git::Base.config.binary_path, global_opts, @logger)
1172
1192
  end
1173
1193
 
1174
- # Runs a block inside an environment with customized ENV variables.
1175
- # It restores the ENV after execution.
1176
- #
1177
- # @param [Proc] block block to be executed within the customized environment
1178
- def with_custom_env_variables(&block)
1179
- @@semaphore.synchronize do
1180
- store_git_system_env_variables()
1181
- set_custom_git_env_variables()
1182
- return block.call()
1183
- end
1184
- ensure
1185
- restore_git_system_env_variables()
1186
- end
1187
-
1188
- def command(*cmd, redirect: '', chomp: true, chdir: nil, &block)
1189
- Git::Lib.warn_if_old_command(self)
1190
-
1191
- raise 'cmd can not include a nested array' if cmd.any? { |o| o.is_a? Array }
1192
-
1193
- global_opts = []
1194
- global_opts << "--git-dir=#{@git_dir}" if !@git_dir.nil?
1195
- global_opts << "--work-tree=#{@git_work_dir}" if !@git_work_dir.nil?
1196
- global_opts << '-c' << 'core.quotePath=true'
1197
- global_opts << '-c' << 'color.ui=false'
1198
-
1199
- escaped_cmd = cmd.map { |part| escape(part) }.join(' ')
1200
-
1201
- global_opts = global_opts.map { |s| escape(s) }.join(' ')
1202
-
1203
- git_cmd = "#{Git::Base.config.binary_path} #{global_opts} #{escaped_cmd} #{redirect} 2>&1"
1204
-
1205
- output = nil
1206
-
1207
- command_thread = nil;
1208
-
1209
- status = nil
1210
-
1211
- with_custom_env_variables do
1212
- command_thread = Thread.new do
1213
- output, status = run_command(git_cmd, chdir, &block)
1214
- end
1215
- command_thread.join
1216
- end
1217
-
1218
- @logger.info(git_cmd)
1219
- @logger.debug(output)
1220
-
1221
- if status.exitstatus > 1 || (status.exitstatus == 1 && output != '')
1222
- result = Git::CommandLineResult.new(git_cmd, status, output, '')
1223
- raise Git::FailedError.new(result)
1224
- end
1225
-
1226
- output.chomp! if output && chomp && !block_given?
1227
-
1228
- output
1194
+ def command(*args, out: nil, err: nil, normalize: true, chomp: true, merge: false, chdir: nil)
1195
+ result = command_line.run(*args, out: out, err: err, normalize: normalize, chomp: chomp, merge: merge, chdir: chdir)
1196
+ result.stdout
1229
1197
  end
1230
1198
 
1231
1199
  # Takes the diff command line output (as Array) and parse it into a Hash
@@ -1291,38 +1259,5 @@ module Git
1291
1259
  end
1292
1260
  arr_opts
1293
1261
  end
1294
-
1295
- def run_command(git_cmd, chdir=nil, &block)
1296
- block ||= Proc.new do |io|
1297
- io.readlines.map { |l| Git::EncodingUtils.normalize_encoding(l) }.join
1298
- end
1299
-
1300
- opts = {}
1301
- opts[:chdir] = File.expand_path(chdir) if chdir
1302
-
1303
- Open3.popen2(git_cmd, opts) do |stdin, stdout, wait_thr|
1304
- [block.call(stdout), wait_thr.value]
1305
- end
1306
- end
1307
-
1308
- def escape(s)
1309
- windows_platform? ? escape_for_windows(s) : escape_for_sh(s)
1310
- end
1311
-
1312
- def escape_for_sh(s)
1313
- "'#{s && s.to_s.gsub('\'','\'"\'"\'')}'"
1314
- end
1315
-
1316
- def escape_for_windows(s)
1317
- # Escape existing double quotes in s and then wrap the result with double quotes
1318
- escaped_string = s.to_s.gsub('"','\\"')
1319
- %Q{"#{escaped_string}"}
1320
- end
1321
-
1322
- def windows_platform?
1323
- # Check if on Windows via RUBY_PLATFORM (CRuby) and RUBY_DESCRIPTION (JRuby)
1324
- win_platform_regex = /mingw|mswin/
1325
- RUBY_PLATFORM =~ win_platform_regex || RUBY_DESCRIPTION =~ win_platform_regex
1326
- end
1327
1262
  end
1328
1263
  end
data/lib/git/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Git
2
2
  # The current gem version
3
3
  # @return [String] the current gem version.
4
- VERSION='1.19.1'
4
+ VERSION='2.0.0.pre1'
5
5
  end
data/lib/git.rb CHANGED
@@ -8,6 +8,7 @@ require 'git/base'
8
8
  require 'git/branch'
9
9
  require 'git/branches'
10
10
  require 'git/command_line_result'
11
+ require 'git/command_line'
11
12
  require 'git/config'
12
13
  require 'git/diff'
13
14
  require 'git/encoding_utils'
@@ -23,6 +24,7 @@ require 'git/remote'
23
24
  require 'git/repository'
24
25
  require 'git/signaled_error'
25
26
  require 'git/status'
27
+ require 'git/signaled_error'
26
28
  require 'git/stash'
27
29
  require 'git/stashes'
28
30
  require 'git/url'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 2.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon and others
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-13 00:00:00.000000000 Z
11
+ date: 2024-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -25,47 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.8'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rchardet
28
+ name: process_executer
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.8'
33
+ version: '0.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.8'
40
+ version: '0.7'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bump
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.10'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.10'
55
- - !ruby/object:Gem::Dependency
56
- name: create_github_release
42
+ name: rchardet
57
43
  requirement: !ruby/object:Gem::Requirement
58
44
  requirements:
59
45
  - - "~>"
60
46
  - !ruby/object:Gem::Version
61
- version: '0.2'
62
- type: :development
47
+ version: '1.8'
48
+ type: :runtime
63
49
  prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
51
  requirements:
66
52
  - - "~>"
67
53
  - !ruby/object:Gem::Version
68
- version: '0.2'
54
+ version: '1.8'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: minitar
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -100,42 +86,42 @@ dependencies:
100
86
  requirements:
101
87
  - - "~>"
102
88
  - !ruby/object:Gem::Version
103
- version: '13.0'
89
+ version: '13.1'
104
90
  type: :development
105
91
  prerelease: false
106
92
  version_requirements: !ruby/object:Gem::Requirement
107
93
  requirements:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
- version: '13.0'
96
+ version: '13.1'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: test-unit
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
101
  - - "~>"
116
102
  - !ruby/object:Gem::Version
117
- version: '3.3'
103
+ version: '3.6'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
108
  - - "~>"
123
109
  - !ruby/object:Gem::Version
124
- version: '3.3'
110
+ version: '3.6'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: redcarpet
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
115
  - - "~>"
130
116
  - !ruby/object:Gem::Version
131
- version: '3.5'
117
+ version: '3.6'
132
118
  type: :development
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
122
  - - "~>"
137
123
  - !ruby/object:Gem::Version
138
- version: '3.5'
124
+ version: '3.6'
139
125
  - !ruby/object:Gem::Dependency
140
126
  name: yard
141
127
  requirement: !ruby/object:Gem::Requirement
@@ -203,6 +189,7 @@ files:
203
189
  - lib/git/base/factory.rb
204
190
  - lib/git/branch.rb
205
191
  - lib/git/branches.rb
192
+ - lib/git/command_line.rb
206
193
  - lib/git/command_line_result.rb
207
194
  - lib/git/config.rb
208
195
  - lib/git/diff.rb
@@ -232,8 +219,8 @@ licenses:
232
219
  metadata:
233
220
  homepage_uri: http://github.com/ruby-git/ruby-git
234
221
  source_code_uri: http://github.com/ruby-git/ruby-git
235
- changelog_uri: https://rubydoc.info/gems/git/1.19.1/file/CHANGELOG.md
236
- documentation_uri: https://rubydoc.info/gems/git/1.19.1
222
+ changelog_uri: https://rubydoc.info/gems/git/2.0.0.pre1/file/CHANGELOG.md
223
+ documentation_uri: https://rubydoc.info/gems/git/2.0.0.pre1
237
224
  post_install_message:
238
225
  rdoc_options: []
239
226
  require_paths:
@@ -242,14 +229,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
242
229
  requirements:
243
230
  - - ">="
244
231
  - !ruby/object:Gem::Version
245
- version: '2.3'
232
+ version: 3.0.0
246
233
  required_rubygems_version: !ruby/object:Gem::Requirement
247
234
  requirements:
248
235
  - - ">="
249
236
  - !ruby/object:Gem::Version
250
237
  version: '0'
251
238
  requirements:
252
- - git 1.6.0.0, or greater
239
+ - git 2.28.0 or greater
253
240
  rubygems_version: 3.5.3
254
241
  signing_key:
255
242
  specification_version: 4