git 1.19.1 → 3.1.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.commitlintrc.yml +38 -0
  3. data/.github/pull_request_template.md +8 -0
  4. data/.github/workflows/continuous_integration.yml +19 -21
  5. data/.github/workflows/enforce_conventional_commits.yml +28 -0
  6. data/.github/workflows/experimental_continuous_integration.yml +50 -0
  7. data/.github/workflows/release.yml +52 -0
  8. data/.gitignore +3 -0
  9. data/.husky/commit-msg +1 -0
  10. data/.release-please-manifest.json +3 -0
  11. data/.yardopts +0 -1
  12. data/CHANGELOG.md +211 -0
  13. data/CONTRIBUTING.md +290 -102
  14. data/README.md +180 -62
  15. data/Rakefile +7 -0
  16. data/git.gemspec +11 -11
  17. data/lib/git/author.rb +3 -2
  18. data/lib/git/base.rb +222 -59
  19. data/lib/git/branch.rb +2 -0
  20. data/lib/git/branches.rb +15 -14
  21. data/lib/git/command_line.rb +287 -0
  22. data/lib/git/config.rb +7 -1
  23. data/lib/git/diff.rb +2 -0
  24. data/lib/git/errors.rb +206 -0
  25. data/lib/git/escaped_path.rb +1 -1
  26. data/lib/git/index.rb +2 -1
  27. data/lib/git/lib.rb +604 -234
  28. data/lib/git/log.rb +74 -6
  29. data/lib/git/object.rb +80 -76
  30. data/lib/git/path.rb +9 -8
  31. data/lib/git/remote.rb +2 -0
  32. data/lib/git/repository.rb +2 -0
  33. data/lib/git/stash.rb +7 -6
  34. data/lib/git/stashes.rb +11 -10
  35. data/lib/git/status.rb +135 -25
  36. data/lib/git/version.rb +3 -1
  37. data/lib/git/working_directory.rb +2 -0
  38. data/lib/git/worktree.rb +2 -0
  39. data/lib/git/worktrees.rb +2 -0
  40. data/lib/git.rb +21 -7
  41. data/package.json +10 -0
  42. data/release-please-config.json +36 -0
  43. metadata +52 -38
  44. data/.github/stale.yml +0 -25
  45. data/Dockerfile.changelog-rs +0 -12
  46. data/PULL_REQUEST_TEMPLATE.md +0 -9
  47. data/RELEASING.md +0 -70
  48. data/lib/git/base/factory.rb +0 -99
  49. data/lib/git/failed_error.rb +0 -53
  50. data/lib/git/git_execute_error.rb +0 -7
  51. data/lib/git/signaled_error.rb +0 -50
  52. /data/{ISSUE_TEMPLATE.md → .github/issue_template.md} +0 -0
