git 4.3.2 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +13 -0
- data/README.md +12 -0
- data/lib/git/base.rb +4 -4
- data/lib/git/branch.rb +302 -23
- data/lib/git/status.rb +0 -2
- data/lib/git/version.rb +1 -1
- data/lib/git.rb +39 -4
- 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: 98b554ddb65a29cb16fc266ea5466c2919c312f5021729ec3719ded044a53a91
|
|
4
|
+
data.tar.gz: c98533fda6126f92b5deba44d7ed38878e537fcbd02508702c5f8d1d99d26355
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 529bc860265d31541e62381dd7e551405e74cf494da695e740578d0e9c5409ea9151f823a44ad6d089f74d533787fd02f1ed9ca6030656a82ffb72a1936fbef0
|
|
7
|
+
data.tar.gz: 3131c1f4ae9e9fb177d6120a6f460e40ed7e592045718e733f861f4289dc4e6668e04eb8f8ab2c2b8fc73c299327817a89ae66f28369382c7856c2ec3d1853d1
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
|
|
6
6
|
# Change Log
|
|
7
7
|
|
|
8
|
+
## [4.4.0](https://github.com/ruby-git/ruby-git/compare/v4.3.2...v4.4.0) (2026-07-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* Allow deprecation behavior env var ([fd622be](https://github.com/ruby-git/ruby-git/commit/fd622bea6513d78f2dbed8dc19c110be80d07ec8))
|
|
14
|
+
* Warn on first direct access to Git::Lib constant ([52059c6](https://github.com/ruby-git/ruby-git/commit/52059c63d5c23b4d80025b95332e946aba942f0c))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Other Changes
|
|
18
|
+
|
|
19
|
+
* Improve YARD documentation for Git::Branch ([#1277](https://github.com/ruby-git/ruby-git/issues/1277)) ([0769bf9](https://github.com/ruby-git/ruby-git/commit/0769bf91a21ecb24d48a31439de073b689bc62b6))
|
|
20
|
+
|
|
8
21
|
## [4.3.2](https://github.com/ruby-git/ruby-git/compare/v4.3.1...v4.3.2) (2026-03-31)
|
|
9
22
|
|
|
10
23
|
|
data/README.md
CHANGED
|
@@ -589,6 +589,18 @@ You can silence deprecation warnings by adding this line to your source code:
|
|
|
589
589
|
Git::Deprecation.behavior = :silence
|
|
590
590
|
```
|
|
591
591
|
|
|
592
|
+
Or by setting this environment variable before loading the gem:
|
|
593
|
+
|
|
594
|
+
```sh
|
|
595
|
+
GIT_DEPRECATION_BEHAVIOR=silence
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Accepted environment variable values are the behavior names supported by your
|
|
599
|
+
installed ActiveSupport version.
|
|
600
|
+
|
|
601
|
+
If `GIT_DEPRECATION_BEHAVIOR` is set to an unsupported value, loading the gem
|
|
602
|
+
raises `ArgumentError` with the accepted behavior names.
|
|
603
|
+
|
|
592
604
|
See [the Active Support Deprecation
|
|
593
605
|
documentation](https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html)
|
|
594
606
|
for more details.
|
data/lib/git/base.rb
CHANGED
|
@@ -23,14 +23,14 @@ module Git
|
|
|
23
23
|
def self.clone(repository_url, directory, options = {})
|
|
24
24
|
lib_options = {}
|
|
25
25
|
lib_options[:git_ssh] = options[:git_ssh] if options.key?(:git_ssh)
|
|
26
|
-
new_options =
|
|
26
|
+
new_options = LibImpl.new(lib_options, options[:log]).clone(repository_url, directory, options)
|
|
27
27
|
normalize_paths(new_options, bare: options[:bare] || options[:mirror])
|
|
28
28
|
new(new_options)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# (see Git.default_branch)
|
|
32
32
|
def self.repository_default_branch(repository, options = {})
|
|
33
|
-
|
|
33
|
+
LibImpl.new(nil, options[:log]).repository_default_branch(repository)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Returns (and initialize if needed) a Git::Config instance
|
|
@@ -90,7 +90,7 @@ module Git
|
|
|
90
90
|
# repository you have a Git::Base instance for. This would not
|
|
91
91
|
# change the existing interface (other than adding to it).
|
|
92
92
|
#
|
|
93
|
-
|
|
93
|
+
LibImpl.new(options).init(init_options)
|
|
94
94
|
|
|
95
95
|
new(options)
|
|
96
96
|
end
|
|
@@ -335,7 +335,7 @@ module Git
|
|
|
335
335
|
# actual 'git' forked system calls. At some point I hope to replace the Git::Lib
|
|
336
336
|
# class with one that uses native methods or libgit C bindings
|
|
337
337
|
def lib
|
|
338
|
-
@lib ||=
|
|
338
|
+
@lib ||= LibImpl.new(self, @logger)
|
|
339
339
|
end
|
|
340
340
|
|
|
341
341
|
# Returns the per-instance git_ssh configuration value.
|
data/lib/git/branch.rb
CHANGED
|
@@ -4,9 +4,81 @@ require 'git/path'
|
|
|
4
4
|
|
|
5
5
|
module Git
|
|
6
6
|
# Represents a Git branch
|
|
7
|
+
#
|
|
8
|
+
# Branch objects provide access to branch metadata and operations like checkout,
|
|
9
|
+
# delete, and merge. They should be obtained via {Git::Base#branch} or
|
|
10
|
+
# {Git::Base#branches}, not constructed directly.
|
|
11
|
+
#
|
|
12
|
+
# @example Getting a branch
|
|
13
|
+
# git = Git.open('.')
|
|
14
|
+
# branch = git.branch('main')
|
|
15
|
+
# branch.checkout
|
|
16
|
+
#
|
|
17
|
+
# @example Listing branches
|
|
18
|
+
# git.branches.each { |b| puts b.name }
|
|
19
|
+
#
|
|
20
|
+
# @api public
|
|
21
|
+
#
|
|
7
22
|
class Branch
|
|
8
|
-
|
|
23
|
+
# The full refname of this branch
|
|
24
|
+
#
|
|
25
|
+
# For local branches this is the short name (e.g. `'main'`). For
|
|
26
|
+
# remote-tracking branches obtained via {Git::Base#branches} this includes
|
|
27
|
+
# the `remotes/` prefix (e.g. `'remotes/origin/main'`). Branches constructed
|
|
28
|
+
# by {Git::Remote#branch} use the `<remote>/<branch>` form (e.g.
|
|
29
|
+
# `'origin/main'`) which does **not** populate {#remote}.
|
|
30
|
+
#
|
|
31
|
+
# @example
|
|
32
|
+
# git.branch('main').full #=> 'main'
|
|
33
|
+
# git.branch('remotes/origin/main').full #=> 'remotes/origin/main'
|
|
34
|
+
#
|
|
35
|
+
# @return [String] the full refname
|
|
36
|
+
#
|
|
37
|
+
attr_accessor :full
|
|
38
|
+
|
|
39
|
+
# The remote for this branch, or `nil` for local or bare-name remote-tracking branches
|
|
40
|
+
#
|
|
41
|
+
# Set to a {Git::Remote} object only when this branch was initialized with a
|
|
42
|
+
# `remotes/<remote>/` or `refs/remotes/<remote>/` prefix. `nil` for local
|
|
43
|
+
# branches and for remote-tracking branches in `<remote>/<branch>` form
|
|
44
|
+
# (such as those returned by {Git::Remote#branch}).
|
|
45
|
+
#
|
|
46
|
+
# @example
|
|
47
|
+
# git.branch('main').remote #=> nil
|
|
48
|
+
# git.branch('remotes/origin/main').remote #=> #<Git::Remote 'origin'>
|
|
49
|
+
# git.remote('origin').branch('main').remote #=> nil # uses 'origin/main' form
|
|
50
|
+
#
|
|
51
|
+
# @return [Git::Remote, nil] the remote object, or `nil`
|
|
52
|
+
#
|
|
53
|
+
attr_accessor :remote
|
|
54
|
+
|
|
55
|
+
# The short branch name without the remote prefix
|
|
56
|
+
#
|
|
57
|
+
# For branches initialized with a `remotes/` or `refs/remotes/` prefix, the
|
|
58
|
+
# prefix is stripped and this returns the bare branch name (e.g. `'main'`
|
|
59
|
+
# rather than `'remotes/origin/main'`). For branches in the
|
|
60
|
+
# `<remote>/<branch>` form (such as those created by {Git::Remote#branch}),
|
|
61
|
+
# no stripping occurs and `name` returns the full form (e.g. `'origin/main'`).
|
|
62
|
+
#
|
|
63
|
+
# @example
|
|
64
|
+
# git.branch('main').name #=> 'main'
|
|
65
|
+
# git.branch('remotes/origin/main').name #=> 'main'
|
|
66
|
+
# git.remote('origin').branch('main').name #=> 'origin/main'
|
|
67
|
+
#
|
|
68
|
+
# @return [String] the branch name
|
|
69
|
+
#
|
|
70
|
+
attr_accessor :name
|
|
9
71
|
|
|
72
|
+
# Initialize a new Branch object
|
|
73
|
+
#
|
|
74
|
+
# @api private
|
|
75
|
+
#
|
|
76
|
+
# @note Use {Git::Base#branch} or {Git::Base#branches} instead of constructing directly
|
|
77
|
+
#
|
|
78
|
+
# @param base [Git::Base] the git repository
|
|
79
|
+
#
|
|
80
|
+
# @param name [String] the full or short branch name
|
|
81
|
+
#
|
|
10
82
|
def initialize(base, name)
|
|
11
83
|
@full = name
|
|
12
84
|
@base = base
|
|
@@ -15,29 +87,102 @@ module Git
|
|
|
15
87
|
@remote, @name = parse_name(name)
|
|
16
88
|
end
|
|
17
89
|
|
|
90
|
+
# Returns the commit at the tip of this branch
|
|
91
|
+
#
|
|
92
|
+
# The result is memoized after the first call.
|
|
93
|
+
#
|
|
94
|
+
# @example Get the tip commit
|
|
95
|
+
# git.branch('main').gcommit #=> #<Git::Object ...>
|
|
96
|
+
#
|
|
97
|
+
# @return [Git::Object] the commit at the tip of this branch
|
|
98
|
+
#
|
|
18
99
|
def gcommit
|
|
19
100
|
@gcommit ||= @base.gcommit(@full)
|
|
20
101
|
@gcommit
|
|
21
102
|
end
|
|
22
103
|
|
|
104
|
+
# Returns the stash list for this repository
|
|
105
|
+
#
|
|
106
|
+
# The result is memoized after the first call.
|
|
107
|
+
#
|
|
108
|
+
# @example Iterate over stash entries
|
|
109
|
+
# git.branch('main').stashes.each { |s| puts s }
|
|
110
|
+
#
|
|
111
|
+
# @return [Git::Stashes] the stash list
|
|
112
|
+
#
|
|
23
113
|
def stashes
|
|
24
114
|
@stashes ||= Git::Stashes.new(@base)
|
|
25
115
|
end
|
|
26
116
|
|
|
117
|
+
# Checks out this branch, attempting to create it first if it does not already exist
|
|
118
|
+
#
|
|
119
|
+
# Branch creation is attempted via {#check_if_create}; any error from that
|
|
120
|
+
# step is silently ignored and the checkout proceeds regardless.
|
|
121
|
+
#
|
|
122
|
+
# **Note:** for remote-tracking branches (where {#remote} is not `nil`),
|
|
123
|
+
# {#full} is a ref such as `'remotes/origin/main'`. Checking out a
|
|
124
|
+
# remote-tracking ref places the repository in a **detached HEAD** state.
|
|
125
|
+
#
|
|
126
|
+
# @example Check out a branch
|
|
127
|
+
# git = Git.open('.')
|
|
128
|
+
# git.branch('main').checkout
|
|
129
|
+
#
|
|
130
|
+
# @return [String] git's stdout from the checkout
|
|
131
|
+
#
|
|
132
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
133
|
+
#
|
|
27
134
|
def checkout
|
|
28
135
|
check_if_create
|
|
29
136
|
@base.checkout(@full)
|
|
30
137
|
end
|
|
31
138
|
|
|
139
|
+
# Archives this branch and writes the result to a file
|
|
140
|
+
#
|
|
141
|
+
# @example Archive to a tar file
|
|
142
|
+
# git.branch('main').archive('/tmp/main.tar')
|
|
143
|
+
#
|
|
144
|
+
# @example Archive to a zip file
|
|
145
|
+
# git.branch('main').archive('/tmp/main.zip', format: 'zip')
|
|
146
|
+
#
|
|
147
|
+
# @param file [String] path to the destination archive file
|
|
148
|
+
#
|
|
149
|
+
# @param opts [Hash] archive options (see {Git::Base#archive})
|
|
150
|
+
#
|
|
151
|
+
# @return [String] the path to the written archive file
|
|
152
|
+
#
|
|
153
|
+
# @raise [Git::FailedError] if `git archive` fails
|
|
154
|
+
#
|
|
32
155
|
def archive(file, opts = {})
|
|
33
156
|
@base.lib.archive(@full, file, opts)
|
|
34
157
|
end
|
|
35
158
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
159
|
+
# Checks out this branch for the duration of a block, then restores the original branch
|
|
160
|
+
#
|
|
161
|
+
# If the block returns a truthy value, all pending changes are committed with the
|
|
162
|
+
# given message before switching back to the original branch. If the block returns
|
|
163
|
+
# a falsy value, a hard reset is performed before switching back.
|
|
164
|
+
#
|
|
165
|
+
# **Note:** the restore checkout is not wrapped in `ensure`. If the block,
|
|
166
|
+
# the commit, or the reset raises an exception, the repository will be left
|
|
167
|
+
# checked out on this branch rather than restored to the original.
|
|
168
|
+
#
|
|
169
|
+
# @example Commit a new file on a feature branch
|
|
170
|
+
# git.branch('feature').in_branch('Add README') do
|
|
171
|
+
# File.write('README.md', '# Hello')
|
|
172
|
+
# git.add('README.md')
|
|
173
|
+
# true # commit and return to original branch
|
|
174
|
+
# end
|
|
175
|
+
#
|
|
176
|
+
# @param message [String] commit message used when the block returns truthy
|
|
177
|
+
#
|
|
178
|
+
# @yield Executes the block with this branch checked out
|
|
179
|
+
#
|
|
180
|
+
# @yieldreturn [Object] return a truthy value to commit all changes, a falsy value to hard-reset
|
|
181
|
+
#
|
|
182
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
183
|
+
#
|
|
184
|
+
# @raise [Git::FailedError] if any of the underlying git operations (checkout, commit, reset) fail
|
|
185
|
+
#
|
|
41
186
|
def in_branch(message = 'in branch work')
|
|
42
187
|
old_current = @base.lib.branch_current
|
|
43
188
|
checkout
|
|
@@ -49,22 +194,112 @@ module Git
|
|
|
49
194
|
@base.checkout(old_current)
|
|
50
195
|
end
|
|
51
196
|
|
|
197
|
+
# Creates this branch if it does not already exist
|
|
198
|
+
#
|
|
199
|
+
# Silently ignores any error raised during branch creation (including the case
|
|
200
|
+
# where the branch already exists).
|
|
201
|
+
#
|
|
202
|
+
# @example Create a new branch
|
|
203
|
+
# git.branch('feature').create
|
|
204
|
+
#
|
|
205
|
+
# @return [String, nil] git's stdout from branch creation (typically empty),
|
|
206
|
+
# or `nil` if an error was rescued
|
|
207
|
+
#
|
|
52
208
|
def create
|
|
53
209
|
check_if_create
|
|
54
210
|
end
|
|
55
211
|
|
|
212
|
+
# Deletes this branch
|
|
213
|
+
#
|
|
214
|
+
# **Note:** this method only works correctly for local branches. Calling it on
|
|
215
|
+
# a remote-tracking branch (one where {#remote} is not `nil`) will attempt to
|
|
216
|
+
# delete a *local* branch with the same short name rather than the
|
|
217
|
+
# remote-tracking ref, which is almost certainly not what you want.
|
|
218
|
+
# See [ruby-git#1280](https://github.com/ruby-git/ruby-git/issues/1280) for
|
|
219
|
+
# the planned fix.
|
|
220
|
+
#
|
|
221
|
+
# @example Delete a local branch
|
|
222
|
+
# git.branch('old-feature').delete
|
|
223
|
+
#
|
|
224
|
+
# @return [String] git's deletion output
|
|
225
|
+
#
|
|
226
|
+
# @raise [Git::FailedError] if the branch cannot be deleted
|
|
227
|
+
#
|
|
56
228
|
def delete
|
|
57
229
|
@base.lib.branch_delete(@name)
|
|
58
230
|
end
|
|
59
231
|
|
|
232
|
+
# Returns true if this is the currently checked-out branch
|
|
233
|
+
#
|
|
234
|
+
# **Note:** this compares the current branch's short name against {#name}.
|
|
235
|
+
# For a remote-tracking branch (where {#remote} is not `nil`), {#name} is
|
|
236
|
+
# still the bare short name (e.g. `'main'`), so this will return `true`
|
|
237
|
+
# whenever the *local* branch with that name is checked out — not the
|
|
238
|
+
# remote-tracking ref itself.
|
|
239
|
+
#
|
|
240
|
+
# @example Check whether currently on main
|
|
241
|
+
# git.branch('main').current #=> true
|
|
242
|
+
#
|
|
243
|
+
# @return [Boolean] whether this branch is currently checked out
|
|
244
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
245
|
+
#
|
|
246
|
+
#
|
|
60
247
|
def current # rubocop:disable Naming/PredicateMethod
|
|
61
248
|
@base.lib.branch_current == @name
|
|
62
249
|
end
|
|
63
250
|
|
|
251
|
+
# Returns true if this branch contains the given commit
|
|
252
|
+
#
|
|
253
|
+
# **Note:** this queries local branches by short name. For a remote-tracking
|
|
254
|
+
# branch (where {#remote} is not `nil`), it checks the *local* branch with
|
|
255
|
+
# the same {#name} rather than the remote-tracking ref, which may give an
|
|
256
|
+
# inaccurate result.
|
|
257
|
+
#
|
|
258
|
+
# @example Check if a commit is reachable from this branch
|
|
259
|
+
# git.branch('main').contains?('abc1234') #=> true
|
|
260
|
+
#
|
|
261
|
+
# @param commit [String] the commit SHA or ref to check
|
|
262
|
+
#
|
|
263
|
+
# @return [Boolean] whether this branch contains the given commit
|
|
264
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
265
|
+
#
|
|
266
|
+
#
|
|
64
267
|
def contains?(commit)
|
|
65
268
|
!@base.lib.branch_contains(commit, name).empty?
|
|
66
269
|
end
|
|
67
270
|
|
|
271
|
+
# Merges a branch into this branch, or merges this branch into the current branch
|
|
272
|
+
#
|
|
273
|
+
# @overload merge(branch, message = nil)
|
|
274
|
+
#
|
|
275
|
+
# Temporarily checks out this branch, merges the given branch into it,
|
|
276
|
+
# then restores the original branch.
|
|
277
|
+
#
|
|
278
|
+
# **Note:** if `self` is a remote-tracking branch (where {#remote} is not
|
|
279
|
+
# `nil`), this delegates to {#checkout} which has the detached-HEAD
|
|
280
|
+
# side-effect described there. The remote-tracking ref will not be updated.
|
|
281
|
+
#
|
|
282
|
+
# @example Merge a feature branch into main
|
|
283
|
+
# git.branch('main').merge('feature')
|
|
284
|
+
#
|
|
285
|
+
# @param branch [String] the name of the branch to merge into this one
|
|
286
|
+
#
|
|
287
|
+
# @param message [String, nil] commit message for the merge commit
|
|
288
|
+
#
|
|
289
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
290
|
+
#
|
|
291
|
+
# @overload merge()
|
|
292
|
+
#
|
|
293
|
+
# Merges this branch into the currently checked-out branch.
|
|
294
|
+
#
|
|
295
|
+
# @example Merge main into the current branch
|
|
296
|
+
# git.branch('main').merge
|
|
297
|
+
#
|
|
298
|
+
# @return [String] git's stdout from the merge command
|
|
299
|
+
#
|
|
300
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status during
|
|
301
|
+
# the merge, checkout, commit, or reset operations
|
|
302
|
+
#
|
|
68
303
|
def merge(branch = nil, message = nil)
|
|
69
304
|
if branch
|
|
70
305
|
in_branch do
|
|
@@ -78,6 +313,26 @@ module Git
|
|
|
78
313
|
end
|
|
79
314
|
end
|
|
80
315
|
|
|
316
|
+
# Updates the git ref for this branch to point to the given commit
|
|
317
|
+
#
|
|
318
|
+
# The target ref depends on whether {#remote} is set:
|
|
319
|
+
# - When {#remote} is not `nil` (i.e. the branch was initialised with a
|
|
320
|
+
# `remotes/<remote>/` or `refs/remotes/<remote>/` prefix), updates
|
|
321
|
+
# `refs/remotes/<remote>/<name>`.
|
|
322
|
+
# - Otherwise updates `refs/heads/<name>`. Note that branches in the
|
|
323
|
+
# `<remote>/<branch>` form (e.g. those returned by {Git::Remote#branch})
|
|
324
|
+
# have `remote == nil` and therefore update `refs/heads/<remote>/<name>`,
|
|
325
|
+
# **not** `refs/remotes/...`.
|
|
326
|
+
#
|
|
327
|
+
# @example Advance a local branch to a new commit
|
|
328
|
+
# git.branch('feature').update_ref('abc1234def5678')
|
|
329
|
+
#
|
|
330
|
+
# @param commit [String] the commit SHA to point this branch at
|
|
331
|
+
#
|
|
332
|
+
# @return [String] the stdout output from `git update-ref`
|
|
333
|
+
#
|
|
334
|
+
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
335
|
+
#
|
|
81
336
|
def update_ref(commit)
|
|
82
337
|
if @remote
|
|
83
338
|
@base.lib.update_ref("refs/remotes/#{@remote.name}/#{@name}", commit)
|
|
@@ -86,17 +341,38 @@ module Git
|
|
|
86
341
|
end
|
|
87
342
|
end
|
|
88
343
|
|
|
344
|
+
# Returns this branch as a single-element array containing its full refname
|
|
345
|
+
#
|
|
346
|
+
# @example Get branch as array
|
|
347
|
+
# git.branch('main').to_a #=> ['main']
|
|
348
|
+
#
|
|
349
|
+
# @return [Array<String>] a single-element array containing the full refname
|
|
350
|
+
#
|
|
89
351
|
def to_a
|
|
90
352
|
[@full]
|
|
91
353
|
end
|
|
92
354
|
|
|
355
|
+
# Returns the full refname of this branch as a string
|
|
356
|
+
#
|
|
357
|
+
# @example Get branch as string
|
|
358
|
+
# git.branch('main').to_s #=> 'main'
|
|
359
|
+
#
|
|
360
|
+
# @return [String] the full refname
|
|
361
|
+
#
|
|
93
362
|
def to_s
|
|
94
363
|
@full
|
|
95
364
|
end
|
|
96
365
|
|
|
366
|
+
# Regular expression for parsing branch refnames
|
|
367
|
+
#
|
|
368
|
+
# Matches full and short refnames, capturing an optional remote name and the
|
|
369
|
+
# branch name. Used internally to identify remote-tracking branches.
|
|
370
|
+
#
|
|
371
|
+
# @api private
|
|
372
|
+
#
|
|
97
373
|
BRANCH_NAME_REGEXP = %r{
|
|
98
374
|
^
|
|
99
|
-
# Optional 'refs/remotes/' at the
|
|
375
|
+
# Optional 'remotes/' or 'refs/remotes/' at the beginning to specify a remote tracking branch
|
|
100
376
|
# with a <remote_name>. <remote_name> is nil if not present.
|
|
101
377
|
(?:
|
|
102
378
|
(?:(?:refs/)?remotes/)(?<remote_name>[^/]+)/
|
|
@@ -107,26 +383,25 @@ module Git
|
|
|
107
383
|
|
|
108
384
|
private
|
|
109
385
|
|
|
110
|
-
#
|
|
386
|
+
# Parses a full branch name into remote and short branch name components
|
|
387
|
+
#
|
|
388
|
+
# Strips an optional `remotes/` or `refs/remotes/` prefix. Only inputs that begin
|
|
389
|
+
# with one of those prefixes yield a remote object; all other inputs (including
|
|
390
|
+
# `'origin/master'`) are treated as local branch names with a `nil` remote.
|
|
111
391
|
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
392
|
+
# @example Local branches
|
|
393
|
+
# parse_name('master') #=> [nil, 'master']
|
|
394
|
+
# parse_name('origin/master') #=> [nil, 'origin/master']
|
|
115
395
|
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
# parse_name('master') #=> [
|
|
119
|
-
# parse_name('origin/master') #=> [nil, 'origin/master']
|
|
120
|
-
# parse_name('origin/master/v2') #=> [nil, 'origin/master']
|
|
396
|
+
# @example Remote-tracking branches
|
|
397
|
+
# parse_name('remotes/origin/master') #=> [#<Git::Remote 'origin'>, 'master']
|
|
398
|
+
# parse_name('refs/remotes/origin/master') #=> [#<Git::Remote 'origin'>, 'master']
|
|
121
399
|
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
# parse_name('refs/remotes/origin/master/v2') #=> ['origin', 'master/v2']
|
|
400
|
+
# @param name [String] the full branch name to parse
|
|
401
|
+
#
|
|
402
|
+
# @return [Array(Git::Remote, String)] a two-element array with the remote object
|
|
403
|
+
# (or `nil`) and the short branch name
|
|
127
404
|
#
|
|
128
|
-
# param [String] name branch full name.
|
|
129
|
-
# return [<Git::Remote,NilClass,String>] an Array containing the remote and branch names.
|
|
130
405
|
def parse_name(name)
|
|
131
406
|
# Expect this will always match
|
|
132
407
|
match = name.match(BRANCH_NAME_REGEXP)
|
|
@@ -135,6 +410,10 @@ module Git
|
|
|
135
410
|
[remote, branch_name]
|
|
136
411
|
end
|
|
137
412
|
|
|
413
|
+
# Creates the branch if it does not already exist, ignoring errors
|
|
414
|
+
#
|
|
415
|
+
# @return [String, nil] stdout from branch creation, or `nil` if an error was rescued
|
|
416
|
+
#
|
|
138
417
|
def check_if_create
|
|
139
418
|
@base.lib.branch_new(@name)
|
|
140
419
|
rescue StandardError
|
data/lib/git/status.rb
CHANGED
data/lib/git/version.rb
CHANGED
data/lib/git.rb
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'active_support'
|
|
4
3
|
require 'active_support/deprecation'
|
|
5
4
|
|
|
5
|
+
# Define Git::Deprecation before requiring the rest of the library to ensure that
|
|
6
|
+
# any deprecation warnings emitted during the loading of the library are properly
|
|
7
|
+
# configured according to the GIT_DEPRECATION_BEHAVIOR environment variable.
|
|
8
|
+
#
|
|
6
9
|
module Git
|
|
10
|
+
# The deprecation instance used to emit deprecation warnings for the Git gem
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
7
13
|
Deprecation = ActiveSupport::Deprecation.new('5.0.0', 'Git')
|
|
14
|
+
|
|
15
|
+
if (behavior = ENV.fetch('GIT_DEPRECATION_BEHAVIOR', nil))
|
|
16
|
+
behavior = behavior.strip
|
|
17
|
+
allowed_behaviors = ActiveSupport::Deprecation::DEFAULT_BEHAVIORS.keys.map(&:to_s)
|
|
18
|
+
|
|
19
|
+
unless allowed_behaviors.include?(behavior)
|
|
20
|
+
raise ArgumentError,
|
|
21
|
+
"Invalid GIT_DEPRECATION_BEHAVIOR=#{behavior.inspect}; " \
|
|
22
|
+
"expected one of: #{allowed_behaviors.join(', ')}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
Deprecation.behavior = behavior.to_sym
|
|
26
|
+
end
|
|
8
27
|
end
|
|
9
28
|
|
|
10
29
|
require 'git/author'
|
|
@@ -44,12 +63,28 @@ require 'git/worktrees'
|
|
|
44
63
|
# @author Scott Chacon (mailto:schacon@gmail.com)
|
|
45
64
|
#
|
|
46
65
|
module Git # rubocop:disable Style/OneClassPerFile
|
|
66
|
+
# Internal alias for Git::Lib, used by the gem itself after the public constant
|
|
67
|
+
# is deprecated. Code outside the gem should not reference this constant.
|
|
68
|
+
# @api private
|
|
69
|
+
LibImpl = remove_const(:Lib)
|
|
70
|
+
|
|
71
|
+
# @api private
|
|
72
|
+
def self.const_missing(name)
|
|
73
|
+
return super unless name == :Lib
|
|
74
|
+
|
|
75
|
+
Git::Deprecation.warn(
|
|
76
|
+
'Git::Lib is deprecated and will be removed in version 5.x. ' \
|
|
77
|
+
'Use the #lib accessor on the object returned by Git.init, Git.open, or Git.clone instead.'
|
|
78
|
+
)
|
|
79
|
+
const_set(:Lib, LibImpl)
|
|
80
|
+
end
|
|
81
|
+
|
|
47
82
|
# g.config('user.name', 'Scott Chacon') # sets value
|
|
48
83
|
# g.config('user.email', 'email@email.com') # sets value
|
|
49
84
|
# g.config('user.name') # returns 'Scott Chacon'
|
|
50
85
|
# g.config # returns whole config hash
|
|
51
86
|
def config(name = nil, value = nil)
|
|
52
|
-
lib =
|
|
87
|
+
lib = LibImpl.new
|
|
53
88
|
if name && value
|
|
54
89
|
# set value
|
|
55
90
|
lib.config_set(name, value)
|
|
@@ -287,7 +322,7 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
287
322
|
# g.config('user.name') # returns 'Scott Chacon'
|
|
288
323
|
# g.config # returns whole config hash
|
|
289
324
|
def self.global_config(name = nil, value = nil)
|
|
290
|
-
lib =
|
|
325
|
+
lib = LibImpl.new(nil, nil)
|
|
291
326
|
if name && value
|
|
292
327
|
# set value
|
|
293
328
|
lib.global_config_set(name, value)
|
|
@@ -369,7 +404,7 @@ module Git # rubocop:disable Style/OneClassPerFile
|
|
|
369
404
|
# @param [String|NilClass] location the target repository location or nil for '.'
|
|
370
405
|
# @return [{String=>Hash}] the available references of the target repo.
|
|
371
406
|
def self.ls_remote(location = nil, options = {})
|
|
372
|
-
|
|
407
|
+
LibImpl.new.ls_remote(location, options)
|
|
373
408
|
end
|
|
374
409
|
|
|
375
410
|
# Open a an existing Git working directory
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Chacon and others
|
|
@@ -310,8 +310,8 @@ licenses:
|
|
|
310
310
|
metadata:
|
|
311
311
|
homepage_uri: http://github.com/ruby-git/ruby-git
|
|
312
312
|
source_code_uri: http://github.com/ruby-git/ruby-git
|
|
313
|
-
changelog_uri: https://rubydoc.info/gems/git/4.
|
|
314
|
-
documentation_uri: https://rubydoc.info/gems/git/4.
|
|
313
|
+
changelog_uri: https://rubydoc.info/gems/git/4.4.0/file/CHANGELOG.md
|
|
314
|
+
documentation_uri: https://rubydoc.info/gems/git/4.4.0
|
|
315
315
|
rubygems_mfa_required: 'true'
|
|
316
316
|
rdoc_options: []
|
|
317
317
|
require_paths:
|
|
@@ -328,7 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
328
328
|
version: '0'
|
|
329
329
|
requirements:
|
|
330
330
|
- git 2.28.0 or greater
|
|
331
|
-
rubygems_version: 4.0.
|
|
331
|
+
rubygems_version: 4.0.10
|
|
332
332
|
specification_version: 4
|
|
333
333
|
summary: An API to create, read, and manipulate Git repositories
|
|
334
334
|
test_files: []
|