git 2.1.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/CONTRIBUTING.md +135 -60
- data/README.md +4 -1
- data/lib/git/base.rb +19 -9
- data/lib/git/lib.rb +346 -65
- data/lib/git/object.rb +9 -9
- data/lib/git/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e24e434e4639e6c31133234cee6d96708baf23d212c2f78cf4b94159810b090
|
4
|
+
data.tar.gz: 9fc37b011ac0cb0e87a0ee50b7993e751a7075a7496d6feb41431d2f3612e823
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 232624614200233e3f2ed308a4e73580345fef5be0a98e64f35992ecb222fa96c4163399b2f08afbfcdf69cd3b2f8f6c57c309fe9122f18a56e9bc31f827b301
|
7
|
+
data.tar.gz: 4ae699244e5ff9f679795279b8dbfeebe35ce8c9bfb7e5d9a18552b77b3d86b630f50bd9fedb4eec4f697269cfec6c90f72adfa2edeada25258ab457f3b5dad8
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,32 @@
|
|
5
5
|
|
6
6
|
# Change Log
|
7
7
|
|
8
|
+
## v2.3.0 (2024-09-01)
|
9
|
+
|
10
|
+
[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.2.0..v2.3.0)
|
11
|
+
|
12
|
+
Changes since v2.2.0:
|
13
|
+
|
14
|
+
* f8bc987 Fix windows CI build error
|
15
|
+
* 471f5a8 Sanatize object ref sent to cat-file command
|
16
|
+
* 604a9a2 Make Git::Base#branch work when HEAD is detached
|
17
|
+
|
18
|
+
## v2.2.0 (2024-08-26)
|
19
|
+
|
20
|
+
[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.1.1..v2.2.0)
|
21
|
+
|
22
|
+
Changes since v2.1.1:
|
23
|
+
|
24
|
+
* 7292f2c Omit the test for signed commit data on Windows
|
25
|
+
* 2d6157c Document this gem's (aspirational) design philosophy
|
26
|
+
* d4f66ab Sanitize non-option arguments passed to `git name-rev`
|
27
|
+
* 0296442 Refactor Git::Lib#rev_parse
|
28
|
+
* 9b9b31e Verify that the revision-range passed to git log does not resemble a command-line option
|
29
|
+
* dc46ede Verify that the commit-ish passed to git describe does not resemble a command-line option
|
30
|
+
* 00c4939 Verify that the commit(s) passed to git diff do not resemble a command-line option
|
31
|
+
* a08f89b Update README
|
32
|
+
* 737c4bb ls-tree optional recursion into subtrees
|
33
|
+
|
8
34
|
## v2.1.1 (2024-06-01)
|
9
35
|
|
10
36
|
[Full Changelog](https://github.com/ruby-git/ruby-git/compare/v2.1.0..v2.1.1)
|
data/CONTRIBUTING.md
CHANGED
@@ -3,116 +3,191 @@
|
|
3
3
|
# @title How To Contribute
|
4
4
|
-->
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
* [How to contribute](#how-to-contribute)
|
7
|
+
* [How to report an issue or request a feature](#how-to-report-an-issue-or-request-a-feature)
|
8
|
+
* [How to submit a code or documentation change](#how-to-submit-a-code-or-documentation-change)
|
9
|
+
* [Commit your changes to a fork of `ruby-git`](#commit-your-changes-to-a-fork-of-ruby-git)
|
10
|
+
* [Create a pull request](#create-a-pull-request)
|
11
|
+
* [Get your pull request reviewed](#get-your-pull-request-reviewed)
|
12
|
+
* [Design philosophy](#design-philosophy)
|
13
|
+
* [Direct mapping to git commands](#direct-mapping-to-git-commands)
|
14
|
+
* [Parameter naming](#parameter-naming)
|
15
|
+
* [Output processing](#output-processing)
|
16
|
+
* [Coding standards](#coding-standards)
|
17
|
+
* [1 PR = 1 Commit](#1-pr--1-commit)
|
18
|
+
* [Unit tests](#unit-tests)
|
19
|
+
* [Continuous integration](#continuous-integration)
|
20
|
+
* [Documentation](#documentation)
|
21
|
+
* [Licensing](#licensing)
|
22
|
+
|
23
|
+
|
24
|
+
# Contributing to the git gem
|
25
|
+
|
26
|
+
Thank you for your interest in contributing to the `ruby-git` project.
|
27
|
+
|
28
|
+
This document provides guidelines for contributing to the `ruby-git` project. While
|
29
|
+
these guidelines may not cover every situation, we encourage you to use your best
|
30
|
+
judgment when contributing.
|
31
|
+
|
32
|
+
If you have suggestions for improving these guidelines, please propose changes via a
|
33
|
+
pull request.
|
15
34
|
|
16
35
|
## How to contribute
|
17
36
|
|
18
|
-
You can contribute in
|
37
|
+
You can contribute in the following ways:
|
19
38
|
|
20
|
-
1. [Report an issue or
|
21
|
-
|
39
|
+
1. [Report an issue or request a
|
40
|
+
feature](#how-to-report-an-issue-or-request-a-feature)
|
41
|
+
2. [Submit a code or documentation
|
42
|
+
change](#how-to-submit-a-code-or-documentation-change)
|
22
43
|
|
23
|
-
## How to report an issue or
|
44
|
+
## How to report an issue or request a feature
|
24
45
|
|
25
|
-
ruby-git utilizes [GitHub
|
46
|
+
`ruby-git` utilizes [GitHub
|
47
|
+
Issues](https://help.github.com/en/github/managing-your-work-on-github/about-issues)
|
26
48
|
for issue tracking and feature requests.
|
27
49
|
|
28
|
-
|
29
|
-
Fill in the template
|
50
|
+
To report an issue or request a feature, please [create a `ruby-git` GitHub
|
51
|
+
issue](https://github.com/ruby-git/ruby-git/issues/new). Fill in the template as
|
52
|
+
thoroughly as possible to describe the issue or feature request.
|
30
53
|
|
31
54
|
## How to submit a code or documentation change
|
32
55
|
|
33
|
-
There is three
|
56
|
+
There is a three-step process for submitting code or documentation changes:
|
34
57
|
|
35
|
-
1. [Commit your changes to a fork of
|
58
|
+
1. [Commit your changes to a fork of
|
59
|
+
`ruby-git`](#commit-your-changes-to-a-fork-of-ruby-git)
|
36
60
|
2. [Create a pull request](#create-a-pull-request)
|
37
61
|
3. [Get your pull request reviewed](#get-your-pull-request-reviewed)
|
38
62
|
|
39
|
-
### Commit changes to a fork of ruby-git
|
63
|
+
### Commit your changes to a fork of `ruby-git`
|
40
64
|
|
41
|
-
Make your changes in a fork of the ruby-git repository.
|
65
|
+
Make your changes in a fork of the `ruby-git` repository.
|
42
66
|
|
43
67
|
### Create a pull request
|
44
68
|
|
45
|
-
|
46
|
-
|
69
|
+
If you are not familiar with GitHub Pull Requests, please refer to [this
|
70
|
+
article](https://help.github.com/articles/about-pull-requests/).
|
47
71
|
|
48
72
|
Follow the instructions in the pull request template.
|
49
73
|
|
50
74
|
### Get your pull request reviewed
|
51
75
|
|
52
|
-
Code review takes place in a GitHub pull request using the [
|
76
|
+
Code review takes place in a GitHub pull request using the [GitHub pull request
|
77
|
+
review
|
78
|
+
feature](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews).
|
53
79
|
|
54
80
|
Once your pull request is ready for review, request a review from at least one
|
55
|
-
[maintainer](MAINTAINERS.md) and any
|
81
|
+
[maintainer](MAINTAINERS.md) and any other contributors you deem necessary.
|
82
|
+
|
83
|
+
During the review process, you may need to make additional commits, which should be
|
84
|
+
squashed. Additionally, you may need to rebase your branch to the latest `master`
|
85
|
+
branch if other changes have been merged.
|
86
|
+
|
87
|
+
At least one approval from a project maintainer is required before your pull request
|
88
|
+
can be merged. The maintainer is responsible for ensuring that the pull request meets
|
89
|
+
[the project's coding standards](#coding-standards).
|
90
|
+
|
91
|
+
## Design philosophy
|
92
|
+
|
93
|
+
*Note: As of v2.x of the `git` gem, this design philosophy is aspirational. Future
|
94
|
+
versions may include interface changes to fully align with these principles.*
|
95
|
+
|
96
|
+
The `git` gem is designed as a lightweight wrapper around the `git` command-line
|
97
|
+
tool, providing Ruby developers with a simple and intuitive interface for
|
98
|
+
programmatically interacting with Git.
|
99
|
+
|
100
|
+
This gem adheres to the "principle of least surprise," ensuring that it does not
|
101
|
+
introduce unnecessary abstraction layers or modify Git's core functionality. Instead,
|
102
|
+
the gem maintains a close alignment with the existing `git` command-line interface,
|
103
|
+
avoiding extensions or alterations that could lead to unexpected behaviors.
|
104
|
+
|
105
|
+
By following this philosophy, the `git` gem allows users to leverage their existing
|
106
|
+
knowledge of Git while benefiting from the expressiveness and power of Ruby's syntax
|
107
|
+
and paradigms.
|
108
|
+
|
109
|
+
### Direct mapping to git commands
|
56
110
|
|
57
|
-
|
58
|
-
|
59
|
-
|
111
|
+
Git commands are implemented within the `Git::Base` class, with each method directly
|
112
|
+
corresponding to a `git` command. When a `Git::Base` object is instantiated via
|
113
|
+
`Git.open`, `Git.clone`, or `Git.init`, the user can invoke these methods to interact
|
114
|
+
with the underlying Git repository.
|
60
115
|
|
61
|
-
|
62
|
-
|
63
|
-
|
116
|
+
For example, the `git add` command is implemented as `Git::Base#add`, and the `git
|
117
|
+
ls-files` command is implemented as `Git::Base#ls_files`.
|
118
|
+
|
119
|
+
When a single Git command serves multiple distinct purposes, method names within the
|
120
|
+
`Git::Base` class should use the `git` command name as a prefix, followed by a
|
121
|
+
descriptive suffix to indicate the specific function.
|
122
|
+
|
123
|
+
For instance, `#ls_files_untracked` and `#ls_files_staged` could be used to execute
|
124
|
+
the `git ls-files` command and return untracked and staged files, respectively.
|
125
|
+
|
126
|
+
To enhance usability, aliases may be introduced to provide more user-friendly method
|
127
|
+
names where appropriate.
|
128
|
+
|
129
|
+
### Parameter naming
|
130
|
+
|
131
|
+
Parameters within the `git` gem methods are named after their corresponding long
|
132
|
+
command-line options, ensuring familiarity and ease of use for developers already
|
133
|
+
accustomed to Git. Note that not all Git command options are supported.
|
134
|
+
|
135
|
+
### Output processing
|
136
|
+
|
137
|
+
The `git` gem translates the output of many Git commands into Ruby objects, making it
|
138
|
+
easier to work with programmatically.
|
139
|
+
|
140
|
+
These Ruby objects often include methods that allow for further Git operations where
|
141
|
+
useful, providing additional functionality while staying true to the underlying Git
|
142
|
+
behavior.
|
64
143
|
|
65
144
|
## Coding standards
|
66
145
|
|
67
|
-
|
146
|
+
To ensure high-quality contributions, all pull requests must meet the following
|
147
|
+
requirements:
|
68
148
|
|
69
149
|
### 1 PR = 1 Commit
|
70
150
|
|
71
|
-
* All commits for a PR must be squashed into
|
72
|
-
* To avoid an extra merge commit, the PR must be able to be merged as [a fast
|
73
|
-
merge](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging)
|
74
|
-
* The easiest way to ensure a fast
|
75
|
-
|
151
|
+
* All commits for a PR must be squashed into a single commit.
|
152
|
+
* To avoid an extra merge commit, the PR must be able to be merged as [a fast-forward
|
153
|
+
merge](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging).
|
154
|
+
* The easiest way to ensure a fast-forward merge is to rebase your local branch to
|
155
|
+
the `ruby-git` master branch.
|
76
156
|
|
77
157
|
### Unit tests
|
78
158
|
|
79
|
-
* All changes must be accompanied by new or modified unit tests
|
159
|
+
* All changes must be accompanied by new or modified unit tests.
|
80
160
|
* The entire test suite must pass when `bundle exec rake default` is run from the
|
81
161
|
project's local working copy.
|
82
162
|
|
83
|
-
While working on specific features you can run individual test files or
|
84
|
-
|
163
|
+
While working on specific features, you can run individual test files or a group of
|
164
|
+
tests using `bin/test`:
|
85
165
|
|
86
|
-
|
87
|
-
|
166
|
+
```bash
|
167
|
+
# run a single file (from tests/units):
|
168
|
+
$ bin/test test_object
|
88
169
|
|
89
|
-
|
90
|
-
|
170
|
+
# run multiple files:
|
171
|
+
$ bin/test test_object test_archive
|
91
172
|
|
92
|
-
|
93
|
-
|
173
|
+
# run all unit tests:
|
174
|
+
$ bin/test
|
175
|
+
```
|
94
176
|
|
95
177
|
### Continuous integration
|
96
178
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
* The [Continuous Integration
|
101
|
-
workflow](https://github.com/ruby-git/ruby-git/blob/master/.github/workflows/continuous_integration.yml)
|
102
|
-
runs both `bundle exec rake default` and `bundle exec rake test:gem` from the
|
103
|
-
project's [Rakefile](https://github.com/ruby-git/ruby-git/blob/master/Rakefile).
|
179
|
+
All tests must pass in the project's [GitHub Continuous Integration build](https://github.com/ruby-git/ruby-git/actions?query=workflow%3ACI) before the pull request will be merged.
|
180
|
+
|
181
|
+
The [Continuous Integration workflow](https://github.com/ruby-git/ruby-git/blob/master/.github/workflows/continuous_integration.yml) runs both `bundle exec rake default` and `bundle exec rake test:gem` from the project's [Rakefile](https://github.com/ruby-git/ruby-git/blob/master/Rakefile).
|
104
182
|
|
105
183
|
### Documentation
|
106
184
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
[README.md](README.md)
|
185
|
+
New and updated public methods must include [YARD](https://yardoc.org/) documentation.
|
186
|
+
|
187
|
+
New and updated public-facing features should be documented in the project's [README.md](README.md).
|
111
188
|
|
112
189
|
## Licensing
|
113
190
|
|
114
|
-
ruby-git uses [the MIT license](https://choosealicense.com/licenses/mit/) as
|
115
|
-
declared in the [LICENSE](LICENSE) file.
|
191
|
+
`ruby-git` uses [the MIT license](https://choosealicense.com/licenses/mit/) as declared in the [LICENSE](LICENSE) file.
|
116
192
|
|
117
|
-
Licensing is
|
118
|
-
software continues to be available under the terms that the author desired.
|
193
|
+
Licensing is critical to open-source projects as it ensures the software remains available under the terms desired by the author.
|
data/README.md
CHANGED
@@ -236,6 +236,9 @@ g.index.writable?
|
|
236
236
|
g.repo
|
237
237
|
g.dir
|
238
238
|
|
239
|
+
# ls-tree with recursion into subtrees (list files)
|
240
|
+
g.ls_tree("HEAD", recursive: true)
|
241
|
+
|
239
242
|
# log - returns a Git::Log object, which is an Enumerator of Git::Commit objects
|
240
243
|
# default configuration returns a max of 30 commits
|
241
244
|
g.log
|
@@ -274,7 +277,7 @@ tree.blobs
|
|
274
277
|
tree.subtrees
|
275
278
|
tree.children # blobs and subtrees
|
276
279
|
|
277
|
-
g.
|
280
|
+
g.rev_parse('v2.0.0:README.md')
|
278
281
|
|
279
282
|
g.branches # returns Git::Branch objects
|
280
283
|
g.branches.local
|
data/lib/git/base.rb
CHANGED
@@ -634,23 +634,33 @@ module Git
|
|
634
634
|
# runs git rev-parse to convert the objectish to a full sha
|
635
635
|
#
|
636
636
|
# @example
|
637
|
-
# git.
|
638
|
-
# git.
|
639
|
-
# git.
|
637
|
+
# git.rev_parse("HEAD^^")
|
638
|
+
# git.rev_parse('v2.4^{tree}')
|
639
|
+
# git.rev_parse('v2.4:/doc/index.html')
|
640
640
|
#
|
641
|
-
def
|
642
|
-
self.lib.
|
641
|
+
def rev_parse(objectish)
|
642
|
+
self.lib.rev_parse(objectish)
|
643
643
|
end
|
644
644
|
|
645
|
-
|
646
|
-
|
645
|
+
# For backwards compatibility
|
646
|
+
alias revparse rev_parse
|
647
|
+
|
648
|
+
def ls_tree(objectish, opts = {})
|
649
|
+
self.lib.ls_tree(objectish, opts)
|
647
650
|
end
|
648
651
|
|
649
652
|
def cat_file(objectish)
|
650
|
-
self.lib.
|
653
|
+
self.lib.cat_file(objectish)
|
651
654
|
end
|
652
655
|
|
653
|
-
#
|
656
|
+
# The name of the branch HEAD refers to or 'HEAD' if detached
|
657
|
+
#
|
658
|
+
# Returns one of the following:
|
659
|
+
# * The branch name that HEAD refers to (even if it is an unborn branch)
|
660
|
+
# * 'HEAD' if in a detached HEAD state
|
661
|
+
#
|
662
|
+
# @return [String] the name of the branch HEAD refers to or 'HEAD' if detached
|
663
|
+
#
|
654
664
|
def current_branch
|
655
665
|
self.lib.branch_current
|
656
666
|
end
|
data/lib/git/lib.rb
CHANGED
@@ -169,27 +169,33 @@ module Git
|
|
169
169
|
|
170
170
|
## READ COMMANDS ##
|
171
171
|
|
172
|
+
# Finds most recent tag that is reachable from a commit
|
172
173
|
#
|
173
|
-
#
|
174
|
+
# @see https://git-scm.com/docs/git-describe git-describe
|
174
175
|
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
180
|
-
#
|
181
|
-
#
|
182
|
-
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
187
|
-
#
|
188
|
-
#
|
189
|
-
#
|
190
|
-
#
|
191
|
-
#
|
192
|
-
|
176
|
+
# @param commit_ish [String, nil] target commit sha or object name
|
177
|
+
#
|
178
|
+
# @param opts [Hash] the given options
|
179
|
+
#
|
180
|
+
# @option opts :all [Boolean]
|
181
|
+
# @option opts :tags [Boolean]
|
182
|
+
# @option opts :contains [Boolean]
|
183
|
+
# @option opts :debug [Boolean]
|
184
|
+
# @option opts :long [Boolean]
|
185
|
+
# @option opts :always [Boolean]
|
186
|
+
# @option opts :exact_match [Boolean]
|
187
|
+
# @option opts :dirty [true, String]
|
188
|
+
# @option opts :abbrev [String]
|
189
|
+
# @option opts :candidates [String]
|
190
|
+
# @option opts :match [String]
|
191
|
+
#
|
192
|
+
# @return [String] the tag name
|
193
|
+
#
|
194
|
+
# @raise [ArgumentError] if the commit_ish is a string starting with a hyphen
|
195
|
+
#
|
196
|
+
def describe(commit_ish = nil, opts = {})
|
197
|
+
assert_args_are_not_options('commit-ish object', commit_ish)
|
198
|
+
|
193
199
|
arr_opts = []
|
194
200
|
|
195
201
|
arr_opts << '--all' if opts[:all]
|
@@ -207,12 +213,42 @@ module Git
|
|
207
213
|
arr_opts << "--candidates=#{opts[:candidates]}" if opts[:candidates]
|
208
214
|
arr_opts << "--match=#{opts[:match]}" if opts[:match]
|
209
215
|
|
210
|
-
arr_opts <<
|
216
|
+
arr_opts << commit_ish if commit_ish
|
211
217
|
|
212
218
|
return command('describe', *arr_opts)
|
213
219
|
end
|
214
220
|
|
215
|
-
|
221
|
+
# Return the commits that are within the given revision range
|
222
|
+
#
|
223
|
+
# @see https://git-scm.com/docs/git-log git-log
|
224
|
+
#
|
225
|
+
# @param opts [Hash] the given options
|
226
|
+
#
|
227
|
+
# @option opts :count [Integer] the maximum number of commits to return (maps to max-count)
|
228
|
+
# @option opts :all [Boolean]
|
229
|
+
# @option opts :cherry [Boolean]
|
230
|
+
# @option opts :since [String]
|
231
|
+
# @option opts :until [String]
|
232
|
+
# @option opts :grep [String]
|
233
|
+
# @option opts :author [String]
|
234
|
+
# @option opts :between [Array<String>] an array of two commit-ish strings to specify a revision range
|
235
|
+
#
|
236
|
+
# Only :between or :object options can be used, not both.
|
237
|
+
#
|
238
|
+
# @option opts :object [String] the revision range for the git log command
|
239
|
+
#
|
240
|
+
# Only :between or :object options can be used, not both.
|
241
|
+
#
|
242
|
+
# @option opts :path_limiter [Array<String>, String] only include commits that impact files from the specified paths
|
243
|
+
#
|
244
|
+
# @return [Array<String>] the log output
|
245
|
+
#
|
246
|
+
# @raise [ArgumentError] if the resulting revision range is a string starting with a hyphen
|
247
|
+
#
|
248
|
+
def log_commits(opts = {})
|
249
|
+
assert_args_are_not_options('between', opts[:between]&.first)
|
250
|
+
assert_args_are_not_options('object', opts[:object])
|
251
|
+
|
216
252
|
arr_opts = log_common_options(opts)
|
217
253
|
|
218
254
|
arr_opts << '--pretty=oneline'
|
@@ -222,7 +258,47 @@ module Git
|
|
222
258
|
command_lines('log', *arr_opts).map { |l| l.split.first }
|
223
259
|
end
|
224
260
|
|
225
|
-
|
261
|
+
# Return the commits that are within the given revision range
|
262
|
+
#
|
263
|
+
# @see https://git-scm.com/docs/git-log git-log
|
264
|
+
#
|
265
|
+
# @param opts [Hash] the given options
|
266
|
+
#
|
267
|
+
# @option opts :count [Integer] the maximum number of commits to return (maps to max-count)
|
268
|
+
# @option opts :all [Boolean]
|
269
|
+
# @option opts :cherry [Boolean]
|
270
|
+
# @option opts :since [String]
|
271
|
+
# @option opts :until [String]
|
272
|
+
# @option opts :grep [String]
|
273
|
+
# @option opts :author [String]
|
274
|
+
# @option opts :between [Array<String>] an array of two commit-ish strings to specify a revision range
|
275
|
+
#
|
276
|
+
# Only :between or :object options can be used, not both.
|
277
|
+
#
|
278
|
+
# @option opts :object [String] the revision range for the git log command
|
279
|
+
#
|
280
|
+
# Only :between or :object options can be used, not both.
|
281
|
+
#
|
282
|
+
# @option opts :path_limiter [Array<String>, String] only include commits that impact files from the specified paths
|
283
|
+
# @option opts :skip [Integer]
|
284
|
+
#
|
285
|
+
# @return [Array<Hash>] the log output parsed into an array of hashs for each commit
|
286
|
+
#
|
287
|
+
# Each hash contains the following keys:
|
288
|
+
# * 'sha' [String] the commit sha
|
289
|
+
# * 'author' [String] the author of the commit
|
290
|
+
# * 'message' [String] the commit message
|
291
|
+
# * 'parent' [Array<String>] the commit shas of the parent commits
|
292
|
+
# * 'tree' [String] the tree sha
|
293
|
+
# * 'author' [String] the author of the commit and timestamp of when the changes were created
|
294
|
+
# * 'committer' [String] the committer of the commit and timestamp of when the commit was applied
|
295
|
+
#
|
296
|
+
# @raise [ArgumentError] if the revision range (specified with :between or :object) is a string starting with a hyphen
|
297
|
+
#
|
298
|
+
def full_log_commits(opts = {})
|
299
|
+
assert_args_are_not_options('between', opts[:between]&.first)
|
300
|
+
assert_args_are_not_options('object', opts[:object])
|
301
|
+
|
226
302
|
arr_opts = log_common_options(opts)
|
227
303
|
|
228
304
|
arr_opts << '--pretty=raw'
|
@@ -235,36 +311,147 @@ module Git
|
|
235
311
|
process_commit_log_data(full_log)
|
236
312
|
end
|
237
313
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
314
|
+
# Verify and resolve a Git revision to its full SHA
|
315
|
+
#
|
316
|
+
# @see https://git-scm.com/docs/git-rev-parse git-rev-parse
|
317
|
+
# @see https://git-scm.com/docs/git-rev-parse#_specifying_revisions Valid ways to specify revisions
|
318
|
+
# @see https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrefnamegtemegemmasterememheadsmasterememrefsheadsmasterem Ref disambiguation rules
|
319
|
+
#
|
320
|
+
# @example
|
321
|
+
# lib.rev_parse('HEAD') # => '9b9b31e704c0b85ffdd8d2af2ded85170a5af87d'
|
322
|
+
# lib.rev_parse('9b9b31e') # => '9b9b31e704c0b85ffdd8d2af2ded85170a5af87d'
|
323
|
+
#
|
324
|
+
# @param revision [String] the revision to resolve
|
325
|
+
#
|
326
|
+
# @return [String] the full commit hash
|
327
|
+
#
|
328
|
+
# @raise [Git::FailedError] if the revision cannot be resolved
|
329
|
+
# @raise [ArgumentError] if the revision is a string starting with a hyphen
|
330
|
+
#
|
331
|
+
def rev_parse(revision)
|
332
|
+
assert_args_are_not_options('rev', revision)
|
333
|
+
|
334
|
+
command('rev-parse', revision)
|
247
335
|
end
|
248
336
|
|
249
|
-
|
250
|
-
|
337
|
+
# For backwards compatibility with the old method name
|
338
|
+
alias :revparse :rev_parse
|
339
|
+
|
340
|
+
# Find the first symbolic name for given commit_ish
|
341
|
+
#
|
342
|
+
# @param commit_ish [String] the commit_ish to find the symbolic name of
|
343
|
+
#
|
344
|
+
# @return [String, nil] the first symbolic name or nil if the commit_ish isn't found
|
345
|
+
#
|
346
|
+
# @raise [ArgumentError] if the commit_ish is a string starting with a hyphen
|
347
|
+
#
|
348
|
+
def name_rev(commit_ish)
|
349
|
+
assert_args_are_not_options('commit_ish', commit_ish)
|
350
|
+
|
351
|
+
command('name-rev', commit_ish).split[1]
|
251
352
|
end
|
252
353
|
|
253
|
-
|
254
|
-
|
354
|
+
alias :namerev :name_rev
|
355
|
+
|
356
|
+
# Output the contents or other properties of one or more objects.
|
357
|
+
#
|
358
|
+
# @see https://git-scm.com/docs/git-cat-file git-cat-file
|
359
|
+
#
|
360
|
+
# @example Get the contents of a file without a block
|
361
|
+
# lib.cat_file_contents('README.md') # => "This is a README file\n"
|
362
|
+
#
|
363
|
+
# @example Get the contents of a file with a block
|
364
|
+
# lib.cat_file_contents('README.md') { |f| f.read } # => "This is a README file\n"
|
365
|
+
#
|
366
|
+
# @param object [String] the object whose contents to return
|
367
|
+
#
|
368
|
+
# @return [String] the object contents
|
369
|
+
#
|
370
|
+
# @raise [ArgumentError] if object is a string starting with a hyphen
|
371
|
+
#
|
372
|
+
def cat_file_contents(object, &block)
|
373
|
+
assert_args_are_not_options('object', object)
|
374
|
+
|
375
|
+
if block_given?
|
376
|
+
Tempfile.create do |file|
|
377
|
+
# If a block is given, write the output from the process to a temporary
|
378
|
+
# file and then yield the file to the block
|
379
|
+
#
|
380
|
+
command('cat-file', "-p", object, out: file, err: file)
|
381
|
+
file.rewind
|
382
|
+
yield file
|
383
|
+
end
|
384
|
+
else
|
385
|
+
# If a block is not given, return the file contents as a string
|
386
|
+
command('cat-file', '-p', object)
|
387
|
+
end
|
255
388
|
end
|
256
389
|
|
257
|
-
|
258
|
-
|
390
|
+
alias :object_contents :cat_file_contents
|
391
|
+
|
392
|
+
# Get the type for the given object
|
393
|
+
#
|
394
|
+
# @see https://git-scm.com/docs/git-cat-file git-cat-file
|
395
|
+
#
|
396
|
+
# @param object [String] the object to get the type
|
397
|
+
#
|
398
|
+
# @return [String] the object type
|
399
|
+
#
|
400
|
+
# @raise [ArgumentError] if object is a string starting with a hyphen
|
401
|
+
#
|
402
|
+
def cat_file_type(object)
|
403
|
+
assert_args_are_not_options('object', object)
|
404
|
+
|
405
|
+
command('cat-file', '-t', object)
|
259
406
|
end
|
260
407
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
408
|
+
alias :object_type :cat_file_type
|
409
|
+
|
410
|
+
# Get the size for the given object
|
411
|
+
#
|
412
|
+
# @see https://git-scm.com/docs/git-cat-file git-cat-file
|
413
|
+
#
|
414
|
+
# @param object [String] the object to get the type
|
415
|
+
#
|
416
|
+
# @return [String] the object type
|
417
|
+
#
|
418
|
+
# @raise [ArgumentError] if object is a string starting with a hyphen
|
419
|
+
#
|
420
|
+
def cat_file_size(object)
|
421
|
+
assert_args_are_not_options('object', object)
|
422
|
+
|
423
|
+
command('cat-file', '-s', object).to_i
|
424
|
+
end
|
425
|
+
|
426
|
+
alias :object_size :cat_file_size
|
427
|
+
|
428
|
+
# Return a hash of commit data
|
429
|
+
#
|
430
|
+
# @see https://git-scm.com/docs/git-cat-file git-cat-file
|
431
|
+
#
|
432
|
+
# @param object [String] the object to get the type
|
433
|
+
#
|
434
|
+
# @return [Hash] commit data
|
435
|
+
#
|
436
|
+
# The returned commit data has the following keys:
|
437
|
+
# * tree [String]
|
438
|
+
# * parent [Array<String>]
|
439
|
+
# * author [String] the author name, email, and commit timestamp
|
440
|
+
# * committer [String] the committer name, email, and merge timestamp
|
441
|
+
# * message [String] the commit message
|
442
|
+
# * gpgsig [String] the public signing key of the commit (if signed)
|
443
|
+
#
|
444
|
+
# @raise [ArgumentError] if object is a string starting with a hyphen
|
445
|
+
#
|
446
|
+
def cat_file_commit(object)
|
447
|
+
assert_args_are_not_options('object', object)
|
448
|
+
|
449
|
+
cdata = command_lines('cat-file', 'commit', object)
|
450
|
+
process_commit_data(cdata, object)
|
266
451
|
end
|
267
452
|
|
453
|
+
alias :commit_data :cat_file_commit
|
454
|
+
|
268
455
|
def process_commit_data(data, sha)
|
269
456
|
hsh = {
|
270
457
|
'sha' => sha,
|
@@ -299,12 +486,50 @@ module Git
|
|
299
486
|
end
|
300
487
|
end
|
301
488
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
489
|
+
# Return a hash of annotated tag data
|
490
|
+
#
|
491
|
+
# Does not work with lightweight tags. List all annotated tags in your repository with the following command:
|
492
|
+
#
|
493
|
+
# ```sh
|
494
|
+
# git for-each-ref --format='%(refname:strip=2)' refs/tags | while read tag; do git cat-file tag $tag >/dev/null 2>&1 && echo $tag; done
|
495
|
+
# ```
|
496
|
+
#
|
497
|
+
# @see https://git-scm.com/docs/git-cat-file git-cat-file
|
498
|
+
#
|
499
|
+
# @param object [String] the tag to retrieve
|
500
|
+
#
|
501
|
+
# @return [Hash] tag data
|
502
|
+
#
|
503
|
+
# Example tag data returned:
|
504
|
+
# ```ruby
|
505
|
+
# {
|
506
|
+
# "name" => "annotated_tag",
|
507
|
+
# "object" => "46abbf07e3c564c723c7c039a43ab3a39e5d02dd",
|
508
|
+
# "type" => "commit",
|
509
|
+
# "tag" => "annotated_tag",
|
510
|
+
# "tagger" => "Scott Chacon <schacon@gmail.com> 1724799270 -0700",
|
511
|
+
# "message" => "Creating an annotated tag\n"
|
512
|
+
# }
|
513
|
+
# ```
|
514
|
+
#
|
515
|
+
# The returned commit data has the following keys:
|
516
|
+
# * object [String] the sha of the tag object
|
517
|
+
# * type [String]
|
518
|
+
# * tag [String] tag name
|
519
|
+
# * tagger [String] the name and email of the user who created the tag and the timestamp of when the tag was created
|
520
|
+
# * message [String] the tag message
|
521
|
+
#
|
522
|
+
# @raise [ArgumentError] if object is a string starting with a hyphen
|
523
|
+
#
|
524
|
+
def cat_file_tag(object)
|
525
|
+
assert_args_are_not_options('object', object)
|
526
|
+
|
527
|
+
tdata = command_lines('cat-file', 'tag', object)
|
528
|
+
process_tag_data(tdata, object)
|
306
529
|
end
|
307
530
|
|
531
|
+
alias :tag_data :cat_file_tag
|
532
|
+
|
308
533
|
def process_tag_data(data, name)
|
309
534
|
hsh = { 'name' => name }
|
310
535
|
|
@@ -358,26 +583,15 @@ module Git
|
|
358
583
|
return hsh_array
|
359
584
|
end
|
360
585
|
|
361
|
-
def
|
362
|
-
if block_given?
|
363
|
-
Tempfile.create do |file|
|
364
|
-
# If a block is given, write the output from the process to a temporary
|
365
|
-
# file and then yield the file to the block
|
366
|
-
#
|
367
|
-
command('cat-file', "-p", sha, out: file, err: file)
|
368
|
-
file.rewind
|
369
|
-
yield file
|
370
|
-
end
|
371
|
-
else
|
372
|
-
# If a block is not given, return stdout
|
373
|
-
command('cat-file', '-p', sha)
|
374
|
-
end
|
375
|
-
end
|
376
|
-
|
377
|
-
def ls_tree(sha)
|
586
|
+
def ls_tree(sha, opts = {})
|
378
587
|
data = { 'blob' => {}, 'tree' => {}, 'commit' => {} }
|
379
588
|
|
380
|
-
|
589
|
+
ls_tree_opts = []
|
590
|
+
ls_tree_opts << '-r' if opts[:recursive]
|
591
|
+
# path must be last arg
|
592
|
+
ls_tree_opts << opts[:path] if opts[:path]
|
593
|
+
|
594
|
+
command_lines('ls-tree', sha, *ls_tree_opts).each do |line|
|
381
595
|
(info, filenm) = line.split("\t")
|
382
596
|
(mode, type, sha) = info.split
|
383
597
|
data[type][filenm] = {:mode => mode, :sha => sha}
|
@@ -483,8 +697,54 @@ module Git
|
|
483
697
|
files
|
484
698
|
end
|
485
699
|
|
700
|
+
# The state and name of branch pointed to by `HEAD`
|
701
|
+
#
|
702
|
+
# HEAD can be in the following states:
|
703
|
+
#
|
704
|
+
# **:active**: `HEAD` points to a branch reference which in turn points to a
|
705
|
+
# commit representing the tip of that branch. This is the typical state when
|
706
|
+
# working on a branch.
|
707
|
+
#
|
708
|
+
# **:unborn**: `HEAD` points to a branch reference that does not yet exist
|
709
|
+
# because no commits have been made on that branch. This state occurs in two
|
710
|
+
# scenarios:
|
711
|
+
#
|
712
|
+
# * When a repository is newly initialized, and no commits have been made on the
|
713
|
+
# initial branch.
|
714
|
+
# * When a new branch is created using `git checkout --orphan <branch>`, starting
|
715
|
+
# a new branch with no history.
|
716
|
+
#
|
717
|
+
# **:detached**: `HEAD` points directly to a specific commit (identified by its
|
718
|
+
# SHA) rather than a branch reference. This state occurs when you check out a
|
719
|
+
# commit, a tag, or any state that is not directly associated with a branch. The
|
720
|
+
# branch name in this case is `HEAD`.
|
721
|
+
#
|
722
|
+
HeadState = Struct.new(:state, :name)
|
723
|
+
|
724
|
+
# The current branch state which is the state of `HEAD`
|
725
|
+
#
|
726
|
+
# @return [HeadState] the state and name of the current branch
|
727
|
+
#
|
728
|
+
def current_branch_state
|
729
|
+
branch_name = command('branch', '--show-current')
|
730
|
+
return HeadState.new(:detached, 'HEAD') if branch_name.empty?
|
731
|
+
|
732
|
+
state =
|
733
|
+
begin
|
734
|
+
command('rev-parse', '--verify', '--quiet', branch_name)
|
735
|
+
:active
|
736
|
+
rescue Git::FailedError => e
|
737
|
+
raise unless e.result.status.exitstatus == 1 && e.result.stderr.empty?
|
738
|
+
|
739
|
+
:unborn
|
740
|
+
end
|
741
|
+
|
742
|
+
return HeadState.new(state, branch_name)
|
743
|
+
end
|
744
|
+
|
486
745
|
def branch_current
|
487
|
-
|
746
|
+
branch_name = command('branch', '--show-current')
|
747
|
+
branch_name.empty? ? 'HEAD' : branch_name
|
488
748
|
end
|
489
749
|
|
490
750
|
def branch_contains(commit, branch_name="")
|
@@ -521,7 +781,24 @@ module Git
|
|
521
781
|
hsh
|
522
782
|
end
|
523
783
|
|
784
|
+
# Validate that the given arguments cannot be mistaken for a command-line option
|
785
|
+
#
|
786
|
+
# @param arg_name [String] the name of the arguments to mention in the error message
|
787
|
+
# @param args [Array<String, nil>] the arguments to validate
|
788
|
+
#
|
789
|
+
# @raise [ArgumentError] if any of the parameters are a string starting with a hyphen
|
790
|
+
# @return [void]
|
791
|
+
#
|
792
|
+
def assert_args_are_not_options(arg_name, *args)
|
793
|
+
invalid_args = args.select { |arg| arg&.start_with?('-') }
|
794
|
+
if invalid_args.any?
|
795
|
+
raise ArgumentError, "Invalid #{arg_name}: '#{invalid_args.join("', '")}'"
|
796
|
+
end
|
797
|
+
end
|
798
|
+
|
524
799
|
def diff_full(obj1 = 'HEAD', obj2 = nil, opts = {})
|
800
|
+
assert_args_are_not_options('commit or commit range', obj1, obj2)
|
801
|
+
|
525
802
|
diff_opts = ['-p']
|
526
803
|
diff_opts << obj1
|
527
804
|
diff_opts << obj2 if obj2.is_a?(String)
|
@@ -531,6 +808,8 @@ module Git
|
|
531
808
|
end
|
532
809
|
|
533
810
|
def diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {})
|
811
|
+
assert_args_are_not_options('commit or commit range', obj1, obj2)
|
812
|
+
|
534
813
|
diff_opts = ['--numstat']
|
535
814
|
diff_opts << obj1
|
536
815
|
diff_opts << obj2 if obj2.is_a?(String)
|
@@ -551,6 +830,8 @@ module Git
|
|
551
830
|
end
|
552
831
|
|
553
832
|
def diff_name_status(reference1 = nil, reference2 = nil, opts = {})
|
833
|
+
assert_args_are_not_options('commit or commit range', reference1, reference2)
|
834
|
+
|
554
835
|
opts_arr = ['--name-status']
|
555
836
|
opts_arr << reference1 if reference1
|
556
837
|
opts_arr << reference2 if reference2
|
data/lib/git/object.rb
CHANGED
@@ -23,11 +23,11 @@ module Git
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def sha
|
26
|
-
@sha ||= @base.lib.
|
26
|
+
@sha ||= @base.lib.rev_parse(@objectish)
|
27
27
|
end
|
28
28
|
|
29
29
|
def size
|
30
|
-
@size ||= @base.lib.
|
30
|
+
@size ||= @base.lib.cat_file_size(@objectish)
|
31
31
|
end
|
32
32
|
|
33
33
|
# Get the object's contents.
|
@@ -38,9 +38,9 @@ module Git
|
|
38
38
|
# Use this for large files so that they are not held in memory.
|
39
39
|
def contents(&block)
|
40
40
|
if block_given?
|
41
|
-
@base.lib.
|
41
|
+
@base.lib.cat_file_contents(@objectish, &block)
|
42
42
|
else
|
43
|
-
@contents ||= @base.lib.
|
43
|
+
@contents ||= @base.lib.cat_file_contents(@objectish)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -175,7 +175,7 @@ module Git
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def name
|
178
|
-
@base.lib.
|
178
|
+
@base.lib.name_rev(sha)
|
179
179
|
end
|
180
180
|
|
181
181
|
def gtree
|
@@ -237,7 +237,7 @@ module Git
|
|
237
237
|
def check_commit
|
238
238
|
return if @tree
|
239
239
|
|
240
|
-
data = @base.lib.
|
240
|
+
data = @base.lib.cat_file_commit(@objectish)
|
241
241
|
set_commit(data)
|
242
242
|
end
|
243
243
|
|
@@ -254,7 +254,7 @@ module Git
|
|
254
254
|
end
|
255
255
|
|
256
256
|
def annotated?
|
257
|
-
@annotated ||= (@base.lib.
|
257
|
+
@annotated ||= (@base.lib.cat_file_type(self.name) == 'tag')
|
258
258
|
end
|
259
259
|
|
260
260
|
def message
|
@@ -279,7 +279,7 @@ module Git
|
|
279
279
|
if !self.annotated?
|
280
280
|
@message = @tagger = nil
|
281
281
|
else
|
282
|
-
tdata = @base.lib.
|
282
|
+
tdata = @base.lib.cat_file_tag(@name)
|
283
283
|
@message = tdata['message'].chomp
|
284
284
|
@tagger = Git::Author.new(tdata['tagger'])
|
285
285
|
end
|
@@ -300,7 +300,7 @@ module Git
|
|
300
300
|
return Git::Object::Tag.new(base, sha, objectish)
|
301
301
|
end
|
302
302
|
|
303
|
-
type ||= base.lib.
|
303
|
+
type ||= base.lib.cat_file_type(objectish)
|
304
304
|
klass =
|
305
305
|
case type
|
306
306
|
when /blob/ then Blob
|
data/lib/git/version.rb
CHANGED
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: 2.
|
4
|
+
version: 2.3.0
|
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-
|
11
|
+
date: 2024-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -243,8 +243,8 @@ licenses:
|
|
243
243
|
metadata:
|
244
244
|
homepage_uri: http://github.com/ruby-git/ruby-git
|
245
245
|
source_code_uri: http://github.com/ruby-git/ruby-git
|
246
|
-
changelog_uri: https://rubydoc.info/gems/git/2.
|
247
|
-
documentation_uri: https://rubydoc.info/gems/git/2.
|
246
|
+
changelog_uri: https://rubydoc.info/gems/git/2.3.0/file/CHANGELOG.md
|
247
|
+
documentation_uri: https://rubydoc.info/gems/git/2.3.0
|
248
248
|
post_install_message:
|
249
249
|
rdoc_options: []
|
250
250
|
require_paths:
|