git 5.5.0 → 5.6.1
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 +24 -0
- data/README.md +35 -5
- data/UPGRADING.md +75 -19
- data/lib/git/errors.rb +14 -2
- data/lib/git/repository/context_helpers.rb +81 -14
- data/lib/git/repository/object_operations.rb +12 -2
- data/lib/git/repository/worktree_operations.rb +8 -0
- data/lib/git/version.rb +1 -1
- data/lib/git.rb +9 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8ec4da3066f7c301611783c89f0a127f6c8ad4e7cf2467db9fe9071b7e0f943
|
|
4
|
+
data.tar.gz: 10fc3f33082886e7ca47e1ea97bd50075ffb15afbb91e1b309d9a12168a590ac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 91e896c14c04e2135468d70031721cfbb29ba873284160f208315025bacc331a0fefaa04c837467d33b284253a04267ee8f4c003ea564770d619f9365ecb1b73
|
|
7
|
+
data.tar.gz: 03c6e84729ce4a4e6809cf53b92a6bcfb48572f1b8724e83cc451e829d1357b93da286e8fd6c669ddce3aa946cb0890237008992b9230e8cf41991e291fb8f76
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@
|
|
|
5
5
|
|
|
6
6
|
# Change Log
|
|
7
7
|
|
|
8
|
+
## [5.6.1](https://github.com/ruby-git/ruby-git/compare/v5.6.0...v5.6.1) (2026-09-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Other Changes
|
|
12
|
+
|
|
13
|
+
* **errors:** Document that filesystem and gzip errors can escape unconverted ([0b171e4](https://github.com/ruby-git/ruby-git/commit/0b171e42713a884354a84138696102f8e3cd83e5)), closes [#1809](https://github.com/ruby-git/ruby-git/issues/1809)
|
|
14
|
+
* **remote:** Correct the argument forms in the Git::Remote and Git::Branch entries ([cea622a](https://github.com/ruby-git/ruby-git/commit/cea622a14cce54a90c2203953a457b13b298aa22)), closes [#1852](https://github.com/ruby-git/ruby-git/issues/1852)
|
|
15
|
+
* **tag:** Note that tag_create raises UnexpectedResultError in v6.0.0 ([050aa44](https://github.com/ruby-git/ruby-git/commit/050aa443136156d7ecab47ad6fb44f436d9c2b7f)), closes [#1856](https://github.com/ruby-git/ruby-git/issues/1856)
|
|
16
|
+
* **worktree:** Look the new worktree up with File.identical? in the v5.x note ([0c941ec](https://github.com/ruby-git/ruby-git/commit/0c941ec34204ef5c3aeb6cf1de9e61f33212a0d9))
|
|
17
|
+
* **worktree:** Look the new worktree up with File.identical? in the YARD note ([8eb10ec](https://github.com/ruby-git/ruby-git/commit/8eb10eccb50ff14911e09033cfeec33666ce5c6a)), closes [#1845](https://github.com/ruby-git/ruby-git/issues/1845)
|
|
18
|
+
* **worktree:** Note that worktree_add returns Git::WorktreeInfo in v6.0.0 ([24af07e](https://github.com/ruby-git/ruby-git/commit/24af07e24199303727d823804063732fcaa98c98)), closes [#1845](https://github.com/ruby-git/ruby-git/issues/1845)
|
|
19
|
+
|
|
20
|
+
## [5.6.0](https://github.com/ruby-git/ruby-git/compare/v5.5.0...v5.6.0) (2026-09-12)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* **repository:** Deprecate with_* context helper blocks that declare no parameter ([231b65c](https://github.com/ruby-git/ruby-git/commit/231b65c435e9b3d9cdbf8b113b3aba9313da5110)), closes [#1835](https://github.com/ruby-git/ruby-git/issues/1835)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Other Changes
|
|
29
|
+
|
|
30
|
+
* **export:** Describe what a failed .git removal leaves behind ([bd08096](https://github.com/ruby-git/ruby-git/commit/bd080964e44a11594202726e3823a8cafad62bd5)), closes [#1823](https://github.com/ruby-git/ruby-git/issues/1823)
|
|
31
|
+
|
|
8
32
|
## [5.5.0](https://github.com/ruby-git/ruby-git/compare/v5.4.1...v5.5.0) (2026-09-10)
|
|
9
33
|
|
|
10
34
|
|
data/README.md
CHANGED
|
@@ -201,11 +201,41 @@ the full API of its result.
|
|
|
201
201
|
|
|
202
202
|
## Errors raised by this gem
|
|
203
203
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
204
|
+
Errors the git gem raises deliberately are either `ArgumentError` or a subclass of
|
|
205
|
+
`Git::Error`, with one exception: with the `raise` behavior described under
|
|
206
|
+
[Deprecations](#deprecations), a deprecated call raises
|
|
207
|
+
`ActiveSupport::DeprecationException`, which is intentionally not a `Git::Error` so a
|
|
208
|
+
broad rescue cannot hide a deprecation your code opted to treat as fatal. The errors
|
|
209
|
+
described below come from Ruby's standard library and are not converted.
|
|
210
|
+
|
|
211
|
+
The gem's own filesystem operations, such as reading a `.git` pointer file,
|
|
212
|
+
creating a temporary file, or changing directory, do not convert operating system
|
|
213
|
+
errors. These can be raised as a bare `SystemCallError` (for example `Errno::ENOENT`
|
|
214
|
+
or `Errno::EACCES`) rather than `Git::Error`. Gzip compression in `archive` can
|
|
215
|
+
likewise raise a `Zlib::Error`. Rescue `SystemCallError` and `Zlib::Error` alongside
|
|
216
|
+
`Git::Error` if your code needs to handle them.
|
|
217
|
+
|
|
218
|
+
The affected methods are `Git.open` when the `.git` file is a gitdir pointer or the
|
|
219
|
+
path is relative, `Git.init`, `Git.bare`, and `Git.clone` when the path is relative,
|
|
220
|
+
`Git.export`, and these `Git::Repository` methods: `#chdir`, `#with_index`,
|
|
221
|
+
`#with_working`, `#with_temp_index`, `#with_temp_working`, `#set_index`,
|
|
222
|
+
`#set_working`, `#cat_file_contents` in block form, `#each_conflict`, `#conflicts`,
|
|
223
|
+
`#archive` (including the gzip step), `#repo_size`, and `#tag_sha` when it reads a
|
|
224
|
+
loose ref.
|
|
225
|
+
|
|
226
|
+
Any method that captures git output can also raise
|
|
227
|
+
`Encoding::ConverterNotFoundError` when the output contains a line whose detected
|
|
228
|
+
encoding, such as UTF-7, has no Ruby converter.
|
|
229
|
+
|
|
230
|
+
Starting with v6.0.0, the filesystem and gzip errors are raised as `Git::Error`
|
|
231
|
+
with the original error available through `cause`, except that `#tag_sha` falls
|
|
232
|
+
back to `git show-ref` instead of raising. Lines with no Ruby converter are
|
|
233
|
+
scrubbed instead of raising.
|
|
234
|
+
|
|
235
|
+
Rescue `Git::Error` to catch the runtime errors this gem raises itself, and add
|
|
236
|
+
`SystemCallError`, `Zlib::Error`, and `Encoding::ConverterNotFoundError` where the
|
|
237
|
+
paragraphs above say they can escape. Rescue a more specific subclass when you need
|
|
238
|
+
finer-grained handling.
|
|
209
239
|
|
|
210
240
|
```ruby
|
|
211
241
|
begin
|
data/UPGRADING.md
CHANGED
|
@@ -35,6 +35,7 @@ to update your code when upgrading from the preceding major version.
|
|
|
35
35
|
- [`Git::Log` Enumerable interface deprecated](#gitlog-enumerable-interface-deprecated)
|
|
36
36
|
- [`Git::Object::Commit#set_commit` deprecated](#gitobjectcommitset_commit-deprecated)
|
|
37
37
|
- [`Git.export` `:remote` option deprecated](#gitexport-remote-option-deprecated)
|
|
38
|
+
- [Context helper blocks that declare no parameter deprecated](#context-helper-blocks-that-declare-no-parameter-deprecated)
|
|
38
39
|
|
|
39
40
|
## Upgrading to v6.0.0
|
|
40
41
|
|
|
@@ -636,7 +637,8 @@ with N remotes produces N + 1 warnings per call.
|
|
|
636
637
|
> the last one configured, so use `r.url.last` to reproduce that exact value.
|
|
637
638
|
> Likewise, `Git::Remote#fetch_opts` returned only the last configured fetch
|
|
638
639
|
> refspec, while `fetch` holds all of them. Operations that lived on
|
|
639
|
-
> `Git::Remote` are called on the repository
|
|
640
|
+
> `Git::Remote` are called on the repository instead; the table below shows
|
|
641
|
+
> the argument each one takes.
|
|
640
642
|
>
|
|
641
643
|
> **Order change:** `remotes` lists remotes in the order `git remote` prints
|
|
642
644
|
> them, while `remote_list` keeps the order in which remotes first appear in the
|
|
@@ -655,8 +657,8 @@ with N remotes produces N + 1 warnings per call.
|
|
|
655
657
|
| `remote.fetch(opts)` | `g.fetch(remote.name, opts)` — same options hash |
|
|
656
658
|
| `remote.merge` | `g.merge("#{remote.name}/#{g.current_branch}")` |
|
|
657
659
|
| `remote.merge(branch)` | `g.merge("#{remote.name}/#{branch}")` |
|
|
658
|
-
| `remote.branch` | `g.branch_list("#{remote.name}/#{g.current_branch}").
|
|
659
|
-
| `remote.branch(name)` | `g.branch_list("#{remote.name}/#{name}").
|
|
660
|
+
| `remote.branch` | `g.branch_list("#{remote.name}/#{g.current_branch}").find(&:remote?)` — returns a `Git::BranchInfo` |
|
|
661
|
+
| `remote.branch(name)` | `g.branch_list("#{remote.name}/#{name}").find(&:remote?)` — returns a `Git::BranchInfo` |
|
|
660
662
|
| `remote.remove` | `g.remote_remove(remote.name)` |
|
|
661
663
|
|
|
662
664
|
#### `Git::Remote` deprecated
|
|
@@ -664,13 +666,13 @@ with N remotes produces N + 1 warnings per call.
|
|
|
664
666
|
`Git::Remote`, `Git::Repository#remote`, and `Git::Repository#config_remote` are
|
|
665
667
|
deprecated and are removed in v6.0.0. Read a remote's configuration through
|
|
666
668
|
`Git::Repository#remote_list`, which returns one `Git::RemoteInfo` value object per
|
|
667
|
-
remote
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
`
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
669
|
+
remote; the table below shows the replacement for each operation. Return values
|
|
670
|
+
are unchanged. Constructing a `Git::Remote` directly emits one deprecation warning,
|
|
671
|
+
and so does calling `g.config_remote`. Calling `g.remote` emits two: one for
|
|
672
|
+
`Git::Repository#remote` and one for the `Git::Remote` it constructs. Likewise
|
|
673
|
+
`g.remotes` emits one warning for itself plus one per `Git::Remote` it returns
|
|
674
|
+
(N + 1 for N remotes). The extra warnings from `g.remote` and `g.remotes` are
|
|
675
|
+
expected, not a bug.
|
|
674
676
|
|
|
675
677
|
> **Return type changes:** `Git::RemoteInfo#url` and `Git::RemoteInfo#fetch` are
|
|
676
678
|
> frozen `Array<String>` because a remote may carry more than one URL or fetch
|
|
@@ -685,8 +687,9 @@ warnings from `g.remote` and `g.remotes` are expected, not a bug.
|
|
|
685
687
|
> Code that reads custom keys should filter `g.config_list` instead (see the
|
|
686
688
|
> table); that yields the same `Hash{String => String}` as `config_remote`.
|
|
687
689
|
> `Git::Remote#branch` returned a `Git::Branch`. Its replacement,
|
|
688
|
-
> `g.branch_list("#{name}/#{branch}").
|
|
689
|
-
> object, or `nil` when the remote-tracking branch does
|
|
690
|
+
> `g.branch_list("#{name}/#{branch}").find(&:remote?)`, returns a
|
|
691
|
+
> `Git::BranchInfo` value object, or `nil` when the remote-tracking branch does
|
|
692
|
+
> not exist.
|
|
690
693
|
|
|
691
694
|
In the table, `name` is the remote name (`g.remote` defaults it to `'origin'`).
|
|
692
695
|
|
|
@@ -703,8 +706,8 @@ In the table, `name` is the remote name (`g.remote` defaults it to `'origin'`).
|
|
|
703
706
|
| `remote.fetch(opts)` | `g.fetch(name, opts)` — same option keys |
|
|
704
707
|
| `remote.merge` | `g.merge("#{name}/#{g.current_branch}")` |
|
|
705
708
|
| `remote.merge(branch)` | `g.merge("#{name}/#{branch}")` |
|
|
706
|
-
| `remote.branch` | `g.branch_list("#{name}/#{g.current_branch}").
|
|
707
|
-
| `remote.branch(branch)` | `g.branch_list("#{name}/#{branch}").
|
|
709
|
+
| `remote.branch` | `g.branch_list("#{name}/#{g.current_branch}").find(&:remote?)` — returns a `Git::BranchInfo` |
|
|
710
|
+
| `remote.branch(branch)` | `g.branch_list("#{name}/#{branch}").find(&:remote?)` — returns a `Git::BranchInfo` |
|
|
708
711
|
| `remote.remove` | `g.remote_remove(name)` |
|
|
709
712
|
|
|
710
713
|
#### `Git::Commands::CatFile::Raw` `allow_unknown_type` option deprecated
|
|
@@ -734,10 +737,12 @@ that constructs the command class directly is affected.
|
|
|
734
737
|
data through `Git::Repository#branch_list`, which returns one `Git::BranchInfo`
|
|
735
738
|
value object per local and remote-tracking branch, and call the repository-level
|
|
736
739
|
operations (`checkout`, `branch_new`, `branch_delete`, `merge`, `merge_into`,
|
|
737
|
-
`in_branch`, and so on) with the branch name.
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
740
|
+
`in_branch`, and so on) with the branch name. For a remote-tracking branch the
|
|
741
|
+
argument differs by operation; the table below shows the form each one takes.
|
|
742
|
+
Calling `g.branch` or `g.branches`, constructing a `Git::Branches`, and calling
|
|
743
|
+
any operation on a `Git::Branch` each emit a deprecation warning; their return
|
|
744
|
+
values are unchanged. The `full`, `name`, `remote`, `to_s`, and `to_a` readers
|
|
745
|
+
on `Git::Branch` do not warn.
|
|
741
746
|
|
|
742
747
|
> **Return shape change:** `Git::Branch` exposes `full` (`main` or
|
|
743
748
|
> `remotes/origin/main`), `name`, and `remote` (a `Git::Remote`, or `nil`).
|
|
@@ -862,6 +867,13 @@ warn.
|
|
|
862
867
|
> **Missing tags:** `g.tag(name)` raises `Git::UnexpectedResultError` when no tag
|
|
863
868
|
> has that name. `g.tag_list(name).first` returns `nil`.
|
|
864
869
|
>
|
|
870
|
+
> **`tag_create` when the new tag is missing in v6.0.0:** on v5.x, `g.tag_create`
|
|
871
|
+
> returns `nil` when the tag it has just created is missing from the tag list
|
|
872
|
+
> (for example, another process deleted it before the lookup). In v6.0.0 it
|
|
873
|
+
> raises `Git::UnexpectedResultError` instead, so its return value is always a
|
|
874
|
+
> `Git::TagInfo`. A `nil` check on the result keeps working today and becomes
|
|
875
|
+
> unreachable in v6.0.0.
|
|
876
|
+
>
|
|
865
877
|
> **Deleting through `tag_add`:** `g.tag_add(name, d: true)`, which was already
|
|
866
878
|
> deprecated, deletes the tag and emits a second warning pointing at
|
|
867
879
|
> `g.tag_delete`. `g.tag_create` rejects `:d` and `:delete` with `ArgumentError`.
|
|
@@ -1008,7 +1020,7 @@ and are removed in v6.0.0. Read worktree data through
|
|
|
1008
1020
|
object per worktree, and call the repository-level operations (`worktree_add`,
|
|
1009
1021
|
`worktree_remove`, `worktree_move`, `worktree_lock`, `worktree_unlock`,
|
|
1010
1022
|
`worktree_repair`, and `worktree_prune`) with the worktree path or its
|
|
1011
|
-
`Git::WorktreeInfo`. Return values are unchanged. Calling `g.worktree`,
|
|
1023
|
+
`Git::WorktreeInfo`. Return values are unchanged on v5.x. Calling `g.worktree`,
|
|
1012
1024
|
`g.worktrees`, or `g.worktrees_all`, constructing a `Git::Worktrees`, and calling
|
|
1013
1025
|
`gcommit`, `add`, or `remove` on a `Git::Worktree` each emit a deprecation
|
|
1014
1026
|
warning; the `dir`, `full`, `to_s`, and `to_a` readers on `Git::Worktree` do not.
|
|
@@ -1034,6 +1046,14 @@ it constructs, and `g.worktree(dir).add` emits one for `g.worktree` and one for
|
|
|
1034
1046
|
> **`full` and `to_s`:** `Git::Worktree#full` and `#to_s` append the commitish
|
|
1035
1047
|
> given at construction to the path, so entries from `g.worktrees` read
|
|
1036
1048
|
> `"/path/to/wt <sha>"`. `Git::WorktreeInfo#to_s` is the path alone.
|
|
1049
|
+
>
|
|
1050
|
+
> **`worktree_add` return type in v6.0.0:** on v5.x, `worktree_add` returns the
|
|
1051
|
+
> `git worktree add` output (`"HEAD is now at …"`). In v6.0.0 it returns the new
|
|
1052
|
+
> `Git::WorktreeInfo` instead. To get the entry today, look it up after the add:
|
|
1053
|
+
> `g.worktree_list.find { |w| File.identical?(w.path, dir) }`. Compare with
|
|
1054
|
+
> `File.identical?`, not string equality: git stores worktree paths with
|
|
1055
|
+
> symlinks resolved, so `/tmp/...` on macOS is listed as `/private/tmp/...`,
|
|
1056
|
+
> and on case-insensitive filesystems the listed casing may differ from `dir`.
|
|
1037
1057
|
|
|
1038
1058
|
In the table, `dir` is the worktree path, `wt` is a `Git::Worktree`, and `info`
|
|
1039
1059
|
is the `Git::WorktreeInfo` that replaces it.
|
|
@@ -1135,4 +1155,40 @@ observable in the result. Delete the option from the call.
|
|
|
1135
1155
|
|--------------------------------------------------------------------|-------------|
|
|
1136
1156
|
| `Git.export(url, dir, remote: name)` | `Git.export(url, dir)` |
|
|
1137
1157
|
|
|
1158
|
+
#### Context helper blocks that declare no parameter deprecated
|
|
1159
|
+
|
|
1160
|
+
`Git::Repository#with_index`, `#with_temp_index`, `#with_working`, and
|
|
1161
|
+
`#with_temp_working` yield `self` in v5.x, so a block could ignore the yielded
|
|
1162
|
+
value and call methods on the receiver. Calling one of these helpers with a block
|
|
1163
|
+
that declares no positional parameter (`do ... end`, `{ }`, `{ || }`, or a block
|
|
1164
|
+
with only keyword or block parameters) now emits a deprecation warning. The
|
|
1165
|
+
behavior is otherwise unchanged: the helpers still yield `self`, and a call with
|
|
1166
|
+
no block still raises `LocalJumpError`.
|
|
1167
|
+
|
|
1168
|
+
In v6.0.0 these helpers yield a separate repository bound to the other index or
|
|
1169
|
+
working tree instead of rebinding the receiver, and they raise `ArgumentError` for
|
|
1170
|
+
a block that declares no positional parameter. A call with no block also raises
|
|
1171
|
+
`ArgumentError` in v6.0.0 instead of `LocalJumpError`. Declare a block parameter
|
|
1172
|
+
and call methods on it. The parameter is required even when the block never uses
|
|
1173
|
+
the repository, for example a `with_temp_working` block that only writes files
|
|
1174
|
+
(`do |_scratch|`). Blocks that already declare a positional parameter (`|repo|`,
|
|
1175
|
+
`|_|`, `|repo = nil|`, `|*args|`, or a symbol-to-proc such as `&:write_tree`) do
|
|
1176
|
+
not warn. Both versions read the block's parameter list rather than its arity, so
|
|
1177
|
+
the v5.x warning and the v6.0.0 error agree on every block form.
|
|
1178
|
+
|
|
1179
|
+
The warning detects only the block's parameter list. Adding an unused parameter
|
|
1180
|
+
(`|_|`) silences it but does not fix a block that still calls methods on the outer
|
|
1181
|
+
repository; that block does not warn and acts on the wrong repository in v6.0.0,
|
|
1182
|
+
so review those blocks by hand.
|
|
1183
|
+
|
|
1184
|
+
| Deprecated call (works in v5.x, raises in v6.0.0) | Replacement |
|
|
1185
|
+
|---------------------------------------------------|-------------|
|
|
1186
|
+
| `g.with_index(path) { g.read_tree('HEAD') }` | `g.with_index(path) { \|r\| r.read_tree('HEAD') }` |
|
|
1187
|
+
| `g.with_temp_index { g.read_tree('HEAD') }` | `g.with_temp_index { \|r\| r.read_tree('HEAD') }` |
|
|
1188
|
+
| `g.with_working(dir) { g.add('.') }` | `g.with_working(dir) { \|r\| r.add('.') }` |
|
|
1189
|
+
| `g.with_temp_working { g.add('.') }` | `g.with_temp_working { \|r\| r.add('.') }` |
|
|
1190
|
+
|
|
1191
|
+
`chdir` is not part of this deprecation. It yields the directory path in both
|
|
1192
|
+
versions.
|
|
1193
|
+
|
|
1138
1194
|
---
|
data/lib/git/errors.rb
CHANGED
|
@@ -5,8 +5,20 @@ module Git
|
|
|
5
5
|
|
|
6
6
|
# Base class for all custom git module errors
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
# `Git::Error`.
|
|
8
|
+
# Errors the git gem raises deliberately are either `ArgumentError` or a subclass
|
|
9
|
+
# of `Git::Error`. The exceptions described below come from Ruby's standard
|
|
10
|
+
# library and are not converted.
|
|
11
|
+
#
|
|
12
|
+
# The gem's own filesystem operations, such as reading a `.git` pointer file,
|
|
13
|
+
# creating a temporary file, or changing directory, do not convert operating
|
|
14
|
+
# system errors. These can be raised as a bare `SystemCallError` (for example
|
|
15
|
+
# `Errno::ENOENT` or `Errno::EACCES`) rather than `Git::Error`. Gzip compression
|
|
16
|
+
# in `archive` can likewise raise a `Zlib::Error`. Rescue `SystemCallError` and
|
|
17
|
+
# `Zlib::Error` alongside `Git::Error` if your code needs to handle them. Any
|
|
18
|
+
# method that captures git output can also raise
|
|
19
|
+
# `Encoding::ConverterNotFoundError` when a line's detected encoding has no Ruby
|
|
20
|
+
# converter. See the "Errors raised by this gem" section of the README for the
|
|
21
|
+
# affected methods.
|
|
10
22
|
#
|
|
11
23
|
# It is recommended to rescue `Git::Error` to catch any runtime error raised by
|
|
12
24
|
# this gem unless you need more specific error handling.
|
|
@@ -18,6 +18,10 @@ module Git
|
|
|
18
18
|
# @api private
|
|
19
19
|
#
|
|
20
20
|
module ContextHelpers
|
|
21
|
+
# Parameter types from `Proc#parameters` that receive a positional argument
|
|
22
|
+
CONTEXT_HELPERS_POSITIONAL_PARAMETERS = %i[req opt rest].freeze
|
|
23
|
+
private_constant :CONTEXT_HELPERS_POSITIONAL_PARAMETERS
|
|
24
|
+
|
|
21
25
|
# Changes the current working directory to the repository working directory
|
|
22
26
|
# for the duration of the block
|
|
23
27
|
#
|
|
@@ -51,9 +55,13 @@ module Git
|
|
|
51
55
|
# yields `self`, then unconditionally restores the original execution
|
|
52
56
|
# context — even if the block raises an exception.
|
|
53
57
|
#
|
|
58
|
+
# Deprecated form: a block that declares no positional parameter emits a
|
|
59
|
+
# deprecation warning, because v6.0.0 yields a separate repository
|
|
60
|
+
# instead of `self`.
|
|
61
|
+
#
|
|
54
62
|
# @example Read a tree into a custom index
|
|
55
|
-
# repo.with_index('/tmp/custom.index') do
|
|
56
|
-
#
|
|
63
|
+
# repo.with_index('/tmp/custom.index') do |r|
|
|
64
|
+
# r.read_tree('HEAD')
|
|
57
65
|
# end
|
|
58
66
|
#
|
|
59
67
|
# @param new_index [String, Pathname] path to the replacement index file
|
|
@@ -66,7 +74,8 @@ module Git
|
|
|
66
74
|
#
|
|
67
75
|
# @yieldreturn [Object] returned as the method's return value
|
|
68
76
|
#
|
|
69
|
-
def with_index(new_index) # :yields: self
|
|
77
|
+
def with_index(new_index, &block) # :yields: self
|
|
78
|
+
context_helpers_warn_if_block_declares_no_parameter(:with_index, block)
|
|
70
79
|
old_context = @execution_context
|
|
71
80
|
set_index(new_index, must_exist: false)
|
|
72
81
|
yield self
|
|
@@ -84,10 +93,14 @@ module Git
|
|
|
84
93
|
# are removed unconditionally after the block exits, even if the block
|
|
85
94
|
# raises an exception.
|
|
86
95
|
#
|
|
96
|
+
# Deprecated form: a block that declares no positional parameter emits a
|
|
97
|
+
# deprecation warning, because v6.0.0 yields a separate repository
|
|
98
|
+
# instead of `self`.
|
|
99
|
+
#
|
|
87
100
|
# @example Stage changes using a temporary index
|
|
88
|
-
# repo.with_temp_index do
|
|
89
|
-
#
|
|
90
|
-
#
|
|
101
|
+
# repo.with_temp_index do |r|
|
|
102
|
+
# r.read_tree('HEAD')
|
|
103
|
+
# r.write_tree
|
|
91
104
|
# end
|
|
92
105
|
#
|
|
93
106
|
# @return [Object] the value returned by the block
|
|
@@ -98,13 +111,17 @@ module Git
|
|
|
98
111
|
#
|
|
99
112
|
# @yieldreturn [Object] returned as the method's return value
|
|
100
113
|
#
|
|
101
|
-
def with_temp_index(&) # :yields: self
|
|
114
|
+
def with_temp_index(&block) # :yields: self
|
|
115
|
+
context_helpers_warn_if_block_declares_no_parameter(:with_temp_index, block)
|
|
102
116
|
# Use a unique temp directory so the index file path is collision-free
|
|
103
117
|
# and does not exist until git writes it. An existing empty file would
|
|
104
118
|
# be treated as a corrupt index by git.
|
|
105
119
|
temp_dir = Dir.mktmpdir('git-temp-index-')
|
|
106
120
|
begin
|
|
107
|
-
with_index
|
|
121
|
+
# The inner block declares a parameter so with_index does not warn a
|
|
122
|
+
# second time under its own name; forwarding &block would.
|
|
123
|
+
# rubocop:disable-next Style/ExplicitBlockArgument
|
|
124
|
+
with_index(File.join(temp_dir, 'index')) { |repo| yield repo }
|
|
108
125
|
ensure
|
|
109
126
|
FileUtils.remove_entry(temp_dir, true)
|
|
110
127
|
end
|
|
@@ -118,10 +135,14 @@ module Git
|
|
|
118
135
|
# `self`, then unconditionally restores the original execution context —
|
|
119
136
|
# even if the block raises an exception.
|
|
120
137
|
#
|
|
138
|
+
# Deprecated form: a block that declares no positional parameter emits a
|
|
139
|
+
# deprecation warning, because v6.0.0 yields a separate repository
|
|
140
|
+
# instead of `self`.
|
|
141
|
+
#
|
|
121
142
|
# @example Commit changes from a different worktree path
|
|
122
|
-
# repo.with_working('/path/to/worktree') do
|
|
123
|
-
#
|
|
124
|
-
#
|
|
143
|
+
# repo.with_working('/path/to/worktree') do |r|
|
|
144
|
+
# r.add('.')
|
|
145
|
+
# r.commit('chore: automated update')
|
|
125
146
|
# end
|
|
126
147
|
#
|
|
127
148
|
# @param work_dir [String, Pathname] path to the replacement working
|
|
@@ -138,7 +159,8 @@ module Git
|
|
|
138
159
|
#
|
|
139
160
|
# @yieldreturn [Object] returned as the method's return value
|
|
140
161
|
#
|
|
141
|
-
def with_working(work_dir) # :yields: self
|
|
162
|
+
def with_working(work_dir, &block) # :yields: self
|
|
163
|
+
context_helpers_warn_if_block_declares_no_parameter(:with_working, block)
|
|
142
164
|
old_context = @execution_context
|
|
143
165
|
set_working(work_dir)
|
|
144
166
|
Dir.chdir(dir.to_s) { yield self }
|
|
@@ -153,9 +175,14 @@ module Git
|
|
|
153
175
|
# The temporary directory is removed unconditionally after the block
|
|
154
176
|
# exits, even if the block raises an exception.
|
|
155
177
|
#
|
|
178
|
+
# Deprecated form: a block that declares no positional parameter emits a
|
|
179
|
+
# deprecation warning, because v6.0.0 yields a separate repository
|
|
180
|
+
# instead of `self`.
|
|
181
|
+
#
|
|
156
182
|
# @example Write files in an isolated temporary working directory
|
|
157
|
-
# repo.with_temp_working do
|
|
183
|
+
# repo.with_temp_working do |r|
|
|
158
184
|
# File.write('scratch.txt', 'temporary content')
|
|
185
|
+
# r.add('scratch.txt')
|
|
159
186
|
# end
|
|
160
187
|
#
|
|
161
188
|
# @return [Object] the value returned by the block
|
|
@@ -168,7 +195,11 @@ module Git
|
|
|
168
195
|
# @yieldreturn [Object] returned as the method's return value
|
|
169
196
|
#
|
|
170
197
|
def with_temp_working(&block) # :yields: self
|
|
171
|
-
|
|
198
|
+
context_helpers_warn_if_block_declares_no_parameter(:with_temp_working, block)
|
|
199
|
+
# The inner block declares a parameter so with_working does not warn a
|
|
200
|
+
# second time under its own name; forwarding &block would.
|
|
201
|
+
# rubocop:disable-next Style/ExplicitBlockArgument
|
|
202
|
+
Dir.mktmpdir('temp-workdir') { |temp_dir| with_working(temp_dir) { |repo| yield repo } }
|
|
172
203
|
end
|
|
173
204
|
|
|
174
205
|
# Sets the git index to `index_file` and rebuilds the execution context
|
|
@@ -231,6 +262,42 @@ module Git
|
|
|
231
262
|
|
|
232
263
|
private
|
|
233
264
|
|
|
265
|
+
# Emits a deprecation warning when `block` declares no positional parameter
|
|
266
|
+
#
|
|
267
|
+
# In v6.0.0 the `with_*` helpers yield a separate repository instead of
|
|
268
|
+
# rebinding the receiver, so a block that calls methods on the receiver
|
|
269
|
+
# (the v5.x form) acts on the wrong repository there. v6.0.0 raises
|
|
270
|
+
# `ArgumentError` for that form using this same rule: the block must
|
|
271
|
+
# declare a required, optional, or splat positional parameter. The rule
|
|
272
|
+
# reads `Proc#parameters` rather than arity because an optional parameter
|
|
273
|
+
# gives a proc an arity of zero although it receives the repository,
|
|
274
|
+
# while keyword and block parameters cannot receive it.
|
|
275
|
+
#
|
|
276
|
+
# A missing block is not checked here; the helper's `yield` raises
|
|
277
|
+
# `LocalJumpError` as before.
|
|
278
|
+
#
|
|
279
|
+
# The warning reports the helper's caller, not this helper's caller, so
|
|
280
|
+
# the location points at the block that needs changing.
|
|
281
|
+
#
|
|
282
|
+
# @param helper [Symbol] the public helper name used in the warning
|
|
283
|
+
#
|
|
284
|
+
# @param block [Proc, nil] the block passed to the helper
|
|
285
|
+
#
|
|
286
|
+
# @return [void]
|
|
287
|
+
#
|
|
288
|
+
def context_helpers_warn_if_block_declares_no_parameter(helper, block)
|
|
289
|
+
return if block.nil?
|
|
290
|
+
return if block.parameters.any? { |type, _name| CONTEXT_HELPERS_POSITIONAL_PARAMETERS.include?(type) }
|
|
291
|
+
|
|
292
|
+
Git::Deprecation.warn(
|
|
293
|
+
"Calling Git::Repository##{helper} with a block that declares no positional " \
|
|
294
|
+
'parameter is deprecated and will be removed in v6.0.0, where the helper ' \
|
|
295
|
+
'yields a separate repository instead of self. Declare a block parameter and ' \
|
|
296
|
+
"call methods on it instead: #{helper} { |repo| repo.some_method }",
|
|
297
|
+
caller_locations(2)
|
|
298
|
+
)
|
|
299
|
+
end
|
|
300
|
+
|
|
234
301
|
# Resolves deprecated `check` argument semantics with `must_exist:`
|
|
235
302
|
#
|
|
236
303
|
# @param check [Boolean, nil] deprecated positional existence-check value
|
|
@@ -928,7 +928,9 @@ module Git
|
|
|
928
928
|
# @option options [Boolean, nil] :create_reflog (nil) create a reflog for
|
|
929
929
|
# the tag
|
|
930
930
|
#
|
|
931
|
-
# @return [Git::TagInfo] the newly created tag
|
|
931
|
+
# @return [Git::TagInfo, nil] the newly created tag, or `nil` when the tag
|
|
932
|
+
# is missing from the tag list after the create (for example, another
|
|
933
|
+
# process deleted it before the lookup)
|
|
932
934
|
#
|
|
933
935
|
# @overload tag_create(name, target, options = {})
|
|
934
936
|
#
|
|
@@ -945,7 +947,9 @@ module Git
|
|
|
945
947
|
# @param options [Hash] options for creating the tag (same keys as the
|
|
946
948
|
# first overload)
|
|
947
949
|
#
|
|
948
|
-
# @return [Git::TagInfo] the newly created tag
|
|
950
|
+
# @return [Git::TagInfo, nil] the newly created tag, or `nil` when the tag
|
|
951
|
+
# is missing from the tag list after the create (for example, another
|
|
952
|
+
# process deleted it before the lookup)
|
|
949
953
|
#
|
|
950
954
|
# @raise [ArgumentError] if unsupported options are provided, including the
|
|
951
955
|
# `:d` and `:delete` keys that {#tag_add} accepts; use {#tag_delete} to
|
|
@@ -960,6 +964,12 @@ module Git
|
|
|
960
964
|
#
|
|
961
965
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
962
966
|
#
|
|
967
|
+
# @note In v6.0.0 this method raises {Git::UnexpectedResultError} instead of
|
|
968
|
+
# returning `nil` when the tag it has just created is missing from the tag
|
|
969
|
+
# list, so its return value is always a {Git::TagInfo}. Code that checks
|
|
970
|
+
# the result for `nil` today can be left as is; the check becomes
|
|
971
|
+
# unreachable in v6.0.0.
|
|
972
|
+
#
|
|
963
973
|
# @see https://git-scm.com/docs/git-tag git-tag
|
|
964
974
|
#
|
|
965
975
|
def tag_create(name, *args)
|
|
@@ -99,6 +99,14 @@ module Git
|
|
|
99
99
|
#
|
|
100
100
|
# @raise [Git::FailedError] if git exits with a non-zero exit status
|
|
101
101
|
#
|
|
102
|
+
# @note In v6.0.0 this method returns the new {Git::WorktreeInfo} instead of
|
|
103
|
+
# the command output. To get the entry today, look it up after the add:
|
|
104
|
+
# `worktree_list.find { |w| File.identical?(w.path, dir) }`.
|
|
105
|
+
# Compare with `File.identical?`, not string equality: git stores
|
|
106
|
+
# worktree paths with symlinks resolved, so `/tmp/...` on macOS is
|
|
107
|
+
# listed as `/private/tmp/...`, and on case-insensitive filesystems the
|
|
108
|
+
# listed casing may differ from `dir`.
|
|
109
|
+
#
|
|
102
110
|
# @see https://git-scm.com/docs/git-worktree git-worktree documentation
|
|
103
111
|
#
|
|
104
112
|
def worktree_add(dir, commitish = nil)
|
data/lib/git/version.rb
CHANGED
data/lib/git.rb
CHANGED
|
@@ -327,6 +327,11 @@ module Git
|
|
|
327
327
|
# Exports the current HEAD (or the specific branch given in <tt>options[:branch]</tt>)
|
|
328
328
|
# into the given `directory`. It then removes all traces of git from the directory.
|
|
329
329
|
#
|
|
330
|
+
# Removing `.git` is not atomic. If it fails, the exported files are complete and
|
|
331
|
+
# usable, but the directory keeps whatever part of `.git` could not be deleted.
|
|
332
|
+
# Nothing is cleaned up, because the exported files are the deliverable and the
|
|
333
|
+
# leftover has to be removed by hand once the cause of the failure is fixed.
|
|
334
|
+
#
|
|
330
335
|
# Takes the same options as {Git.clone} except that `:depth` defaults to 1 and
|
|
331
336
|
# `:remote` is ignored with a deprecation warning.
|
|
332
337
|
#
|
|
@@ -348,6 +353,10 @@ module Git
|
|
|
348
353
|
#
|
|
349
354
|
# @return [void]
|
|
350
355
|
#
|
|
356
|
+
# @raise [SystemCallError] if the `.git` directory cannot be removed. The exported
|
|
357
|
+
# files are left in place, and the directory keeps whatever part of `.git` could
|
|
358
|
+
# not be deleted.
|
|
359
|
+
#
|
|
351
360
|
def self.export(repository_url, directory = nil, options = {})
|
|
352
361
|
if options.key?(:remote)
|
|
353
362
|
Git::Deprecation.warn(
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: git
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Scott Chacon and others
|
|
@@ -548,8 +548,8 @@ licenses:
|
|
|
548
548
|
metadata:
|
|
549
549
|
homepage_uri: http://github.com/ruby-git/ruby-git
|
|
550
550
|
source_code_uri: http://github.com/ruby-git/ruby-git
|
|
551
|
-
changelog_uri: https://rubydoc.info/gems/git/5.
|
|
552
|
-
documentation_uri: https://rubydoc.info/gems/git/5.
|
|
551
|
+
changelog_uri: https://rubydoc.info/gems/git/5.6.1/file/CHANGELOG.md
|
|
552
|
+
documentation_uri: https://rubydoc.info/gems/git/5.6.1
|
|
553
553
|
rubygems_mfa_required: 'true'
|
|
554
554
|
rdoc_options: []
|
|
555
555
|
require_paths:
|
|
@@ -566,7 +566,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
566
566
|
version: '0'
|
|
567
567
|
requirements:
|
|
568
568
|
- git 2.28.0 or greater
|
|
569
|
-
rubygems_version: 4.0.
|
|
569
|
+
rubygems_version: 4.0.20
|
|
570
570
|
specification_version: 4
|
|
571
571
|
summary: An API to create, read, and manipulate Git repositories
|
|
572
572
|
test_files: []
|