git 5.2.0 → 5.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/CHANGELOG.md +49 -0
- data/CONTRIBUTING.md +17 -4
- data/README.md +49 -8
- data/UPGRADING.md +587 -3
- data/lib/git/author.rb +11 -0
- data/lib/git/author_info.rb +66 -0
- data/lib/git/branch.rb +216 -17
- data/lib/git/branch_info.rb +1 -1
- data/lib/git/branches.rb +35 -7
- data/lib/git/commands/cat_file/raw.rb +60 -6
- data/lib/git/object.rb +69 -15
- data/lib/git/parsers/stash.rb +50 -17
- data/lib/git/parsers/status.rb +251 -0
- data/lib/git/parsers/tag.rb +54 -8
- data/lib/git/parsers/worktree.rb +185 -0
- data/lib/git/remote.rb +37 -7
- data/lib/git/remote_info.rb +67 -10
- data/lib/git/repository/branching.rb +111 -1
- data/lib/git/repository/merging.rb +96 -2
- data/lib/git/repository/object_operations.rb +257 -20
- data/lib/git/repository/remote_operations.rb +57 -0
- data/lib/git/repository/shared_private.rb +67 -0
- data/lib/git/repository/stashing.rb +532 -52
- data/lib/git/repository/status_operations.rb +56 -8
- data/lib/git/repository/worktree_operations.rb +198 -18
- data/lib/git/stash.rb +31 -2
- data/lib/git/stash_info.rb +32 -34
- data/lib/git/stashes.rb +47 -11
- data/lib/git/status.rb +14 -0
- data/lib/git/status_file_info.rb +258 -0
- data/lib/git/status_info.rb +189 -0
- data/lib/git/tag_info.rb +23 -30
- data/lib/git/version.rb +1 -1
- data/lib/git/worktree.rb +39 -0
- data/lib/git/worktree_info.rb +128 -0
- data/lib/git/worktrees.rb +19 -1
- data/lib/git.rb +5 -0
- metadata +9 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Git
|
|
4
|
+
# Immutable value object representing an author or committer identity
|
|
5
|
+
#
|
|
6
|
+
# This is a lightweight, immutable data structure holding the identity data
|
|
7
|
+
# git records for commit authors, committers, and taggers. It replaces the
|
|
8
|
+
# mutable {Git::Author}, which is deprecated.
|
|
9
|
+
#
|
|
10
|
+
# @example Construct from individual values
|
|
11
|
+
# info = Git::AuthorInfo.new(
|
|
12
|
+
# name: 'John Doe',
|
|
13
|
+
# email: 'john.doe@example.com',
|
|
14
|
+
# date: Time.at(1627849923)
|
|
15
|
+
# )
|
|
16
|
+
# info.name #=> 'John Doe'
|
|
17
|
+
#
|
|
18
|
+
# @example Parse from a raw git author string
|
|
19
|
+
# info = Git::AuthorInfo.parse('John Doe <john.doe@example.com> 1627849923 +0200')
|
|
20
|
+
# info.email #=> 'john.doe@example.com'
|
|
21
|
+
# info.date.to_i #=> 1627849923
|
|
22
|
+
#
|
|
23
|
+
# @see Git::Object::Commit#author
|
|
24
|
+
#
|
|
25
|
+
# @see Git::Object::Commit#committer
|
|
26
|
+
#
|
|
27
|
+
# @api public
|
|
28
|
+
#
|
|
29
|
+
# @!attribute [r] name
|
|
30
|
+
# @return [String, nil] the person's name, or `nil` if not available
|
|
31
|
+
#
|
|
32
|
+
# @!attribute [r] email
|
|
33
|
+
# @return [String, nil] the person's email address, or `nil` if not available
|
|
34
|
+
#
|
|
35
|
+
# @!attribute [r] date
|
|
36
|
+
# @return [Time, nil] the timestamp of the change, or `nil` if not available
|
|
37
|
+
#
|
|
38
|
+
AuthorInfo = Data.define(:name, :email, :date) do
|
|
39
|
+
# Parses a raw git identity string into a Git::AuthorInfo
|
|
40
|
+
#
|
|
41
|
+
# The expected format is `"Name <email> timestamp offset"` as emitted by
|
|
42
|
+
# `git cat-file` for the `author`, `committer`, and `tagger` headers. The
|
|
43
|
+
# timestamp is interpreted as seconds since the Unix epoch; the timezone
|
|
44
|
+
# offset is not preserved in the resulting `date`.
|
|
45
|
+
#
|
|
46
|
+
# @example Parse a well-formed identity string
|
|
47
|
+
# Git::AuthorInfo.parse('John Doe <john.doe@example.com> 1627849923 +0200')
|
|
48
|
+
# #=> #<data Git::AuthorInfo name="John Doe", email="john.doe@example.com", ...>
|
|
49
|
+
#
|
|
50
|
+
# @example A string that does not match the expected format
|
|
51
|
+
# Git::AuthorInfo.parse('garbage')
|
|
52
|
+
# #=> #<data Git::AuthorInfo name=nil, email=nil, date=nil>
|
|
53
|
+
#
|
|
54
|
+
# @param author_string [String] the raw identity string to parse
|
|
55
|
+
#
|
|
56
|
+
# @return [Git::AuthorInfo] the parsed identity; all attributes are `nil`
|
|
57
|
+
# when the string does not match the expected format
|
|
58
|
+
#
|
|
59
|
+
def self.parse(author_string)
|
|
60
|
+
match = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string)
|
|
61
|
+
return new(name: nil, email: nil, date: nil) unless match
|
|
62
|
+
|
|
63
|
+
new(name: match[1], email: match[2], date: Time.at(match[3].to_i))
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/git/branch.rb
CHANGED
|
@@ -17,6 +17,17 @@ module Git
|
|
|
17
17
|
# @example Listing branches
|
|
18
18
|
# git.branches.each { |b| puts b.name }
|
|
19
19
|
#
|
|
20
|
+
# @deprecated Use {Git::Repository::Branching#branch_list} and the
|
|
21
|
+
# name-based branch operations on {Git::Repository} instead
|
|
22
|
+
#
|
|
23
|
+
# {Git::Repository::Branching#branch_list} returns immutable
|
|
24
|
+
# {Git::BranchInfo} value objects. Operations that lived on this class are
|
|
25
|
+
# called on the repository with the branch name instead (for example
|
|
26
|
+
# {Git::Repository::Branching#checkout} and
|
|
27
|
+
# {Git::Repository::Branching#branch_delete}). Every operation on a
|
|
28
|
+
# `Git::Branch` emits a deprecation warning; the `full`, `name`, `remote`,
|
|
29
|
+
# `to_s`, and `to_a` readers do not.
|
|
30
|
+
#
|
|
20
31
|
# @api public
|
|
21
32
|
#
|
|
22
33
|
class Branch
|
|
@@ -94,22 +105,53 @@ module Git
|
|
|
94
105
|
#
|
|
95
106
|
# @return [Git::Object] the commit at the tip of this branch
|
|
96
107
|
#
|
|
108
|
+
# @deprecated Use {Git::Repository::ObjectOperations#gcommit} with the branch name instead
|
|
109
|
+
#
|
|
110
|
+
# Pass the branch name for a local branch, or `"remotes/#{remote}/#{name}"`
|
|
111
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
112
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
113
|
+
#
|
|
114
|
+
# @see Git::Repository::ObjectOperations#gcommit
|
|
115
|
+
#
|
|
97
116
|
def gcommit
|
|
117
|
+
Git::Deprecation.warn(
|
|
118
|
+
'Git::Branch#gcommit is deprecated and will be removed in v6.0.0. ' \
|
|
119
|
+
'Use Git::Repository#gcommit(name) or, for a remote-tracking branch, ' \
|
|
120
|
+
'Git::Repository#gcommit("remotes/remote/name") instead.'
|
|
121
|
+
)
|
|
98
122
|
@gcommit ||= branch_repository.gcommit(@full)
|
|
99
123
|
@gcommit
|
|
100
124
|
end
|
|
101
125
|
|
|
102
126
|
# Returns the stash list for this repository
|
|
103
127
|
#
|
|
128
|
+
# This method ignores the branch receiver and returns every stash in the
|
|
129
|
+
# repository, so `git.branch('feature').stashes` and
|
|
130
|
+
# `git.branch('main').stashes` return the same entries. It is deprecated and
|
|
131
|
+
# will be removed in v6.0.0.
|
|
132
|
+
#
|
|
104
133
|
# The result is memoized after the first call.
|
|
105
134
|
#
|
|
106
|
-
# @example Iterate over stash entries
|
|
135
|
+
# @example Iterate over stash entries (deprecated)
|
|
107
136
|
# git.branch('main').stashes.each { |s| puts s }
|
|
108
137
|
#
|
|
138
|
+
# @example The replacement
|
|
139
|
+
# repo.stash_infos.each { |info| puts info.message }
|
|
140
|
+
#
|
|
109
141
|
# @return [Git::Stashes] the stash list
|
|
110
142
|
#
|
|
143
|
+
# @deprecated Use {Git::Repository#stash_infos} instead
|
|
144
|
+
#
|
|
145
|
+
# @see Git::Repository#stash_infos
|
|
146
|
+
#
|
|
111
147
|
def stashes
|
|
112
|
-
|
|
148
|
+
Git::Deprecation.warn(
|
|
149
|
+
'Git::Branch#stashes is deprecated and will be removed in v6.0.0. ' \
|
|
150
|
+
'It ignores the branch and returns all repository stashes. ' \
|
|
151
|
+
'Use Git::Repository#stash_infos instead.'
|
|
152
|
+
)
|
|
153
|
+
# Git::Stashes is deprecated too; silence it so one stashes call emits one warning
|
|
154
|
+
@stashes ||= Git::Deprecation.silence { Git::Stashes.new(branch_repository) }
|
|
113
155
|
end
|
|
114
156
|
|
|
115
157
|
# Checks out this branch, attempting to create it first if it does not already exist
|
|
@@ -131,7 +173,30 @@ module Git
|
|
|
131
173
|
#
|
|
132
174
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
133
175
|
#
|
|
176
|
+
# @deprecated Use {Git::Repository::Branching#checkout} with the branch name instead
|
|
177
|
+
#
|
|
178
|
+
# {Git::Repository::Branching#checkout} does not create a missing local
|
|
179
|
+
# branch, apart from the guess git makes on its own: with no `:no_guess`
|
|
180
|
+
# option, git creates a tracking branch when exactly one remote has a
|
|
181
|
+
# branch of that name. To reproduce the create-or-checkout behavior of
|
|
182
|
+
# this method, call {Git::Repository::Branching#branch_new} when
|
|
183
|
+
# {Git::Repository::Branching#local_branch?} is false, then
|
|
184
|
+
# {Git::Repository::Branching#checkout}. Pass `"remotes/#{remote}/#{name}"`
|
|
185
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
186
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
187
|
+
#
|
|
188
|
+
# @see Git::Repository::Branching#checkout
|
|
189
|
+
#
|
|
190
|
+
# @see Git::Repository::Branching#branch_new
|
|
191
|
+
#
|
|
134
192
|
def checkout
|
|
193
|
+
Git::Deprecation.warn(
|
|
194
|
+
'Git::Branch#checkout is deprecated and will be removed in v6.0.0. ' \
|
|
195
|
+
'Use Git::Repository#checkout(name) or, for a remote-tracking branch, ' \
|
|
196
|
+
'Git::Repository#checkout("remotes/remote/name") instead. Git::Repository#checkout does not ' \
|
|
197
|
+
'create a missing local branch (beyond the guess git makes from a unique remote-tracking ' \
|
|
198
|
+
'branch); call Git::Repository#branch_new first unless Git::Repository#local_branch? is true.'
|
|
199
|
+
)
|
|
135
200
|
check_if_create
|
|
136
201
|
branch_repository.checkout(@full)
|
|
137
202
|
end
|
|
@@ -172,7 +237,20 @@ module Git
|
|
|
172
237
|
#
|
|
173
238
|
# @raise [Git::FailedError] if `git archive` fails
|
|
174
239
|
#
|
|
240
|
+
# @deprecated Use {Git::Repository::ObjectOperations#archive} with the branch name instead
|
|
241
|
+
#
|
|
242
|
+
# Pass the branch name for a local branch, or `"remotes/#{remote}/#{name}"`
|
|
243
|
+
# (the value of {#full}) for a remote-tracking branch; the shorter
|
|
244
|
+
# `"#{remote}/#{name}"` can resolve a local branch of that name.
|
|
245
|
+
#
|
|
246
|
+
# @see Git::Repository::ObjectOperations#archive
|
|
247
|
+
#
|
|
175
248
|
def archive(file, opts = {})
|
|
249
|
+
Git::Deprecation.warn(
|
|
250
|
+
'Git::Branch#archive is deprecated and will be removed in v6.0.0. ' \
|
|
251
|
+
'Use Git::Repository#archive(name, file, opts) or, for a remote-tracking branch, ' \
|
|
252
|
+
'Git::Repository#archive("remotes/remote/name", file, opts) instead.'
|
|
253
|
+
)
|
|
176
254
|
branch_repository.archive(@full, file, opts)
|
|
177
255
|
end
|
|
178
256
|
|
|
@@ -203,14 +281,27 @@ module Git
|
|
|
203
281
|
#
|
|
204
282
|
# @yieldreturn [Object] return a truthy value to commit all changes, a falsy value to hard-reset
|
|
205
283
|
#
|
|
284
|
+
# @deprecated Use {Git::Repository::Branching#in_branch} with the branch name instead
|
|
285
|
+
#
|
|
286
|
+
# {Git::Repository::Branching#in_branch} does not create the branch and
|
|
287
|
+
# restores a detached HEAD to its original commit.
|
|
288
|
+
# It takes an existing local branch, so a remote-tracking `Git::Branch` has
|
|
289
|
+
# no direct replacement: this method checked out the remote-tracking ref,
|
|
290
|
+
# detaching HEAD. Create a local branch from that ref with
|
|
291
|
+
# {Git::Repository::Branching#branch_new} first.
|
|
292
|
+
#
|
|
293
|
+
# @see Git::Repository::Branching#in_branch
|
|
294
|
+
#
|
|
206
295
|
def in_branch(message = 'in branch work')
|
|
296
|
+
Git::Deprecation.warn(
|
|
297
|
+
'Git::Branch#in_branch is deprecated and will be removed in v6.0.0. ' \
|
|
298
|
+
'Use Git::Repository#in_branch(name, message) instead. It takes an existing local ' \
|
|
299
|
+
'branch; for a remote-tracking branch, create a local branch from it first.'
|
|
300
|
+
)
|
|
207
301
|
old_current = branch_repository.current_branch
|
|
208
|
-
checkout
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
else
|
|
212
|
-
branch_repository.reset(nil, hard: true)
|
|
213
|
-
end
|
|
302
|
+
# checkout is deprecated too; silence it so one in_branch call emits one warning
|
|
303
|
+
Git::Deprecation.silence { checkout }
|
|
304
|
+
yield ? branch_repository.commit_all(message) : branch_repository.reset(nil, hard: true)
|
|
214
305
|
branch_repository.checkout(old_current)
|
|
215
306
|
end
|
|
216
307
|
|
|
@@ -224,7 +315,18 @@ module Git
|
|
|
224
315
|
#
|
|
225
316
|
# @return [nil]
|
|
226
317
|
#
|
|
318
|
+
# @deprecated Use {Git::Repository::Branching#branch_new} instead
|
|
319
|
+
#
|
|
320
|
+
# {Git::Repository::Branching#branch_new} raises {Git::FailedError} when
|
|
321
|
+
# the branch already exists rather than ignoring the error.
|
|
322
|
+
#
|
|
323
|
+
# @see Git::Repository::Branching#branch_new
|
|
324
|
+
#
|
|
227
325
|
def create
|
|
326
|
+
Git::Deprecation.warn(
|
|
327
|
+
'Git::Branch#create is deprecated and will be removed in v6.0.0. ' \
|
|
328
|
+
'Use Git::Repository#branch_new instead.'
|
|
329
|
+
)
|
|
228
330
|
check_if_create
|
|
229
331
|
end
|
|
230
332
|
|
|
@@ -240,7 +342,19 @@ module Git
|
|
|
240
342
|
#
|
|
241
343
|
# @raise [Git::Error] if the branch cannot be deleted
|
|
242
344
|
#
|
|
345
|
+
# @deprecated Use {Git::Repository::Branching#branch_delete} instead
|
|
346
|
+
#
|
|
347
|
+
# Pass the branch name for a local branch, or `"#{remote}/#{name}"` with
|
|
348
|
+
# `remotes: true` for a remote-tracking branch.
|
|
349
|
+
#
|
|
350
|
+
# @see Git::Repository::Branching#branch_delete
|
|
351
|
+
#
|
|
243
352
|
def delete
|
|
353
|
+
Git::Deprecation.warn(
|
|
354
|
+
'Git::Branch#delete is deprecated and will be removed in v6.0.0. ' \
|
|
355
|
+
'Use Git::Repository#branch_delete(name) or, for a remote-tracking branch, ' \
|
|
356
|
+
'Git::Repository#branch_delete("remote/name", remotes: true) instead.'
|
|
357
|
+
)
|
|
244
358
|
if @remote
|
|
245
359
|
branch_repository.branch_delete("#{@remote.name}/#{@name}", remotes: true)
|
|
246
360
|
else
|
|
@@ -263,7 +377,16 @@ module Git
|
|
|
263
377
|
#
|
|
264
378
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
265
379
|
#
|
|
380
|
+
# @deprecated Compare {Git::Repository::Branching#current_branch} with the
|
|
381
|
+
# branch name instead
|
|
382
|
+
#
|
|
383
|
+
# @see Git::Repository::Branching#current_branch
|
|
384
|
+
#
|
|
266
385
|
def current # rubocop:disable Naming/PredicateMethod
|
|
386
|
+
Git::Deprecation.warn(
|
|
387
|
+
'Git::Branch#current is deprecated and will be removed in v6.0.0. ' \
|
|
388
|
+
'Use Git::Repository#current_branch == name instead.'
|
|
389
|
+
)
|
|
267
390
|
branch_repository.current_branch == @name
|
|
268
391
|
end
|
|
269
392
|
|
|
@@ -283,7 +406,19 @@ module Git
|
|
|
283
406
|
#
|
|
284
407
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
285
408
|
#
|
|
409
|
+
# @deprecated Use {Git::Repository::Branching#branch_contains} with the
|
|
410
|
+
# commit and branch name instead
|
|
411
|
+
#
|
|
412
|
+
# {Git::Repository::Branching#branch_contains} returns the matching
|
|
413
|
+
# branch names as a String; test it with `empty?`.
|
|
414
|
+
#
|
|
415
|
+
# @see Git::Repository::Branching#branch_contains
|
|
416
|
+
#
|
|
286
417
|
def contains?(commit)
|
|
418
|
+
Git::Deprecation.warn(
|
|
419
|
+
'Git::Branch#contains? is deprecated and will be removed in v6.0.0. ' \
|
|
420
|
+
'Use !Git::Repository#branch_contains(commit, name).empty? instead.'
|
|
421
|
+
)
|
|
287
422
|
!branch_repository.branch_contains(commit, name).empty?
|
|
288
423
|
end
|
|
289
424
|
|
|
@@ -318,16 +453,27 @@ module Git
|
|
|
318
453
|
#
|
|
319
454
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
320
455
|
#
|
|
456
|
+
# @deprecated Use {Git::Repository::Merging#merge_into} in place of
|
|
457
|
+
# `merge(branch)` and {Git::Repository::Merging#merge} with the branch
|
|
458
|
+
# name in place of `merge()`
|
|
459
|
+
#
|
|
460
|
+
# {Git::Repository::Merging#merge_into} returns the merge's stdout, does
|
|
461
|
+
# not hard-reset after the merge, and restores a detached HEAD to its
|
|
462
|
+
# original commit.
|
|
463
|
+
# It takes an existing local branch, so a remote-tracking `Git::Branch` has
|
|
464
|
+
# no direct replacement: `merge(branch)` checked out the remote-tracking ref,
|
|
465
|
+
# detaching HEAD. Create a local branch from that ref with
|
|
466
|
+
# {Git::Repository::Branching#branch_new} first.
|
|
467
|
+
#
|
|
468
|
+
# @see Git::Repository::Merging#merge_into
|
|
469
|
+
#
|
|
470
|
+
# @see Git::Repository::Merging#merge
|
|
471
|
+
#
|
|
321
472
|
def merge(branch = nil, message = nil)
|
|
322
473
|
if branch
|
|
323
|
-
|
|
324
|
-
branch_repository.merge(branch, message)
|
|
325
|
-
false
|
|
326
|
-
end
|
|
327
|
-
# merge a branch into this one
|
|
474
|
+
merge_into_this_branch(branch, message)
|
|
328
475
|
else
|
|
329
|
-
|
|
330
|
-
branch_repository.merge(@name)
|
|
476
|
+
merge_into_current_branch
|
|
331
477
|
end
|
|
332
478
|
end
|
|
333
479
|
|
|
@@ -351,7 +497,19 @@ module Git
|
|
|
351
497
|
#
|
|
352
498
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
353
499
|
#
|
|
500
|
+
# @deprecated Use {Git::Repository::Branching#update_ref} instead
|
|
501
|
+
#
|
|
502
|
+
# Pass the branch name for a local branch, or
|
|
503
|
+
# `"remotes/#{remote}/#{name}"` for a remote-tracking branch.
|
|
504
|
+
#
|
|
505
|
+
# @see Git::Repository::Branching#update_ref
|
|
506
|
+
#
|
|
354
507
|
def update_ref(commit)
|
|
508
|
+
Git::Deprecation.warn(
|
|
509
|
+
'Git::Branch#update_ref is deprecated and will be removed in v6.0.0. ' \
|
|
510
|
+
'Use Git::Repository#update_ref(name, commit) or, for a remote-tracking branch, ' \
|
|
511
|
+
'Git::Repository#update_ref("remotes/remote/name", commit) instead.'
|
|
512
|
+
)
|
|
355
513
|
if @remote
|
|
356
514
|
branch_repository.update_ref("remotes/#{@remote.name}/#{@name}", commit)
|
|
357
515
|
else
|
|
@@ -429,7 +587,9 @@ module Git
|
|
|
429
587
|
#
|
|
430
588
|
def initialize_from_branch_info(branch_info)
|
|
431
589
|
@name = branch_info.short_name
|
|
432
|
-
|
|
590
|
+
remote_name = branch_info.remote_name
|
|
591
|
+
# Git::Remote is deprecated too; silence it so one Git::Branch call emits one warning
|
|
592
|
+
@remote = remote_name ? Git::Deprecation.silence { Git::Remote.new(@base, remote_name) } : nil
|
|
433
593
|
@full = @remote ? "remotes/#{@remote.name}/#{@name}" : @name
|
|
434
594
|
end
|
|
435
595
|
|
|
@@ -468,11 +628,50 @@ module Git
|
|
|
468
628
|
def parse_name(name)
|
|
469
629
|
# Expect this will always match
|
|
470
630
|
match = name.match(BRANCH_NAME_REGEXP)
|
|
471
|
-
|
|
631
|
+
remote_name = match[:remote_name]
|
|
632
|
+
# Git::Remote is deprecated too; silence it so one Git::Branch call emits one warning
|
|
633
|
+
remote = remote_name ? Git::Deprecation.silence { Git::Remote.new(@base, remote_name) } : nil
|
|
472
634
|
branch_name = match[:branch_name]
|
|
473
635
|
[remote, branch_name]
|
|
474
636
|
end
|
|
475
637
|
|
|
638
|
+
# Merges the given branch into this branch, then restores the original branch
|
|
639
|
+
#
|
|
640
|
+
# @param branch [String] the name of the branch to merge into this one
|
|
641
|
+
#
|
|
642
|
+
# @param message [String, nil] commit message for the merge commit
|
|
643
|
+
#
|
|
644
|
+
# @return [String] git's stdout from the final checkout back to the original branch
|
|
645
|
+
#
|
|
646
|
+
# @api private
|
|
647
|
+
#
|
|
648
|
+
def merge_into_this_branch(branch, message)
|
|
649
|
+
Git::Deprecation.warn(
|
|
650
|
+
'Git::Branch#merge(branch) is deprecated and will be removed in v6.0.0. ' \
|
|
651
|
+
'Use Git::Repository#merge_into(name, branch, message) instead. It takes an existing ' \
|
|
652
|
+
'local branch; for a remote-tracking branch, create a local branch from it first.'
|
|
653
|
+
)
|
|
654
|
+
# in_branch is deprecated too; silence it so one merge call emits one warning.
|
|
655
|
+
# The falsy block value makes in_branch hard-reset instead of committing.
|
|
656
|
+
Git::Deprecation.silence do
|
|
657
|
+
in_branch { branch_repository.merge(branch, message) && false }
|
|
658
|
+
end
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# Merges this branch into the currently checked-out branch
|
|
662
|
+
#
|
|
663
|
+
# @return [String] git's stdout from the merge command
|
|
664
|
+
#
|
|
665
|
+
# @api private
|
|
666
|
+
#
|
|
667
|
+
def merge_into_current_branch
|
|
668
|
+
Git::Deprecation.warn(
|
|
669
|
+
'Git::Branch#merge with no arguments is deprecated and will be removed in v6.0.0. ' \
|
|
670
|
+
'Use Git::Repository#merge(name) instead.'
|
|
671
|
+
)
|
|
672
|
+
branch_repository.merge(@name)
|
|
673
|
+
end
|
|
674
|
+
|
|
476
675
|
# Creates the branch if it does not already exist, ignoring errors
|
|
477
676
|
#
|
|
478
677
|
# @return [nil]
|
data/lib/git/branch_info.rb
CHANGED
|
@@ -70,7 +70,7 @@ module Git
|
|
|
70
70
|
# info.remote_name #=> 'origin'
|
|
71
71
|
# info.short_name #=> 'main'
|
|
72
72
|
#
|
|
73
|
-
# @see Git::
|
|
73
|
+
# @see Git::Repository::Branching#branch_list for the repository method that returns these
|
|
74
74
|
#
|
|
75
75
|
# @see Git::Commands::Branch::List for the command that produces these
|
|
76
76
|
#
|
data/lib/git/branches.rb
CHANGED
|
@@ -10,6 +10,14 @@ module Git
|
|
|
10
10
|
# branches = repo.branches
|
|
11
11
|
# branches.each { |b| puts b.name }
|
|
12
12
|
#
|
|
13
|
+
# @deprecated Use {Git::Repository::Branching#branch_list} instead
|
|
14
|
+
#
|
|
15
|
+
# {Git::Repository::Branching#branch_list} returns `Array<Git::BranchInfo>`
|
|
16
|
+
# (immutable value objects). Filter it with `select(&:remote?)` or
|
|
17
|
+
# `reject(&:remote?)` in place of {#remote} and {#local}, and look a
|
|
18
|
+
# branch up by name with `branch_list(name).first` in place of {#[]}.
|
|
19
|
+
# Constructing a `Git::Branches` emits a deprecation warning.
|
|
20
|
+
#
|
|
13
21
|
# @api public
|
|
14
22
|
#
|
|
15
23
|
class Branches
|
|
@@ -24,18 +32,21 @@ module Git
|
|
|
24
32
|
#
|
|
25
33
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
26
34
|
#
|
|
35
|
+
# @deprecated Use {Git::Repository::Branching#branch_list} instead
|
|
36
|
+
#
|
|
37
|
+
# @see Git::Repository::Branching#branch_list
|
|
38
|
+
#
|
|
27
39
|
def initialize(base)
|
|
40
|
+
Git::Deprecation.warn(
|
|
41
|
+
'Git::Branches is deprecated and will be removed in v6.0.0. ' \
|
|
42
|
+
'Use Git::Repository#branch_list instead.'
|
|
43
|
+
)
|
|
28
44
|
@branches = {}
|
|
29
45
|
@lookup = {}
|
|
30
46
|
|
|
31
47
|
@base = base
|
|
32
48
|
|
|
33
|
-
|
|
34
|
-
branch = Git::Branch.new(base, branch_info)
|
|
35
|
-
|
|
36
|
-
@branches[branch_info.refname] = branch
|
|
37
|
-
index_branch_lookup(branch, refname: branch_info.refname)
|
|
38
|
-
end
|
|
49
|
+
load_branches
|
|
39
50
|
end
|
|
40
51
|
|
|
41
52
|
# Returns all local (non-remote-tracking) branches
|
|
@@ -127,13 +138,30 @@ module Git
|
|
|
127
138
|
def to_s
|
|
128
139
|
out = +''
|
|
129
140
|
@branches.each_value do |b|
|
|
130
|
-
|
|
141
|
+
# Git::Branch#current is deprecated too; silence it so one to_s call emits one warning
|
|
142
|
+
current = Git::Deprecation.silence { b.current }
|
|
143
|
+
out << (current ? '* ' : ' ') << b.to_s << "\n"
|
|
131
144
|
end
|
|
132
145
|
out
|
|
133
146
|
end
|
|
134
147
|
|
|
135
148
|
private
|
|
136
149
|
|
|
150
|
+
# Builds a Git::Branch for every branch in the repository and indexes it
|
|
151
|
+
#
|
|
152
|
+
# @return [void]
|
|
153
|
+
#
|
|
154
|
+
# @api private
|
|
155
|
+
#
|
|
156
|
+
def load_branches
|
|
157
|
+
branch_repository.branch_list.each do |branch_info|
|
|
158
|
+
branch = Git::Branch.new(@base, branch_info)
|
|
159
|
+
|
|
160
|
+
@branches[branch_info.refname] = branch
|
|
161
|
+
index_branch_lookup(branch, refname: branch_info.refname)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
137
165
|
# @return [Git::Repository] the repository used to enumerate branches
|
|
138
166
|
#
|
|
139
167
|
# @api private
|
|
@@ -50,8 +50,10 @@ module Git
|
|
|
50
50
|
flag_option :s
|
|
51
51
|
|
|
52
52
|
# Allow -t and -s to query broken or corrupt objects of unknown type.
|
|
53
|
-
#
|
|
54
|
-
#
|
|
53
|
+
# Deprecated and removed in v6.0.0 (see issue 1709); passing it emits a
|
|
54
|
+
# deprecation warning. Git 2.28-2.49 honors it with -t and -s and rejects
|
|
55
|
+
# it in other modes; git 2.50+ accepts and ignores it everywhere (the
|
|
56
|
+
# unknown-type feature was removed).
|
|
55
57
|
# See https://git-scm.com/docs/git-cat-file/2.49.0#Documentation/git-cat-file.txt---allow-unknown-type
|
|
56
58
|
flag_option :allow_unknown_type
|
|
57
59
|
|
|
@@ -91,6 +93,13 @@ module Git
|
|
|
91
93
|
#
|
|
92
94
|
# @param options [Hash] command options
|
|
93
95
|
#
|
|
96
|
+
# @option options [Boolean, nil] :allow_unknown_type (nil) pass `--allow-unknown-type` through to git,
|
|
97
|
+
# which rejects it in this mode on git 2.28-2.49 and accepts it as a no-op
|
|
98
|
+
# on git 2.50 and later
|
|
99
|
+
#
|
|
100
|
+
# Deprecated and removed in v6.0.0; passing it emits a deprecation
|
|
101
|
+
# warning.
|
|
102
|
+
#
|
|
94
103
|
# @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
|
|
95
104
|
#
|
|
96
105
|
# @option options [Boolean, nil] :no_use_mailmap (nil) suppress mailmap remapping (`--no-use-mailmap`)
|
|
@@ -113,8 +122,11 @@ module Git
|
|
|
113
122
|
# @param options [Hash] command options
|
|
114
123
|
#
|
|
115
124
|
# @option options [Boolean, nil] :allow_unknown_type (nil) allow querying broken or corrupt objects of
|
|
116
|
-
# unknown type on git 2.28-2.49
|
|
117
|
-
#
|
|
125
|
+
# unknown type on git 2.28-2.49
|
|
126
|
+
#
|
|
127
|
+
# Deprecated and removed in v6.0.0; passing it emits a deprecation
|
|
128
|
+
# warning. Git 2.50 removed the unknown-type feature and accepts this
|
|
129
|
+
# flag as a no-op.
|
|
118
130
|
#
|
|
119
131
|
# @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
|
|
120
132
|
#
|
|
@@ -138,8 +150,11 @@ module Git
|
|
|
138
150
|
# @param options [Hash] command options
|
|
139
151
|
#
|
|
140
152
|
# @option options [Boolean, nil] :allow_unknown_type (nil) allow querying broken or corrupt objects of
|
|
141
|
-
# unknown type on git 2.28-2.49
|
|
142
|
-
#
|
|
153
|
+
# unknown type on git 2.28-2.49
|
|
154
|
+
#
|
|
155
|
+
# Deprecated and removed in v6.0.0; passing it emits a deprecation
|
|
156
|
+
# warning. Git 2.50 removed the unknown-type feature and accepts this
|
|
157
|
+
# flag as a no-op.
|
|
143
158
|
#
|
|
144
159
|
# @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
|
|
145
160
|
#
|
|
@@ -162,6 +177,13 @@ module Git
|
|
|
162
177
|
#
|
|
163
178
|
# @param options [Hash] command options
|
|
164
179
|
#
|
|
180
|
+
# @option options [Boolean, nil] :allow_unknown_type (nil) pass `--allow-unknown-type` through to git,
|
|
181
|
+
# which rejects it in this mode on git 2.28-2.49 and accepts it as a no-op
|
|
182
|
+
# on git 2.50 and later
|
|
183
|
+
#
|
|
184
|
+
# Deprecated and removed in v6.0.0; passing it emits a deprecation
|
|
185
|
+
# warning.
|
|
186
|
+
#
|
|
165
187
|
# @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
|
|
166
188
|
#
|
|
167
189
|
# @option options [Boolean, nil] :no_use_mailmap (nil) suppress mailmap remapping (`--no-use-mailmap`)
|
|
@@ -183,6 +205,13 @@ module Git
|
|
|
183
205
|
#
|
|
184
206
|
# @param options [Hash] command options
|
|
185
207
|
#
|
|
208
|
+
# @option options [Boolean, nil] :allow_unknown_type (nil) pass `--allow-unknown-type` through to git,
|
|
209
|
+
# which rejects it in this mode on git 2.28-2.49 and accepts it as a no-op
|
|
210
|
+
# on git 2.50 and later
|
|
211
|
+
#
|
|
212
|
+
# Deprecated and removed in v6.0.0; passing it emits a deprecation
|
|
213
|
+
# warning.
|
|
214
|
+
#
|
|
186
215
|
# @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
|
|
187
216
|
#
|
|
188
217
|
# @option options [Boolean, nil] :no_use_mailmap (nil) suppress mailmap remapping (`--no-use-mailmap`)
|
|
@@ -199,6 +228,7 @@ module Git
|
|
|
199
228
|
# @option options [Numeric, nil] :timeout (nil) abort the command after this many seconds
|
|
200
229
|
#
|
|
201
230
|
def call(*, **)
|
|
231
|
+
warn_allow_unknown_type_deprecated(**)
|
|
202
232
|
bound = args_definition.bind(*, **)
|
|
203
233
|
validate_version!(bound.execution_options)
|
|
204
234
|
result = execute_command(bound)
|
|
@@ -211,6 +241,30 @@ module Git
|
|
|
211
241
|
|
|
212
242
|
result
|
|
213
243
|
end
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
|
|
247
|
+
# Emit the deprecation warning when the `allow_unknown_type` keyword is passed
|
|
248
|
+
#
|
|
249
|
+
# Keys on the keyword being present, whatever its value: `false` and `nil`
|
|
250
|
+
# suppress the flag but still name a deprecated option.
|
|
251
|
+
#
|
|
252
|
+
# @param options [Hash] the keyword arguments passed to {#call}
|
|
253
|
+
#
|
|
254
|
+
# @option options [Boolean, nil] :allow_unknown_type the deprecated option;
|
|
255
|
+
# any value, including `false` and `nil`, triggers the warning
|
|
256
|
+
#
|
|
257
|
+
# @return [void]
|
|
258
|
+
#
|
|
259
|
+
def warn_allow_unknown_type_deprecated(**options)
|
|
260
|
+
return unless options.key?(:allow_unknown_type)
|
|
261
|
+
|
|
262
|
+
Git::Deprecation.warn(
|
|
263
|
+
'The allow_unknown_type option of Git::Commands::CatFile::Raw is deprecated ' \
|
|
264
|
+
'and will be removed in v6.0.0. Git 2.50 removed the unknown-type feature ' \
|
|
265
|
+
'and accepts --allow-unknown-type as a no-op.'
|
|
266
|
+
)
|
|
267
|
+
end
|
|
214
268
|
end
|
|
215
269
|
end
|
|
216
270
|
end
|