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.
@@ -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
- @stashes ||= Git::Stashes.new(branch_repository)
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
- if yield
210
- branch_repository.commit_all(message)
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
- in_branch do
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
- # merge this branch into the current one
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
- @remote = branch_info.remote_name ? Git::Remote.new(@base, branch_info.remote_name) : nil
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
- remote = match[:remote_name] ? Git::Remote.new(@base, match[:remote_name]) : nil
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]
@@ -70,7 +70,7 @@ module Git
70
70
  # info.remote_name #=> 'origin'
71
71
  # info.short_name #=> 'main'
72
72
  #
73
- # @see Git::Branch for the full-featured branch object with operations
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
- branch_repository.branch_list.each do |branch_info|
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
- out << (b.current ? '* ' : ' ') << b.to_s << "\n"
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
- # Git 2.28-2.49 rejects this flag in other modes; git 2.50+ accepts and
54
- # ignores it everywhere (the unknown-type feature was removed; see issue 1709).
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; git 2.50 removed the unknown-type feature
117
- # and accepts this flag as a no-op
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; git 2.50 removed the unknown-type feature
142
- # and accepts this flag as a no-op
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