git 5.0.4 → 5.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04104dc235012494d8e6b9718421d02f040a6216aec0991bce962b17b1e61c43
4
- data.tar.gz: bbfe9f44799e29f24e5baa4095d42159af56b9a8c568a51b9358d8ba3758e90f
3
+ metadata.gz: c7e6fda47311cb6c004daa4c42830658e97f5c95a37f325da3dee7bee64f8222
4
+ data.tar.gz: 7ce4dd95073b4419f883ca79fc2985352575ac909c22739be7d3c43ae4d734b8
5
5
  SHA512:
6
- metadata.gz: 0cc7b0792f17d8972999f33f7412477996a6d865bcce5fb24bf27bb9add5dc0ee83f8623e1940bf88a9deebcba1b409a2f3910ee99dbf1d6d33b2eb5dc5afa86
7
- data.tar.gz: 64d890f4273c6a56389bfa5ae42bce90a4aa5d8e63a1536361662bab9cc0ba88e7e317f47bc9b1dbaa0e454b8a5bb7b065bd87aec8a33e1f4367c68feb89092f
6
+ metadata.gz: 3e3420fd700a1440102c3a8b186841ce3cfc3c442f7f80afb9691e1a337b35e947a8ffdf668916889218c839393e5971706667f4df492a04ead0afb27ecd1925
7
+ data.tar.gz: d0a7ea7e2150e56bcd0da3cd4c86645b1430eb4193f8610709bd2d07394fbb320ec3d9b7b77e2eafb42324ba58740437ac5b433c2575058d7e01a72bc23998d5
@@ -5,7 +5,51 @@ on:
5
5
  branches: [main, 4.x]
6
6
  workflow_dispatch:
7
7
 
8
+ # Cancel an in-progress run when the same PR (or branch) gets a new push. For
9
+ # pull_request events github.ref is refs/pull/<n>/merge, so runs are grouped per PR
10
+ # and pushing a new commit -- or force-pushing during a rebase -- no longer leaves a
11
+ # full matrix running to completion against a commit nobody will merge.
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
8
16
  jobs:
17
+ # RuboCop and YARD analyze source text, so their results do not depend on the
18
+ # runtime executing them: RuboCop's verdict is fixed by TargetRubyVersion in
19
+ # .rubocop.yml, not by the host Ruby. Running them once here instead of inside the
20
+ # matrix removes the single largest cost in the build -- RuboCop alone accounted for
21
+ # over half the wall time of the JRuby and TruffleRuby jobs -- while checking exactly
22
+ # the same things.
23
+ #
24
+ # Ruby 3.4 hosts this job rather than the newest supported Ruby because it gates
25
+ # merges: a lint gate should be insulated from churn in a brand-new major, and Ruby
26
+ # 4.0 deprecations still surface through the matrix jobs below, which do run 4.0.
27
+ # 3.3+ is also a hard floor here, since yard-lint is only installed on 3.3 and later
28
+ # (see the gemspec) and YARD itself cannot build on JRuby or TruffleRuby.
29
+ lint:
30
+ name: Lint and Docs
31
+
32
+ # Skip this job if triggered by a release PR
33
+ if: >-
34
+ github.event_name == 'workflow_dispatch' ||
35
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
36
+
37
+ runs-on: ubuntu-latest
38
+
39
+ steps:
40
+ - name: Checkout Code
41
+ uses: actions/checkout@v6
42
+
43
+ - name: Setup Ruby
44
+ uses: ruby/setup-ruby@v1
45
+ with:
46
+ ruby-version: "3.4"
47
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
48
+
49
+ - name: Run RuboCop and YARD
50
+ run: bundle exec rake rubocop yard
51
+ timeout-minutes: 15
52
+
9
53
  build:
10
54
  name: Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
11
55
 
