git 5.3.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 +16 -0
- data/README.md +1 -1
- data/UPGRADING.md +320 -22
- data/lib/git/branch.rb +9 -5
- data/lib/git/object.rb +56 -8
- data/lib/git/parsers/status.rb +251 -0
- data/lib/git/parsers/worktree.rb +185 -0
- data/lib/git/repository/object_operations.rb +257 -20
- 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/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 +2 -1
- 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 +4 -0
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1b0ec11636ea561f0c879744f4c7b94fd12f2a2fae29da23ac22f338edefe9fe
|
|
4
|
+
data.tar.gz: b70d5290d89c34293b3dd47b839b1a6d091f7d081236623b844160269e07e2ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 449e637646f9faba003af92629c11dbf3a42703f4331a331c3bf03f218659335fd1abd17344bc74f91ffd78a9e4823c3f4dd6cb1ac9a2546a5884cd673dd2a47
|
|
7
|
+
data.tar.gz: f2a797c6f9a56ae2c877c01a3b7f3da3db46f5d82b5b930de44998035404255692a44c012efb610d4032e5b8d72231f782cf7e5ba921de344c94dde4c5c7b52a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@
|
|
|
5
5
|
|
|
6
6
|
# Change Log
|
|
7
7
|
|
|
8
|
+
## [5.4.0](https://github.com/ruby-git/ruby-git/compare/v5.3.0...v5.4.0) (2026-09-04)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **stash:** Add the StashInfo facade surface and deprecate the legacy stash API ([3cc4c6b](https://github.com/ruby-git/ruby-git/commit/3cc4c6bdc58203eedf7f3207f8b915e52ebc6eee)), closes [#1730](https://github.com/ruby-git/ruby-git/issues/1730)
|
|
14
|
+
* **status:** Add Git::StatusInfo and Git::StatusFileInfo and deprecate Git::Status ([b0a376b](https://github.com/ruby-git/ruby-git/commit/b0a376b19fb3ac100a11b8fa5f07b0700a6f4ce6)), closes [#1720](https://github.com/ruby-git/ruby-git/issues/1720)
|
|
15
|
+
* **tag:** Add tag_list and tag_create and deprecate the Git::Object::Tag returns ([6f9c55c](https://github.com/ruby-git/ruby-git/commit/6f9c55c7d2e845c7ec595b9db5ad8117b28e90f8)), closes [#1719](https://github.com/ruby-git/ruby-git/issues/1719)
|
|
16
|
+
* **worktree:** Add WorktreeInfo, cover every subcommand, and deprecate the legacy API ([581d6ad](https://github.com/ruby-git/ruby-git/commit/581d6ad908fb746a3b5e1726157da3d33a04bae4)), closes [#1731](https://github.com/ruby-git/ruby-git/issues/1731)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Other Changes
|
|
20
|
+
|
|
21
|
+
* **release:** Move the workflow description into comments ([a5d90bd](https://github.com/ruby-git/ruby-git/commit/a5d90bdd7b9e07859007942eb07f9b153e9c9e0a)), closes [#1734](https://github.com/ruby-git/ruby-git/issues/1734)
|
|
22
|
+
* **tag:** Add failing specs for TagInfo facade methods and Object::Tag deprecation ([749c327](https://github.com/ruby-git/ruby-git/commit/749c327bf793fd8f4b06b7a2dd1740aa977e9b57)), closes [#1719](https://github.com/ruby-git/ruby-git/issues/1719)
|
|
23
|
+
|
|
8
24
|
## [5.3.0](https://github.com/ruby-git/ruby-git/compare/v5.2.0...v5.3.0) (2026-09-03)
|
|
9
25
|
|
|
10
26
|
|
data/README.md
CHANGED
|
@@ -98,7 +98,7 @@ Clone, read status, and log:
|
|
|
98
98
|
require 'git'
|
|
99
99
|
|
|
100
100
|
repo = Git.clone('https://github.com/ruby-git/ruby-git.git', 'ruby-git')
|
|
101
|
-
repo.
|
|
101
|
+
repo.status_info.changed.each_key { |path| puts "changed: #{path}" }
|
|
102
102
|
repo.log(5).execute.each { |c| puts c.message }
|
|
103
103
|
```
|
|
104
104
|
|
data/UPGRADING.md
CHANGED
|
@@ -20,10 +20,14 @@ to update your code when upgrading from the preceding major version.
|
|
|
20
20
|
- [`Git` module mixin deprecations](#git-module-mixin-deprecations)
|
|
21
21
|
- [`Git::Author` deprecated](#gitauthor-deprecated)
|
|
22
22
|
- [`Git::Branch#stashes` deprecated](#gitbranchstashes-deprecated)
|
|
23
|
+
- [Legacy stash API deprecated](#legacy-stash-api-deprecated)
|
|
23
24
|
- [`Git::Repository#remotes` deprecated](#gitrepositoryremotes-deprecated)
|
|
24
25
|
- [`Git::Remote` deprecated](#gitremote-deprecated)
|
|
25
26
|
- [`Git::Commands::CatFile::Raw` `allow_unknown_type` option deprecated](#gitcommandscatfileraw-allow_unknown_type-option-deprecated)
|
|
26
27
|
- [`Git::Branch` and `Git::Branches` deprecated](#gitbranch-and-gitbranches-deprecated)
|
|
28
|
+
- [`Git::Object::Tag` deprecated](#gitobjecttag-deprecated)
|
|
29
|
+
- [`Git::Status` deprecated](#gitstatus-deprecated)
|
|
30
|
+
- [`Git::Worktree` and `Git::Worktrees` deprecated](#gitworktree-and-gitworktrees-deprecated)
|
|
27
31
|
|
|
28
32
|
## Upgrading to v6.0.0
|
|
29
33
|
|
|
@@ -234,7 +238,7 @@ to the replacement shown to silence it.
|
|
|
234
238
|
| `g.lib.config_list` | `g.config_list` — returns `Array<Git::ConfigEntryInfo>` |
|
|
235
239
|
| `g.lib.config_set(name, value)` | `g.config_set(name, value)` |
|
|
236
240
|
| `g.lib.git_version` | `g.git_version` |
|
|
237
|
-
| `g.lib.stash_list` | `g.
|
|
241
|
+
| `g.lib.stash_list` | `g.stash_infos` — returns `Array<Git::StashInfo>`, newest first |
|
|
238
242
|
| `g.lib.unmerged` | `g.unmerged` |
|
|
239
243
|
| `g.lib.change_head_branch(name)` | `g.change_head_branch(name)` |
|
|
240
244
|
| `g.lib.ls_remote(location, opts)` | `g.ls_remote(location, opts)` |
|
|
@@ -266,7 +270,7 @@ shim cannot forward them). Update call sites directly:
|
|
|
266
270
|
|
|
267
271
|
| v4.x call | Notes |
|
|
268
272
|
|-----------|-------|
|
|
269
|
-
| `g.lib.list_files(ref_dir)` | Walked `.git/refs/` directly. Use `g.branch_list`, `g.
|
|
273
|
+
| `g.lib.list_files(ref_dir)` | Walked `.git/refs/` directly. Use `g.branch_list`, `g.tag_list`, or `g.remote_list` instead. |
|
|
270
274
|
|
|
271
275
|
##### Internal plumbing methods (no replacement)
|
|
272
276
|
|
|
@@ -372,7 +376,7 @@ purpose-named methods.
|
|
|
372
376
|
| `g.global_config` | `g.config_list(global: true)` |
|
|
373
377
|
| `g.global_config(name, value)` | `g.config_set(name, value, global: true)` |
|
|
374
378
|
| `g.parse_config(file)` | `g.config_list(file: file)` |
|
|
375
|
-
| `g.stash_list` | `g.
|
|
379
|
+
| `g.stash_list` | `g.stash_infos` — returns `Array<Git::StashInfo>`; see [Legacy stash API deprecated](#legacy-stash-api-deprecated) |
|
|
376
380
|
|
|
377
381
|
#### `Git` module mixin deprecations
|
|
378
382
|
|
|
@@ -413,34 +417,97 @@ Constructing `Git::Author` directly emits a deprecation warning naming
|
|
|
413
417
|
|
|
414
418
|
`Git::Branch#stashes` ignores the branch it is called on and returns every stash
|
|
415
419
|
in the repository, so `g.branch('feature').stashes` and `g.branch('main').stashes`
|
|
416
|
-
return the same entries. Call `Git::Repository#
|
|
420
|
+
return the same entries. Call `Git::Repository#stash_infos` instead; it is the
|
|
417
421
|
query `Git::Branch#stashes` was already running.
|
|
418
422
|
|
|
419
423
|
> **Return type change:** `Git::Branch#stashes` returns a `Git::Stashes`
|
|
420
|
-
> collection of `Git::Stash` objects
|
|
421
|
-
>
|
|
422
|
-
>
|
|
423
|
-
>
|
|
424
|
-
> `Git::
|
|
425
|
-
> first.
|
|
424
|
+
> collection of `Git::Stash` objects. `g.stash_infos` returns an array of
|
|
425
|
+
> `Git::StashInfo` values. Both are newest first, so indexes carry over unchanged.
|
|
426
|
+
> `Git::Stash#message` strips the `WIP on <branch>:` or `On <branch>:` prefix;
|
|
427
|
+
> `Git::StashInfo#message` keeps the full message and exposes the branch name as
|
|
428
|
+
> `Git::StashInfo#branch`.
|
|
426
429
|
|
|
427
430
|
`Git::Stashes` also exposes `save`, `apply`, and `clear`. Those map to the
|
|
428
|
-
repository's `
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
431
|
+
repository's `stash_push`, `stash_apply`, and `stash_clear`. `Git::Stashes#apply(i)`
|
|
432
|
+
already passed `i` to git as `stash@{i}` (`0` = newest), and `g.stash_apply(i)` does
|
|
433
|
+
the same, so that index needs no conversion. The `Git::Stashes` class is deprecated
|
|
434
|
+
as well; [Legacy stash API deprecated](#legacy-stash-api-deprecated) maps each of
|
|
435
|
+
its methods.
|
|
432
436
|
|
|
433
437
|
| Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
|
|
434
438
|
|-----------------------------------------------------|-------------|
|
|
435
|
-
| `g.branch(name).stashes` | `g.
|
|
436
|
-
| `g.branch(name).stashes.each { \|s\| puts s.message }` | `g.
|
|
437
|
-
| `g.branch(name).stashes.all` | `g.
|
|
438
|
-
| `g.branch(name).stashes.size` | `g.
|
|
439
|
-
| `g.branch(name).stashes[i].message` (`0` = newest, `i` coerced with `to_i`) | `g.
|
|
440
|
-
| `g.branch(name).stashes.save(message)` | `g.
|
|
439
|
+
| `g.branch(name).stashes` | `g.stash_infos` — returns `Array<Git::StashInfo>`, newest first |
|
|
440
|
+
| `g.branch(name).stashes.each { \|s\| puts s.message }` | `g.stash_infos.each { \|info\| puts info.message }` |
|
|
441
|
+
| `g.branch(name).stashes.all` (`[index, message]` pairs, oldest first) | `g.stash_infos.reverse` — see the ordering note in [Legacy stash API deprecated](#legacy-stash-api-deprecated) |
|
|
442
|
+
| `g.branch(name).stashes.size` | `g.stash_infos.size` |
|
|
443
|
+
| `g.branch(name).stashes[i].message` (`0` = newest, `i` coerced with `to_i`) | `g.stash_infos[i.to_i].message` |
|
|
444
|
+
| `g.branch(name).stashes.save(message)` | `g.stash_push(message: message)` |
|
|
441
445
|
| `g.branch(name).stashes.apply` | `g.stash_apply` |
|
|
442
446
|
| `g.branch(name).stashes.apply(i)` (`0` = newest) | `g.stash_apply(i)` |
|
|
443
|
-
| `g.branch(name).stashes.clear` | `g.stash_clear` |
|
|
447
|
+
| `g.branch(name).stashes.clear` | `g.stash_clear` — returns git's stdout (normally `""`, which is truthy) where `Git::Stashes#clear` returned `nil` |
|
|
448
|
+
|
|
449
|
+
#### Legacy stash API deprecated
|
|
450
|
+
|
|
451
|
+
Starting in v5.4.0, the stash methods on `Git::Repository` are built around the
|
|
452
|
+
immutable `Git::StashInfo` value object. `g.stash_infos` returns every entry as a
|
|
453
|
+
`Git::StashInfo`, and `stash_push`, `stash_pop`, `stash_drop`, `stash_show`,
|
|
454
|
+
`stash_branch`, `stash_create`, and `stash_store` each map onto the `git stash`
|
|
455
|
+
subcommand of the same name. Every method that takes a stash (`stash_apply`,
|
|
456
|
+
`stash_pop`, `stash_drop`, `stash_show`, `stash_branch`) accepts a `Git::StashInfo`,
|
|
457
|
+
a `stash@{N}` name, an Integer index (`0` = newest), or `nil` for the newest entry.
|
|
458
|
+
|
|
459
|
+
The legacy methods and classes are deprecated and removed in v6.0.0:
|
|
460
|
+
`Git::Repository#stashes_all`, `Git::Repository#stash_save`,
|
|
461
|
+
`Git::Repository#stash_list`, `Git::Stash`, and `Git::Stashes`. Constructing a
|
|
462
|
+
`Git::Stash` or `Git::Stashes` emits one warning per object.
|
|
463
|
+
|
|
464
|
+
> **Ordering flip:** `g.stashes_all` returns entries **oldest first** with a
|
|
465
|
+
> sequential index of its own (`0` is the oldest). `g.stash_infos` returns entries
|
|
466
|
+
> **newest first**, the order `git stash list` uses, and `Git::StashInfo#index` is
|
|
467
|
+
> git's own `stash@{N}` number (`0` is the newest). `g.stashes_all.first` is
|
|
468
|
+
> `g.stash_infos.last`. Code that reads an entry by position must reverse the
|
|
469
|
+
> array or the index.
|
|
470
|
+
|
|
471
|
+
> **Message difference:** `g.stashes_all` strips the `WIP on <branch>:` or
|
|
472
|
+
> `On <branch>:` prefix from each message. `Git::StashInfo#message` keeps the full
|
|
473
|
+
> message git stores, and `Git::StashInfo#branch` holds the branch name. A stash
|
|
474
|
+
> created from a detached HEAD has the branch `"(no branch)"`, the label git writes
|
|
475
|
+
> in its message. `branch` is `nil` only when the message has no branch prefix at
|
|
476
|
+
> all, as for a `stash_store` entry with a custom message.
|
|
477
|
+
|
|
478
|
+
`g.stash_save(message)` returned `true` when it created a stash and `false` when
|
|
479
|
+
there were no local changes to save. `g.stash_push(message: message)` returns the
|
|
480
|
+
new `Git::StashInfo`, or `nil` when there were no local changes, so a truthiness
|
|
481
|
+
check such as `if g.stash_push(message: 'WIP')` still works.
|
|
482
|
+
|
|
483
|
+
`g.stash_list` returned the `git stash list` text as a String. Build that text from
|
|
484
|
+
`g.stash_infos` if you need it. In v6.0.0, `stash_list` returns
|
|
485
|
+
`Array<Git::StashInfo>`, the same value as `stash_infos`, and `stash_infos` stays as
|
|
486
|
+
a permanent alias. Move String callers of `stash_list` to `stash_infos` before
|
|
487
|
+
upgrading so the return type change cannot go unnoticed.
|
|
488
|
+
|
|
489
|
+
| Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
|
|
490
|
+
|-----------------------------------------------------|-------------|
|
|
491
|
+
| `g.stashes_all` | `g.stash_infos` — returns `Array<Git::StashInfo>`, newest first |
|
|
492
|
+
| `g.stashes_all.each { \|index, message\| ... }` | `g.stash_infos.reverse_each.with_index { \|info, index\| ... info.message }` |
|
|
493
|
+
| `g.stashes_all[i]` (`0` = oldest) | `g.stash_infos.reverse[i]` |
|
|
494
|
+
| `g.stashes_all.last` | `g.stash_infos.first` |
|
|
495
|
+
| `g.stash_save(message)` | `g.stash_push(message: message)` — returns `Git::StashInfo` or `nil` |
|
|
496
|
+
| `g.stash_list` (String) | `g.stash_infos.map { \|s\| "#{s.name}: #{s.message}" }.join("\n")` |
|
|
497
|
+
| `Git::Stash.new(g, message)` | `info = g.stash_push(message: message)` |
|
|
498
|
+
| `Git::Stash.new(g, message, existing: true)` | `message` — `existing: true` only wrapped the String and never looked an entry up; code that needs a real entry picks one from `g.stash_infos` by index or name |
|
|
499
|
+
| `stash.save` | `info = g.stash_push(message: message)` |
|
|
500
|
+
| `stash.saved?` | `!info.nil?` — check the value `stash_push` returned rather than pushing again |
|
|
501
|
+
| `stash.message` / `stash.to_s` | `info.message` — keeps the branch prefix; see the note above |
|
|
502
|
+
| `Git::Stashes.new(g)` | `g.stash_infos` |
|
|
503
|
+
| `stashes.all` (`[index, message]` pairs, oldest first) | `g.stash_infos.reverse` — see the ordering note above |
|
|
504
|
+
| `stashes.each { \|s\| ... }` (newest first) | `g.stash_infos.each { \|info\| ... }` |
|
|
505
|
+
| `stashes[i]` (`0` = newest, `i` coerced with `to_i`) | `g.stash_infos[i.to_i]` |
|
|
506
|
+
| `stashes.size` | `g.stash_infos.size` |
|
|
507
|
+
| `stashes.save(message)` | `g.stash_push(message: message)` |
|
|
508
|
+
| `stashes.apply` / `stashes.apply(i)` | `g.stash_apply` / `g.stash_apply(i)` |
|
|
509
|
+
| `stashes.clear` | `g.stash_clear` — returns git's stdout (normally `""`, which is truthy) where `Git::Stashes#clear` returned `nil` |
|
|
510
|
+
|
|
444
511
|
#### `Git::Repository#remotes` deprecated
|
|
445
512
|
|
|
446
513
|
`Git::Repository#remotes` is deprecated in favor of `Git::Repository#remote_list`
|
|
@@ -646,6 +713,237 @@ can resolve a local branch of that name and is only used where git expects it
|
|
|
646
713
|
| `b.update_ref(commit)` (remote-tracking) | `g.update_ref("remotes/#{remote}/#{name}", commit)` |
|
|
647
714
|
| `b.archive(file, opts)` | `g.archive(name, file, opts)` — pass `info.refname` for a remote-tracking branch |
|
|
648
715
|
| `b.in_branch(message) { ... }` | `g.in_branch(name, message) { ... }` — local `b` only; see the differences above |
|
|
649
|
-
| `b.stashes` | `g.
|
|
716
|
+
| `b.stashes` | `g.stash_infos` — see [`Git::Branch#stashes` deprecated](#gitbranchstashes-deprecated) |
|
|
717
|
+
|
|
718
|
+
#### `Git::Object::Tag` deprecated
|
|
719
|
+
|
|
720
|
+
`Git::Object::Tag`, `Git::Repository#tag`, `Git::Repository#tags`, and
|
|
721
|
+
`Git::Repository#tag_add` are deprecated and are removed in v6.0.0. Read tag data
|
|
722
|
+
through `Git::Repository#tag_list`, which returns one `Git::TagInfo` value object per
|
|
723
|
+
tag, create tags with `Git::Repository#tag_create`, which returns the new tag's
|
|
724
|
+
`Git::TagInfo`, and call the repository-level operations (`archive`, `log`, `diff`,
|
|
725
|
+
`cat_file_contents`, and so on) with the tag's object ID,
|
|
726
|
+
`info.oid || info.target_oid`, which is the object a `Git::Object::Tag` pinned when
|
|
727
|
+
it was constructed. Calling `g.tag`, `g.tags`, or
|
|
728
|
+
`g.tag_add`, and constructing a `Git::Object::Tag`, each emit one deprecation
|
|
729
|
+
warning; their return values are unchanged. `g.add_tag` already warned, pointing at
|
|
730
|
+
`g.tag_add`, and now emits two warnings for a creation call, one for itself and one
|
|
731
|
+
for the `g.tag_add` it calls; `g.add_tag(name, d: true)` emits three, adding the
|
|
732
|
+
`:d`/`:delete` warning described below. The readers on a `Git::Object::Tag` do not
|
|
733
|
+
warn.
|
|
734
|
+
|
|
735
|
+
> **Return shape change:** `Git::Object::Tag` exposes `name`, `sha`, `objectish`,
|
|
736
|
+
> `annotated?`, `message`, and `tagger`. `Git::TagInfo` exposes `name`, `oid`,
|
|
737
|
+
> `target_oid`, `objecttype`, `annotated?`, `lightweight?`, `message`, and
|
|
738
|
+
> `tagger`. `name` and `annotated?` are unchanged. `tagger` keeps the same `name`
|
|
739
|
+
> and `email`, but `tagger.date` differs: `t.tagger.date` is a `Time` in the
|
|
740
|
+
> process's local zone, while `info.tagger.date` keeps the UTC offset recorded in
|
|
741
|
+
> the tag object. Both name the same instant. `message` differs for an annotated
|
|
742
|
+
> tag created with an empty message (`message: ''`): `t.message` returns `""` and
|
|
743
|
+
> `info.message` returns `nil`, the same value a lightweight tag has. `t.sha` and
|
|
744
|
+
> `t.objectish` are the tag object's ID for an annotated tag and
|
|
745
|
+
> the tagged object's ID for a lightweight tag. `Git::TagInfo` separates the two:
|
|
746
|
+
> `oid` is the tag object's ID (`nil` for a lightweight tag) and `target_oid` is
|
|
747
|
+
> the ID of the object the tag points to (set for both kinds), so
|
|
748
|
+
> `info.oid || info.target_oid` reproduces `t.sha`. The target is usually a
|
|
749
|
+
> commit, but a tag can point at any git object, and `info.objecttype` reports
|
|
750
|
+
> which kind (`tag` for an annotated tag, or the target's own type such as
|
|
751
|
+
> `commit` or `blob` for a lightweight one).
|
|
752
|
+
>
|
|
753
|
+
> **Missing tags:** `g.tag(name)` raises `Git::UnexpectedResultError` when no tag
|
|
754
|
+
> has that name. `g.tag_list(name).first` returns `nil`.
|
|
755
|
+
>
|
|
756
|
+
> **Deleting through `tag_add`:** `g.tag_add(name, d: true)`, which was already
|
|
757
|
+
> deprecated, deletes the tag and emits a second warning pointing at
|
|
758
|
+
> `g.tag_delete`. `g.tag_create` rejects `:d` and `:delete` with `ArgumentError`.
|
|
759
|
+
>
|
|
760
|
+
> **Extra positional arguments:** `g.tag_add(name, target, extra)` ignores
|
|
761
|
+
> `extra` and tags `target`. `g.tag_create` raises `ArgumentError` when more than
|
|
762
|
+
> one positional argument follows the name.
|
|
763
|
+
>
|
|
764
|
+
> **Object identity:** every `Git::Object::Tag` resolves its tag to an object ID
|
|
765
|
+
> when it is constructed and runs `size`, `contents`, `grep`, `diff`, `log`, and
|
|
766
|
+
> `archive` against that ID, so moving or deleting the tag afterwards does not
|
|
767
|
+
> redirect an existing object. `Git::Object::Tag.new(g, sha, name)` uses the
|
|
768
|
+
> supplied `sha` as that ID; the other forms look it up from the ref. `annotated?`,
|
|
769
|
+
> `message`, and `tagger` always read the ref `name`. `Git::TagInfo` describes the
|
|
770
|
+
> ref only: `g.tag_list(name).first` returns whatever `name` points at now, or
|
|
771
|
+
> `nil` once the tag is deleted. Keep the same identity by passing `id` (see the
|
|
772
|
+
> table) rather than `name` to the operation replacements; they accept any object.
|
|
773
|
+
> To read an annotated tag object by ID without going through its ref, use
|
|
774
|
+
> `g.cat_file_tag(id)`, which returns the tag object's `object`, `type`, `tag`,
|
|
775
|
+
> `tagger`, and `message`.
|
|
776
|
+
|
|
777
|
+
In the table, `name` is the tag name, `t` is a `Git::Object::Tag`, `info` is the
|
|
778
|
+
`Git::TagInfo` that replaces it, and `id` is `info.oid || info.target_oid` (or the
|
|
779
|
+
`sha` given to the three-argument constructor), the object `t` pinned.
|
|
780
|
+
|
|
781
|
+
| Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
|
|
782
|
+
|-----------------------------------------------------|-------------|
|
|
783
|
+
| `g.tag(name)` | `g.tag_list(name).first` — a `Git::TagInfo`, or `nil` when the tag does not exist |
|
|
784
|
+
| `g.tags` | `g.tag_list` — returns `Array<Git::TagInfo>` |
|
|
785
|
+
| `g.tags.map(&:name)` | `g.tag_list.map(&:name)` |
|
|
786
|
+
| `g.tag_add(name, opts)` | `g.tag_create(name, opts)` — returns a `Git::TagInfo` |
|
|
787
|
+
| `g.tag_add(name, target, opts)` | `g.tag_create(name, target, opts)` |
|
|
788
|
+
| `g.tag_add(name, d: true)` | `g.tag_delete(name)` |
|
|
789
|
+
| `g.add_tag(name, opts)`, `g.add_tag(name, target, opts)` | `g.tag_create(name, ...)` — its warning names `g.tag_add`, which is deprecated too; go straight to `g.tag_create` |
|
|
790
|
+
| `g.add_tag(name, d: true)` | `g.tag_delete(name)` — `g.tag_create` rejects `:d`; see the deletion note above |
|
|
791
|
+
| `Git::Object::Tag.new(g, name)` | `g.tag_list(name).first` |
|
|
792
|
+
| `Git::Object::Tag.new(g, sha, name)` | `g.tag_list(name).first` — reads the ref rather than `sha`; use `sha` as `id` for the operations below, or read the object with `g.cat_file_tag(sha)`; see the object identity note above |
|
|
793
|
+
| `Git::Object.new(g, name, nil, true)` | `g.tag_list(name).first` — its warning names `Git::Object::Tag.new`, which is deprecated too |
|
|
794
|
+
| `t.name` | `info.name` |
|
|
795
|
+
| `t.sha`, `t.objectish`, `t.to_s` | `info.oid \|\| info.target_oid` — see the return shape change above |
|
|
796
|
+
| `t.annotated?` | `info.annotated?` |
|
|
797
|
+
| `t.message` | `info.message` — `nil` rather than `""` for an annotated tag with an empty message |
|
|
798
|
+
| `t.tagger` | `info.tagger` — `date` keeps the recorded UTC offset; see the return shape change above |
|
|
799
|
+
| `t.tag?` | not needed; every `Git::TagInfo` is a tag |
|
|
800
|
+
| `t.size` | `g.cat_file_size(id)` — `id` rather than `name` keeps this and the operations below on the object `t` pinned; see the object identity note above |
|
|
801
|
+
| `t.contents` | `g.cat_file_contents(id)` |
|
|
802
|
+
| `t.contents { \|file\| ... }` | `g.cat_file_contents(id) { \|file\| ... }` — streams to a temporary file instead of buffering the object |
|
|
803
|
+
| `t.contents_array` | `g.cat_file_contents(id).split("\n")` |
|
|
804
|
+
| `t.grep(string, path, opts)` | `g.grep(string, path, opts.merge(object: id))` |
|
|
805
|
+
| `t.diff(other)` | `g.diff(id, other)` |
|
|
806
|
+
| `t.log(count)` | `g.log(count).object(id)` |
|
|
807
|
+
| `t.archive(file, opts)` | `g.archive(id, file, opts)` |
|
|
808
|
+
|
|
809
|
+
#### `Git::Status` deprecated
|
|
810
|
+
|
|
811
|
+
Starting in v5.4.0, `Git::Status`, `Git::Status::StatusFile`, and
|
|
812
|
+
`Git::Repository#status` are deprecated and will be removed in v6.0.0. Read the
|
|
813
|
+
index and working tree state through `Git::Repository#status_info`, which
|
|
814
|
+
returns an immutable `Git::StatusInfo` holding one `Git::StatusFileInfo` per
|
|
815
|
+
path that `git status --porcelain=v2` reports. Calling `g.status` emits one
|
|
816
|
+
deprecation warning, and so does constructing a `Git::Status` directly.
|
|
817
|
+
|
|
818
|
+
`Git::StatusInfo` keeps the `changed`, `added`, `deleted`, and `untracked`
|
|
819
|
+
readers and the `changed?`, `added?`, `deleted?`, and `untracked?` predicates,
|
|
820
|
+
so code that only uses those can change `status` to `status_info` and needs
|
|
821
|
+
no other edit, subject to the category differences below. The readers now
|
|
822
|
+
return `Hash{String => Git::StatusFileInfo}`, and a new `unmerged` reader
|
|
823
|
+
lists conflicted paths, which `Git::Status` did not report. The predicates
|
|
824
|
+
still compare paths case-insensitively when `core.ignoreCase` is `true`.
|
|
825
|
+
`Git::StatusInfo` is not `Enumerable`; iterate `status_info.files`, an
|
|
826
|
+
`Array<Git::StatusFileInfo>` in git's output order.
|
|
827
|
+
|
|
828
|
+
The categories are derived differently. `Git::Status` gave each file one
|
|
829
|
+
`type`, and `changed` held only files whose type was `M`, so `changed`,
|
|
830
|
+
`added`, and `deleted` were disjoint: a file staged as new and then modified
|
|
831
|
+
in the working tree was only `added`. `Git::StatusInfo` derives the
|
|
832
|
+
categories from both status characters, so `changed` also includes type
|
|
833
|
+
changes (`T`), and one path can be in more than one category: that same file
|
|
834
|
+
(`AM`) is in both `added` and `changed`, and a file modified in the index and
|
|
835
|
+
then deleted from the working tree (`MD`) is in both `changed` and `deleted`.
|
|
836
|
+
Code that relied on the sets being disjoint should test `index_status` and
|
|
837
|
+
`worktree_status` directly.
|
|
838
|
+
|
|
839
|
+
`Git::StatusInfo` holds only the paths `git status` reports. `Git::Status`
|
|
840
|
+
also held an entry for every clean tracked file, seeded from `git ls-files`,
|
|
841
|
+
so `status[path]` returned a `Git::Status::StatusFile` with a `nil` type for an
|
|
842
|
+
unchanged path and `status.each` yielded one. `status_info[path]` returns `nil`
|
|
843
|
+
for a clean path and `status_info.files` omits it. Code that inspected clean
|
|
844
|
+
files should read `g.ls_files`, which still returns the index mode and SHA of
|
|
845
|
+
every tracked path.
|
|
846
|
+
|
|
847
|
+
`Git::StatusFileInfo` replaces the single `type` character with the two status
|
|
848
|
+
characters of the porcelain v2 format, `index_status` (HEAD versus index) and
|
|
849
|
+
`worktree_status` (index versus working tree), plus the `changed?`, `added?`,
|
|
850
|
+
`deleted?`, `renamed?`, `unmerged?`, `untracked?`, and `ignored?` predicates:
|
|
851
|
+
`added?` is true when `index_status` is `A`, `deleted?` when either status is
|
|
852
|
+
`D`, and `changed?` when either status is `M` or `T`. It holds no repository
|
|
853
|
+
reference, so `blob` is gone; fetch the object through the repository instead.
|
|
854
|
+
`stage` is gone too: an unmerged entry carries its stage 1, 2, and 3 modes and
|
|
855
|
+
SHAs in `unmerged_stages`, and every other entry is at stage 0.
|
|
856
|
+
|
|
857
|
+
> **Field renames:** the legacy mode and SHA readers were named for the wrong
|
|
858
|
+
> sides. `sha_index` and `mode_index` held the working-tree side of the diff:
|
|
859
|
+
> the index blob when the working tree matched the index, and an all-zero SHA
|
|
860
|
+
> when it did not. `sha_repo` and `mode_repo` held the side git compared the
|
|
861
|
+
> working tree against: the index in a repository with no commits, and HEAD
|
|
862
|
+
> once a commit exists (the factory applied `git diff-index HEAD` last). The
|
|
863
|
+
> new names follow git: `sha_head` and `mode_head` are the HEAD side,
|
|
864
|
+
> `sha_index` and `mode_index` are the index (staged) side, and
|
|
865
|
+
> `mode_worktree` is the working-tree mode. There is no working-tree SHA
|
|
866
|
+
> because `git status` does not compute one; `worktree_status` says whether
|
|
867
|
+
> the working tree differs from the index.
|
|
868
|
+
|
|
869
|
+
In the table, `g` is a `Git::Repository`, `status` is the `Git::Status` from
|
|
870
|
+
`g.status`, `file` is a `Git::Status::StatusFile`, and `info` is the
|
|
871
|
+
`Git::StatusFileInfo` that replaces it.
|
|
872
|
+
|
|
873
|
+
| Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
|
|
874
|
+
|-----------------------------------------------------|-------------|
|
|
875
|
+
| `g.status` | `g.status_info` — returns a `Git::StatusInfo` |
|
|
876
|
+
| `Git::Status.new(g)` | `g.status_info` |
|
|
877
|
+
| `status.changed`, `status.added`, `status.deleted`, `status.untracked` | same names on `g.status_info` — now `Hash{String => Git::StatusFileInfo}` keyed by path |
|
|
878
|
+
| `status.changed?(path)`, `status.added?(path)`, `status.deleted?(path)`, `status.untracked?(path)` | same names on `g.status_info` |
|
|
879
|
+
| `status[path]` | `g.status_info[path]` — a `Git::StatusFileInfo`, or `nil`; `nil` for a clean tracked path, which `status[path]` reported (see above) |
|
|
880
|
+
| `status.each { \|file\| ... }` | `g.status_info.files.each { \|info\| ... }` — does not yield clean tracked paths (see above) |
|
|
881
|
+
| `status.pretty` | no replacement; format `g.status_info.files` yourself |
|
|
882
|
+
| `file.path` | `info.path` |
|
|
883
|
+
| `file.type` | `info.index_status` and `info.worktree_status`, or the `info.changed?`, `info.added?`, and `info.deleted?` predicates |
|
|
884
|
+
| `file.untracked` | `info.untracked?` |
|
|
885
|
+
| `file.stage` | gone; `info.unmerged?` and `info.unmerged_stages` describe conflicted entries |
|
|
886
|
+
| `file.sha_repo` | `info.sha_head`, or `info.sha_index` in a repository with no commits |
|
|
887
|
+
| `file.mode_repo` | `info.mode_head`, or `info.mode_index` in a repository with no commits |
|
|
888
|
+
| `file.sha_index` | `info.sha_index` for the staged blob; `info.worktree_status` says whether the working tree differs from it |
|
|
889
|
+
| `file.mode_index` | `info.mode_worktree` |
|
|
890
|
+
| `file.blob` | `g.object(info.sha_index)` when `info.sha_index` is set and not all zeros — it is `nil` for untracked, ignored, and unmerged entries and all zeros when the path is not in the index; legacy `blob` returned `nil` without a lookup when no SHA was available and fell back to `sha_repo` when `sha_index` was `nil`. For an unmerged entry read a stage instead: `g.object(info.unmerged_stages[2][:sha])` |
|
|
891
|
+
| `file.blob(:repo)` | `g.object(info.sha_head)` when `info.sha_head` is set and not all zeros — it is `nil` for untracked, ignored, and unmerged entries and all zeros when the path is not in HEAD |
|
|
892
|
+
|
|
893
|
+
#### `Git::Worktree` and `Git::Worktrees` deprecated
|
|
894
|
+
|
|
895
|
+
`Git::Worktree`, `Git::Worktrees`, `Git::Repository#worktree`,
|
|
896
|
+
`Git::Repository#worktrees`, and `Git::Repository#worktrees_all` are deprecated
|
|
897
|
+
and are removed in v6.0.0. Read worktree data through
|
|
898
|
+
`Git::Repository#worktree_list`, which returns one `Git::WorktreeInfo` value
|
|
899
|
+
object per worktree, and call the repository-level operations (`worktree_add`,
|
|
900
|
+
`worktree_remove`, `worktree_move`, `worktree_lock`, `worktree_unlock`,
|
|
901
|
+
`worktree_repair`, and `worktree_prune`) with the worktree path or its
|
|
902
|
+
`Git::WorktreeInfo`. Return values are unchanged. Calling `g.worktree`,
|
|
903
|
+
`g.worktrees`, or `g.worktrees_all`, constructing a `Git::Worktrees`, and calling
|
|
904
|
+
`gcommit`, `add`, or `remove` on a `Git::Worktree` each emit a deprecation
|
|
905
|
+
warning; the `dir`, `full`, `to_s`, and `to_a` readers on `Git::Worktree` do not.
|
|
906
|
+
`g.worktrees` emits two warnings, one for itself and one for the `Git::Worktrees`
|
|
907
|
+
it constructs, and `g.worktree(dir).add` emits one for `g.worktree` and one for
|
|
908
|
+
`add`.
|
|
909
|
+
|
|
910
|
+
> **Return shape change:** `worktrees_all` returns `[directory, sha]` pairs and
|
|
911
|
+
> omits the main worktree of a bare repository, which has no checked-out commit.
|
|
912
|
+
> `worktree_list` returns `Git::WorktreeInfo` objects with `path`, `head`,
|
|
913
|
+
> `branch` (the full refname, such as `refs/heads/main`, or `nil` when detached
|
|
914
|
+
> or bare), `bare?`, `detached?`, `locked?` with `lock_reason`, and `prunable?`
|
|
915
|
+
> with `prune_reason`. It includes the bare main worktree, with `head` and
|
|
916
|
+
> `branch` set to `nil`. `Git::WorktreeInfo#to_s` is the path, so an entry can be
|
|
917
|
+
> passed to any method that takes a worktree path.
|
|
918
|
+
>
|
|
919
|
+
> **`gcommit` return type:** `Git::Worktree#gcommit` returned a
|
|
920
|
+
> `Git::Object::Commit` for a worktree obtained from `g.worktree(dir)` and a raw
|
|
921
|
+
> SHA `String` for one obtained from `g.worktrees`. `info.head` is always a
|
|
922
|
+
> `String` (or `nil` for a bare main worktree); call `g.gcommit(info.head)` for
|
|
923
|
+
> the commit object.
|
|
924
|
+
>
|
|
925
|
+
> **`full` and `to_s`:** `Git::Worktree#full` and `#to_s` append the commitish
|
|
926
|
+
> given at construction to the path, so entries from `g.worktrees` read
|
|
927
|
+
> `"/path/to/wt <sha>"`. `Git::WorktreeInfo#to_s` is the path alone.
|
|
928
|
+
|
|
929
|
+
In the table, `dir` is the worktree path, `wt` is a `Git::Worktree`, and `info`
|
|
930
|
+
is the `Git::WorktreeInfo` that replaces it.
|
|
931
|
+
|
|
932
|
+
| Deprecated call (works in v5.x, removed in v6.0.0) | Replacement |
|
|
933
|
+
|-----------------------------------------------------|-------------|
|
|
934
|
+
| `g.worktrees_all` | `g.worktree_list.map { \|w\| [w.path, w.head] }` — includes a bare main worktree as `[path, nil]`; add `.reject(&:bare?)` before `map` to omit it as `worktrees_all` did |
|
|
935
|
+
| `g.worktrees` | `g.worktree_list` — returns `Array<Git::WorktreeInfo>`; the deprecated call emits two warnings |
|
|
936
|
+
| `g.worktrees[dir]` | `g.worktree_list.find { \|w\| w.path == dir }` — `nil` when not found; `dir` is the path as git reports it (absolute, with symlinks resolved), as before |
|
|
937
|
+
| `g.worktrees.size` | `g.worktree_list.size` |
|
|
938
|
+
| `g.worktrees.each { \|wt\| ... }` | `g.worktree_list.each { \|info\| ... }` |
|
|
939
|
+
| `g.worktrees.to_s` | `g.worktree_list.map { \|w\| "#{w.path} #{w.head}\n" }.join` |
|
|
940
|
+
| `g.worktrees.prune` | `g.worktree_prune` |
|
|
941
|
+
| `g.worktree(dir).add` | `g.worktree_add(dir)` |
|
|
942
|
+
| `g.worktree(dir, commitish).add` | `g.worktree_add(dir, commitish)` |
|
|
943
|
+
| `g.worktree(dir).remove` | `g.worktree_remove(dir)` — or `g.worktree_remove(info)` |
|
|
944
|
+
| `wt.gcommit` | `info.head` — always a `String`, or `nil` for a bare main worktree; `g.gcommit(info.head)` for the commit object |
|
|
945
|
+
| `wt.dir` | `info.path` |
|
|
946
|
+
| `wt.full`, `wt.to_s` | `info.path` — or `"#{info.path} #{info.head}"` for the descriptor that entries from `g.worktrees` produced |
|
|
947
|
+
| `wt.to_a` | `[info.path]` |
|
|
650
948
|
|
|
651
949
|
---
|
data/lib/git/branch.rb
CHANGED
|
@@ -132,22 +132,26 @@ module Git
|
|
|
132
132
|
#
|
|
133
133
|
# The result is memoized after the first call.
|
|
134
134
|
#
|
|
135
|
-
# @example Iterate over stash entries
|
|
135
|
+
# @example Iterate over stash entries (deprecated)
|
|
136
136
|
# git.branch('main').stashes.each { |s| puts s }
|
|
137
137
|
#
|
|
138
|
+
# @example The replacement
|
|
139
|
+
# repo.stash_infos.each { |info| puts info.message }
|
|
140
|
+
#
|
|
138
141
|
# @return [Git::Stashes] the stash list
|
|
139
142
|
#
|
|
140
|
-
# @deprecated Use {Git::Repository#
|
|
143
|
+
# @deprecated Use {Git::Repository#stash_infos} instead
|
|
141
144
|
#
|
|
142
|
-
# @see Git::Repository#
|
|
145
|
+
# @see Git::Repository#stash_infos
|
|
143
146
|
#
|
|
144
147
|
def stashes
|
|
145
148
|
Git::Deprecation.warn(
|
|
146
149
|
'Git::Branch#stashes is deprecated and will be removed in v6.0.0. ' \
|
|
147
150
|
'It ignores the branch and returns all repository stashes. ' \
|
|
148
|
-
'Use Git::Repository#
|
|
151
|
+
'Use Git::Repository#stash_infos instead.'
|
|
149
152
|
)
|
|
150
|
-
|
|
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) }
|
|
151
155
|
end
|
|
152
156
|
|
|
153
157
|
# Checks out this branch, attempting to create it first if it does not already exist
|
data/lib/git/object.rb
CHANGED
|
@@ -538,6 +538,18 @@ module Git
|
|
|
538
538
|
# Annotated tags contain additional metadata such as the tagger's name, email, and
|
|
539
539
|
# the date when the tag was created, along with a message.
|
|
540
540
|
#
|
|
541
|
+
# @deprecated Use {Git::Repository::ObjectOperations#tag_list} and
|
|
542
|
+
# {Git::TagInfo} instead
|
|
543
|
+
#
|
|
544
|
+
# {Git::TagInfo} is an immutable value object carrying the tag's `name`,
|
|
545
|
+
# `oid`, `target_oid`, `annotated?`, `message`, and `tagger`. Call the
|
|
546
|
+
# corresponding {Git::Repository} method (e.g. `archive`, `log`, `diff`,
|
|
547
|
+
# `cat_file_contents`) with `info.oid || info.target_oid` for operations
|
|
548
|
+
# on a tag; that is the object this class resolves and pins at
|
|
549
|
+
# construction, so a later move of the tag does not redirect an existing
|
|
550
|
+
# object, whereas the tag name would. Constructing a `Git::Object::Tag`
|
|
551
|
+
# emits a deprecation warning.
|
|
552
|
+
#
|
|
541
553
|
class Tag < AbstractObject
|
|
542
554
|
# @return [String] the tag name
|
|
543
555
|
#
|
|
@@ -551,6 +563,13 @@ module Git
|
|
|
551
563
|
#
|
|
552
564
|
# @overload initialize(base, sha, name)
|
|
553
565
|
#
|
|
566
|
+
# `sha` is kept as the object that the inherited operations (`size`,
|
|
567
|
+
# `contents`, `grep`, `diff`, `log`, `archive`) run against; `annotated?`,
|
|
568
|
+
# `message`, and `tagger` read the ref `name`. {Git::TagInfo} describes a
|
|
569
|
+
# ref, so there is no OID-based replacement for this form: pass `sha` to
|
|
570
|
+
# the {Git::Repository} operation directly, or read the tag object with
|
|
571
|
+
# {Git::Repository::ObjectOperations#cat_file_tag}.
|
|
572
|
+
#
|
|
554
573
|
# @param base [Git::Repository] the git repository
|
|
555
574
|
#
|
|
556
575
|
# @param sha [String] the SHA of the tag object
|
|
@@ -558,12 +577,11 @@ module Git
|
|
|
558
577
|
# @param name [String] the name of the tag
|
|
559
578
|
#
|
|
560
579
|
def initialize(base, sha, name = nil)
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
580
|
+
Git::Deprecation.warn(
|
|
581
|
+
'Git::Object::Tag is deprecated and will be removed in v6.0.0. ' \
|
|
582
|
+
'Use Git::Repository#tag_list and Git::TagInfo instead.'
|
|
583
|
+
)
|
|
584
|
+
sha, name = resolve_sha_and_name(base, sha, name)
|
|
567
585
|
super(base, sha)
|
|
568
586
|
|
|
569
587
|
@name = name
|
|
@@ -609,6 +627,31 @@ module Git
|
|
|
609
627
|
|
|
610
628
|
private
|
|
611
629
|
|
|
630
|
+
# Resolves the two-argument constructor form to a SHA and a tag name
|
|
631
|
+
#
|
|
632
|
+
# In the two-argument form `sha` carries the tag name and the SHA is
|
|
633
|
+
# looked up from the repository.
|
|
634
|
+
#
|
|
635
|
+
# @param base [Git::Repository] the git repository
|
|
636
|
+
#
|
|
637
|
+
# @param sha [String] the SHA of the tag object, or the tag name in the
|
|
638
|
+
# two-argument form
|
|
639
|
+
#
|
|
640
|
+
# @param name [String, nil] the tag name, or `nil` in the two-argument form
|
|
641
|
+
#
|
|
642
|
+
# @return [Array(String, String)] the resolved `[sha, name]` pair
|
|
643
|
+
#
|
|
644
|
+
# @raise [Git::UnexpectedResultError] if the tag does not exist
|
|
645
|
+
#
|
|
646
|
+
def resolve_sha_and_name(base, sha, name)
|
|
647
|
+
return [sha, name] unless name.nil?
|
|
648
|
+
|
|
649
|
+
resolved = base.tag_sha(sha)
|
|
650
|
+
raise Git::UnexpectedResultError, "Tag '#{sha}' does not exist." if resolved == ''
|
|
651
|
+
|
|
652
|
+
[resolved, sha]
|
|
653
|
+
end
|
|
654
|
+
|
|
612
655
|
# Loads annotated tag data when available
|
|
613
656
|
#
|
|
614
657
|
# @return [void]
|
|
@@ -663,14 +706,19 @@ module Git
|
|
|
663
706
|
#
|
|
664
707
|
# @return [Git::Object::Tag] the tag object wrapper
|
|
665
708
|
#
|
|
666
|
-
# @deprecated
|
|
709
|
+
# @deprecated Use {Git::Repository::ObjectOperations#tag_list} instead
|
|
710
|
+
#
|
|
711
|
+
# The warning names `Git::Object::Tag.new`, the replacement this path
|
|
712
|
+
# shipped with, and the {Git::Object::Tag} constructor is deprecated as
|
|
713
|
+
# well; this method silences it so one call emits one warning. Go
|
|
714
|
+
# straight to `Git::Repository#tag_list(name).first`.
|
|
667
715
|
#
|
|
668
716
|
private_class_method def self.new_tag(base, objectish)
|
|
669
717
|
Git::Deprecation.warn(
|
|
670
718
|
'Git::Object.new with is_tag argument is deprecated and will be removed in v6.0.0. ' \
|
|
671
719
|
'Use Git::Object::Tag.new instead.'
|
|
672
720
|
)
|
|
673
|
-
Git::Object::Tag.new(base, objectish)
|
|
721
|
+
Git::Deprecation.silence { Git::Object::Tag.new(base, objectish) }
|
|
674
722
|
end
|
|
675
723
|
|
|
676
724
|
# Returns the repository used for object lookup
|