git 5.1.0 → 5.2.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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -0
  3. data/CONTRIBUTING.md +185 -165
  4. data/LICENSE +1 -1
  5. data/README.md +151 -151
  6. data/git.gemspec +35 -3
  7. data/lib/git/command_line/base.rb +1 -2
  8. data/lib/git/commands/base.rb +1 -1
  9. data/lib/git/commands/cat_file/raw.rb +8 -7
  10. data/lib/git/repository/branching.rb +79 -5
  11. data/lib/git/version.rb +1 -1
  12. metadata +5 -94
  13. data/.claude/commands/address-copilot-reviews.md +0 -14
  14. data/.claude/settings.json +0 -16
  15. data/.claude/skills +0 -1
  16. data/.commitlintrc.yml +0 -38
  17. data/.dockerignore +0 -27
  18. data/.github/copilot-instructions.md +0 -30
  19. data/.github/hooks/bin-setup-on-worktree.json +0 -11
  20. data/.github/hooks/run-bin-setup-once.sh +0 -20
  21. data/.github/issue_template.md +0 -15
  22. data/.github/prompts/iteratively-address-copilot-reviews.prompt.md +0 -188
  23. data/.github/pull_request_template.md +0 -21
  24. data/.github/skills/breaking-change-analysis/SKILL.md +0 -99
  25. data/.github/skills/ci-cd-troubleshooting/SKILL.md +0 -264
  26. data/.github/skills/command-implementation/REFERENCE.md +0 -994
  27. data/.github/skills/command-implementation/SKILL.md +0 -230
  28. data/.github/skills/command-test-conventions/SKILL.md +0 -664
  29. data/.github/skills/command-yard-documentation/SKILL.md +0 -434
  30. data/.github/skills/dependency-management/SKILL.md +0 -72
  31. data/.github/skills/development-workflow/SKILL.md +0 -512
  32. data/.github/skills/facade-implementation/REFERENCE.md +0 -837
  33. data/.github/skills/facade-implementation/SKILL.md +0 -269
  34. data/.github/skills/facade-test-conventions/SKILL.md +0 -391
  35. data/.github/skills/facade-yard-documentation/SKILL.md +0 -435
  36. data/.github/skills/make-skill-template/SKILL.md +0 -226
  37. data/.github/skills/pr-readiness-review/SKILL.md +0 -205
  38. data/.github/skills/project-context/SKILL.md +0 -306
  39. data/.github/skills/pull-request-review/SKILL.md +0 -168
  40. data/.github/skills/rebase/SKILL.md +0 -148
  41. data/.github/skills/refactor-command-to-commandlineresult/SKILL.md +0 -131
  42. data/.github/skills/release-management/SKILL.md +0 -125
  43. data/.github/skills/resolve-feedback/SKILL.md +0 -288
  44. data/.github/skills/review-arguments-dsl/CHECKLIST.md +0 -788
  45. data/.github/skills/review-arguments-dsl/SKILL.md +0 -214
  46. data/.github/skills/review-cross-command-consistency/SKILL.md +0 -139
  47. data/.github/skills/reviewing-skills/SKILL.md +0 -214
  48. data/.github/skills/rspec-unit-testing-standards/SKILL.md +0 -685
  49. data/.github/skills/tdd-refactor-step/SKILL.md +0 -236
  50. data/.github/skills/test-debugging/SKILL.md +0 -161
  51. data/.github/skills/yard-documentation/SKILL.md +0 -981
  52. data/.github/skills/yard-documentation/element-rules.md +0 -162
  53. data/.github/skills-deprecated/README.md +0 -21
  54. data/.github/skills-deprecated/extract-command-from-lib/SKILL.md +0 -487
  55. data/.github/skills-deprecated/extract-facade-from-base-lib/KEYWORD_ARG_REMEDIATION.md +0 -22
  56. data/.github/skills-deprecated/extract-facade-from-base-lib/SKILL.md +0 -600
  57. data/.github/skills-deprecated/review-backward-compatibility/SKILL.md +0 -275
  58. data/.github/workflows/continuous_integration.yml +0 -358
  59. data/.github/workflows/enforce_conventional_commits.yml +0 -35
  60. data/.github/workflows/experimental_continuous_integration.yml +0 -59
  61. data/.github/workflows/release.yml +0 -52
  62. data/.github/workflows/warm_bundler_caches.yml +0 -82
  63. data/.gitignore +0 -30
  64. data/.husky/commit-msg +0 -1
  65. data/.husky/pre-commit +0 -13
  66. data/.release-please-config.json +0 -36
  67. data/.release-please-manifest.json +0 -3
  68. data/.rspec +0 -2
  69. data/.rubocop.yml +0 -44
  70. data/.rubocop_todo.yml +0 -30
  71. data/.yard-lint.yml +0 -75
  72. data/CLAUDE.md +0 -11
  73. data/Gemfile +0 -22
  74. data/Rakefile +0 -41
  75. data/docker/test/Dockerfile +0 -32
  76. data/docker/test/docker-compose.yml +0 -0
  77. data/package.json +0 -10
  78. data/redesign/1_architecture_existing.md +0 -102
  79. data/redesign/2_architecture_redesign.md +0 -449
  80. data/redesign/3_architecture_implementation.md +0 -1623
  81. data/redesign/Phase 4 - Step A.md +0 -366
  82. data/redesign/Phase 4 - Step B.md +0 -921
  83. data/redesign/Phase 4 - Step C.md +0 -833
  84. data/redesign/beta_release.md +0 -107
  85. data/redesign/branch_parse_refactor_plan.md +0 -163
  86. data/redesign/c1a-public-api-scope.tsv +0 -256
  87. data/redesign/c1c2_audit.md +0 -566
  88. data/redesign/c1c2_bucket6_lib_orphans.md +0 -626
  89. data/redesign/config_design.rb +0 -501
  90. data/redesign/index.md +0 -34
  91. data/redesign/info_object_migration_plan.md +0 -126
  92. data/redesign/integration_test_analysis.md +0 -521
  93. data/redesign/phase-4-step-b-test-audit.tsv +0 -485
  94. data/redesign/remote_refactor_plan.md +0 -164
  95. data/redesign/reverse_dependencies.sql +0 -44
  96. data/tasks/gem_tasks.rake +0 -14
  97. data/tasks/npm_tasks.rake +0 -7
  98. data/tasks/rspec.rake +0 -111
  99. data/tasks/rubocop.rake +0 -5
  100. data/tasks/test_gem.rake +0 -12
  101. data/tasks/yard.rake +0 -57
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2008 Scott Chacon
3
+ Copyright (c) 2008 Scott Chacon, 2020 James Couball, and the ruby-git contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  # @title README
4
4
  -->