@@ -15,42 +59,34 @@ jobs:
15
59
  (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
16
60
 
17
61
  runs-on: ${{ matrix.operating-system }}
18
- continue-on-error: ${{ matrix.experimental == 'Yes' }}
19
62
  env: { JAVA_OPTS: -Djdk.io.File.enableADS=true }
20
63
 
21
64
  strategy:
22
65
  fail-fast: false
23
66
  matrix:
24
- # Only the minimum required versions of JRuby and TruffleRuby are tested
25
- ruby: ["3.2", "3.4", "4.0", "truffleruby-24.2.1", "jruby-10.0.0.1"]
67
+ # Only the minimum required versions of JRuby and TruffleRuby are tested.
68
+ #
69
+ ruby: ["3.2", "4.0", "truffleruby-24.2.1", "jruby-10.0.0.1"]
26
70
  operating-system: [ubuntu-latest]
27
- experimental: [No]
28
- java_version: [""]
29
71
  include:
30
72
  - ruby: "3.2"
31
73
  operating-system: windows-latest
32
- experimental: No
33
- java_version: ""
34
74
 
35
75
  steps:
36
76
  - name: Checkout Code
37
77
  uses: actions/checkout@v6
38
78
 
39
- - name: Setup Java
40
- if: matrix.java_version != ''
41
- uses: actions/setup-java@v5
42
- with:
43
- distribution: 'temurin'
44
- java-version: ${{ matrix.java_version }}
45
-
46
79
  - name: Setup Ruby
47
80
  uses: ruby/setup-ruby@v1
48
81
  with:
49
82
  ruby-version: ${{ matrix.ruby }}
50
83
  bundler-cache: true # runs 'bundle install' and caches installed gems automatically
51
84
 
52
- - name: Run Build
53
- run: bundle exec rake default
85
+ # Specs only. RuboCop and YARD run once in the lint job above instead of being
86
+ # repeated identically on every runtime. `rake build` still runs on every
87
+ # platform, as a prerequisite of the Test Gem step below.
88
+ - name: Run Specs
89
+ run: bundle exec rake spec
54
90
  timeout-minutes: 15
55
91
 
56
92
  # The unit suite enforces 100% line and branch coverage (see the "Test coverage
@@ -67,3 +103,241 @@ jobs:
67
103
 
68
104
  - name: Test Gem
69
105
  run: bundle exec rake test:gem
106
+
107
+ # The branch ruleset cannot require the matrix jobs above directly. A required status
108
+ # check is matched by name, and `build`'s name is a template -- GitHub only expands it
109
+ # into "Ruby 3.2 on ubuntu-latest" and friends when it evaluates the matrix. The
110
+ # job-level `if:` short-circuits before that happens, so a release PR reports one check
111
+ # named literally "Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}" and the
112
+ # five expanded names never report at all. Required checks that never report block a PR
113
+ # indefinitely rather than passing, which is what stranded the v5.0.5 release PR.
114
+ #
115
+ # So the ruleset requires this job instead: one stable name, no matrix, no template to
116
+ # expand. It also decouples the required-check list from the matrix, so adding or
117
+ # dropping a Ruby version no longer needs a matching ruleset edit.
118
+ #
119
+ # This job carries the same release-PR guard as every job above, so that a release PR
120
+ # reports it as skipped rather than as a success for specs that never ran. Skipping is
121
+ # safe here and was not safe for `build`: this job's name is a literal string, so the
122
+ # check run exists and reports a skipped conclusion whether or not the job runs, and
123
+ # rulesets treat skipped as passing. A matrix job's name does not exist at all until the
124
+ # matrix is evaluated, which is the whole reason this job exists.
125
+ #
126
+ # `always()` is load-bearing and must stay. Without a status check function a job-level
127
+ # `if:` implies `success()`, so a failing matrix would skip this job -- and a skipped
128
+ # required check counts as passing, meaning a red build would merge. `always()` forces a
129
+ # real verdict on every run that is not a release PR. `!cancelled()` is not a substitute:
130
+ # a cancelled run would then skip the gate, and a skipped conclusion is one rulesets treat
131
+ # as passing -- so a build that never finished would stop blocking the merge.
132
+ #
133
+ # The case below accepts `success` only. `build` and this job now carry the same release-PR
134
+ # guard, so this job runs exactly when `build` ran; a `skipped` result would mean the two
135
+ # guards have drifted apart, and failing closed on it turns that into a loud failure rather
136
+ # than a silent pass.
137
+ build-complete:
138
+ name: All Specs Passed
139
+
140
+ needs: [build]
141
+
142
+ # Report a verdict on every non-release PR regardless of the matrix result, and skip
143
+ # on release PRs, where the matrix was never meant to run.
144
+ if: >-
145
+ always() &&
146
+ (github.event_name == 'workflow_dispatch' ||
147
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--')))
148
+
149
+ runs-on: ubuntu-latest
150
+
151
+ steps:
152
+ - name: Check the result of the build job
153
+ run: |
154
+ case "${{ needs.build.result }}" in
155
+ success)
156
+ echo "build: ${{ needs.build.result }}"
157
+ ;;
158
+ *)
159
+ echo "::error::build: ${{ needs.build.result }}"
160
+ exit 1
161
+ ;;
162
+ esac
163
+
164
+ # Everything above runs in English, because GitHub-hosted runners generate no locale
165
+ # beyond C/C.UTF-8. That makes git's translated diagnostics invisible to CI even
166
+ # though they are the default experience for any contributor whose shell locale is not
167
+ # English -- so a spec that matches an English git message passes here and fails for
168
+ # them, on code they did not touch. This job is what stops such a spec from reaching
169
+ # main. See issue #1670.
170
+ #
171
+ # German because git's `de` translation is close enough to complete that a
172
+ # message-matching assumption cannot hide behind a string that was never translated.
173
+ # Most of the suite is insulated from this by the LC_ALL pin in Git::ExecutionContext;
174
+ # what this job really exercises is the code that bypasses that pin.
175
+ locale:
176
+ name: Non-English Locale
177
+
178
+ # Skip this job if triggered by a release PR
179
+ if: >-
180
+ github.event_name == 'workflow_dispatch' ||
181
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
182
+
183
+ runs-on: ubuntu-latest
184
+
185
+ # Set at job scope rather than on the spec step so that every step -- including the
186
+ # check below that the locale is real -- sees exactly the environment the suite runs
187
+ # under. Setting these before locale-gen is harmless: they are simply inert until
188
+ # the locale exists.
189
+ env:
190
+ LANG: de_DE.UTF-8
191
+ LC_ALL: de_DE.UTF-8
192
+
193
+ steps:
194
+ - name: Checkout Code
195
+ uses: actions/checkout@v6
196
+
197
+ # Two separate things are missing from a stock runner, and skipping either one
198
+ # leaves the env above inert -- git keeps answering in English and the job proves
199
+ # nothing:
200
+ #
201
+ # 1. The locale itself. Only C and C.UTF-8 are generated, so setlocale fails for
202
+ # anything else and every process falls back to English.
203
+ # 2. git's German message catalog. Unlike Debian, Ubuntu strips gettext catalogs
204
+ # out of packages and ships them in language packs, so the installed git has
205
+ # no de translation until language-pack-de provides one.
206
+ #
207
+ # `update-locale` is deliberately not run: it edits /etc/default/locale, which is
208
+ # only consulted for logins that do not already set LANG and LC_ALL, and this job
209
+ # sets both explicitly.
210
+ - name: Install the German locale and message catalogs
211
+ run: |
212
+ sudo apt-get update -qq
213
+ sudo apt-get install -y --no-install-recommends language-pack-de
214
+ sudo locale-gen de_DE.UTF-8
215
+
216
+ # Ruby 3.4 to share the bundler cache the lint job already warms. Nothing about
217
+ # this job is Ruby-version specific -- the locale is what is under test.
218
+ - name: Setup Ruby
219
+ uses: ruby/setup-ruby@v1
220
+ with:
221
+ ruby-version: "3.4"
222
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
223
+
224
+ # Guard against a vacuous pass. Diffing git's output against the same command run
225
+ # under LC_ALL=C proves translation is actually active, without pinning a German
226
+ # string that a future git release is free to reword.
227
+ - name: Verify the Locale Took Effect
228
+ run: |
229
+ dir="$(mktemp -d)"
230
+ localized="$(cd "$dir" && git status 2>&1 || true)"
231
+ english="$(cd "$dir" && LC_ALL=C git status 2>&1 || true)"
232
+ echo "LC_ALL=$LC_ALL -> $localized"
233
+ echo "LC_ALL=C -> $english"
234
+ if [ "$localized" = "$english" ]; then
235
+ echo "::error::git is still emitting English: de_DE.UTF-8 did not take effect, so this job would test nothing"
236
+ exit 1
237
+ fi
238
+
239
+ - name: Run Specs
240
+ run: bundle exec rake spec
241
+ timeout-minutes: 15
242
+
243
+ # On the ubuntu jobs above, `C.UTF-8` and `en_US.UTF-8` both resolve to a UTF-8 ctype
244
+ # (measured on the runner in issue #1669), and on windows the pinned value makes no
245
+ # difference under any value at all. So the non-ASCII regex coverage those jobs run
246
+ # passes whatever `Git::ExecutionContext` pins, and cannot tell a correct `LC_ALL`
247
+ # value from a wrong one. That blind spot is what let the original defect go
248
+ # unreported for eighteen months: the gem pinned `en_US.UTF-8`, stock Debian, Ubuntu,
249
+ # and RHEL images generate no such locale, git silently fell back to a C ctype, and
250
+ # every non-ASCII regex in `grep`, `log`, and the `config` value regexes returned a
251
+ # wrong answer with exit status zero -- while CI stayed green throughout.
252
+ #
253
+ # This job makes one run discriminating. `LOCPATH` overrides where glibc looks for
254
+ # compiled locale data, so pointing it at an empty directory takes away every locale
255
+ # that needs a locale archive -- `en_US.UTF-8` among them -- while leaving `C.UTF-8`
256
+ # working, because glibc 2.35 and later compile that one into the library itself.
257
+ # The suite then runs in an environment where the value shipped before #1681 fails
258
+ # and the value shipped now passes: no container image, no second bundle install,
259
+ # no cache miss. Measured on ubuntu:24.04 (glibc 2.39, the runner's base) with
260
+ # `en_US.UTF-8` generated first:
261
+ #
262
+ # normal en_US.UTF-8 charmap=UTF-8 C.UTF-8 charmap=UTF-8
263
+ # LOCPATH=empty en_US.UTF-8 charmap=ANSI_X3.4-1968 C.UTF-8 charmap=UTF-8
264
+ #
265
+ # This has to be a property of the run rather than of a spec. Never gate a spec on
266
+ # whether the pinned locale loads: such a spec skips itself in exactly the
267
+ # environments where this defect lives, which is how the defect went unreported for
268
+ # eighteen months.
269
+ #
270
+ # LANG is set explicitly so only `en_US.UTF-8` is taken away and the ambient
271
+ # environment stays UTF-8. The runner already sets this value; pinning it here keeps
272
+ # the job from depending on the image's default.
273
+ missing-locale:
274
+ name: Missing en_US.UTF-8 Locale
275
+
276
+ # Skip this job if triggered by a release PR
277
+ if: >-
278
+ github.event_name == 'workflow_dispatch' ||
279
+ (github.event_name == 'pull_request' && !startsWith(github.event.pull_request.head.ref, 'release-please--'))
280
+
281
+ runs-on: ubuntu-latest
282
+
283
+ env:
284
+ LANG: C.UTF-8
285
+
286
+ steps:
287
+ - name: Checkout Code
288
+ uses: actions/checkout@v6
289
+
290
+ # Exported through GITHUB_ENV rather than set at job scope because the `runner`
291
+ # context is not available there, and the directory has to exist before anything
292
+ # reads a locale -- glibc warns on every process when LOCPATH names a directory
293
+ # that does not exist. RUNNER_TEMP rather than the workspace so that
294
+ # actions/checkout cannot clean it away.
295
+ - name: Point LOCPATH at an Empty Directory
296
+ run: |
297
+ mkdir -p "$RUNNER_TEMP/empty-locale-dir"
298
+ echo "LOCPATH=$RUNNER_TEMP/empty-locale-dir" >> "$GITHUB_ENV"
299
+
300
+ # Ruby 3.4 to share the bundler cache the lint job already warms. Nothing about
301
+ # this job is Ruby-version specific -- the locale environment is what differs.
302
+ - name: Setup Ruby
303
+ uses: ruby/setup-ruby@v1
304
+ with:
305
+ ruby-version: "3.4"
306
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
307
+
308
+ # Guard against a vacuous pass, functionally. `locale -a` still lists en_US.utf8
309
+ # under LOCPATH (measured) even though setlocale then refuses it, so asking git
310
+ # to match is the only assertion worth making: `.` spans the two-byte U+00C4 only
311
+ # under a UTF-8 ctype. The metacharacter-free control has to keep matching under
312
+ # the removed locale as well -- it matches bytes under any ctype, so if it fails,
313
+ # the probe never delivered UTF-8 bytes to git and the rest proves nothing.
314
+ - name: Verify the Run Discriminates
315
+ run: |
316
+ dir="$(mktemp -d)"
317
+ cd "$dir"
318
+ git init -q .
319
+ printf '\xc3\x84PFEL sind gut\n' > w.txt
320
+ git add w.txt
321
+
322
+ if ! LC_ALL=C.UTF-8 git grep -q '^.PFEL' -- w.txt; then
323
+ echo "::error::C.UTF-8 no longer yields a UTF-8 ctype under LOCPATH, so this job would fail for the wrong reason"
324
+ exit 1
325
+ fi
326
+ if ! LC_ALL=en_US.UTF-8 git grep -q 'PFEL sind' -- w.txt; then
327
+ echo "::error::the control pattern did not match, so this probe is not delivering UTF-8 bytes to git"
328
+ exit 1
329
+ fi
330
+ if LC_ALL=en_US.UTF-8 git grep -q '^.PFEL' -- w.txt; then
331
+ echo "::error::en_US.UTF-8 still yields a UTF-8 ctype, so this job cannot detect a wrong LC_ALL pin"
332
+ exit 1
333
+ fi
334
+ echo "en_US.UTF-8 is unusable and C.UTF-8 works: a wrong pin fails this job"
335
+
336
+ # The whole suite rather than the non-ASCII regex spec alone: the point is that
337
+ # this run is indistinguishable from any other except for the missing locale, so
338
+ # every locale-sensitive surface added later is covered without touching this
339
+ # file. It also keeps the coverage gate satisfied, which a single spec file
340
+ # cannot do.
341
+ - name: Run Specs
342
+ run: bundle exec rake spec
343
+ timeout-minutes: 15
@@ -10,6 +10,12 @@ on:
10
10
  - main