data/README.md CHANGED
@@ -8,50 +8,49 @@
8
8
  [![Gem Version](https://badge.fury.io/rb/git.svg)](https://badge.fury.io/rb/git)
9
9
  [![Documentation](https://img.shields.io/badge/Documentation-Latest-green)](https://rubydoc.info/gems/git/)
10
10
  [![Change Log](https://img.shields.io/badge/CHANGELOG-Latest-green)](https://rubydoc.info/gems/git/file/CHANGELOG.md)
11
- [![Build Status](https://github.com/ruby-git/ruby-git/workflows/CI/badge.svg?branch=master)](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
12
- [![Code Climate](https://codeclimate.com/github/ruby-git/ruby-git.png)](https://codeclimate.com/github/ruby-git/ruby-git)
11
+ [![Build Status](https://github.com/ruby-git/ruby-git/workflows/CI/badge.svg?branch=main)](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI)
12
+ [![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)
13
13
 
14
- The [git gem](https://rubygems.org/gems/git) provides an API that can be used to
15
- create, read, and manipulate Git repositories by wrapping system calls to the `git`
16
- command line. The API can be used for working with Git in complex interactions
17
- including branching and merging, object inspection and manipulation, history, patch
18
- generation and more.
14
+ - [📢 Default Branch Rename 📢](#-default-branch-rename-)
15
+ - [📢 We've Switched to Conventional Commits 📢](#-weve-switched-to-conventional-commits-)
16
+ - [Summary](#summary)
17
+ - [Install](#install)
18
+ - [Major Objects](#major-objects)
19
+ - [Errors Raised By This Gem](#errors-raised-by-this-gem)
20
+ - [Specifying And Handling Timeouts](#specifying-and-handling-timeouts)
21
+ - [Examples](#examples)
22
+ - [Ruby version support policy](#ruby-version-support-policy)
23
+ - [License](#license)
19
24
 
20
- ## v2.0.0 pre-release
25
+ ## 📢 Default Branch Rename 📢
21
26
 
22
- git 2.0.0 is available as a pre-release version for testing! Please give it a try.
27
+ On June 6th, 2025, the default branch was renamed from 'master' to 'main'.
23
28
 
24
- **JRuby on Windows is not yet supported by the 2.x release line. Users running JRuby
25
- on Windows should continue to use the 1.x release line.**
29
+ Instructions for renaming your local or forked branch to match can be found in the
30
+ gist [Default Branch Name
31
+ Change](https://gist.github.com/jcouball/580a10e395f7fdfaaa4297bbe816cc7d).
26
32
 
27
- The changes coming in this major release include:
33
+ ## 📢 We've Switched to Conventional Commits 📢
28
34
 
29
- * Create a policy of supported Ruby versions to support only non-EOL Ruby versions
30
- * Create a policy of supported Git CLI versions (released 2020-12-25)
31
- * Update the required Ruby version to at least 3.0 (released 2020-07-27)
32
- * Update the required Git command line version to at least 2.28
33
- * Update how CLI commands are called to use the [process_executer](https://github.com/main-branch/process_executer)
34
- 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
36
- on the motivation for this implementation.
35
+ To enhance our development workflow, enable automated changelog generation, and pave
36
+ the way for Continuous Delivery, the `ruby-git` project has adopted the [Conventional
37
+ Commits standard](https://www.conventionalcommits.org/en/v1.0.0/) for all commit
38
+ messages.
37
39
 
38
- The tentative plan is to release `2.0.0` near the end of March 2024 depending on
39
- the feedback received during the pre-release period.
40
+ Going forward, all commits to this repository **MUST** adhere to the Conventional
41
+ Commits standard. Commits not adhering to this standard will cause the CI build to
42
+ fail. PRs will not be merged if they include non-conventional commits.
40
43
 
41
- The `master` branch will be used for `2.x` development. If needed, fixes for `1.x`
42
- version will be done on the `v1` branch.
44
+ A git pre-commit hook may be installed to validate your conventional commit messages
45
+ before pushing them to GitHub by running `bin/setup` in the project root.
43
46
 
44
- ## Homepage
47
+ Read more about this change in the [Commit Message Guidelines section of
48
+ CONTRIBUTING.md](CONTRIBUTING.md#commit-message-guidelines)
45
49
 
46
- The project source code is at:
50
+ ## Summary
47
51
 
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
52
+ The [git gem](https://rubygems.org/gems/git) provides a Ruby interface to the `git`
53
+ command line.
55
54
 
56
55
  Get started by obtaining a repository object by:
57
56
 
@@ -63,14 +62,29 @@ Methods that can be called on a repository object are documented in [Git::Base](
63
62
 
64
63
  ## Install
65
64
 
66
- You can install Ruby/Git like this:
65
+ Install the gem and add to the application's Gemfile by executing:
66
+
67
+ ```shell
68
+ bundle add git
69
+ ```
70
+
71
+ to install version 1.x:
67
72
 
73
+ ```shell
74
+ bundle add git --version "~> 1.19"
68
75
  ```
69
- sudo gem install git
76
+
77
+ If bundler is not being used to manage dependencies, install the gem by executing:
78
+
79
+ ```shell
80
+ gem install git
70
81
  ```
71
82
 
72
- ## Code Status
83
+ to install version 1.x:
73
84
 
85
+ ```shell
86
+ gem install git --version "~> 1.19"
87
+ ```
74
88
 
75
89
  ## Major Objects
76
90
 
@@ -88,28 +102,112 @@ directory, in the index and in the repository. Similar to running 'git status'
88
102
 
89
103
  **Git::Remote**- A reference to a remote repository that is tracked by this repository.
90
104
 
91
- **Git::Log** - An Enumerable object that references all the `Git::Object::Commit` objects that encompass your log query, which can be constructed through methods on the `Git::Log object`,
92
- like:
105
+ **Git::Log** - An Enumerable object that references all the `Git::Object::Commit`
106
+ objects that encompass your log query, which can be constructed through methods on
107
+ the `Git::Log object`, like:
93
108
 
94
- `@git.log(20).object("some_file").since("2 weeks ago").between('v2.6', 'v2.7').each { |commit| [block] }`
109
+ ```ruby
110
+ git.log
111
+ .max_count(:all)
112
+ .object('README.md')
113
+ .since('10 years ago')
114
+ .between('v1.0.7', 'HEAD')
115
+ .map { |commit| commit.sha }
116
+ ```
95
117
 
96
- Pass the `--all` option to `git log` as follows:
118
+ A maximum of 30 commits are returned if `max_count` is not called. To get all commits
119
+ that match the log query, call `max_count(:all)`.
97
120
 
98
- `@git.log.all.each { |commit| [block] }`
121
+ Note that `git.log.all` adds the `--all` option to the underlying `git log` command.
122
+ This asks for the logs of all refs (basically all commits reachable by HEAD,
123
+ branches, and tags). This does not control the maximum number of commits returned. To
124
+ control how many commits are returned, you should call `max_count`.
99
125
 
100
- **Git::Worktrees** - Enumerable object that holds `Git::Worktree objects`.
126
+ **Git::Worktrees** - Enumerable object that holds `Git::Worktree objects`.
101
127
 
102
- ## Examples
128
+ ## Errors Raised By This Gem
103
129
 
104
- Here are a bunch of examples of how to use the Ruby/Git package.
130
+ The git gem will only raise an `ArgumentError` or an error that is a subclass of
131
+ `Git::Error`. It does not explicitly raise any other types of errors.
105
132
 
106
- Ruby < 1.9 will require rubygems to be loaded.
133
+ It is recommended to rescue `Git::Error` to catch any runtime error raised by
134
+ this gem unless you need more specific error handling.
107
135
 
108
136
  ```ruby
109
- require 'rubygems'
137
+ begin
138
+ # some git operation
139
+ rescue Git::Error => e
140
+ puts "An error occurred: #{e.message}"
141
+ end
110
142
  ```
111
143
 
144
+ See [`Git::Error`](https://rubydoc.info/gems/git/Git/Error) for more information.
145
+
146
+ ## Specifying And Handling Timeouts
147
+
148
+ The timeout feature was added in git gem version `2.0.0`.
149
+
150
+ A timeout for git command line operations can be set either globally or for specific
151
+ method calls that accept a `:timeout` parameter.
152
+
153
+ The timeout value must be a real, non-negative `Numeric` value that specifies a
154
+ number of seconds a `git` command will be given to complete before being sent a KILL
155
+ signal. This library may hang if the `git` command does not terminate after receiving
156
+ the KILL signal.
157
+
158
+ When a command times out, it is killed by sending it the `SIGKILL` signal and a
159
+ `Git::TimeoutError` is raised. This error derives from the `Git::SignaledError` and
160
+ `Git::Error`.
161
+
162
+ If the timeout value is `0` or `nil`, no timeout will be enforced.
163
+
164
+ If a method accepts a `:timeout` parameter and a receives a non-nil value, the value
165
+ of this parameter will override the global timeout value. In this context, a value of
166
+ `nil` (which is usually the default) will use the global timeout value and a value of
167
+ `0` will turn off timeout enforcement for that method call no matter what the global
168
+ value is.
169
+
170
+ To set a global timeout, use the `Git.config` object:
171
+
172
+ ```ruby
173
+ Git.config.timeout = nil # a value of nil or 0 means no timeout is enforced
174
+ Git.config.timeout = 1.5 # can be any real, non-negative Numeric interpreted as number of seconds
175
+ ```
176
+
177
+ The global timeout can be overridden for a specific method if the method accepts a
178
+ `:timeout` parameter:
179
+
180
+ ```ruby
181
+ repo_url = 'https://github.com/ruby-git/ruby-git.git'
182
+ Git.clone(repo_url) # Use the global timeout value
183
+ Git.clone(repo_url, timeout: nil) # Also uses the global timeout value
184
+ Git.clone(repo_url, timeout: 0) # Do not enforce a timeout
185
+ Git.clone(repo_url, timeout: 10.5) # Timeout after 10.5 seconds raising Git::SignaledError
186
+ ```
187
+
188
+ If the command takes too long, a `Git::TimeoutError` will be raised:
189
+
190
+ ```ruby
191
+ begin
192
+ Git.clone(repo_url, timeout: 10)
193
+ rescue Git::TimeoutError => e
194
+ e.result.tap do |r|
195
+ r.class #=> Git::CommandLineResult
196
+ r.status #=> #<Process::Status: pid 62173 SIGKILL (signal 9)>
197
+ r.status.timeout? #=> true
198
+ r.git_cmd # The git command ran as an array of strings
199
+ r.stdout # The command's output to stdout until it was terminated
200
+ r.stderr # The command's output to stderr until it was terminated
201
+ end
202
+ end
203
+ ```
204
+
205
+ ## Examples
206
+
207
+ Here are a bunch of examples of how to use the Ruby/Git package.
208
+
112
209
  Require the 'git' gem.
210
+
113
211
  ```ruby
114
212
  require 'git'
115
213
  ```
@@ -139,9 +237,15 @@ g.index.writable?
139
237
  g.repo
140
238
  g.dir
141
239
 
142
- g.log # returns a Git::Log object, which is an Enumerator of Git::Commit objects
143
- g.log(200)
144
- g.log.since('2 weeks ago')
240
+ # ls-tree with recursion into subtrees (list files)
241
+ g.ls_tree("HEAD", recursive: true)
242
+
243
+ # log - returns a Git::Log object, which is an Enumerator of Git::Commit objects
244
+ # default configuration returns a max of 30 commits
245
+ g.log
246
+ g.log(200) # 200 most recent commits
247
+ g.log.since('2 weeks ago') # default count of commits since 2 weeks ago.
248
+ g.log(200).since('2 weeks ago') # commits since 2 weeks ago, limited to 200.
145
249
  g.log.between('v2.5', 'v2.6')
146
250
  g.log.each {|l| puts l.sha }
147
251
  g.gblob('v2.5:Makefile').log.since('2 weeks ago')
@@ -174,14 +278,14 @@ tree.blobs
174
278
  tree.subtrees
175
279
  tree.children # blobs and subtrees
176
280
 
177
- g.revparse('v2.5:Makefile')
281
+ g.rev_parse('v2.0.0:README.md')
178
282
 
179
283
  g.branches # returns Git::Branch objects
180
284
  g.branches.local
181
285
  g.current_branch
182
286
  g.branches.remote
183
- g.branches[:master].gcommit
184
- g.branches['origin/master'].gcommit
287
+ g.branches[:main].gcommit
288
+ g.branches['origin/main'].gcommit
185
289
 
186
290
  g.grep('hello') # implies HEAD
187
291
  g.blob('v2.5:Makefile').grep('hello')
@@ -238,7 +342,7 @@ Git.ls_remote('https://github.com/ruby-git/ruby-git.git') # returns a hash conta
238
342
  Git.ls_remote('/path/to/local/repo')
239
343
  Git.ls_remote() # same as Git.ls_remote('.')
240
344
 
241
- Git.default_branch('https://github.com/ruby-git/ruby-git') #=> 'master'
345
+ Git.default_branch('https://github.com/ruby-git/ruby-git') #=> 'main'
242
346
  ```
243
347
 
244
348
  And here are the operations that will need to write to your git repository.
@@ -276,11 +380,11 @@ g.add(:all=>true) # git add --all -- "."
276
380
  g.add('file_path') # git add -- "file_path"
277
381
  g.add(['file_path_1', 'file_path_2']) # git add -- "file_path_1" "file_path_2"
278
382
 
279
- g.remove() # git rm -f -- "."
280
- g.remove('file.txt') # git rm -f -- "file.txt"
281
- g.remove(['file.txt', 'file2.txt']) # git rm -f -- "file.txt" "file2.txt"
282
- g.remove('file.txt', :recursive => true) # git rm -f -r -- "file.txt"
283
- g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"
383
+ g.remove() # git rm -f -- "."
384
+ g.remove('file.txt') # git rm -f -- "file.txt"
385
+ g.remove(['file.txt', 'file2.txt']) # git rm -f -- "file.txt" "file2.txt"
386
+ g.remove('file.txt', :recursive => true) # git rm -f -r -- "file.txt"
387
+ g.remove('file.txt', :cached => true) # git rm -f --cached -- "file.txt"
284
388
 
285
389
  g.commit('message')
286
390
  g.commit_all('message')
@@ -311,13 +415,13 @@ g.branch('new_branch') # creates new or fetches existing
311
415
  g.branch('new_branch').checkout
312
416
  g.branch('new_branch').delete
313
417
  g.branch('existing_branch').checkout
314
- g.branch('master').contains?('existing_branch')
418
+ g.branch('main').contains?('existing_branch')
315
419
 
316
420
  # delete remote branch
317
421
  g.push('origin', 'remote_branch_name', force: true, delete: true)
318
422
 
319
423
  g.checkout('new_branch')
320
- g.checkout('new_branch', new_branch: true, start_point: 'master')
424
+ g.checkout('new_branch', new_branch: true, start_point: 'main')
321
425
  g.checkout(g.branch('new_branch'))
322
426
 
323
427
  g.branch(name).merge(branch2)
@@ -327,7 +431,7 @@ g.branch(name).in_branch(message) { # add files } # auto-commits
327
431
  g.merge('new_branch')
328
432
  g.merge('new_branch', 'merge commit message', no_ff: true)
329
433
  g.merge('origin/remote_branch')
330
- g.merge(g.branch('master'))
434
+ g.merge(g.branch('main'))
331
435
  g.merge([branch1, branch2])
332
436
 
333
437
  g.merge_base('branch1', 'branch2')
@@ -422,6 +526,20 @@ g.with_temp_working(dir) do
422
526
  end
423
527
  ```
424
528
 
529
+ ## Ruby version support policy
530
+
531
+ This gem will be expected to function correctly on:
532
+
533
+ * All non-EOL versions of the MRI Ruby on Mac, Linux, and Windows
534
+ * The latest version of JRuby on Linux
535
+ * The latest version of Truffle Ruby on Linus
536
+
537
+ It is this project's intent to support the latest version of JRuby on Windows
538
+ once the following JRuby bug is fixed:
539
+
540
+ jruby/jruby#7515
541
+
425
542
  ## License
426
543
 
427
- licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further details.
544
+ Licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further
545
+ details.
data/Rakefile CHANGED
@@ -58,3 +58,10 @@ task :'test:gem' => :install do
58
58
 
59
59
  puts 'Gem Test Succeeded'
60
60
  end
61
+
62
+ # Make it so that calling `rake release` just calls `rake release:rubygem_push` to
63
+ # avoid creating and pushing a new tag.
64
+
65
+ Rake::Task['release'].clear
66
+ desc 'Customized release task to avoid creating a new tag'
67
+ task release: 'release:rubygem_push'
data/git.gemspec CHANGED
@@ -24,22 +24,22 @@ 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
 
30
+ s.add_runtime_dependency 'activesupport', '>= 5.0'
31
31
  s.add_runtime_dependency 'addressable', '~> 2.8'
32
- s.add_runtime_dependency 'rchardet', '~> 1.8'
32
+ s.add_runtime_dependency 'process_executer', '~> 1.3'
33
+ s.add_runtime_dependency 'rchardet', '~> 1.9'
33
34
 
34
- s.add_development_dependency 'bump', '~> 0.10'
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'
35
+ s.add_development_dependency 'create_github_release', '~> 2.1'
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'
40
40
 
41
41
  unless RUBY_PLATFORM == 'java'
42
- s.add_development_dependency 'redcarpet', '~> 3.5'
42
+ s.add_development_dependency 'redcarpet', '~> 3.6'
43
43
  s.add_development_dependency 'yard', '~> 0.9', '>= 0.9.28'
44
44
  s.add_development_dependency 'yardstick', '~> 0.9'
45
45
  end
data/lib/git/author.rb CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Git
2
4
  class Author
3
5
  attr_accessor :name, :email, :date
4
-
6
+
5
7
  def initialize(author_string)
6
8
  if m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string)
7
9
  @name = m[1]
@@ -9,6 +11,5 @@ module Git
9
11
  @date = Time.at(m[3].to_i)
10
12
  end
11
13
  end
12
-
13
14
  end
14
15
  end