5
5
 
6
- # The Git Gem
6
+ # The git gem
7
7
 
8
8
  [![Gem Version](https://badge.fury.io/rb/git.svg)](https://badge.fury.io/rb/git)
9
9
  [![Build Status](https://github.com/ruby-git/ruby-git/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/ruby-git/ruby-git/actions/workflows/continuous_integration.yml)
@@ -22,33 +22,34 @@ Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?log
22
22
 
23
23
  - [Summary](#summary)
24
24
  - [Install](#install)
25
- - [Quick Start](#quick-start)
25
+ - [Quick start](#quick-start)
26
26
  - [Examples](#examples)
27
- - [Gem Configuration](#gem-configuration)
28
- - [Git Configuration](#git-configuration)
27
+ - [Gem configuration](#gem-configuration)
28
+ - [Git configuration](#git-configuration)
29
29
  - [Full API](#full-api)
30
- - [Errors Raised by This Gem](#errors-raised-by-this-gem)
31
- - [Specifying and Handling Timeouts](#specifying-and-handling-timeouts)
30
+ - [Errors raised by this gem](#errors-raised-by-this-gem)
31
+ - [Specifying and handling timeouts](#specifying-and-handling-timeouts)
32
32
  - [Deprecations](#deprecations)
33
- - [Platform Limitations](#platform-limitations)
34
- - [Regex Metacharacters on Git for Windows](#regex-metacharacters-on-git-for-windows)
35
- - [Project Policies](#project-policies)
36
- - [Ruby Version Support Policy](#ruby-version-support-policy)
37
- - [Git Version Support Policy](#git-version-support-policy)
38
- - [Project Announcements](#project-announcements)
39
- - [2026-07-28: v5.0.0 Released](#2026-07-28-v500-released)
40
- - [2026-01-07: AI Policy Introduced](#2026-01-07-ai-policy-introduced)
41
- - [2025-07-09: Architectural Redesign](#2025-07-09-architectural-redesign)
42
- - [2025-07-07: We Now Use RuboCop](#2025-07-07-we-now-use-rubocop)
43
- - [2025-06-06: Default Branch Rename](#2025-06-06-default-branch-rename)
44
- - [2025-05-15: We've Switched to Conventional Commits](#2025-05-15-weve-switched-to-conventional-commits)
33
+ - [Platform limitations](#platform-limitations)
34
+ - [Regex metacharacters on Git for Windows](#regex-metacharacters-on-git-for-windows)
35
+ - [Project policies](#project-policies)
36
+ - [Ruby version support policy](#ruby-version-support-policy)
37
+ - [Git version support policy](#git-version-support-policy)
38
+ - [Project announcements](#project-announcements)
39
+ - [2026-08-23: v5.x deprecations and the v6.0.0 roadmap](#2026-08-23-v5x-deprecations-and-the-v600-roadmap)
40
+ - [2026-07-28: v5.0.0 released](#2026-07-28-v500-released)
41
+ - [2026-01-07: AI policy introduced](#2026-01-07-ai-policy-introduced)
42
+ - [2025-07-09: Architectural redesign](#2025-07-09-architectural-redesign)
43
+ - [2025-07-07: We now use RuboCop](#2025-07-07-we-now-use-rubocop)
44
+ - [2025-06-06: Default branch rename](#2025-06-06-default-branch-rename)
45
+ - [2025-05-15: We've switched to Conventional Commits](#2025-05-15-weve-switched-to-conventional-commits)
45
46
 
46
47
  ## Summary
47
48
 
48
49
  The [git gem](https://rubygems.org/gems/git) provides a Ruby interface to the `git`
49
50
  command line.
50
51
 
51
- Get started by obtaining a repository object by:
52
+ Get a repository object by:
52
53
 
53
54
  - opening an existing working copy with
54
55
  [Git.open](https://rubydoc.info/gems/git/Git#open-class_method)
@@ -57,14 +58,14 @@ Get started by obtaining a repository object by:
57
58
  - cloning a repository with
58
59
  [Git.clone](https://rubydoc.info/gems/git/Git#clone-class_method)
59
60
 
60
- Methods that can be called on a repository object are documented in
61
- [Git::Repository](https://rubydoc.info/gems/git/Git/Repository)
61
+ [Git::Repository](https://rubydoc.info/gems/git/Git/Repository) documents the
62
+ methods you can call on a repository object.
62
63
 
63
64
  ## Install
64
65
 
65
66
  This gem is a wrapper around the `git` command line, so a `git` executable (version
66
- 2.28.0 or greater) must be installed and on your `PATH`. See the [Git Version Support
67
- Policy](#git-version-support-policy) for details.
67
+ 2.28.0 or greater) must be installed and on your `PATH`. See the [Git version support
68
+ policy](#git-version-support-policy) for details.
68
69
 
69
70
  Install the gem and add to the application's Gemfile by executing:
70
71
 
@@ -72,21 +73,21 @@ Install the gem and add to the application's Gemfile by executing:
72
73
  bundle add git
73
74
  ```
74
75
 
75
- If bundler is not being used to manage dependencies, install the gem by executing:
76
+ If you are not using bundler to manage dependencies, install the gem by executing:
76
77
 
77
78
  ```shell
78
79
  gem install git
79
80
  ```
80
81
 
81
- ## Quick Start
82
+ ## Quick start
82
83
 
83
84
  All functionality for this gem starts with the top-level
84
- [`Git`](https://rubydoc.info/gems/git/Git) module. This module can be used to run
85
- non-repo scoped `git` commands such as `config`.
85
+ [`Git`](https://rubydoc.info/gems/git/Git) module. Use this module to run non-repo
86
+ scoped `git` commands such as `config`.
86
87
 
87
88
  The `Git` module also has factory methods such as `open`, `clone`, and `init` which
88
- return a [`Git::Repository`](https://rubydoc.info/gems/git/Git/Repository) object. The
89
- `Git::Repository` object is used to run repo-specific `git` commands such as `add`,
89
+ return a [`Git::Repository`](https://rubydoc.info/gems/git/Git/Repository) object. Use
90
+ the `Git::Repository` object to run repo-specific `git` commands such as `add`,
90
91
  `commit`, `push`, and `log`.
91
92
 
92
93
  Clone, read status, and log:
@@ -125,7 +126,7 @@ repo.commit('initial commit')
125
126
  These examples cover configuring the gem and git itself. For the full set of
126
127
  repository operations, see [Full API](#full-api) below.
127
128
 
128
- ### Gem Configuration
129
+ ### Gem configuration
129
130
 
130
131
  Configure the git gem:
131
132
 
@@ -141,7 +142,7 @@ Git.config.binary_path = '/usr/local/bin/git'
141
142
  Git.config.git_ssh = 'ssh -i ~/.ssh/id_rsa'
142
143
  ```
143
144
 
144
- **How SSH configuration is determined:**
145
+ How SSH configuration is determined:
145
146
 
146
147
  - If `git_ssh` is not specified in the API call, the global config (`Git.configure {
147
148
  |c| c.git_ssh = ... }`) is used.
@@ -167,7 +168,7 @@ git = Git.init('new-repo', git_ssh: 'ssh -i /path/to/private_key')
167
168
  This is especially useful in multi-threaded applications where different repositories
168
169
  require different SSH credentials.
169
170
 
170
- ### Git Configuration
171
+ ### Git configuration
171
172
 
172
173
  Read and set `git` configuration values (via `git config`):
173
174
 
@@ -188,21 +189,21 @@ repo.config_set('user.email', 'anotheruser@example.com')
188
189
 
189
190
  ### Full API
190
191
 
191
- Quick Start and the configuration sections above cover the most common setup. For
192
- the complete set of operations — reading history, diffs, branches, remotes,
193
- worktrees, staging, and low-level index and tree work — see the
194
- [`Git::Repository`](https://rubydoc.info/gems/git/Git/Repository) reference. It
195
- documents every method along with the object types each one returns (such as
196
- `Git::Log`, `Git::Object::Commit`, `Git::Diff`, `Git::Branch`, and `Git::Worktree`),
197
- so you can follow the links from a method to the full API of its result.
192
+ The quick start and the configuration sections above cover the most common setup.
193
+ The [`Git::Repository`](https://rubydoc.info/gems/git/Git/Repository) reference
194
+ covers everything else: reading history, diffs, branches, remotes, worktrees,
195
+ staging, and low-level index and tree work. It documents every method and the object
196
+ type each one returns (such as `Git::Log`, `Git::Object::Commit`, `Git::Diff`,
197
+ `Git::Branch`, and `Git::Worktree`), so you can follow the links from a method to
198
+ the full API of its result.
198
199
 
199
- ## Errors Raised by This Gem
200
+ ## Errors raised by this gem
200
201
 
201
- The git gem will only raise an `ArgumentError` or an error that is a subclass of
202
- `Git::Error`. It does not explicitly raise any other types of errors.
202
+ The git gem raises only `ArgumentError` or errors that subclass `Git::Error`. It
203
+ does not explicitly raise any other types of errors.
203
204
 
204
- It is recommended to rescue `Git::Error` to catch any runtime error raised by this
205
- gem unless you need more specific error handling.
205
+ Rescue `Git::Error` to catch any runtime error raised by this gem, unless you need
206
+ more specific error handling.
206
207
 
207
208
  ```ruby
208
209
  begin
@@ -214,27 +215,25 @@ end
214
215
 
215
216
  See [`Git::Error`](https://rubydoc.info/gems/git/Git/Error) for more information.
216
217
 
217
- ## Specifying and Handling Timeouts
218
+ ## Specifying and handling timeouts
218
219
 
219
- A timeout for git command line operations can be set either globally or for specific
220
- method calls that accept a `:timeout` parameter.
220
+ Set a timeout for git command line operations either globally or per method call for
221
+ methods that accept a `:timeout` parameter.
221
222
 
222
- The timeout value must be a real, non-negative `Numeric` value that specifies a
223
- number of seconds a `git` command will be given to complete before being sent a KILL
224
- signal. This library may hang if the `git` command does not terminate after receiving
225
- the KILL signal.
223
+ The timeout value must be a real, non-negative `Numeric` value that specifies the
224
+ number of seconds a `git` command is given to complete before being sent a KILL
225
+ signal. This library may hang if the `git` command does not terminate after
226
+ receiving the KILL signal.
226
227
 
227
- When a command times out, it is killed by sending it the `SIGKILL` signal and a
228
- `Git::TimeoutError` is raised. This error derives from the `Git::SignaledError` and
229
- `Git::Error`.
228
+ When a command times out, the gem kills it with the `SIGKILL` signal and raises a
229
+ `Git::TimeoutError`. This error derives from `Git::SignaledError` and `Git::Error`.
230
230
 
231
- If the timeout value is `0` or `nil`, no timeout will be enforced.
231
+ If the timeout value is `0` or `nil`, no timeout is enforced.
232
232
 
233
- If a method accepts a `:timeout` parameter and a receives a non-nil value, the value
234
- of this parameter will override the global timeout value. In this context, a value of
235
- `nil` (which is usually the default) will use the global timeout value and a value of
236
- `0` will turn off timeout enforcement for that method call no matter what the global
237
- value is.
233
+ If a method accepts a `:timeout` parameter and receives a non-nil value, that value
234
+ overrides the global timeout. In this context, a value of `nil`, which is usually
235
+ the default, uses the global timeout value, and a value of `0` turns off timeout
236
+ enforcement for that method call no matter what the global value is.
238
237
 
239
238
  To set a global timeout, use the `Git.config` object:
240
239
 
@@ -254,7 +253,7 @@ Git.clone(repo_url, timeout: 0) # Do not enforce a timeout
254
253
  Git.clone(repo_url, timeout: 10.5) # Timeout after 10.5 seconds raising Git::TimeoutError
255
254
  ```
256
255
 
257
- If the command takes too long, a `Git::TimeoutError` will be raised:
256
+ If the command takes too long, the gem raises `Git::TimeoutError`:
258
257
 
259
258
  ```ruby
260
259
  begin
@@ -297,22 +296,22 @@ See [the Active Support Deprecation
297
296
  documentation](https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html)
298
297
  for more details.
299
298
 
300
- If deprecation warnings are silenced, you should reenable them before upgrading the
301
- git gem to the next major version. This will make it easier to identify changes
302
- needed for the upgrade.
299
+ If you silence deprecation warnings, reenable them before upgrading the git gem to
300
+ the next major version. This makes it easier to identify changes needed for the
301
+ upgrade.
303
302
 
304
303
  For the full list of deprecated methods and their replacements, see
305
304
  [UPGRADING.md](UPGRADING.md).
306
305
 
307
- ## Platform Limitations
306
+ ## Platform limitations
308
307
 
309
- ### Regex Metacharacters on Git for Windows
308
+ ### Regex metacharacters on Git for Windows
310
309
 
311
310
  On Git for Windows, git's regex engine matches **bytes** rather than characters. A
312
311
  metacharacter such as `.`, or a POSIX character class such as `[[:alpha:]]`, therefore
313
312
  never matches a whole multi-byte character. The same call matches on Linux and macOS.
314
313
 
315
- The failure is silent nothing raises, and the result is indistinguishable from a
314
+ The failure is silent. Nothing raises, and the result is indistinguishable from a
316
315
  pattern that genuinely does not occur:
317
316
 
318
317
  ```ruby
@@ -340,9 +339,10 @@ repo.full_log_commits(grep: '^.PFEL', perl_regexp: true)
340
339
 
341
340
  Two caveats:
342
341
 
343
- - **PCRE is a different dialect** than git's default POSIX basic/extended regular
344
- expressions. Selecting it is a deliberate choice by the caller, so the gem does not
345
- substitute it automatically based on the host.
342
+ - **PCRE is a different dialect.** Git's other modes are POSIX basic regular
343
+ expressions (the default) and POSIX extended regular expressions (selected
344
+ explicitly). Selecting PCRE is a deliberate choice by the caller, so the gem does
345
+ not substitute it automatically based on the host.
346
346
  - **PCRE must be compiled in.** Git for Windows and the mainstream Linux and macOS
347
347
  packages ship it, but git built without `USE_LIBPCRE` fails with `cannot use
348
348
  Perl-compatible regexes...`.
@@ -353,23 +353,23 @@ regular expressions with no PCRE mode, so `config_get`, `config_get_all`,
353
353
  match a metacharacter against a non-ASCII character on Git for Windows. Match on ASCII
354
354
  text or an exact value instead.
355
355
 
356
- `config_replace_all` deserves particular care, because there the failure is not merely an
357
- empty result. When the value pattern selects nothing, `git config --replace-all` *adds*
358
- the new value as an additional entry rather than replacing one, and exits zero:
356
+ `config_replace_all` deserves particular care, because there the failure is worse than
357
+ an empty result. When the value pattern selects nothing, `git config --replace-all`
358
+ *adds* the new value as an additional entry rather than replacing one, and exits zero:
359
359
 
360
360
  ```ruby
361
361
  # Existing value of test.desc is 'ÄPFEL sind gut'
362
362
  repo.config_replace_all('test.desc', 'NEW', '^.PFEL')
363
363
 
364
364
  repo.config_get_all('test.desc').map(&:value)
365
- # => ["NEW"] elsewhere replaced, as intended
366
- # => ["ÄPFEL sind gut", "NEW"] on Windows original kept, duplicate added
365
+ # => ["NEW"] elsewhere, replaced as intended
366
+ # => ["ÄPFEL sind gut", "NEW"] on Windows, original kept and duplicate added
367
367
  ```
368
368
 
369
369
  So a replace can silently leave the original value in place and add a second entry beside
370
370
  it. Confirm with `config_get_all` when the key must end up single-valued.
371
371
 
372
- ## Project Policies
372
+ ## Project policies
373
373
 
374
374
  These documents set expectations for behavior, contribution workflows, AI-assisted
375
375
  changes, decision making, maintainer roles, and licensing. Please review them before
@@ -386,7 +386,7 @@ opening issues or pull requests.
386
386
  | [MAINTAINERS](MAINTAINERS.md) | Lists active maintainers (Project Lead noted) and emeritus alumni with links; see governance for role scope. |
387
387
  | [LICENSE](LICENSE) | MIT License terms for using, modifying, and redistributing this project. |
388
388
 
389
- ### Ruby Version Support Policy
389
+ ### Ruby version support policy
390
390
 
391
391
  This gem is expected to function correctly on:
392
392
 
@@ -395,18 +395,18 @@ This gem is expected to function correctly on:
395
395
  - The latest version of JRuby 9.4+ on Linux
396
396
  - The latest version of TruffleRuby 24+ on Linux
397
397
 
398
- It is this project's intent to support the latest version of JRuby on Windows once
398
+ This project intends to support the latest version of JRuby on Windows once
399
399
  the [process_executer](https://github.com/main-branch/process_executer) gem properly
400
400
  supports subprocess status reporting on JRuby for Windows (see
401
401
  [main-branch/process_executer#156](https://github.com/main-branch/process_executer/issues/156)).
402
402
 
403
- ### Git Version Support Policy
403
+ ### Git version support policy
404
404
 
405
405
  This gem requires git version 2.28.0 or greater as specified in the gemspec. This
406
406
  requirement reflects:
407
407
 
408
408
  - The minimum git version necessary to support all features provided by this gem
409
- - A reasonable balance between supporting older systems and leveraging modern git
409
+ - A reasonable balance between supporting older systems and using modern git
410
410
  capabilities
411
411
  - The practical limitations of testing across multiple git versions in CI
412
412
 
@@ -416,16 +416,31 @@ guaranteed. Users on older git versions should upgrade to at least 2.28.0.
416
416
 
417
417
  The supported git version may be increased in future major or minor releases of this
418
418
  gem as new git features are adopted or as maintaining backward compatibility becomes
419
- impractical. Such changes will be clearly documented in the CHANGELOG and release
420
- notes.
419
+ impractical. Such changes will be documented in the CHANGELOG and release notes.
421
420
 
422
- ## Project Announcements
421
+ ## Project announcements
423
422
 
424
- ### 2026-07-28: v5.0.0 Released
423
+ ### 2026-08-23: v5.x deprecations and the v6.0.0 roadmap
425
424
 
426
- We have published [`git v5.0.0`](https://rubygems.org/gems/git/versions/5.0.0)
427
- the first stable release of the v5.x series, after five public beta releases
428
- spanning June–July 2026.
425
+ The road to v6.0.0 is now planned and public. The remaining ActiveRecord-style
426
+ classes (`Git::Branch`, `Git::Remote`, `Git::Stash`, `Git::Worktree`,
427
+ `Git::Object::Tag`, `Git::Status`, `Git::Author`, and their collections) will be
428
+ deprecated during the v5.x series in favor of the immutable `*Info` value-object
429
+ APIs. v6.0.0 will remove each deprecated class that passes the project's removal
430
+ gate: a mandated deprecation soak period plus a proven-safe check. Any class that
431
+ does not pass carries forward, still deprecated. v6.0.0 also raises the version
432
+ floors: git ≥ 2.42.0, Ruby ≥ 3.4.
433
+
434
+ [Issue #1717](https://github.com/ruby-git/ruby-git/issues/1717) is the living
435
+ roadmap, tracking scope, sequencing, and status. If your code uses the classes
436
+ above, you can start migrating now. Each deprecation names its replacement, and
437
+ [UPGRADING.md](UPGRADING.md) carries the migration guide as releases ship.
438
+
439
+ ### 2026-07-28: v5.0.0 released
440
+
441
+ We have published [`git v5.0.0`](https://rubygems.org/gems/git/versions/5.0.0), the
442
+ first stable release of the v5.x series, after five public beta releases in June and
443
+ July 2026.
429
444
 
430
445
  **v5.0.0 is a major release with breaking changes.** See
431
446
  [UPGRADING.md](UPGRADING.md) for the complete migration guide.
@@ -442,100 +457,85 @@ Or:
442
457
  gem install git
443
458
  ```
444
459
 
445
- Most v4.x code requires **no changes** compatibility shims keep the old API
446
- working while emitting deprecation warnings that tell you what to migrate before
447
- v6.0.0.
460
+ Most v4.x code requires no changes. Compatibility shims keep the old API working
461
+ while emitting deprecation warnings that tell you what to migrate before v6.0.0.
448
462
 
449
- ### 2026-01-07: AI Policy Introduced
463
+ ### 2026-01-07: AI policy introduced
450
464
 
451
465
  We have adopted a formal [AI Policy](AI_POLICY.md) to clarify expectations for
452
466
  AI-assisted contributions. Please review it before opening a PR to ensure your
453
467
  changes are fully understood, meet our quality bar, and respect licensing
454
468
  requirements.
455
469
 
456
- We chose a principles-based policy to respect contributors time and expertise. It’s
457
- quick to read, easy to remember, and avoids unnecessary policy overhead while still
458
- setting clear expectations.
459
-
460
- ### 2025-07-09: Architectural Redesign
461
-
462
- The git gem is undergoing a significant architectural redesign for the upcoming
463
- v5.0.0 release. The current architecture has several design challenges that make it
464
- difficult to maintain and evolve. This redesign aims to address these issues by
465
- introducing a clearer, more robust, and more testable structure.
470
+ We chose a principles-based policy to respect contributors' time and expertise. It
471
+ is quick to read and easy to remember, and it still sets clear expectations.
466
472
 
467
- We have prepared detailed documents outlining the analysis of the current
468
- architecture and the proposed changes. We encourage our community and contributors to
469
- review them:
473
+ ### 2025-07-09: Architectural redesign
470
474
 
471
- 1. [Analysis of the Current Architecture](redesign/1_architecture_existing.md): A
472
- breakdown of the existing design and its challenges.
473
- 2. [The Proposed Redesign](redesign/2_architecture_redesign.md): An overview of the
474
- new three-layered architecture.
475
- 3. [Implementation Plan](redesign/3_architecture_implementation.md): The step-by-step
476
- plan for implementing the redesign.
475
+ On this date we announced an architectural redesign of the git gem. The architecture
476
+ at the time was difficult to maintain and evolve; the redesign replaced it with a
477
+ clearer, more testable three-layer structure of commands, parsers, and a
478
+ `Git::Repository` facade.
477
479
 
478
- Your feedback is welcome! Please feel free to open an issue to discuss the proposed
479
- changes.
480
+ **The redesign shipped in v5.0.0 and is complete.** `Git::Base` and `Git::Lib` are
481
+ gone, along with the `g.lib` accessor. See [UPGRADING.md](UPGRADING.md) for what
482
+ changed and how to migrate.
480
483
 
481
- > **DON'T PANIC!**
482
- >
483
- > While this is a major internal refactoring, our goal is to keep the primary public
484
- API on the main repository object as stable as possible. Most users who rely on
485
- documented methods like `g.commit`, `g.add`, and `g.status` should find the
486
- transition to v5.0.0 straightforward.
487
- >
488
- > The breaking changes will primarily affect users who have been relying on the
489
- internal g.lib accessor, which will be removed as part of this cleanup. For more
490
- details, please see the "Impact on Users" section in [the redesign
491
- document](redesign/2_architecture_redesign.md).
484
+ The three documents written to plan it are kept as a historical record in
485
+ [`archive/v5-redesign/`](archive/v5-redesign/). They describe the state of the code
486
+ before and during the migration and are not current policy. The standards that apply
487
+ to new code live in [`.github/skills/`](.github/skills/).
492
488
 
493
- ### 2025-07-07: We Now Use RuboCop
489
+ 1. [Analysis of the Current Architecture](archive/v5-redesign/1_architecture_existing.md):
490
+ a breakdown of the v4.x design and its challenges.
491
+ 2. [The Proposed Redesign](archive/v5-redesign/2_architecture_redesign.md): an overview
492
+ of the three-layer architecture.
493
+ 3. [Implementation Plan](archive/v5-redesign/3_architecture_implementation.md): the
494
+ step-by-step plan that was followed.
494
495
 
495
- To improve code consistency and maintainability, the `ruby-git` project has now
496
- adopted [RuboCop](https://rubocop.org/) as our static code analyzer and formatter.
496
+ ### 2025-07-07: We now use RuboCop
497
497
 
498
- This integration is a key part of our ongoing commitment to making `ruby-git` a
499
- high-quality, stable, and easy-to-contribute-to project. All new contributions will
500
- be expected to adhere to the style guidelines enforced by our RuboCop configuration.
498
+ To improve code consistency and maintainability, the `ruby-git` project has adopted
499
+ [RuboCop](https://rubocop.org/) as our static code analyzer and formatter. All new
500
+ contributions must follow the style guidelines enforced by our RuboCop
501
+ configuration.
501
502
 
502
- RuboCop can be run from the project's Rakefile:
503
+ Run RuboCop from the project's Rakefile:
503
504
 
504
505
  ```shell
505
506
  rake rubocop
506
507
  ```
507
508
 
508
- RuboCop is also run as part of the default rake task (by running `rake`) that is run
509
- in our Continuous Integration workflow.
509
+ RuboCop also runs as part of the default rake task, which our continuous integration
510
+ workflow runs.
510
511
 
511
- Going forward, any PRs that have any Robocop offenses will not be merged. In certain
512
- rare cases, it might be acceptable to disable a RuboCop check for the most limited
513
- scope possible.
512
+ PRs with RuboCop offenses will not be merged. In rare cases, it might be acceptable
513
+ to disable a RuboCop check for the most limited scope possible.
514
514
 
515
- If you have a problem fixing a RuboCop offense, don't be afraid to ask a
515
+ If you have a problem fixing a RuboCop offense, don't be afraid to ask a
516
516
  contributor.
517
517
 
518
- ### 2025-06-06: Default Branch Rename
518
+ ### 2025-06-06: Default branch rename
519
519
 
520
- On June 6th, 2025, the default branch was renamed from 'master' to 'main'.
520
+ On June 6, 2025, we renamed the default branch from `master` to `main`.
521
521
 
522
- Instructions for renaming your local or forked branch to match can be found in the
523
- gist [Default Branch Name
522
+ Instructions for renaming your local or forked branch to match are in the gist
523
+ [Default Branch Name
524
524
  Change](https://gist.github.com/jcouball/580a10e395f7fdfaaa4297bbe816cc7d).
525
525
 
526
- ### 2025-05-15: We've Switched to Conventional Commits
526
+ ### 2025-05-15: We've switched to Conventional Commits
527
527
 
528
- To enhance our development workflow, enable automated changelog generation, and pave
529
- the way for Continuous Delivery, the `ruby-git` project has adopted the [Conventional
530
- Commits standard](https://www.conventionalcommits.org/en/v1.0.0/) for all commit
531
- messages.
528
+ The `ruby-git` project has adopted the [Conventional Commits
529
+ standard](https://www.conventionalcommits.org/en/v1.0.0/) for all commit messages.
530
+ This enables automated changelog generation and is a step toward continuous
531
+ delivery.
532
532
 
533
- Going forward, all commits to this repository **MUST** adhere to the Conventional
534
- Commits standard. Commits not adhering to this standard will cause the CI build to
535
- fail. PRs will not be merged if they include non-conventional commits.
533
+ All commits to this repository must follow the Conventional Commits standard.
534
+ Commits that do not follow it will fail the CI build, and PRs that include them will
535
+ not be merged.
536
536
 
537
- A git pre-commit hook may be installed to validate your conventional commit messages
538
- before pushing them to GitHub by running `bin/setup` in the project root.
537
+ To validate your commit messages locally before pushing them to GitHub, install the
538
+ git `commit-msg` hook by running `bin/setup` in the project root.
539
539
 
540
540
  Read more about this change in the [Commit Message Guidelines section of
541
- CONTRIBUTING.md](CONTRIBUTING.md#commit-message-guidelines)
541
+ CONTRIBUTING.md](CONTRIBUTING.md#commit-message-guidelines).
data/git.gemspec CHANGED
@@ -43,7 +43,7 @@ Gem::Specification.new do |spec|
43
43
 
44
44
  spec.add_dependency 'activesupport', '>= 5.0'
45
45
  spec.add_dependency 'addressable', '~> 2.8'
46
- spec.add_dependency 'process_executer', '~> 4.0'
46
+ spec.add_dependency 'process_executer', '~> 4.1'
47
47
  spec.add_dependency 'rchardet', '~> 1.9'
48
48
 
49
49
  # Not every development dependency is installed on every runtime. Each predicate
@@ -101,8 +101,40 @@ Gem::Specification.new do |spec|
101
101
  spec.add_development_dependency 'yard-lint', '~> 1.8' if install_yard_lint
102
102
 
103
103
  # Specify which files should be added to the gem when it is released.
104
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
104
+ #
105
+ # This is an allowlist rather than a denylist. A denylist admitted every new
106
+ # development-only path by default, so the gem shipped `.github/`, `tasks/`, the
107
+ # husky hooks, and -- the reason this became an allowlist -- the `.claude/skills`
108
+ # symlink. Extracting a symlink needs a privilege that Windows grants only under
109
+ # Developer Mode or an elevated shell, so installing the gem there either failed
110
+ # outright or, on RubyGems new enough to fall back to a copy, silently duplicated
111
+ # the whole skills tree into the installed gem.
112
+ #
113
+ # spec/unit/gemspec_spec.rb guards both directions: nothing in the list may be a
114
+ # symlink, and every tracked file under lib/ must be present, so the allowlist
115
+ # cannot quietly drop runtime code.
116
+ #
117
+ # doc_files must stay in sync with the extra files named in .yardopts -- those are
118
+ # what rubydoc.info renders for the published documentation, so a file listed there
119
+ # but absent from the gem becomes a broken link.
120
+ doc_files = %w[
121
+ AI_POLICY.md
122
+ CHANGELOG.md
123
+ CODE_OF_CONDUCT.md
124
+ CONTRIBUTING.md
125
+ GOVERNANCE.md
126
+ LICENSE
127
+ MAINTAINERS.md
128
+ README.md
129
+ UPGRADING.md
130
+ ]
131
+
132
+ # .yardopts drives the rubydoc.info build; the gemspec is included by convention.
133
+ build_files = %w[.yardopts git.gemspec]
134
+
105
135
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
106
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(tests|spec|features|bin)/}) }
136
+ `git ls-files -z`.split("\x0").select do |f|
137
+ f.start_with?('lib/') || doc_files.include?(f) || build_files.include?(f)
138
+ end
107
139
  end
108
140
  end
@@ -232,7 +232,7 @@ module Git
232
232
  #
233
233
  # @api private
234
234
  #
235
- # rubocop:disable Metrics/ParameterLists
235
+ # rubocop:disable-next Metrics/ParameterLists
236
236
  def command_line_result(command, result, processed_out, processed_err, timeout, raise_on_failure)
237
237
  Git::CommandLine::Result.new(command, result, processed_out, processed_err).tap do |processed_result|
238
238
  raise Git::TimeoutError.new(processed_result, timeout) if result.timed_out?
@@ -242,7 +242,6 @@ module Git
242
242
  raise Git::FailedError, processed_result if raise_on_failure && !result.success?
243
243
  end
244
244
  end
245
- # rubocop:enable Metrics/ParameterLists
246
245
  end
247
246
  end
248
247
  end
@@ -453,7 +453,7 @@ module Git
453
453
  #
454
454
  # @example Feed bound object names to a git batch command
455
455
  # bound = args_definition.bind(*args, **kwargs)
456
- # stdin_content = Array(bound.objects).map { |object| "#{object}\n" }.join
456
+ # stdin_content = Array(bound.object).map { |object| "#{object}\n" }.join
457
457
  # with_stdin(stdin_content) do |reader|
458
458
  # @execution_context.command_capturing('cat-file', '--batch-check', in: reader, raise_on_failure: false)
459
459
  # end
@@ -49,9 +49,10 @@ module Git
49
49
  # See https://git-scm.com/docs/git-cat-file#Documentation/git-cat-file.txt--s
50
50
  flag_option :s
51
51
 
52
- # Allow -t and -s to query broken or corrupt objects of unknown type;
53
- # rejected by git in any other mode enforced by constraint below
54
- # See https://git-scm.com/docs/git-cat-file#Documentation/git-cat-file.txt---allow-unknown-type
52
+ # Allow -t and -s to query broken or corrupt objects of unknown type.
53
+ # Git 2.28-2.49 rejects this flag in other modes; git 2.50+ accepts and
54
+ # ignores it everywhere (the unknown-type feature was removed; see issue 1709).
55
+ # See https://git-scm.com/docs/git-cat-file/2.49.0#Documentation/git-cat-file.txt---allow-unknown-type
55
56
  flag_option :allow_unknown_type
56
57
 
57
58
  # Map committer/author identities through the mailmap before reporting size
@@ -74,8 +75,6 @@ module Git
74
75
 
75
76
  # Object name: SHA, ref, `HEAD`, treeish path reference, etc.
76
77
  operand :object, required: true
77
-
78
- requires_one_of :t, :s, when: :allow_unknown_type
79
78
  end
80
79
 
81
80
  # Execute `git cat-file` for a single object.
@@ -114,7 +113,8 @@ module Git
114
113
  # @param options [Hash] command options
115
114
  #
116
115
  # @option options [Boolean, nil] :allow_unknown_type (nil) allow querying broken or corrupt objects of
117
- # unknown type
116
+ # unknown type on git 2.28-2.49; git 2.50 removed the unknown-type feature
117
+ # and accepts this flag as a no-op
118
118
  #
119
119
  # @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
120
120
  #
@@ -138,7 +138,8 @@ module Git
138
138
  # @param options [Hash] command options
139
139
  #
140
140
  # @option options [Boolean, nil] :allow_unknown_type (nil) allow querying broken or corrupt objects of
141
- # unknown type
141
+ # unknown type on git 2.28-2.49; git 2.50 removed the unknown-type feature
142
+ # and accepts this flag as a no-op
142
143
  #
143
144
  # @option options [Boolean, nil] :use_mailmap (nil) remap identities via mailmap (`--use-mailmap`)
144
145
  #