11
11
  - 4.x
12
12
 
13
+ # Cancel an in-progress run when the same PR gets a new push; only the commit messages
14
+ # as they stand after the latest push are worth linting.
15
+ concurrency:
16
+ group: ${{ github.workflow }}-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
13
19
  jobs:
14
20
  commit-lint:
15
21
  name: Verify Conventional Commits
@@ -0,0 +1,82 @@
1
+ name: Warm Bundler Caches
2
+
3
+ # GitHub Actions scopes every cache to the ref that wrote it, and only caches
4
+ # written at *default-branch* scope are readable from other refs. The CI workflow runs
5
+ # on `pull_request`, where github.ref is refs/pull/<n>/merge, so the caches it writes
6
+ # are visible to that one PR and nothing else. The result is that nearly every PR paid
7
+ # a cold `bundle install` on nearly every job. See issue #1674 for the measurements.
8
+ #
9
+ # This workflow exists solely to write those caches from refs/heads/main so that a
10
+ # PR's *first* run can read them. It does no checkout-and-test work beyond what
11
+ # `bundler-cache: true` needs: no specs, no RuboCop, no YARD.
12
+ #
13
+ # The matrix below must stay in sync with continuous_integration.yml: setup-ruby's
14
+ # cache key embeds the runner OS, the resolved Ruby version, and the Gemfile.lock hash,
15
+ # so a pair that is not warmed here still starts cold in CI. That includes the lint
16
+ # job's Ruby 3.4 and the Windows 3.2 job, neither of which appears in CI's main matrix
17
+ # list. The head rubies from experimental_continuous_integration.yml are deliberately
18
+ # absent: that workflow already runs on `push: [main]` and warms its own caches.
19
+ #
20
+ # Only `main` is listed below. A run's readable caches are its own ref, its base ref,
21
+ # and the default branch, so warming 4.x would need this file backported to the 4.x
22
+ # branch with that branch's own matrix -- the copy on main is never what runs for a
23
+ # push to 4.x.
24
+ on:
25
+ push:
26
+ branches: [main]
27
+
28
+ workflow_dispatch:
29
+
30
+ # Deliberately NOT cancel-in-progress. Two merges landing close together would
31
+ # otherwise cancel the first one's warming mid-save, which is the opposite of the
32
+ # point; queueing them costs a couple of runner-minutes and always leaves a warm cache
33
+ # behind. This group is also distinct from CI's because github.workflow differs.
34
+ concurrency:
35
+ group: ${{ github.workflow }}-${{ github.ref }}
36
+ cancel-in-progress: false
37
+
38
+ permissions:
39
+ contents: read
40
+
41
+ jobs:
42
+ warm:
43
+ name: Warm Ruby ${{ matrix.ruby }} on ${{ matrix.operating-system }}
44
+
45
+ runs-on: ${{ matrix.operating-system }}
46
+ timeout-minutes: 15
47
+
48
+ strategy:
49
+ fail-fast: false
50
+ matrix:
51
+ include:
52
+ - ruby: "3.2"
53
+ operating-system: ubuntu-latest
54
+
55
+ - # Hosts the lint and locale jobs in continuous_integration.yml
56
+ ruby: "3.4"
57
+ operating-system: ubuntu-latest
58
+
59
+ - ruby: "4.0"
60
+ operating-system: ubuntu-latest
61
+
62
+ - ruby: "truffleruby-24.2.1"
63
+ operating-system: ubuntu-latest
64
+
65
+ - ruby: "jruby-10.0.0.1"
66
+ operating-system: ubuntu-latest
67
+
68
+ - ruby: "3.2"
69
+ operating-system: windows-latest
70
+
71
+ steps:
72
+ - name: Checkout Code
73
+ uses: actions/checkout@v6
74
+
75
+ # No bundler-* inputs here on purpose. setup-ruby folds its `bundler`, `with`,
76
+ # `without`, and `only` inputs into the cache key, so any option set here and not
77
+ # in continuous_integration.yml would warm a key CI never looks up.
78
+ - name: Setup Ruby
79
+ uses: ruby/setup-ruby@v1
80
+ with:
81
+ ruby-version: ${{ matrix.ruby }}
82
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "5.0.4"
2
+ ".": "5.0.5"
3
3
  }
data/.rubocop.yml CHANGED
@@ -27,6 +27,11 @@ Style/OneClassPerFile:
27
27
  Enabled: false
28
28
 
29
29
  AllCops:
30
- # Pin this project to Ruby 3.1 in case the shared config above is upgraded to 3.2
31
- # or later.
30
+ # Must match the floor of required_ruby_version in the gemspec: TargetRubyVersion
31
+ # decides which syntax RuboCop permits and suggests, so a value above the floor
32
+ # would let in code that does not parse on the oldest supported Ruby.
33
+ #
34
+ # Pinned explicitly rather than inferred because main_branch_shared_rubocop_config
35
+ # sets 3.1, which is older than this gem supports, and a value inherited through
36
+ # inherit_gem takes precedence over inference from the gemspec.
32
37
  TargetRubyVersion: 3.2
data/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@
5
5
 
6
6
  # Change Log
7
7
 
8
+ ## [5.0.5](https://github.com/ruby-git/ruby-git/compare/v5.0.4...v5.0.5) (2026-08-09)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * Detect Darwin under JRuby when pinning LC_ALL ([89bf625](https://github.com/ruby-git/ruby-git/commit/89bf62579999bec27a9b0f1aab16d37e7d5af2b8)), closes [#1669](https://github.com/ruby-git/ruby-git/issues/1669)
14
+ * Pin LC_ALL to a locale that exists on the host platform ([5a4e0d6](https://github.com/ruby-git/ruby-git/commit/5a4e0d657b0e0828de0b38f283ae60dfbe2d4cc6)), closes [#1669](https://github.com/ruby-git/ruby-git/issues/1669)
15
+
16
+
17
+ ### Other Changes
18
+
19
+ * Correct two imprecise claims in the build-complete comment ([c4391cd](https://github.com/ruby-git/ruby-git/commit/c4391cdf441a8379dee4cda59f800da41bf8e8b2)), closes [#1675](https://github.com/ruby-git/ruby-git/issues/1675)
20
+ * Gate merges on a matrix-free job instead of the per-matrix checks ([47f2d17](https://github.com/ruby-git/ruby-git/commit/47f2d17d16d1ea201bf9cc8f74aedffa7619eb0a)), closes [#1675](https://github.com/ruby-git/ruby-git/issues/1675)
21
+ * Remove vestigial matrix dimensions ([3a89886](https://github.com/ruby-git/ruby-git/commit/3a8988650a7d8f0a81c093c470fb9f524142c9b9)), closes [#1676](https://github.com/ruby-git/ruby-git/issues/1676)
22
+ * Run RuboCop and YARD once instead of on every matrix job ([0726964](https://github.com/ruby-git/ruby-git/commit/072696491662867cfbc0424febcf36542548f051))
23
+ * Run the suite once with en_US.UTF-8 unavailable ([6e012c5](https://github.com/ruby-git/ruby-git/commit/6e012c54d52c8b0c25bf629f07e310b6fcbac229)), closes [#1669](https://github.com/ruby-git/ruby-git/issues/1669)
24
+ * Run the test suite under a non-English locale ([c65d402](https://github.com/ruby-git/ruby-git/commit/c65d4022f358a4e4e676dbf2492427851205cdd6)), closes [#1670](https://github.com/ruby-git/ruby-git/issues/1670)
25
+ * Skip the All Specs Passed gate on release PRs ([6dfeee0](https://github.com/ruby-git/ruby-git/commit/6dfeee0ed508932393106c8887d9b7c9ef9dbbca)), closes [#1675](https://github.com/ruby-git/ruby-git/issues/1675)
26
+ * Warm bundler caches at default-branch scope on push to main ([2821477](https://github.com/ruby-git/ruby-git/commit/282147796f6b859fb9c7f8b5a614cab399cc9539)), closes [#1674](https://github.com/ruby-git/ruby-git/issues/1674)
27
+
8
28
  ## [5.0.4](https://github.com/ruby-git/ruby-git/compare/v5.0.3...v5.0.4) (2026-08-07)
9
29
 
10
30
 
data/CONTRIBUTING.md CHANGED
@@ -301,7 +301,7 @@ The `git` gem is organized into three architectural layers:
301
301
  | --- | --- | --- |
302
302
  | **Facade** (`Git::Repository` and `Git`) | Public API | Normalizes Ruby arguments, sets safe defaults, calls one or more `Git::Commands::*` classes, and may parse output into public Ruby objects |
303
303
  | **Command** (`Git::Commands::*`) | Neutral git CLI interface | Declares CLI arguments via the [Arguments DSL](lib/git/commands/arguments.rb), builds the git argv and executes git via `#call`, and returns `Git::CommandLine::Result` |
304
- | **Execution** (`Git::ExecutionContext::*`) | Execution context and subprocess defaults | Carries execution settings such as working directory, environment, timeout, binary path, and logging; runs the git CLI with default global options (such as `-c color.ui=false`) and subprocess environment variables (such as `LC_ALL=en_US.UTF-8`) |
304
+ | **Execution** (`Git::ExecutionContext::*`) | Execution context and subprocess defaults | Carries execution settings such as working directory, environment, timeout, binary path, and logging; runs the git CLI with default global options (such as `-c color.ui=false`) and subprocess environment variables (such as a platform-conditional `LC_ALL` — `en_US.UTF-8` on macOS, `C.UTF-8` elsewhere) |
305
305
 
306
306
  Command classes (`Git::Commands::*`) are **faithful, neutral representations of the
307
307
  git CLI**. Each command class does the following:
@@ -453,12 +453,68 @@ module Git
453
453
  'GIT_INDEX_FILE' => git_index_file,
454
454
  'GIT_SSH' => git_ssh,
455
455
  'GIT_EDITOR' => 'true',
456
- 'LC_ALL' => 'en_US.UTF-8'
456
+ # Pin the locale so git's behavior does not depend on the user's environment.
457
+ # Added for issue #753, where a German user's `git branch` output
458
+ # ("* (HEAD losgelöst bei origin/25.1)") broke branch parsing.
459
+ #
460
+ # The pin has two halves, and the load-bearing one is not the obvious one:
461
+ #
462
+ # - Messages: keeps git's human-readable text in English. This is now only
463
+ # defense-in-depth — lib/ reads `--format=%(refname:short)` rather than
464
+ # git's prose, and matches no English git message.
465
+ # - Ctype: makes git's regex engine match *characters* rather than *bytes*.
466
+ # This is the half that matters. Under a C ctype, `grep`, `log`, and the
467
+ # `config` value regexes silently return wrong answers — with exit status
468
+ # zero — for any pattern whose metacharacters span non-ASCII text.
469
+ #
470
+ # So do not "simplify" this to `C`: that yields English messages and a broken
471
+ # ctype, which is the worst of both. A pinned locale the host does not have
472
+ # degrades to that same C ctype, which is why each branch below has to name a
473
+ # locale that actually exists on the platform it applies to:
474
+ #
475
+ # - Non-Darwin: `C.UTF-8`. Stock Debian, Ubuntu, and RHEL images generate no
476
+ # `en_US.UTF-8`, so pinning it there produced exactly the silent breakage
477
+ # above. (musl ignores the locale name for ctype, so Alpine is UTF-8 either
478
+ # way.)
479
+ # - Darwin: `en_US.UTF-8`, which every macOS release ships. `C.UTF-8` did not
480
+ # arrive until macOS 15, so macOS 11–14 — including Intel Macs that are
481
+ # hardware-capped below 15 — would break under it. Delete this branch once
482
+ # macOS 14 and earlier are out of support.
483
+ #
484
+ # Windows takes the non-Darwin branch, where the value makes no difference:
485
+ # Git for Windows folds case and runs PCRE in UTF mode under every value, and
486
+ # matches bytes for `.` and POSIX classes under every value — measured on git
487
+ # 2.55.0 against `en_US.UTF-8`, `C.UTF-8`, `C`, and no pin at all.
488
+ #
489
+ # RHEL 7 (glibc 2.17) has neither locale and gets a C ctype whatever is pinned.
490
+ # It is EOL, and there is deliberately no public override for this value.
491
+ 'LC_ALL' => darwin_platform? ? 'en_US.UTF-8' : 'C.UTF-8'
457
492
  }.merge(additional_overrides)
458
493
  end
459
494
 
460
495
  private
461
496
 
497
+ # Whether this process is running on macOS
498
+ #
499
+ # Checks `RUBY_DESCRIPTION` as well as `RUBY_PLATFORM` because JRuby reports
500
+ # `RUBY_PLATFORM` as `"java"` on every host and records the real platform only in
501
+ # `RUBY_DESCRIPTION` (as, for example, `"... [arm64-darwin]"`). Testing
502
+ # `RUBY_PLATFORM` alone would put JRuby on macOS onto the non-Darwin branch of the
503
+ # `LC_ALL` pin, which is the one platform pairing that branch must never be given —
504
+ # see {#env_overrides}.
505
+ #
506
+ # Test the platform plainly rather than sniffing the Darwin version: `RUBY_PLATFORM`
507
+ # records the version Ruby was *built* against, so a Ruby built on macOS 14 still
508
+ # reports `darwin23` when run on macOS 15.
509
+ #
510
+ # @return [Boolean] true if this process is running on macOS
511
+ #
512
+ # @api private
513
+ #
514
+ def darwin_platform?
515
+ RUBY_PLATFORM.include?('darwin') || RUBY_DESCRIPTION.include?('darwin')
516
+ end
517
+
462
518
  # Returns the Array of git global option strings for this context
463
519
  #
464
520
  # Prepends `--git-dir` and `--work-tree` when the corresponding attributes
data/lib/git/version.rb CHANGED
@@ -4,7 +4,7 @@ module Git
4
4
  # The current gem version
5
5
  #
6
6
  # @return [String] the current gem version
7
- VERSION = '5.0.4'
7
+ VERSION = '5.0.5'
8
8
 
9
9
  # Represents a git version with major, minor, and patch components
10
10
  #
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.0.4
4
+ version: 5.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon and others
@@ -347,6 +347,7 @@ files:
347
347
  - ".github/workflows/enforce_conventional_commits.yml"
348
348
  - ".github/workflows/experimental_continuous_integration.yml"
349
349
  - ".github/workflows/release.yml"
350
+ - ".github/workflows/warm_bundler_caches.yml"
350
351
  - ".gitignore"
351
352
  - ".husky/commit-msg"
352
353
  - ".husky/pre-commit"
@@ -630,8 +631,8 @@ licenses:
630
631
  metadata:
631
632
  homepage_uri: http://github.com/ruby-git/ruby-git
632
633
  source_code_uri: http://github.com/ruby-git/ruby-git
633
- changelog_uri: https://rubydoc.info/gems/git/5.0.4/file/CHANGELOG.md
634
- documentation_uri: https://rubydoc.info/gems/git/5.0.4
634
+ changelog_uri: https://rubydoc.info/gems/git/5.0.5/file/CHANGELOG.md
635
+ documentation_uri: https://rubydoc.info/gems/git/5.0.5
635
636
  rubygems_mfa_required: 'true'
636
637
  rdoc_options: []
637
638
  require_paths: