git 4.0.7 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/copilot-instructions.md +2212 -330
- data/.release-please-manifest.json +1 -1
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +24 -0
- data/README.md +52 -3
- data/lib/git/base.rb +83 -10
- data/lib/git/diff.rb +40 -2
- data/lib/git/diff_path_status.rb +1 -1
- data/lib/git/lib.rb +190 -14
- data/lib/git/version.rb +1 -1
- data/lib/git.rb +39 -0
- metadata +3 -3
|
@@ -5,347 +5,2219 @@
|
|
|
5
5
|
ruby-git is a Ruby gem that provides a Ruby interface to Git repositories.
|
|
6
6
|
|
|
7
7
|
The git gem wraps system calls to the `git` command line and provides an API to:
|
|
8
|
+
|
|
8
9
|
- Create, read, and manipulate Git repositories
|
|
9
10
|
- Work with branches, commits, tags, and remotes
|
|
10
11
|
- Inspect repository history and objects
|
|
11
12
|
- Perform Git operations like merge, clone, fetch, push, etc.
|
|
12
13
|
- Handle complex interactions including branching, merging, and patch generation
|
|
13
14
|
|
|
14
|
-
**Current Status:** Stable project supporting Ruby 3.2.0+ minimum and Git 2.28.0+.
|
|
15
|
-
Compatible with MRI Ruby 3.2+ on Mac, Linux, and Windows.
|
|
15
|
+
**Current Status:** Stable project supporting Ruby 3.2.0+ minimum and Git 2.28.0+.
|
|
16
|
+
Compatible with MRI Ruby 3.2+ on Mac, Linux, and Windows.
|
|
17
|
+
|
|
18
|
+
## AI Use Cases
|
|
19
|
+
|
|
20
|
+
This document guides AI agents in handling the following types of tasks. Each
|
|
21
|
+
category includes a link to the workflow that should be followed.
|
|
22
|
+
|
|
23
|
+
### Issue Triage & Investigation
|
|
24
|
+
|
|
25
|
+
**→ Use [Development Workflow](#development-workflow) (Phase 0: TRIAGE only -- do not proceed to implementation)**
|
|
26
|
+
|
|
27
|
+
- **"Diagnose issue #999"** - Investigate reported issues, identify root causes, and
|
|
28
|
+
report findings without implementing changes
|
|
29
|
+
- **"Is issue #999 a bug or feature request?"** - Analyze and categorize issues
|
|
30
|
+
- **"Check if issue #999 is a duplicate"** - Search for similar existing issues
|
|
31
|
+
- **"Respond to issue #999"** - Answer questions or provide clarification on issues
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
**→ Use [Development Workflow](#development-workflow) (Phases 0-3: TRIAGE → PREPARE → EXECUTE → FINALIZE)**
|
|
36
|
+
|
|
37
|
+
- **"Fix issue #999"** - Implement a fix for a reported bug following the full TDD
|
|
38
|
+
workflow (diagnose → implement → test → PR)
|
|
39
|
+
- **"Fix the timeout handling in Git::CommandLine"** - Address specific bugs in the
|
|
40
|
+
codebase
|
|
41
|
+
|
|
42
|
+
### Feature Implementation
|
|
43
|
+
|
|
44
|
+
**→ Use [Development Workflow](#development-workflow) (Phases 0-3: TRIAGE → PREPARE → EXECUTE → FINALIZE)**
|
|
45
|
+
|
|
46
|
+
- **"Implement issue #999"** - Build new features requested in issues
|
|
47
|
+
- **"Add support for git worktree commands"** - Implement specific functionality
|
|
48
|
+
- **"Implement the feature requested in issue #999 and create a PR"** - Full
|
|
49
|
+
implementation workflow ending with PR creation
|
|
50
|
+
|
|
51
|
+
### Code Improvements
|
|
52
|
+
|
|
53
|
+
**→ Use [Development Workflow](#development-workflow) (Phases 1-3: PREPARE → EXECUTE → FINALIZE)**
|
|
54
|
+
|
|
55
|
+
- **"Refactor the Git::Branch class to reduce duplication"** - Improve code quality
|
|
56
|
+
without changing behavior
|
|
57
|
+
- **"Add missing YARD documentation to Git::Base methods"** - Enhance documentation
|
|
58
|
+
- **"Add tests for Git::Remote#fetch"** - Improve test coverage
|
|
59
|
+
|
|
60
|
+
### Pull Request Review
|
|
61
|
+
|
|
62
|
+
**→ Use [Pull Request Review Workflow](#pull-request-review-workflow)**
|
|
63
|
+
|
|
64
|
+
- **"Review PR #999"** - Review a pull request, analyze changes against project
|
|
65
|
+
standards, and post review comments
|
|
66
|
+
- **"Review PR #999 and approve if it looks good"** - Perform review with potential
|
|
67
|
+
approval
|
|
68
|
+
- **"Check if PR #999 follows our coding standards"** - Focused review on specific
|
|
69
|
+
criteria
|
|
70
|
+
|
|
71
|
+
### Maintenance Tasks
|
|
72
|
+
|
|
73
|
+
**→ Use [Development Workflow](#development-workflow) (Phases 1-3: PREPARE → EXECUTE → FINALIZE)**
|
|
74
|
+
|
|
75
|
+
- **"Update Ruby version support"** - Modify compatibility requirements
|
|
76
|
+
- **"Fix rubocop violations in lib/git/base.rb"** - Address linting issues
|
|
77
|
+
- **"Run the test suite and fix any failures"** - Ensure code quality
|
|
78
|
+
|
|
79
|
+
### Dependency Management
|
|
80
|
+
|
|
81
|
+
**→ Use [Dependency Management Workflow](#dependency-management-workflow)**
|
|
82
|
+
|
|
83
|
+
- **"Update all gem dependencies"** - Update dependencies to latest versions
|
|
84
|
+
- **"Check for outdated dependencies"** - List gems that have newer versions available
|
|
85
|
+
- **"Fix security vulnerabilities in dependencies"** - Address CVEs and security issues
|
|
86
|
+
- **"Update \<gem-name\> to version X.Y.Z"** - Update a specific dependency
|
|
87
|
+
|
|
88
|
+
### Test Debugging & Maintenance
|
|
89
|
+
|
|
90
|
+
**→ Use [Test Debugging & Maintenance Workflow](#test-debugging--maintenance-workflow)**
|
|
91
|
+
|
|
92
|
+
- **"Why is test_branch failing?"** - Debug consistently failing tests
|
|
93
|
+
- **"Fix flaky test in test_remote.rb"** - Address intermittent test failures
|
|
94
|
+
- **"Debug intermittent test failure"** - Investigate non-deterministic test behavior
|
|
95
|
+
- **"Improve test coverage for Git::Base#add"** - Add missing tests for existing code
|
|
96
|
+
|
|
97
|
+
### CI/CD Troubleshooting
|
|
98
|
+
|
|
99
|
+
**→ Use [CI/CD Troubleshooting Workflow](#cicd-troubleshooting-workflow)**
|
|
100
|
+
|
|
101
|
+
- **"Why is CI failing on PR #999?"** - Diagnose CI/CD failures and report root causes
|
|
102
|
+
- **"Fix the failing GitHub Actions build"** - Investigate and resolve CI failures
|
|
103
|
+
- **"Debug test failures in CI for PR #999"** - Identify why tests pass locally but fail in CI
|
|
104
|
+
- **"Check CI status for this branch"** - View current build status
|
|
105
|
+
|
|
106
|
+
### Code Review & Analysis
|
|
107
|
+
|
|
108
|
+
**→ No specific workflow required (use standard code analysis techniques)**
|
|
109
|
+
|
|
110
|
+
- **"Review the changes in this file"** - Analyze code quality and suggest
|
|
111
|
+
improvements
|
|
112
|
+
- **"Explain how Git::CommandLine handles timeouts"** - Provide code explanations
|
|
113
|
+
- **"What would break if we change this method signature?"** - Impact analysis
|
|
114
|
+
|
|
115
|
+
### Merge Conflict Resolution
|
|
116
|
+
|
|
117
|
+
**→ Use [Merge Conflict Resolution Workflow](#merge-conflict-resolution-workflow)**
|
|
118
|
+
|
|
119
|
+
- **"Resolve merge conflicts in PR #999"** - Help resolve conflicts in a pull request
|
|
120
|
+
- **"Help merge feature branch into main"** - Assist with branch merging and conflict
|
|
121
|
+
resolution
|
|
122
|
+
- **"Show merge conflicts between branches"** - Identify conflicting changes before
|
|
123
|
+
merging
|
|
124
|
+
|
|
125
|
+
### Code Archaeology & History Analysis
|
|
126
|
+
|
|
127
|
+
**→ Use [Code Archaeology & History Analysis Workflow](#code-archaeology--history-analysis-workflow)**
|
|
128
|
+
|
|
129
|
+
- **"When was this bug introduced?"** - Use git bisect to find the commit that
|
|
130
|
+
introduced a bug
|
|
131
|
+
- **"Find all callers of Git::Base#checkout"** - Search codebase for method usage
|
|
132
|
+
- **"Show the history of this method"** - Track changes to specific code over time
|
|
133
|
+
- **"Who last changed this file?"** - Use git blame to identify recent contributors
|
|
134
|
+
- **"What changed in this file between v1.0 and v2.0?"** - Compare file history
|
|
135
|
+
across versions
|
|
136
|
+
|
|
137
|
+
### Release Management
|
|
138
|
+
|
|
139
|
+
**→ Use [Release Management Workflow](#release-management-workflow)**
|
|
140
|
+
|
|
141
|
+
- **"Prepare a new release"** - Guide through version bump, changelog, and release
|
|
142
|
+
process
|
|
143
|
+
- **"Generate release notes from recent PRs"** - Compile changes since last release
|
|
144
|
+
- **"What PRs are included in this release?"** - List merged PRs between versions
|
|
145
|
+
- **"Tag and publish a release"** - Create git tags and publish gem
|
|
146
|
+
- **"Check release readiness"** - Verify all checks pass before release
|
|
147
|
+
|
|
148
|
+
### Breaking Change Analysis
|
|
149
|
+
|
|
150
|
+
**→ Use [Breaking Change Analysis Workflow](#breaking-change-analysis-workflow)**
|
|
151
|
+
|
|
152
|
+
- **"What would break if we remove this method?"** - Assess impact of deprecation
|
|
153
|
+
- **"Find all usages of deprecated API"** - Search for code using deprecated features
|
|
154
|
+
- **"Assess impact of changing this interface"** - Analyze downstream effects of API
|
|
155
|
+
changes
|
|
156
|
+
- **"List all public API methods"** - Enumerate the public interface for audit
|
|
157
|
+
|
|
158
|
+
### Documentation Tasks
|
|
159
|
+
|
|
160
|
+
**→ Use [Documentation Workflow](#documentation-workflow)**
|
|
161
|
+
|
|
162
|
+
- **"Generate missing YARD documentation"** - Add documentation to undocumented
|
|
163
|
+
methods
|
|
164
|
+
- **"Update README examples to match current API"** - Keep examples current
|
|
165
|
+
- **"Fix documentation errors"** - Correct inaccurate or outdated documentation
|
|
166
|
+
- **"Document this class/method"** - Add comprehensive YARD documentation
|
|
167
|
+
- **"Check documentation coverage"** - Identify undocumented public methods
|
|
168
|
+
|
|
169
|
+
## Architecture & Module Organization
|
|
170
|
+
|
|
171
|
+
The codebase is structured to separate high-level API interactions from low-level
|
|
172
|
+
command execution, ensuring maintainability and testability. ruby-git follows a
|
|
173
|
+
modular architecture:
|
|
174
|
+
|
|
175
|
+
- **Git::Base** - Main interface for repository operations (most major actions)
|
|
176
|
+
- **Git::Lib** - Low-level Git command execution via system calls
|
|
177
|
+
- **Git::CommandLine** - Handles Git command construction and execution with timeout
|
|
178
|
+
support
|
|
179
|
+
- **Git Objects** - Repository objects (Commit, Tree, Blob, Tag) via `Git::Object`
|
|
180
|
+
- **Git::Status** - Working directory status (tracked/untracked/modified files)
|
|
181
|
+
- **Git::Diff** - Diff operations returning file-level patches and statistics
|
|
182
|
+
- **Git::Log** - Enumerable query builder for commit history
|
|
183
|
+
- **Git::Branch/Branches** - Branch management (local and remote)
|
|
184
|
+
- **Git::Remote** - Remote repository references
|
|
185
|
+
- **Git::Worktree/Worktrees** - Git worktree support
|
|
186
|
+
- **Git::Stash/Stashes** - Stash management
|
|
187
|
+
|
|
188
|
+
Key directories:
|
|
189
|
+
|
|
190
|
+
- `lib/git/` - Core library code
|
|
191
|
+
- `tests/units/` - Test::Unit test suite
|
|
192
|
+
- `doc/` - YARD-generated documentation
|
|
193
|
+
- `pkg/` - Built gem packages
|
|
194
|
+
- `redesign/` - Architecture redesign documentation
|
|
195
|
+
|
|
196
|
+
## Coding Standards
|
|
197
|
+
|
|
198
|
+
High-quality code is essential for the long-term maintenance of this library. Adhere
|
|
199
|
+
to the following standards to ensure consistency, readability, and reliability across
|
|
200
|
+
the codebase.
|
|
201
|
+
|
|
202
|
+
### Ruby Style
|
|
203
|
+
|
|
204
|
+
To ensure code consistency and leverage modern Ruby features, adhere to the following
|
|
205
|
+
style guidelines:
|
|
206
|
+
|
|
207
|
+
- Use `frozen_string_literal: true` at the top of all Ruby files
|
|
208
|
+
- Follow Ruby community style guide (Rubocop-compatible)
|
|
209
|
+
- Require Ruby 3.2.0+ features and idioms
|
|
210
|
+
- Use keyword arguments for methods with multiple parameters
|
|
211
|
+
- Prefer `private` over `private :method_name` for method visibility
|
|
212
|
+
- Use pattern matching for complex conditional logic where appropriate
|
|
213
|
+
|
|
214
|
+
### Code Organization
|
|
215
|
+
|
|
216
|
+
To maintain a clean, modular, and navigable codebase, structure your code according
|
|
217
|
+
to these principles:
|
|
218
|
+
|
|
219
|
+
- Keep classes focused and single-responsibility
|
|
220
|
+
- Use modules for mixins and namespace organization
|
|
221
|
+
- Place related classes in the same file only if they're tightly coupled
|
|
222
|
+
- One public class per file as a general rule
|
|
223
|
+
- Core library code organized in `lib/git/` directory
|
|
224
|
+
|
|
225
|
+
### Naming Conventions
|
|
226
|
+
|
|
227
|
+
Follow these naming conventions to ensure code readability and consistency with the
|
|
228
|
+
existing codebase and idiomatic Ruby:
|
|
229
|
+
|
|
230
|
+
- Classes/Modules: PascalCase (e.g., `Git::Base`, `Git::Branch`, `Git::CommandLine`)
|
|
231
|
+
- Methods/variables: snake_case (e.g., `current_branch`, `ls_files`, `commit_all`)
|
|
232
|
+
- Constants: UPPER_SNAKE_CASE (e.g., `VERSION`)
|
|
233
|
+
- Predicate methods: end with `?` (e.g., `bare?`, `success?`, `exist?`)
|
|
234
|
+
- Dangerous methods: end with `!` if they modify in place
|
|
235
|
+
- Instance variables: `@variable_name`
|
|
236
|
+
- Avoid class variables; prefer class instance variables or constants
|
|
237
|
+
|
|
238
|
+
## Design Philosophy
|
|
239
|
+
|
|
240
|
+
**Note:** As of v2.x, this design philosophy is aspirational. Future versions may
|
|
241
|
+
include interface changes to fully align with these principles.
|
|
242
|
+
|
|
243
|
+
The git gem is designed as a lightweight wrapper around the `git` command-line tool,
|
|
244
|
+
providing a simple and intuitive Ruby interface for programmatically interacting with
|
|
245
|
+
Git.
|
|
246
|
+
|
|
247
|
+
### Principle of Least Surprise
|
|
248
|
+
|
|
249
|
+
The design should prioritize predictability and familiarity for users already
|
|
250
|
+
accustomed to the Git command line:
|
|
251
|
+
|
|
252
|
+
- Do not introduce unnecessary abstraction layers
|
|
253
|
+
- Do not modify Git's core functionality
|
|
254
|
+
- Maintain close alignment with the existing `git` command-line interface
|
|
255
|
+
- Avoid extensions or alterations that could lead to unexpected behaviors
|
|
256
|
+
- Allow users to leverage their existing knowledge of Git
|
|
257
|
+
|
|
258
|
+
### Direct Mapping to Git Commands
|
|
259
|
+
|
|
260
|
+
To maintain clarity and ease of use, the API should mirror the underlying Git
|
|
261
|
+
commands as closely as possible:
|
|
262
|
+
|
|
263
|
+
- Git commands are implemented within the `Git::Base` class
|
|
264
|
+
- Each method should directly correspond to a `git` command
|
|
265
|
+
- Example: `git add` → `Git::Base#add`, `git ls-files` → `Git::Base#ls_files`
|
|
266
|
+
- When a single Git command serves multiple distinct purposes, use the command name
|
|
267
|
+
as a prefix followed by a descriptive suffix
|
|
268
|
+
- Example: `#ls_files_untracked`, `#ls_files_staged`
|
|
269
|
+
- Introduce aliases to provide more user-friendly method names where appropriate
|
|
270
|
+
|
|
271
|
+
### Parameter Naming
|
|
272
|
+
|
|
273
|
+
Adopt a naming strategy that reinforces the connection to the Git CLI:
|
|
274
|
+
|
|
275
|
+
- Parameters are named after their corresponding long command-line options
|
|
276
|
+
- Ensures familiarity for developers already accustomed to Git
|
|
277
|
+
- Note: Not all Git command options are supported
|
|
278
|
+
|
|
279
|
+
### Output Processing
|
|
280
|
+
|
|
281
|
+
To provide a rich and idiomatic Ruby experience, process raw Git output into
|
|
282
|
+
structured objects when the output is important to the user:
|
|
283
|
+
|
|
284
|
+
- Translate Git command output into Ruby objects for easier programmatic use
|
|
285
|
+
- Ruby objects often include methods that allow for further Git operations
|
|
286
|
+
- Provide additional functionality while staying true to underlying Git behavior
|
|
287
|
+
|
|
288
|
+
### User Documentation
|
|
289
|
+
|
|
290
|
+
Comprehensive documentation is essential for a public library. Follow these
|
|
291
|
+
guidelines:
|
|
292
|
+
|
|
293
|
+
- Use YARD syntax for all public methods
|
|
294
|
+
- Include `@param`, `@return`, `@raise`, `@example` tags
|
|
295
|
+
- Document edge cases, platform differences, and security considerations
|
|
296
|
+
- Keep method documentation up-to-date with implementation
|
|
297
|
+
- Add `@api private` for internal-only methods
|
|
298
|
+
- Document Git version requirements and compatibility
|
|
299
|
+
|
|
300
|
+
Example:
|
|
301
|
+
|
|
302
|
+
```ruby
|
|
303
|
+
# Opens a Git repository
|
|
304
|
+
#
|
|
305
|
+
# @param [String, Pathname] path The path to the working directory or .git directory
|
|
306
|
+
# @param [Hash] options The options for this command (see list of valid options below)
|
|
307
|
+
# @option options [Logger] :log A logger to use for Git operations
|
|
308
|
+
# @option options [Numeric] :timeout Maximum seconds to wait for Git commands (0 for no timeout)
|
|
309
|
+
# @return [Git::Base] an object that can execute git commands in the context of the repository
|
|
310
|
+
# @raise [ArgumentError] if path is not a valid Git repository
|
|
311
|
+
# @example Open a repository
|
|
312
|
+
# git = Git.open('/path/to/repo')
|
|
313
|
+
# puts git.log.first.message
|
|
314
|
+
# @api public
|
|
315
|
+
def self.open(path, options = {})
|
|
316
|
+
# implementation
|
|
317
|
+
end
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Key Technical Details
|
|
321
|
+
|
|
322
|
+
This section outlines the critical technical mechanisms that power the gem.
|
|
323
|
+
Understanding these details is important for implementing new features or debugging
|
|
324
|
+
complex issues.
|
|
325
|
+
|
|
326
|
+
### Git Command Execution
|
|
327
|
+
|
|
328
|
+
All Git commands are executed through the `Git::CommandLine` class which:
|
|
329
|
+
|
|
330
|
+
- Constructs Git commands with proper argument escaping
|
|
331
|
+
- Handles environment variables and working directory context
|
|
332
|
+
- Manages command execution with timeout support
|
|
333
|
+
- Captures stdout, stderr, and exit status
|
|
334
|
+
- Raises appropriate errors on command failures
|
|
335
|
+
|
|
336
|
+
### Major Classes and Their Responsibilities
|
|
337
|
+
|
|
338
|
+
Understanding the core classes is crucial for navigating the codebase and ensuring
|
|
339
|
+
logic is placed correctly. The following list outlines the primary classes and their
|
|
340
|
+
specific responsibilities:
|
|
341
|
+
|
|
342
|
+
1. **Git::Base**: The main repository interface
|
|
343
|
+
- Entry point for most Git operations
|
|
344
|
+
- Delegates to `Git::Lib` for low-level operations
|
|
345
|
+
- Manages working directory, index, and repository references
|
|
346
|
+
- Returns domain objects (Branch, Status, Diff, Log, etc.)
|
|
347
|
+
|
|
348
|
+
2. **Git::Lib**: Low-level command execution
|
|
349
|
+
- Executes Git commands via `Git::CommandLine`
|
|
350
|
+
- Parses Git command output
|
|
351
|
+
- Minimal business logic - focuses on command execution
|
|
352
|
+
|
|
353
|
+
3. **Git::CommandLine**: Command execution layer
|
|
354
|
+
- Builds Git command arrays with proper escaping
|
|
355
|
+
- Manages subprocess execution with timeout support
|
|
356
|
+
- Handles timeout and error conditions
|
|
357
|
+
- Returns `Git::CommandLineResult` with output and status
|
|
358
|
+
|
|
359
|
+
4. **Git Objects** (Commit, Tree, Blob, Tag)
|
|
360
|
+
- Immutable representations of Git objects
|
|
361
|
+
- Lazy-loaded from repository
|
|
362
|
+
- Methods for inspecting object properties and relationships
|
|
363
|
+
|
|
364
|
+
5. **Git::Status**: Working directory status
|
|
365
|
+
- Enumerable collection of `Git::Status::StatusFile`
|
|
366
|
+
- Tracks added, changed, deleted, and untracked files
|
|
367
|
+
- Similar to `git status` command output
|
|
368
|
+
|
|
369
|
+
6. **Git::Diff**: Diff operations
|
|
370
|
+
- Enumerable collection of `Git::Diff::DiffFile`
|
|
371
|
+
- Per-file patches and statistics
|
|
372
|
+
- Total insertion/deletion statistics
|
|
373
|
+
|
|
374
|
+
7. **Git::Log**: Commit history query builder
|
|
375
|
+
- Chainable methods for building log queries
|
|
376
|
+
- Enumerable returning `Git::Object::Commit` objects
|
|
377
|
+
- Supports filtering by path, date range, author, etc.
|
|
378
|
+
|
|
379
|
+
### Path Handling
|
|
380
|
+
|
|
381
|
+
ruby-git handles three types of paths:
|
|
382
|
+
|
|
383
|
+
- **Working directory paths**: Relative to repository working directory
|
|
384
|
+
- **Git directory paths**: The `.git` directory location
|
|
385
|
+
- **Object paths**: Paths within Git tree objects
|
|
386
|
+
|
|
387
|
+
The gem provides `Git::Path` and `Git::EscapedPath` for handling paths with special
|
|
388
|
+
characters.
|
|
389
|
+
|
|
390
|
+
### Error Hierarchy
|
|
391
|
+
|
|
392
|
+
Proper error handling is essential for robust applications. The gem defines a
|
|
393
|
+
specific hierarchy of exception classes to allow callers to rescue specific failure
|
|
394
|
+
modes. All custom exceptions inherit from `Git::Error`:
|
|
395
|
+
|
|
396
|
+
- `Git::FailedError`: Git command exited with non-zero status
|
|
397
|
+
- `Git::SignaledError`: Git command was killed by a signal
|
|
398
|
+
- `Git::TimeoutError`: Git command exceeded timeout (subclass of SignaledError)
|
|
399
|
+
- `ArgumentError`: Invalid arguments passed to methods
|
|
400
|
+
|
|
401
|
+
All Git command errors include the command, output, and status for debugging.
|
|
402
|
+
|
|
403
|
+
## Project Configuration
|
|
404
|
+
|
|
405
|
+
The following configuration values define the project's environment and operational
|
|
406
|
+
parameters. Use these settings to ensure your development environment matches the
|
|
407
|
+
project's requirements.
|
|
408
|
+
|
|
409
|
+
- **Language:** Ruby
|
|
410
|
+
- **Refactoring Strategy:** Maintain close alignment with git CLI commands, use
|
|
411
|
+
descriptive method names, avoid over-abstraction, favor Ruby idioms while keeping
|
|
412
|
+
git concepts clear
|
|
413
|
+
|
|
414
|
+
> **INSTRUCTIONS FOR AI:** Read these configuration values and use them strictly for
|
|
415
|
+
> the phases below. Do not guess commands.
|
|
416
|
+
|
|
417
|
+
- **Setup Project:** `bin/setup`
|
|
418
|
+
- **Run All Tests:** `bundle exec bin/test`
|
|
419
|
+
- **Run A Specific Test:** `bundle exec bin/test <test_file_name_without_extension>`
|
|
420
|
+
(e.g., `bundle exec bin/test test_branch`)
|
|
421
|
+
- **Run Linters:** `bundle exec rake rubocop yard`
|
|
422
|
+
- **Run Continuous Integration Workflow:** `bundle exec rake default`
|
|
423
|
+
|
|
424
|
+
## Development Workflow
|
|
425
|
+
|
|
426
|
+
You are an expert and practical software engineer following a strict Test-Driven
|
|
427
|
+
Development (TDD) workflow.
|
|
428
|
+
|
|
429
|
+
**This project strictly follows Test Driven Development (TDD) practices. All
|
|
430
|
+
production code MUST be written using the TDD process described below.**
|
|
431
|
+
|
|
432
|
+
### Workflow Overview
|
|
433
|
+
|
|
434
|
+
When assigned a task involving a GitHub issue, follow this workflow:
|
|
435
|
+
|
|
436
|
+
1. **Phase 0: TRIAGE** - Understand the issue and determine if action is needed
|
|
437
|
+
2. **Phase 1: PREPARE** - Set up the environment and plan the implementation
|
|
438
|
+
3. **Phase 2: EXECUTE** - Implement the solution using TDD
|
|
439
|
+
4. **Phase 3: FINALIZE** - Squash commits and create the PR
|
|
440
|
+
|
|
441
|
+
**Note:** Not all issues require implementation. Phase 0 may result in requesting
|
|
442
|
+
clarification, confirming the issue is a duplicate, or determining no changes are
|
|
443
|
+
needed.
|
|
444
|
+
|
|
445
|
+
### Core TDD Principles
|
|
446
|
+
|
|
447
|
+
Adhere to the following fundamental principles to ensure high code quality and test
|
|
448
|
+
coverage:
|
|
449
|
+
|
|
450
|
+
- **Never Write Production Code without a Failing Test**
|
|
451
|
+
- **Bug Fixes Start with Tests:** Before fixing any bug, write a failing test that
|
|
452
|
+
demonstrates the bug and fails in the expected way. Only then fix the code to make
|
|
453
|
+
the test pass.
|
|
454
|
+
- **Tests Drive Design:** Let the test dictate the API and architecture. If the test
|
|
455
|
+
is hard to write, the design is likely wrong. When this happens, stop and suggest
|
|
456
|
+
one or more design alternatives. Offer to stash any current changes and work on the
|
|
457
|
+
design improvements first before continuing with the original task.
|
|
458
|
+
- **Write Tests Incrementally:** Build tests in small steps, writing just enough to
|
|
459
|
+
get the next expected failure. For example, first write a test that references a
|
|
460
|
+
class that doesn't exist (fails), then define the empty class (passes), then extend
|
|
461
|
+
the test to call a method (fails), then define the method (passes), etc.
|
|
462
|
+
- **Tests Should Be Atomic:** Each test should verify exactly one logical behavior,
|
|
463
|
+
making failures easy to diagnose and understand.
|
|
464
|
+
- **Prefer the Simplest Solution:** Choose the simplest implementation that could
|
|
465
|
+
possibly work, even if it seems naive. Complexity should only be added when driven
|
|
466
|
+
by actual requirements in tests.
|
|
467
|
+
- **No Implementation in Advance:** Only write the code strictly needed to pass the
|
|
468
|
+
current test.
|
|
469
|
+
|
|
470
|
+
### Phase 0: TRIAGE
|
|
471
|
+
|
|
472
|
+
The purpose of this phase is to understand what the issue is asking for, investigate
|
|
473
|
+
the current state of the codebase, and determine whether implementation is needed.
|
|
474
|
+
|
|
475
|
+
**Use this phase when the user references a GitHub issue number** (e.g., "Fix issue
|
|
476
|
+
\#999", "Implement \#999", "Diagnose issue \#999").
|
|
477
|
+
|
|
478
|
+
1. **Fetch the Issue:** Use `gh issue view #999` to read the full issue content,
|
|
479
|
+
including description, comments, and labels.
|
|
480
|
+
|
|
481
|
+
2. **Understand the Request:** Analyze what is being asked:
|
|
482
|
+
- Is this a bug report? Feature request? Question? Documentation issue?
|
|
483
|
+
- Is the issue clear and actionable, or does it need clarification?
|
|
484
|
+
- Are there reproduction steps or examples provided?
|
|
485
|
+
|
|
486
|
+
3. **Search for Context:** Investigate the codebase to understand the area affected:
|
|
487
|
+
- Use `grep_search` or `semantic_search` to find relevant code
|
|
488
|
+
- Read related test files to understand existing behavior
|
|
489
|
+
- Check if similar functionality already exists
|
|
490
|
+
- Look for related issues or PRs that might be relevant
|
|
491
|
+
|
|
492
|
+
4. **Reproduce (if applicable):** For bug reports:
|
|
493
|
+
- Try to reproduce the issue based on the provided steps
|
|
494
|
+
- Run existing tests to see if they catch the issue
|
|
495
|
+
- Verify the issue still exists in the current codebase
|
|
496
|
+
|
|
497
|
+
5. **Determine Next Steps and Report Findings:**
|
|
498
|
+
|
|
499
|
+
**Option A: Issue needs clarification**
|
|
500
|
+
- Comment on the issue using `gh issue comment #999 --body "..."`
|
|
501
|
+
- Ask specific questions about reproduction steps, expected behavior, or use case
|
|
502
|
+
- **STOP here** - wait for user/reporter response before proceeding
|
|
503
|
+
|
|
504
|
+
**Option B: Issue is not actionable (duplicate, won't-fix, already resolved)**
|
|
505
|
+
- Comment on the issue explaining your findings
|
|
506
|
+
- Suggest closing the issue or linking to related issues
|
|
507
|
+
- **STOP here** - no implementation needed
|
|
508
|
+
|
|
509
|
+
**Option C: Issue is clear and actionable**
|
|
510
|
+
- Comment on the issue confirming you understand the request and plan to implement
|
|
511
|
+
- Summarize your understanding and proposed approach
|
|
512
|
+
- **Proceed to Phase 1: PREPARE** to begin implementation
|
|
513
|
+
|
|
514
|
+
**Option D: User asked only to diagnose (not implement)**
|
|
515
|
+
- Comment on the issue with your diagnostic findings
|
|
516
|
+
- Explain what you discovered (root cause, affected code, potential solutions)
|
|
517
|
+
- **STOP here** - wait for confirmation to proceed with implementation
|
|
518
|
+
|
|
519
|
+
**GitHub CLI Commands for Phase 0:**
|
|
520
|
+
|
|
521
|
+
- View issue: `gh issue view #999`
|
|
522
|
+
- View with comments: `gh issue view #999 --comments`
|
|
523
|
+
- Comment on issue: `gh issue comment #999 --body "Your comment here"`
|
|
524
|
+
- Search issues: `gh issue list --search "keyword"`
|
|
525
|
+
|
|
526
|
+
### Phase 1: PREPARE
|
|
527
|
+
|
|
528
|
+
The purpose of this phase is to ensure the project environment is ready, establish a
|
|
529
|
+
clean baseline, and create a clear implementation plan before writing any code.
|
|
530
|
+
|
|
531
|
+
**Only proceed to this phase if Phase 0 determined that implementation is needed.**
|
|
532
|
+
|
|
533
|
+
1. **Check Uncommitted Changes:** If there are any uncommitted changes in the
|
|
534
|
+
project, ask the user what to do with them before continuing: include them in the
|
|
535
|
+
current implementation plan, ignore them, or stash them before continuing.
|
|
536
|
+
2. **Create Feature Branch:** Create a new branch from `origin/main` using the naming
|
|
537
|
+
convention `<type>/<short-description>` (e.g., `fix/issue-999`).
|
|
538
|
+
3. **Verify Project Setup:** Run the `Setup Project` command to ensure that the
|
|
539
|
+
project is ready for development.
|
|
540
|
+
4. **Verify Clean Baseline:** Ensure that all existing tests and linters pass by
|
|
541
|
+
running the `Run Continuous Integration Workflow` command.
|
|
542
|
+
5. **Analyze and Plan:** Understand the requirements, identify edge cases and
|
|
543
|
+
potential challenges, and break the work into small, isolated tasks. Consider what
|
|
544
|
+
tests will be needed and in what order they should be written.
|
|
545
|
+
6. **Consider Refactoring:** Look for ways to make the implementation of the feature
|
|
546
|
+
or bug fix easier by performing one or more refactorings. If any are found,
|
|
547
|
+
suggest them to the user. If the user confirms the refactoring, do the refactoring
|
|
548
|
+
in a separate TDD process. Only once the refactoring is completed should the
|
|
549
|
+
current feature or bug fix be worked on.
|
|
550
|
+
|
|
551
|
+
### Phase 2: EXECUTE
|
|
552
|
+
|
|
553
|
+
The purpose of this phase is to implement each planned task using strict TDD cycles,
|
|
554
|
+
ensuring every line of production code is driven by a failing test.
|
|
555
|
+
|
|
556
|
+
Execute each task by repeating the following cycle of steps until all tasks are
|
|
557
|
+
complete:
|
|
558
|
+
|
|
559
|
+
1. **RED-GREEN:** Write failing tests and implement code to make them pass
|
|
560
|
+
2. **REFACTOR:** Improve code quality and design without changing behavior
|
|
561
|
+
3. **VERIFY:** Confirm the task is complete and code meets quality standards
|
|
562
|
+
4. **COMMIT:** Create a commit for the completed task
|
|
563
|
+
5. **REPLAN:** Review the implementation plan, then return to step 1 for the next
|
|
564
|
+
task
|
|
565
|
+
|
|
566
|
+
When all tasks are complete, proceed to [Phase 3: FINALIZE](#phase-3-finalize).
|
|
567
|
+
|
|
568
|
+
#### RED-GREEN Step
|
|
569
|
+
|
|
570
|
+
1. **RED Substep**
|
|
571
|
+
|
|
572
|
+
The purpose of this substep is to write a failing test that you hypothesize will
|
|
573
|
+
pass with the next incremental bit of task implementation.
|
|
574
|
+
|
|
575
|
+
- **Write the Test:** Write a single, focused, failing test or extend an existing
|
|
576
|
+
test for the current task.
|
|
577
|
+
- **Keep It Minimal:** Only write enough of a test to get an expected, failing
|
|
578
|
+
result (the test should fail for the *right* reason).
|
|
579
|
+
- **Execute and Analyze:** Run the `Run A Specific Test` command and analyze the
|
|
580
|
+
output.
|
|
581
|
+
- **Confirm Expected Failure:** Confirm it fails with an expected error (e.g.,
|
|
582
|
+
assertion failure or missing definition).
|
|
583
|
+
- **Validate:** If the test passes without implementation, the test is invalid or
|
|
584
|
+
the logic already exists. When that happens, revise or skip.
|
|
585
|
+
|
|
586
|
+
2. **GREEN Substep**
|
|
587
|
+
|
|
588
|
+
The purpose of this substep is to write just enough production code to make the
|
|
589
|
+
failing test(s) pass.
|
|
590
|
+
|
|
591
|
+
- **Write Minimal Code:** Write the minimum amount of code required to make the
|
|
592
|
+
test pass.
|
|
593
|
+
- **Use Simple Solutions:** It is acceptable to use hardcoded values or "quick and
|
|
594
|
+
dirty" logic here just to get to green, even if this means intentionally writing
|
|
595
|
+
clearly suboptimal code that you will improve during the REFACTOR step.
|
|
596
|
+
- **No Premature Optimization:** Do NOT optimize, clean up, or improve code style
|
|
597
|
+
during GREEN—that work belongs in the REFACTOR step.
|
|
598
|
+
- **Execute and Verify:** Run the `Run A Specific Test` command
|
|
599
|
+
- **If the test passes**, proceed to the REFACTOR step
|
|
600
|
+
- **If the test fails**, read the FULL error output including the stack trace.
|
|
601
|
+
Identify the exact failing line and assertion before modifying any code. Fix
|
|
602
|
+
only what the error indicates, then re-run. Repeat until the test passes.
|
|
603
|
+
- **Rollback on Repeated Failure:** If the test cannot be made to pass within 3
|
|
604
|
+
attempts, revert all changes from this RED-GREEN cycle, report the issue to the
|
|
605
|
+
user, and ask for guidance before proceeding.
|
|
606
|
+
- **Stay Focused:** Do not implement future features or optimizations yet.
|
|
607
|
+
|
|
608
|
+
#### REFACTOR Step
|
|
609
|
+
|
|
610
|
+
The purpose of this step is to improve code quality and design without changing
|
|
611
|
+
behavior, ensuring the codebase remains clean and maintainable.
|
|
612
|
+
|
|
613
|
+
**You must consider refactoring before starting the next task.** Remove duplication,
|
|
614
|
+
improve variable names, and apply design patterns. Skip this step only if the code is
|
|
615
|
+
already clean and simple—avoid over-engineering.
|
|
616
|
+
|
|
617
|
+
- **Generalize the Implementation:** Ensure the code solves the general case, not
|
|
618
|
+
just the specific test case. Replace hardcoded values used to pass the test with
|
|
619
|
+
actual logic.
|
|
620
|
+
- **Limit Scope:** Do not perform refactorings that affect files outside the
|
|
621
|
+
immediate scope of the current task. If a broader refactor is needed, add it to the
|
|
622
|
+
task list during the REPLAN step as a separate task.
|
|
623
|
+
- **Execute All Tests:** Run the `Run All Tests` command and verify they still pass.
|
|
624
|
+
- **Verify Test Independence:** Verify tests can run independently in any order.
|
|
625
|
+
- **Confirm Improvement:** Ensure the refactoring made the code clearer, simpler, or
|
|
626
|
+
more maintainable.
|
|
627
|
+
|
|
628
|
+
#### VERIFY Step
|
|
629
|
+
|
|
630
|
+
The purpose of this step is to confirm that the current task is fully complete before
|
|
631
|
+
moving to the next task.
|
|
632
|
+
|
|
633
|
+
- **Confirm Implementation Complete:** Verify all functionality for the task is
|
|
634
|
+
implemented.
|
|
635
|
+
- **Run All Tests:** Run the `Run All Tests` command to ensure all tests pass.
|
|
636
|
+
- **Run Linters:** Run the `Run Linters` command to verify code style and
|
|
637
|
+
documentation standards.
|
|
638
|
+
- **Check Code Quality:** Confirm the code is clean and well-factored.
|
|
639
|
+
- **STOP on Unexpected Failure:** If any test unexpectedly fails during VERIFY, STOP
|
|
640
|
+
immediately and report the failure to the user. Do not attempt to fix the failure
|
|
641
|
+
without first explaining what went wrong and getting confirmation to proceed.
|
|
642
|
+
|
|
643
|
+
#### COMMIT Step
|
|
644
|
+
|
|
645
|
+
The purpose of this step is to create a checkpoint after successfully completing a
|
|
646
|
+
task, providing a safe rollback point.
|
|
647
|
+
|
|
648
|
+
- **Create Commit:** Commit all changes from this task using the appropriate
|
|
649
|
+
conventional commit type (see [Per-Task Commits](#per-task-commits) for guidance).
|
|
650
|
+
- **Keep Commits Atomic:** Each commit should represent one completed task with all
|
|
651
|
+
tests passing and linters clean.
|
|
652
|
+
|
|
653
|
+
#### REPLAN Step
|
|
654
|
+
|
|
655
|
+
The purpose of this step is to review progress and adjust the implementation plan
|
|
656
|
+
based on what was learned during the current task.
|
|
657
|
+
|
|
658
|
+
- **Review Implementation Plan:** Assess whether the remaining tasks are still valid
|
|
659
|
+
and appropriately scoped based on what was learned.
|
|
660
|
+
- **Identify New Tasks:** If the implementation revealed new requirements, edge
|
|
661
|
+
cases, or necessary refactorings, add them to the task list.
|
|
662
|
+
- **Reprioritize if Needed:** Adjust task order if dependencies or priorities have
|
|
663
|
+
changed.
|
|
664
|
+
- **Report Progress:** Briefly summarize what was completed and what remains.
|
|
665
|
+
**ALWAYS** print the updated task list with status (e.g., `[x] Task 1`, `[ ] Task
|
|
666
|
+
2`).
|
|
667
|
+
- **Continue or Complete:** If tasks remain, return to RED-GREEN for the next task.
|
|
668
|
+
If all tasks are complete, proceed to [Phase 3: FINALIZE](#phase-3-finalize).
|
|
669
|
+
|
|
670
|
+
### Phase 3: FINALIZE
|
|
671
|
+
|
|
672
|
+
The purpose of this phase is to consolidate all task commits into a single, clean
|
|
673
|
+
commit and complete the feature or bug fix.
|
|
674
|
+
|
|
675
|
+
1. **Run Final Verification:** Run the `Run Continuous Integration Workflow` command
|
|
676
|
+
one final time to ensure everything passes.
|
|
677
|
+
2. **Safety Check:** Run `git log --oneline HEAD~N..HEAD` (where N is the number of
|
|
678
|
+
task commits) to list the commits included in the squash. Verify these are
|
|
679
|
+
strictly the commits generated during the current session. If unexpected commits
|
|
680
|
+
appear, STOP and ask the user for the correct value of N.
|
|
681
|
+
3. **Capture Commit Messages:** Run `git log --format="- %s" HEAD~N..HEAD` to capture
|
|
682
|
+
individual commit messages for inclusion in the final commit body.
|
|
683
|
+
4. **Draft the Squash Message:** Prepare a commit message with:
|
|
684
|
+
- **Subject:** A single line summarizing the entire feature or fix (e.g.,
|
|
685
|
+
`feat(branch): add Branch#create method`)
|
|
686
|
+
- **Body:** A summary of what was implemented, the captured commit messages from
|
|
687
|
+
step 2, key decisions made, and any relevant context. Wrap lines at 100
|
|
688
|
+
characters.
|
|
689
|
+
5. **Propose the Squash:** Present the drafted message and the commands to squash to
|
|
690
|
+
the user:
|
|
691
|
+
- `git reset --soft HEAD~N` (where N is the number of task commits)
|
|
692
|
+
- `git commit -m "<drafted message>"`
|
|
693
|
+
6. **Wait for Confirmation:** Do NOT execute the squash until the user reviews the
|
|
694
|
+
commits and confirms. The user may want to adjust the message or keep some commits
|
|
695
|
+
separate.
|
|
696
|
+
7. **Execute on Confirmation:** Once confirmed, run `git reset --soft HEAD~N` to
|
|
697
|
+
unstage the task commits while preserving all changes, then commit with the
|
|
698
|
+
approved message.
|
|
699
|
+
8. **Handle Commit Hook Failure:** If the commit fails due to a `commit-msg` hook
|
|
700
|
+
rejection (e.g., commitlint error):
|
|
701
|
+
- Read the error message carefully to identify the formatting issue.
|
|
702
|
+
- Fix the commit message to comply with the project's commit conventions.
|
|
703
|
+
- Retry the commit. The changes remain staged after a hook failure, so only the
|
|
704
|
+
`git commit` command needs to be re-run.
|
|
705
|
+
- If the commit fails 3 times, STOP and report the issue to the user with the
|
|
706
|
+
exact error message.
|
|
707
|
+
|
|
708
|
+
## Pull Request Review Workflow
|
|
709
|
+
|
|
710
|
+
When asked to review a pull request (e.g., "Review PR #999"), follow this workflow to
|
|
711
|
+
analyze the changes, provide feedback, and optionally post the review to GitHub.
|
|
712
|
+
|
|
713
|
+
### Step 1: Fetch the PR
|
|
714
|
+
|
|
715
|
+
1. **Read PR Details:** Use `gh pr view #999` to get title, description, author, and
|
|
716
|
+
status.
|
|
717
|
+
2. **Get Changed Files:** Use `gh pr diff #999` to see the complete diff.
|
|
718
|
+
3. **Check PR Status:** Note if it's a draft, has merge conflicts, or has existing
|
|
719
|
+
reviews.
|
|
720
|
+
|
|
721
|
+
### Step 2: Review Against Project Standards
|
|
722
|
+
|
|
723
|
+
Evaluate the PR against these criteria:
|
|
724
|
+
|
|
725
|
+
**Code Quality:** Ruby style (Rubocop-compliant), `frozen_string_literal: true`, proper naming (snake_case/PascalCase), single-responsibility, no duplication, Ruby 3.2+ idioms.
|
|
726
|
+
|
|
727
|
+
**Testing:** Changes covered by atomic Test::Unit tests, well-named, passing CI. Test modifications require justification.
|
|
728
|
+
|
|
729
|
+
**Documentation:** YARD docs on public methods with `@param`, `@return`, `@raise`, `@example`. README updated for user-facing changes. Platform differences and security documented.
|
|
730
|
+
|
|
731
|
+
**Architecture:** Correct layer placement (Base/Lib/CommandLine), principle of least surprise, direct Git command mapping, proper error hierarchy.
|
|
732
|
+
|
|
733
|
+
**Commits:** Conventional Commits format, lowercase subjects under 100 chars, no trailing period. Breaking changes use `!` and `BREAKING CHANGE:` footer.
|
|
734
|
+
|
|
735
|
+
**Compatibility:** Backward compatible (or marked breaking), Ruby 3.2+, Git 2.28.0+, cross-platform (Windows/macOS/Linux).
|
|
736
|
+
|
|
737
|
+
**Security:** No command injection, proper escaping via Git::CommandLine, input validation, resource cleanup.
|
|
738
|
+
|
|
739
|
+
### Step 3: Present Review Findings
|
|
740
|
+
|
|
741
|
+
Present your findings to the user in this format:
|
|
742
|
+
|
|
743
|
+
```text
|
|
744
|
+
## PR Review: #999 - [PR Title]
|
|
745
|
+
|
|
746
|
+
**Author:** [username]
|
|
747
|
+
**Status:** [open/draft/has conflicts/etc.]
|
|
748
|
+
|
|
749
|
+
### Summary
|
|
750
|
+
[Brief description of what the PR does]
|
|
751
|
+
|
|
752
|
+
### Recommendation
|
|
753
|
+
- **Review Type:** [APPROVE / COMMENT / REQUEST CHANGES]
|
|
754
|
+
- **Rationale:** [Why this recommendation]
|
|
755
|
+
|
|
756
|
+
### General Comments
|
|
757
|
+
|
|
758
|
+
[Overall feedback on the PR - architecture decisions, approach, etc.]
|
|
759
|
+
|
|
760
|
+
### Line-Specific Comments
|
|
761
|
+
|
|
762
|
+
[file.rb:123]
|
|
763
|
+
[Specific feedback about this line or section]
|
|
764
|
+
|
|
765
|
+
[file.rb:456-460]
|
|
766
|
+
[Feedback about this range of lines]
|
|
767
|
+
|
|
768
|
+
### Checklist Results
|
|
769
|
+
|
|
770
|
+
**Passing:**
|
|
771
|
+
- Uses proper Ruby style
|
|
772
|
+
- Tests included
|
|
773
|
+
- ...
|
|
774
|
+
|
|
775
|
+
**Issues Found:**
|
|
776
|
+
- Missing YARD documentation on `SomeClass#method`
|
|
777
|
+
- Commit message "Fixed bug" doesn't follow conventional commits
|
|
778
|
+
- ...
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
**Here is the review. Do you have any questions or want additional changes, OR should I go ahead and post this review on the PR?**
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
### Step 4: Get User Approval
|
|
786
|
+
|
|
787
|
+
Wait for the user to respond. They may:
|
|
788
|
+
|
|
789
|
+
- **Approve posting:** Proceed to Step 5
|
|
790
|
+
- **Request changes to review:** Modify your findings and re-present
|
|
791
|
+
- **Ask questions:** Answer and clarify before proceeding
|
|
792
|
+
- **Decide not to post:** End the workflow
|
|
793
|
+
|
|
794
|
+
Do NOT post the review without explicit user confirmation.
|
|
795
|
+
|
|
796
|
+
### Step 5: Post the Review
|
|
797
|
+
|
|
798
|
+
Once the user confirms, post the review using the GitHub CLI:
|
|
799
|
+
|
|
800
|
+
**For reviews with line-specific comments:**
|
|
801
|
+
|
|
802
|
+
1. Create the review: `gh pr review #999 --comment` (or `--approve` or
|
|
803
|
+
`--request-changes`)
|
|
804
|
+
2. Add the general comment as the review body using `-b "comment text"`
|
|
805
|
+
3. For line-specific comments, you may need to use the GitHub API or instruct the
|
|
806
|
+
user to add them manually in the GitHub UI
|
|
807
|
+
|
|
808
|
+
**For reviews with only general comments:**
|
|
809
|
+
|
|
810
|
+
```bash
|
|
811
|
+
gh pr review #999 --approve -b "Your general comment here"
|
|
812
|
+
# or
|
|
813
|
+
gh pr review #999 --comment -b "Your general comment here"
|
|
814
|
+
# or
|
|
815
|
+
gh pr review #999 --request-changes -b "Your general comment here"
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
**Note:** The `gh` CLI has limitations with line-specific comments. If the review
|
|
819
|
+
includes line-specific comments, inform the user of this limitation and either:
|
|
820
|
+
|
|
821
|
+
- Post only the general comment via CLI and provide the line comments for manual
|
|
822
|
+
posting
|
|
823
|
+
- Provide the full review text for the user to post manually
|
|
824
|
+
- Use the GitHub API if line-specific commenting is critical
|
|
825
|
+
|
|
826
|
+
### Step 6: Confirm Completion
|
|
827
|
+
|
|
828
|
+
After posting, confirm with the user:
|
|
829
|
+
|
|
830
|
+
```text
|
|
831
|
+
Review posted successfully to PR #999.
|
|
832
|
+
View at: [PR URL from gh pr view output]
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
## CI/CD Troubleshooting Workflow
|
|
836
|
+
|
|
837
|
+
When asked to diagnose or fix CI/CD failures (e.g., "Why is CI failing on PR #999?",
|
|
838
|
+
"Fix the failing build"), follow this workflow to identify the root cause and
|
|
839
|
+
optionally implement fixes.
|
|
840
|
+
|
|
841
|
+
### Step 1: Identify the Failure
|
|
842
|
+
|
|
843
|
+
1. **Get CI Status:**
|
|
844
|
+
- For PRs: `gh pr checks #999`
|
|
845
|
+
- For branches: `gh run list --branch <branch-name> --limit 5`
|
|
846
|
+
- Note which jobs passed and which failed
|
|
847
|
+
|
|
848
|
+
2. **Categorize the Failure Type:**
|
|
849
|
+
- **Test failures** - Unit tests, integration tests failing
|
|
850
|
+
- **Linter failures** - Rubocop, YARD documentation issues
|
|
851
|
+
- **Build failures** - Dependency installation, compilation errors
|
|
852
|
+
- **Timeout failures** - Jobs exceeding time limits
|
|
853
|
+
- **Platform-specific failures** - Failing on specific Ruby version or OS
|
|
854
|
+
|
|
855
|
+
3. **Identify Specific Failing Steps:**
|
|
856
|
+
- Note the exact job name and step that failed
|
|
857
|
+
- Record the Ruby version, OS, and other environment details
|
|
858
|
+
|
|
859
|
+
### Step 2: Fetch Relevant Logs
|
|
860
|
+
|
|
861
|
+
**CRITICAL: CI logs can be massive (100K+ lines) and exceed token limits.**
|
|
862
|
+
|
|
863
|
+
1. **Get the Run ID:**
|
|
864
|
+
|
|
865
|
+
```bash
|
|
866
|
+
gh run list --branch <branch> --limit 1 --json databaseId --jq '.[0].databaseId'
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
2. **Fetch Failed Job Logs Only:**
|
|
870
|
+
|
|
871
|
+
```bash
|
|
872
|
+
gh run view <run-id> --log-failed
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
This limits output to only failed jobs, making it manageable.
|
|
876
|
+
|
|
877
|
+
3. **Extract Key Error Information:**
|
|
878
|
+
|
|
879
|
+
- For test failures: Look for stack traces, assertion errors, specific test names
|
|
880
|
+
- For linter failures: Extract file names, line numbers, and violation types
|
|
881
|
+
- For build failures: Find dependency errors or missing packages
|
|
882
|
+
- Use `grep` to filter logs if still too large:
|
|
883
|
+
|
|
884
|
+
```bash
|
|
885
|
+
gh run view <run-id> --log-failed | grep -A 10 -B 5 "Error\|FAILED\|Failure"
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
4. **Avoid Full Log Downloads:**
|
|
889
|
+
|
|
890
|
+
- Do NOT use `--log` without `--log-failed` unless specifically requested
|
|
891
|
+
- If logs are still too large, focus on the most recent or critical failure
|
|
892
|
+
|
|
893
|
+
### Step 3: Diagnose Root Cause
|
|
894
|
+
|
|
895
|
+
Based on the failure type, investigate:
|
|
896
|
+
|
|
897
|
+
**For Test Failures:**
|
|
898
|
+
|
|
899
|
+
- Check if the test exists and what it's testing
|
|
900
|
+
- Look for recent changes that might have broken the test
|
|
901
|
+
- Consider environment differences (local vs. CI)
|
|
902
|
+
- Check for flaky tests (intermittent failures)
|
|
903
|
+
|
|
904
|
+
**For Linter Failures:**
|
|
905
|
+
|
|
906
|
+
- Run linters locally: `bundle exec rake rubocop yard`
|
|
907
|
+
- Identify specific violations from the log
|
|
908
|
+
- Check if violations are in files related to recent changes
|
|
909
|
+
|
|
910
|
+
**For Build Failures:**
|
|
911
|
+
|
|
912
|
+
- Check dependency versions in `Gemfile` and `git.gemspec`
|
|
913
|
+
- Look for platform-specific dependency issues
|
|
914
|
+
- Verify Ruby version compatibility
|
|
915
|
+
|
|
916
|
+
**For Timeout Failures:**
|
|
917
|
+
|
|
918
|
+
- Identify which test or step is timing out
|
|
919
|
+
- Check for infinite loops or performance regressions
|
|
920
|
+
- Consider if it's a resource limitation in CI environment
|
|
921
|
+
|
|
922
|
+
### Step 4: Reproduce Locally (if applicable)
|
|
923
|
+
|
|
924
|
+
**For PR Failures:**
|
|
925
|
+
|
|
926
|
+
1. Fetch the PR branch:
|
|
927
|
+
|
|
928
|
+
```bash
|
|
929
|
+
gh pr checkout #999
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
2. Run the failing tests locally:
|
|
933
|
+
|
|
934
|
+
```bash
|
|
935
|
+
bundle exec bin/test <test-name>
|
|
936
|
+
```
|
|
937
|
+
|
|
938
|
+
3. Run linters:
|
|
939
|
+
|
|
940
|
+
```bash
|
|
941
|
+
bundle exec rake rubocop yard
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
**For Branch Failures:**
|
|
945
|
+
|
|
946
|
+
1. Checkout the branch.
|
|
947
|
+
2. Run full CI workflow:
|
|
948
|
+
|
|
949
|
+
```bash
|
|
950
|
+
bundle exec rake default
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
### Step 5: Report Findings or Fix
|
|
954
|
+
|
|
955
|
+
Determine the appropriate action based on the user's request:
|
|
956
|
+
|
|
957
|
+
#### Option A: Diagnostic Report ("Why is CI failing?")
|
|
958
|
+
|
|
959
|
+
Present findings to the user:
|
|
960
|
+
|
|
961
|
+
````markdown
|
|
962
|
+
## CI Failure Diagnosis: <Branch/PR>
|
|
963
|
+
|
|
964
|
+
**Status:** <X of Y jobs failed>
|
|
965
|
+
|
|
966
|
+
### Failed Jobs
|
|
967
|
+
1. **<Job Name>** (<Ruby version>, <OS>)
|
|
968
|
+
- **Step:** <failing step name>
|
|
969
|
+
- **Failure Type:** <test/linter/build/timeout>
|
|
970
|
+
|
|
971
|
+
### Root Cause
|
|
972
|
+
<Explanation of what's causing the failure>
|
|
973
|
+
|
|
974
|
+
### Error Details
|
|
975
|
+
```
|
|
976
|
+
<Relevant error messages and stack traces>
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
### Recommendations
|
|
980
|
+
- <Specific fix suggestion 1>
|
|
981
|
+
- <Specific fix suggestion 2>
|
|
982
|
+
|
|
983
|
+
**Would you like me to implement a fix, or do you need more information?**
|
|
984
|
+
````
|
|
985
|
+
|
|
986
|
+
**STOP here** unless the user asks you to proceed with fixes.
|
|
987
|
+
|
|
988
|
+
#### Option B: Implement Fix ("Fix the failing build")
|
|
989
|
+
|
|
990
|
+
Proceed based on failure type:
|
|
991
|
+
|
|
992
|
+
- **Test Failures:** Use the full TDD workflow (Phase 1-3) to fix the failing tests
|
|
993
|
+
- **Linter Failures:** Fix violations directly, commit with appropriate message
|
|
994
|
+
(e.g., `style: fix rubocop violations in lib/git/base.rb`)
|
|
995
|
+
- **Build Failures:** Update dependencies or configuration as needed
|
|
996
|
+
- **Timeout Failures:** Investigate performance issues, may require user guidance
|
|
997
|
+
|
|
998
|
+
**For PR Failures on Someone Else's PR:**
|
|
999
|
+
|
|
1000
|
+
- You may not have push access to their branch
|
|
1001
|
+
- Present the fix and ask user to either:
|
|
1002
|
+
- Push to the PR branch (if they have access)
|
|
1003
|
+
- Comment on the PR with suggested changes
|
|
1004
|
+
- Create a new PR with fixes
|
|
1005
|
+
|
|
1006
|
+
### Step 6: Verify Fix
|
|
1007
|
+
|
|
1008
|
+
After implementing fixes:
|
|
1009
|
+
|
|
1010
|
+
1. **Run Affected Tests Locally:**
|
|
1011
|
+
|
|
1012
|
+
```bash
|
|
1013
|
+
bundle exec bin/test <test-name>
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
2. **Run Full CI Suite:**
|
|
1017
|
+
|
|
1018
|
+
```bash
|
|
1019
|
+
bundle exec rake default
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
3. **Push and Monitor:**
|
|
1023
|
+
|
|
1024
|
+
- Push the fixes
|
|
1025
|
+
- Monitor CI to confirm the fix worked:
|
|
1026
|
+
|
|
1027
|
+
```bash
|
|
1028
|
+
gh run watch
|
|
1029
|
+
```
|
|
1030
|
+
|
|
1031
|
+
4. **Confirm Resolution:**
|
|
1032
|
+
|
|
1033
|
+
```text
|
|
1034
|
+
Fix implemented and pushed. Monitoring CI run...
|
|
1035
|
+
CI Status: <link to run>
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
### Special Troubleshooting Considerations
|
|
1039
|
+
|
|
1040
|
+
**Platform-Specific Failures:**
|
|
1041
|
+
|
|
1042
|
+
- If tests pass on macOS but fail on Linux/Windows, document the difference
|
|
1043
|
+
- Check for path separator issues (`/` vs. `\`)
|
|
1044
|
+
- Look for encoding differences
|
|
1045
|
+
- Consider file system case sensitivity
|
|
1046
|
+
|
|
1047
|
+
**Flaky Tests:**
|
|
1048
|
+
|
|
1049
|
+
- If a test fails intermittently, note this in your diagnosis
|
|
1050
|
+
- Run the test multiple times locally to confirm flakiness
|
|
1051
|
+
- Suggest fixes for race conditions or timing issues
|
|
1052
|
+
|
|
1053
|
+
**Permission Issues:**
|
|
1054
|
+
|
|
1055
|
+
- If you can't push to a PR branch, clearly communicate this limitation
|
|
1056
|
+
- Provide the exact commands or changes needed for the user to apply
|
|
1057
|
+
|
|
1058
|
+
**Token Limit Management:**
|
|
1059
|
+
|
|
1060
|
+
- Always use `--log-failed` to limit output
|
|
1061
|
+
- If logs are still too large, use `grep` to extract errors
|
|
1062
|
+
- Focus on the first failure if multiple failures exist
|
|
1063
|
+
- Consider running tests locally instead of relying on full CI logs
|
|
1064
|
+
|
|
1065
|
+
## Test Debugging & Maintenance Workflow
|
|
1066
|
+
|
|
1067
|
+
When asked to debug tests or improve test coverage (e.g., "Why is test_branch
|
|
1068
|
+
failing?", "Fix flaky test", "Improve test coverage"), follow this workflow to
|
|
1069
|
+
identify problems, determine root causes, and apply appropriate fixes.
|
|
1070
|
+
|
|
1071
|
+
### Understanding Test Failure Types
|
|
1072
|
+
|
|
1073
|
+
**Consistent Failures:**
|
|
1074
|
+
|
|
1075
|
+
- Test fails every time it runs
|
|
1076
|
+
- Usually indicates a real bug or broken test
|
|
1077
|
+
- Easier to debug than flaky tests
|
|
1078
|
+
|
|
1079
|
+
**Flaky/Intermittent Failures:**
|
|
1080
|
+
|
|
1081
|
+
- Test passes sometimes, fails other times
|
|
1082
|
+
- Often indicates:
|
|
1083
|
+
- Race conditions
|
|
1084
|
+
- Timing dependencies
|
|
1085
|
+
- Shared state between tests
|
|
1086
|
+
- Non-deterministic behavior (random data, time-based logic)
|
|
1087
|
+
- External dependencies (filesystem, network)
|
|
1088
|
+
- Test execution order dependencies
|
|
1089
|
+
|
|
1090
|
+
**Test Coverage Gaps:**
|
|
1091
|
+
|
|
1092
|
+
- Existing code lacks sufficient test coverage
|
|
1093
|
+
- Not a failure, but maintenance task
|
|
1094
|
+
- Use TDD workflow to add tests
|
|
1095
|
+
|
|
1096
|
+
### Step 1: Run and Observe the Test
|
|
1097
|
+
|
|
1098
|
+
1. **Run the Failing Test:**
|
|
1099
|
+
|
|
1100
|
+
```bash
|
|
1101
|
+
bundle exec bin/test <test_file_name>
|
|
1102
|
+
```
|
|
1103
|
+
|
|
1104
|
+
Capture the full output including stack trace.
|
|
1105
|
+
|
|
1106
|
+
2. **Run Specific Test Method (if needed):**
|
|
1107
|
+
|
|
1108
|
+
```bash
|
|
1109
|
+
bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_method_name
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
3. **For Suspected Flaky Tests, Run Multiple Times:**
|
|
1113
|
+
|
|
1114
|
+
```bash
|
|
1115
|
+
# Run 20 times, stop on first failure
|
|
1116
|
+
for i in {1..20}; do
|
|
1117
|
+
echo "Run $i"
|
|
1118
|
+
bundle exec bin/test test_branch || break
|
|
1119
|
+
done
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
If it fails inconsistently, it's flaky.
|
|
1123
|
+
|
|
1124
|
+
4. **Check Test Isolation:**
|
|
1125
|
+
|
|
1126
|
+
```bash
|
|
1127
|
+
# Run test file in isolation
|
|
1128
|
+
bundle exec bin/test test_branch
|
|
1129
|
+
|
|
1130
|
+
# Run full suite to see if other tests affect it
|
|
1131
|
+
bundle exec bin/test
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
### Step 2: Understand the Test
|
|
1135
|
+
|
|
1136
|
+
1. **Read the Test Code:**
|
|
1137
|
+
|
|
1138
|
+
- What behavior is being tested?
|
|
1139
|
+
- What is the expected outcome?
|
|
1140
|
+
- What setup/teardown occurs?
|
|
1141
|
+
- Are there any mocks or stubs?
|
|
1142
|
+
|
|
1143
|
+
2. **Understand the Error:**
|
|
1144
|
+
|
|
1145
|
+
- Read the full error message and stack trace
|
|
1146
|
+
- Identify the exact line that failed
|
|
1147
|
+
- Understand expected vs. actual values
|
|
1148
|
+
- Check if it's an assertion failure or exception
|
|
1149
|
+
|
|
1150
|
+
3. **Review Related Tests:**
|
|
1151
|
+
|
|
1152
|
+
- Do similar tests pass?
|
|
1153
|
+
- Are there patterns in what works vs. what doesn't?
|
|
1154
|
+
|
|
1155
|
+
### Step 3: Investigate Root Cause
|
|
1156
|
+
|
|
1157
|
+
**For Consistent Failures:**
|
|
1158
|
+
|
|
1159
|
+
1. **Check Recent Changes:**
|
|
1160
|
+
|
|
1161
|
+
- Use `git log` to see recent commits to test file or related production code
|
|
1162
|
+
- Use `git blame` on the failing test to see when it was last modified
|
|
1163
|
+
|
|
1164
|
+
2. **Look for Broken Assumptions:**
|
|
1165
|
+
|
|
1166
|
+
- Has the API changed?
|
|
1167
|
+
- Are test fixtures or data still valid?
|
|
1168
|
+
- Are external dependencies (git version, Ruby version) compatible?
|
|
1169
|
+
|
|
1170
|
+
3. **Check Test Setup/Teardown:**
|
|
1171
|
+
|
|
1172
|
+
- Is setup creating the necessary preconditions?
|
|
1173
|
+
- Is teardown cleaning up properly?
|
|
1174
|
+
- Use test helpers (`clone_working_repo`, `create_temp_repo`, etc.)
|
|
1175
|
+
|
|
1176
|
+
4. **Environment Issues:**
|
|
1177
|
+
|
|
1178
|
+
- Platform differences (paths, line endings, permissions)
|
|
1179
|
+
- Missing dependencies or configuration
|
|
1180
|
+
- Git configuration on the system
|
|
1181
|
+
|
|
1182
|
+
**For Flaky Tests:**
|
|
1183
|
+
|
|
1184
|
+
1. **Look for Race Conditions:**
|
|
1185
|
+
|
|
1186
|
+
- Multiple threads or processes
|
|
1187
|
+
- File system operations without proper synchronization
|
|
1188
|
+
- Async operations without proper waiting
|
|
1189
|
+
|
|
1190
|
+
2. **Check for Timing Dependencies:**
|
|
1191
|
+
|
|
1192
|
+
- Tests that depend on execution speed
|
|
1193
|
+
- Sleep statements or timeouts
|
|
1194
|
+
- Time-based logic (dates, timestamps)
|
|
1195
|
+
|
|
1196
|
+
3. **Identify Shared State:**
|
|
1197
|
+
|
|
1198
|
+
- Global variables or class variables
|
|
1199
|
+
- Shared file system resources
|
|
1200
|
+
- Tests affecting each other through side effects
|
|
1201
|
+
|
|
1202
|
+
4. **Look for Non-Determinism:**
|
|
1203
|
+
|
|
1204
|
+
- Random data generation
|
|
1205
|
+
- Hash ordering (though Ruby 1.9+ maintains insertion order)
|
|
1206
|
+
- Iteration over sets without guaranteed order
|
|
1207
|
+
- Time-dependent logic (Time.now, Date.today)
|
|
1208
|
+
|
|
1209
|
+
5. **Check Test Execution Order:**
|
|
1210
|
+
|
|
1211
|
+
- Does the test only pass when run after certain other tests?
|
|
1212
|
+
- Does it fail when run in isolation?
|
|
1213
|
+
- Use `--seed` option to reproduce specific execution order
|
|
1214
|
+
|
|
1215
|
+
### Step 4: Report Findings
|
|
1216
|
+
|
|
1217
|
+
Present your diagnostic findings to the user:
|
|
1218
|
+
|
|
1219
|
+
````markdown
|
|
1220
|
+
## Test Failure Diagnosis: <test_name>
|
|
1221
|
+
|
|
1222
|
+
**Failure Type:** [Consistent / Flaky / Coverage Gap]
|
|
1223
|
+
**Test File:** <path/to/test_file.rb>
|
|
1224
|
+
**Test Method:** <test_method_name>
|
|
1225
|
+
|
|
1226
|
+
### Error
|
|
1227
|
+
```
|
|
1228
|
+
<error message and relevant stack trace>
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1231
|
+
### Root Cause
|
|
1232
|
+
<Explanation of why the test is failing>
|
|
1233
|
+
|
|
1234
|
+
### Affected Code
|
|
1235
|
+
- Test code: <relevant test code>
|
|
1236
|
+
- Production code: <relevant production code if applicable>
|
|
1237
|
+
|
|
1238
|
+
### Recommended Fix
|
|
1239
|
+
<Specific recommendation based on scenario below>
|
|
1240
|
+
|
|
1241
|
+
**Would you like me to implement this fix?**
|
|
1242
|
+
````
|
|
1243
|
+
|
|
1244
|
+
**STOP here** unless the user asks you to proceed with the fix.
|
|
1245
|
+
|
|
1246
|
+
### Step 5: Determine Fix Strategy and Execute
|
|
1247
|
+
|
|
1248
|
+
Based on the root cause, choose the appropriate fix strategy:
|
|
1249
|
+
|
|
1250
|
+
#### Scenario A: Production Code Bug (Test Caught a Real Bug)
|
|
1251
|
+
|
|
1252
|
+
- **Strategy:** Fix production code using TDD workflow
|
|
1253
|
+
- **Process:**
|
|
1254
|
+
1. The failing test already exists (RED step done)
|
|
1255
|
+
2. **Proceed to Phase 1: PREPARE** of the TDD workflow
|
|
1256
|
+
3. Fix the production code (GREEN step)
|
|
1257
|
+
4. Refactor if needed
|
|
1258
|
+
5. Continue through Phase 2-3 as normal
|
|
1259
|
+
- **Commit:** `fix(component): <description>` with test changes if needed
|
|
1260
|
+
|
|
1261
|
+
#### Scenario B: Test Needs Updating (Intentional API Change)
|
|
1262
|
+
|
|
1263
|
+
- **Strategy:** Update test to match new expected behavior
|
|
1264
|
+
- **CRITICAL:** Get user confirmation before modifying test!
|
|
1265
|
+
- **Process:**
|
|
1266
|
+
1. Explain what changed and why test expectations are now different
|
|
1267
|
+
2. Ask if this is a breaking change
|
|
1268
|
+
3. Wait for user approval
|
|
1269
|
+
4. Update test assertions or setup
|
|
1270
|
+
5. Verify test passes
|
|
1271
|
+
6. Run full test suite
|
|
1272
|
+
- **Commit:** `test(component): update test for <change>`
|
|
1273
|
+
|
|
1274
|
+
#### Scenario C: Flaky Test (Non-Determinism)
|
|
1275
|
+
|
|
1276
|
+
- **Strategy:** Make test deterministic
|
|
1277
|
+
- **Process:**
|
|
1278
|
+
1. Identify source of non-determinism
|
|
1279
|
+
2. Fix the test to be deterministic:
|
|
1280
|
+
- Stub time-dependent code (freeze time in tests)
|
|
1281
|
+
- Use fixed seed for random data
|
|
1282
|
+
- Add proper synchronization for async operations
|
|
1283
|
+
- Isolate tests from each other (proper setup/teardown)
|
|
1284
|
+
- Remove timing dependencies
|
|
1285
|
+
3. Run test 20+ times to verify fix
|
|
1286
|
+
4. Run full test suite
|
|
1287
|
+
- **Commit:** `test(component): fix flaky test in <test_name>`
|
|
1288
|
+
- **If production code has race condition:** Also fix that using TDD workflow
|
|
1289
|
+
|
|
1290
|
+
#### Scenario D: Missing Test Coverage
|
|
1291
|
+
|
|
1292
|
+
- **Strategy:** Add tests using TDD workflow
|
|
1293
|
+
- **Process:**
|
|
1294
|
+
1. **Proceed to Phase 1: PREPARE** of the TDD workflow
|
|
1295
|
+
2. Write tests for uncovered code (RED step)
|
|
1296
|
+
3. If tests pass → good! Code works, test documents behavior
|
|
1297
|
+
4. If tests fail → found a bug, proceed with GREEN step
|
|
1298
|
+
5. Continue through normal TDD cycle
|
|
1299
|
+
- **Commit:** `test(component): add tests for <feature>`
|
|
1300
|
+
|
|
1301
|
+
#### Scenario E: Test Refactoring/Cleanup
|
|
1302
|
+
|
|
1303
|
+
- **Strategy:** Improve test quality without changing behavior
|
|
1304
|
+
- **Process:**
|
|
1305
|
+
1. Keep test green while refactoring
|
|
1306
|
+
2. Improve readability, reduce duplication
|
|
1307
|
+
3. Extract test helpers if needed
|
|
1308
|
+
4. Run test after each change to ensure still passing
|
|
1309
|
+
5. Run full test suite
|
|
1310
|
+
- **Commit:** `refactor(test): improve test clarity in <test_name>`
|
|
1311
|
+
|
|
1312
|
+
#### Scenario F: Environment/Setup Issue
|
|
1313
|
+
|
|
1314
|
+
- **Strategy:** Fix environment, not code
|
|
1315
|
+
- **Process:**
|
|
1316
|
+
1. Document the environment requirement
|
|
1317
|
+
2. Update README or test setup if needed
|
|
1318
|
+
3. May need to run `bin/setup` or install dependencies
|
|
1319
|
+
4. No code commit needed unless documenting requirement
|
|
1320
|
+
|
|
1321
|
+
### Step 6: Verify Test Fix
|
|
1322
|
+
|
|
1323
|
+
After implementing the fix:
|
|
1324
|
+
|
|
1325
|
+
1. **Run the Specific Test:**
|
|
1326
|
+
|
|
1327
|
+
```bash
|
|
1328
|
+
bundle exec bin/test <test_file>
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
2. **For Flaky Test Fixes, Run Many Times:**
|
|
1332
|
+
|
|
1333
|
+
```bash
|
|
1334
|
+
for i in {1..50}; do
|
|
1335
|
+
echo "Run $i"
|
|
1336
|
+
bundle exec bin/test test_branch || break
|
|
1337
|
+
done
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
Should pass all 50 times.
|
|
1341
|
+
|
|
1342
|
+
3. **Verify Test Isolation:**
|
|
1343
|
+
|
|
1344
|
+
```bash
|
|
1345
|
+
# Run test alone
|
|
1346
|
+
bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_method
|
|
1347
|
+
|
|
1348
|
+
# Run full suite
|
|
1349
|
+
bundle exec bin/test
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1352
|
+
4. **Run Full Test Suite:**
|
|
1353
|
+
|
|
1354
|
+
```bash
|
|
1355
|
+
bundle exec rake default
|
|
1356
|
+
```
|
|
1357
|
+
|
|
1358
|
+
5. **Confirm Fix:**
|
|
1359
|
+
|
|
1360
|
+
```text
|
|
1361
|
+
Test fix verified:
|
|
1362
|
+
- Test passes consistently (ran 50 times for flaky test)
|
|
1363
|
+
- Test passes in isolation
|
|
1364
|
+
- Full test suite passes
|
|
1365
|
+
- No regressions introduced
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
### Special Considerations
|
|
1369
|
+
|
|
1370
|
+
**Test Isolation:**
|
|
1371
|
+
|
|
1372
|
+
- Each test should be independent
|
|
1373
|
+
- Setup should create fresh state
|
|
1374
|
+
- Teardown should clean up completely
|
|
1375
|
+
- Use `clone_working_repo` or `create_temp_repo` from test helpers
|
|
1376
|
+
- Don't rely on test execution order
|
|
1377
|
+
|
|
1378
|
+
**Platform-Specific Tests:**
|
|
1379
|
+
|
|
1380
|
+
- Some tests may behave differently on Windows vs. Unix
|
|
1381
|
+
- Check for path separator issues (`/` vs. `\\`)
|
|
1382
|
+
- File permissions work differently across platforms
|
|
1383
|
+
- Line endings (CRLF vs. LF) can affect tests
|
|
1384
|
+
|
|
1385
|
+
**CI vs. Local:**
|
|
1386
|
+
|
|
1387
|
+
- CI may have different environment (different Ruby version, Git version, OS)
|
|
1388
|
+
- CI runs tests in different order
|
|
1389
|
+
- CI may have stricter resource limits
|
|
1390
|
+
- Use CI/CD Troubleshooting Workflow if failing only in CI
|
|
1391
|
+
|
|
1392
|
+
**Test Data Management:**
|
|
1393
|
+
|
|
1394
|
+
- Test fixtures are in `tests/files/`
|
|
1395
|
+
- Use test helpers to create temporary repos
|
|
1396
|
+
- Clean up temporary files in teardown
|
|
1397
|
+
- Don't commit generated test data
|
|
1398
|
+
|
|
1399
|
+
**Mocking and Stubbing:**
|
|
1400
|
+
|
|
1401
|
+
- Project uses Mocha for mocking
|
|
1402
|
+
- Be careful with stubs - they can hide real issues
|
|
1403
|
+
- Verify mocks are being called as expected
|
|
1404
|
+
- Clean up stubs in teardown
|
|
1405
|
+
|
|
1406
|
+
**Test Naming:**
|
|
1407
|
+
|
|
1408
|
+
- Test names should describe behavior: `test_creates_new_branch`
|
|
1409
|
+
- Not implementation: `test_branch_method`
|
|
1410
|
+
- Good names make failures self-documenting
|
|
1411
|
+
|
|
1412
|
+
### Integration with TDD Workflow
|
|
1413
|
+
|
|
1414
|
+
Test debugging transitions to TDD workflow in these cases:
|
|
1415
|
+
|
|
1416
|
+
1. **Production Code Bug Found:**
|
|
1417
|
+
- Failing test = RED step already done
|
|
1418
|
+
- **→ Proceed to Phase 1: PREPARE**
|
|
1419
|
+
- Fix bug using GREEN step
|
|
1420
|
+
- Continue through Phase 2-3
|
|
1421
|
+
|
|
1422
|
+
2. **Missing Test Coverage:**
|
|
1423
|
+
- **→ Proceed to Phase 1: PREPARE**
|
|
1424
|
+
- Write new tests using TDD cycle
|
|
1425
|
+
- RED → GREEN → REFACTOR for each test
|
|
1426
|
+
|
|
1427
|
+
3. **Flaky Test Reveals Race Condition in Production Code:**
|
|
1428
|
+
- Fix test first to make deterministic
|
|
1429
|
+
- Then **→ Proceed to Phase 1: PREPARE** to fix production code
|
|
1430
|
+
- Write additional test for the race condition
|
|
1431
|
+
- Fix using TDD workflow
|
|
1432
|
+
|
|
1433
|
+
**Do NOT use TDD workflow for:**
|
|
1434
|
+
|
|
1435
|
+
- Updating tests after intentional API changes (direct test update)
|
|
1436
|
+
- Fixing flaky tests (test maintenance)
|
|
1437
|
+
- Refactoring tests (test cleanup)
|
|
1438
|
+
- Environment issues (no code changes)
|
|
1439
|
+
|
|
1440
|
+
## Dependency Management Workflow
|
|
1441
|
+
|
|
1442
|
+
### Project-Specific Rules
|
|
1443
|
+
|
|
1444
|
+
- **All dependencies go in `git.gemspec`** (both runtime and development) - enforced by Rubocop
|
|
1445
|
+
- **`Gemfile` should remain minimal/empty** - do not add dependencies here
|
|
1446
|
+
- **`Gemfile.lock` is NOT committed** - this is a gem/library project
|
|
1447
|
+
|
|
1448
|
+
### Update Process
|
|
1449
|
+
|
|
1450
|
+
1. **Assess:** Run `bundle outdated` and `bundle audit check --update` (if available)
|
|
1451
|
+
2. **Update:** Edit `git.gemspec` if constraints need changing, then run `bundle update`
|
|
1452
|
+
3. **Test:** Run `bundle exec rake default` - must pass on all Ruby versions (3.2, 3.3, 3.4)
|
|
1453
|
+
4. **Commit:** Use conventional commit format:
|
|
1454
|
+
- Security: `fix(deps): update <gem> to fix CVE-XXXX-XXXX`
|
|
1455
|
+
- Regular: `chore(deps): update dependencies`
|
|
1456
|
+
- Breaking: `chore(deps)!: update <gem>` with `BREAKING CHANGE:` footer
|
|
1457
|
+
|
|
1458
|
+
### Key Considerations
|
|
1459
|
+
|
|
1460
|
+
- Security vulnerabilities are highest priority - address immediately
|
|
1461
|
+
- For gem projects, version constraints in gemspec must be carefully chosen since users resolve dependencies independently
|
|
1462
|
+
- Breaking changes in dependencies may require code changes (use TDD workflow)
|
|
1463
|
+
- Test with both minimum supported versions and latest versions when possible
|
|
1464
|
+
- If tests fail, isolate by updating gems one at a time or use binary search
|
|
1465
|
+
|
|
1466
|
+
### Commit Guidelines
|
|
1467
|
+
|
|
1468
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org/). A
|
|
1469
|
+
commit hook enforces the format. See [Git Commit
|
|
1470
|
+
Conventions](#git-commit-conventions) for the full format and allowed types.
|
|
1471
|
+
|
|
1472
|
+
#### Per-Task Commits
|
|
1473
|
+
|
|
1474
|
+
In the COMMIT step, create a commit for the completed task following these
|
|
1475
|
+
guidelines:
|
|
1476
|
+
|
|
1477
|
+
- **Use Appropriate Types:**
|
|
1478
|
+
- `test:` for adding or modifying tests (RED step)
|
|
1479
|
+
- `feat:` for new **user-facing** functionality (triggers MINOR version bump)
|
|
1480
|
+
- `fix:` for bug fixes (GREEN step for bugs)
|
|
1481
|
+
- `refactor:` for code improvements without behavior change
|
|
1482
|
+
- `chore:` for internal tooling or maintenance
|
|
1483
|
+
- **Use Scope When Relevant:** Include a scope to indicate the affected component
|
|
1484
|
+
(e.g., `feat(branch):`, `test(remote):`).
|
|
1485
|
+
- **Write Clear Subjects:** Use imperative mood, lowercase, no period (e.g.,
|
|
1486
|
+
`feat(branch): add create method`).
|
|
1487
|
+
|
|
1488
|
+
### Additional Guidelines
|
|
1489
|
+
|
|
1490
|
+
These guidelines supplement the TDD process:
|
|
1491
|
+
|
|
1492
|
+
- **Justify Test Modifications:** If an existing test needs to be modified, STOP and
|
|
1493
|
+
report to the user before making the change. Explain which test needs modification,
|
|
1494
|
+
why the expected behavior is changing, and whether this represents a breaking
|
|
1495
|
+
change. Wait for user confirmation before proceeding.
|
|
1496
|
+
- **Unrelated Test Failures:** If you need to modify a test file that is not related
|
|
1497
|
+
to the current task to make the build pass, STOP and report to the user. This
|
|
1498
|
+
usually indicates a deeper regression, environment issue, or flawed assumption. Do
|
|
1499
|
+
not attempt to fix unrelated tests without user guidance.
|
|
1500
|
+
- **Handle Discovered Complexity:** If the implementation reveals a complex logic
|
|
1501
|
+
gap, add it to your task list but finish the current cycle first.
|
|
1502
|
+
- **Test Names Describe Behavior:** Name tests to clearly describe what behavior they
|
|
1503
|
+
verify (e.g., `test_creates_new_branch` not `test_branch`).
|
|
1504
|
+
- **Ask for Clarification:** Stop and ask for clarification if requirements or
|
|
1505
|
+
expectations are ambiguous.
|
|
1506
|
+
|
|
1507
|
+
### Example TDD Cycle
|
|
1508
|
+
|
|
1509
|
+
Each task follows this cycle: **RED → GREEN → REFACTOR → VERIFY → COMMIT → REPLAN**
|
|
1510
|
+
|
|
1511
|
+
**RED:** Write a failing test that describes the desired behavior.
|
|
1512
|
+
|
|
1513
|
+
```ruby
|
|
1514
|
+
def test_creates_new_branch
|
|
1515
|
+
@git.branch('feature').create
|
|
1516
|
+
assert @git.branches.local.map(&:name).include?('feature')
|
|
1517
|
+
end
|
|
1518
|
+
# Run: bundle exec bin/test test_branch → fails with NoMethodError
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
**GREEN:** Write minimal code to make the test pass.
|
|
1522
|
+
|
|
1523
|
+
```ruby
|
|
1524
|
+
def create
|
|
1525
|
+
@base.lib.branch_new(@name)
|
|
1526
|
+
end
|
|
1527
|
+
# Run: bundle exec bin/test test_branch → passes
|
|
1528
|
+
```
|
|
1529
|
+
|
|
1530
|
+
**REFACTOR:** Improve code quality without changing behavior, then run all tests.
|
|
1531
|
+
|
|
1532
|
+
**VERIFY:** Run `bundle exec rake default` to confirm tests and linters pass.
|
|
1533
|
+
|
|
1534
|
+
**COMMIT:** `git commit -m "feat(branch): add Branch#create method"`
|
|
1535
|
+
|
|
1536
|
+
**REPLAN:** Report progress, update task list, proceed to next task or FINALIZE.
|
|
1537
|
+
|
|
1538
|
+
**FINALIZE (after all tasks):** Propose squash commit with captured messages, wait
|
|
1539
|
+
for user confirmation, then execute.
|
|
1540
|
+
|
|
1541
|
+
## Merge Conflict Resolution Workflow
|
|
1542
|
+
|
|
1543
|
+
This workflow guides resolving merge conflicts in pull requests or when merging
|
|
1544
|
+
branches locally.
|
|
1545
|
+
|
|
1546
|
+
### Step 1: Identify Conflicts
|
|
1547
|
+
|
|
1548
|
+
Before resolving conflicts, understand what needs to be merged:
|
|
1549
|
+
|
|
1550
|
+
1. **For PR conflicts:**
|
|
1551
|
+
|
|
1552
|
+
- View PR details and check out the PR branch using `gh pr checkout`
|
|
1553
|
+
- Attempt to merge `main` with `--no-commit` to see conflicts
|
|
1554
|
+
|
|
1555
|
+
2. **For local branch merging:** Fetch origin, then attempt merge with
|
|
1556
|
+
`--no-commit` to see conflicts.
|
|
1557
|
+
|
|
1558
|
+
3. **List conflicted files** using `git diff --name-only --diff-filter=U`.
|
|
1559
|
+
|
|
1560
|
+
### Step 2: Understand the Conflicting Changes
|
|
1561
|
+
|
|
1562
|
+
For each conflicted file:
|
|
1563
|
+
|
|
1564
|
+
1. **View the conflict markers** in the file.
|
|
1565
|
+
2. **Understand both sides:** Compare what each branch changed relative to the
|
|
1566
|
+
common ancestor using `git diff` with the appropriate refs (HEAD, MERGE_HEAD,
|
|
1567
|
+
and the stage numbers `:1:`, `:2:`, `:3:` for base/ours/theirs).
|
|
1568
|
+
3. **Check the history** of the conflicting sections if needed.
|
|
1569
|
+
|
|
1570
|
+
### Step 3: Resolve Conflicts
|
|
1571
|
+
|
|
1572
|
+
Choose the appropriate resolution strategy:
|
|
1573
|
+
|
|
1574
|
+
- **Accept one side entirely:** Use `git checkout --ours <file>` or
|
|
1575
|
+
`git checkout --theirs <file>`
|
|
1576
|
+
- **Manual resolution:** Edit the file to resolve conflict markers
|
|
1577
|
+
(`<<<<<<<`, `=======`, `>>>>>>>`), then stage with `git add`
|
|
1578
|
+
- **Interactive merge tool:** Use `git mergetool <file>`
|
|
1579
|
+
|
|
1580
|
+
### Step 4: Verify Resolution
|
|
1581
|
+
|
|
1582
|
+
After resolving all conflicts:
|
|
1583
|
+
|
|
1584
|
+
1. **Check for remaining conflicts:** `git diff --check`
|
|
1585
|
+
2. **Run the test suite:** `bundle exec bin/test`
|
|
1586
|
+
3. **Run linters:** `bundle exec rake rubocop`
|
|
1587
|
+
4. **Review the final diff:** `git diff --staged`
|
|
1588
|
+
|
|
1589
|
+
### Step 5: Complete the Merge
|
|
1590
|
+
|
|
1591
|
+
Commit the merge with a message listing the resolved conflict files.
|
|
1592
|
+
|
|
1593
|
+
1. **Push the changes:**
|
|
1594
|
+
|
|
1595
|
+
```bash
|
|
1596
|
+
git push
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
2. **For PRs, verify CI passes:**
|
|
1600
|
+
|
|
1601
|
+
```bash
|
|
1602
|
+
gh pr checks #999
|
|
1603
|
+
```
|
|
1604
|
+
|
|
1605
|
+
## Code Archaeology & History Analysis Workflow
|
|
1606
|
+
|
|
1607
|
+
This workflow helps investigate code history to understand when bugs were introduced,
|
|
1608
|
+
track changes to specific code, and find usages of methods or classes.
|
|
1609
|
+
|
|
1610
|
+
### Understanding History Analysis Tools
|
|
1611
|
+
|
|
1612
|
+
ruby-git provides several approaches to code archaeology:
|
|
1613
|
+
|
|
1614
|
+
- **git blame**: See who last modified each line
|
|
1615
|
+
- **git log**: Track commit history for files or code
|
|
1616
|
+
- **git bisect**: Binary search to find the commit that introduced a bug
|
|
1617
|
+
- **grep/semantic search**: Find usages of methods and classes
|
|
1618
|
+
|
|
1619
|
+
### Finding When a Bug Was Introduced (git bisect)
|
|
1620
|
+
|
|
1621
|
+
When you need to find which commit introduced a bug:
|
|
1622
|
+
|
|
1623
|
+
1. **Start bisect session:**
|
|
1624
|
+
|
|
1625
|
+
```bash
|
|
1626
|
+
# Start bisect
|
|
1627
|
+
git bisect start
|
|
1628
|
+
|
|
1629
|
+
# Mark current commit as bad (has the bug)
|
|
1630
|
+
git bisect bad
|
|
1631
|
+
|
|
1632
|
+
# Mark a known good commit (before the bug existed)
|
|
1633
|
+
git bisect good <commit-sha>
|
|
1634
|
+
```
|
|
1635
|
+
|
|
1636
|
+
2. **Test each commit:**
|
|
1637
|
+
|
|
1638
|
+
For each commit git checks out:
|
|
1639
|
+
|
|
1640
|
+
```bash
|
|
1641
|
+
# Run relevant tests
|
|
1642
|
+
bundle exec bin/test <test_name>
|
|
1643
|
+
|
|
1644
|
+
# Mark as good or bad
|
|
1645
|
+
git bisect good # if bug is NOT present
|
|
1646
|
+
git bisect bad # if bug IS present
|
|
1647
|
+
```
|
|
1648
|
+
|
|
1649
|
+
3. **Automated bisect with test script:**
|
|
1650
|
+
|
|
1651
|
+
```bash
|
|
1652
|
+
# Create test script that exits 0 for good, non-zero for bad
|
|
1653
|
+
git bisect run bundle exec ruby -I lib:tests tests/units/test_specific.rb -n test_method
|
|
1654
|
+
```
|
|
1655
|
+
|
|
1656
|
+
4. **Complete bisect:**
|
|
1657
|
+
|
|
1658
|
+
```bash
|
|
1659
|
+
# View the result
|
|
1660
|
+
git bisect log
|
|
1661
|
+
|
|
1662
|
+
# Reset to original state
|
|
1663
|
+
git bisect reset
|
|
1664
|
+
```
|
|
1665
|
+
|
|
1666
|
+
### Tracing Method History
|
|
1667
|
+
|
|
1668
|
+
To see how a specific method has changed over time:
|
|
1669
|
+
|
|
1670
|
+
1. **View file history with changes:**
|
|
1671
|
+
|
|
1672
|
+
```bash
|
|
1673
|
+
# Show commits that touched a specific file
|
|
1674
|
+
git log --oneline -p -- lib/git/base.rb
|
|
1675
|
+
|
|
1676
|
+
# Search for commits that changed specific text
|
|
1677
|
+
git log -p -S "def checkout" -- lib/git/base.rb
|
|
1678
|
+
|
|
1679
|
+
# Show commits that changed a specific function (if supported)
|
|
1680
|
+
git log -p -L :checkout:lib/git/base.rb
|
|
1681
|
+
```
|
|
1682
|
+
|
|
1683
|
+
2. **View the history of a specific line range:**
|
|
1684
|
+
|
|
1685
|
+
```bash
|
|
1686
|
+
git log -p -L 100,150:lib/git/base.rb
|
|
1687
|
+
```
|
|
1688
|
+
|
|
1689
|
+
3. **Find when a method was added:**
|
|
1690
|
+
|
|
1691
|
+
```bash
|
|
1692
|
+
git log --diff-filter=A -p -S "def method_name"
|
|
1693
|
+
```
|
|
1694
|
+
|
|
1695
|
+
### Finding Code Usages
|
|
1696
|
+
|
|
1697
|
+
To find all callers or usages of a method:
|
|
1698
|
+
|
|
1699
|
+
1. **Use grep_search for exact matches:**
|
|
1700
|
+
|
|
1701
|
+
```bash
|
|
1702
|
+
# Find method calls
|
|
1703
|
+
grep -rn "\.checkout" lib/ tests/
|
|
1704
|
+
|
|
1705
|
+
# Find class references
|
|
1706
|
+
grep -rn "Git::Base" lib/ tests/
|
|
1707
|
+
```
|
|
1708
|
+
|
|
1709
|
+
2. **Use semantic_search for broader context:**
|
|
1710
|
+
|
|
1711
|
+
Use the AI's semantic_search capability to find related code patterns.
|
|
1712
|
+
|
|
1713
|
+
3. **Find test coverage for a method:**
|
|
1714
|
+
|
|
1715
|
+
```bash
|
|
1716
|
+
grep -rn "def test.*checkout" tests/
|
|
1717
|
+
```
|
|
1718
|
+
|
|
1719
|
+
### Blame Analysis
|
|
1720
|
+
|
|
1721
|
+
To understand who changed specific code and why:
|
|
1722
|
+
|
|
1723
|
+
1. **Basic blame:**
|
|
1724
|
+
|
|
1725
|
+
```bash
|
|
1726
|
+
git blame lib/git/base.rb
|
|
1727
|
+
```
|
|
1728
|
+
|
|
1729
|
+
2. **Blame with commit messages:**
|
|
1730
|
+
|
|
1731
|
+
```bash
|
|
1732
|
+
git blame -c lib/git/base.rb
|
|
1733
|
+
```
|
|
1734
|
+
|
|
1735
|
+
3. **Ignore whitespace changes:**
|
|
1736
|
+
|
|
1737
|
+
```bash
|
|
1738
|
+
git blame -w lib/git/base.rb
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
4. **Find the original author (ignore moves/copies):**
|
|
1742
|
+
|
|
1743
|
+
```bash
|
|
1744
|
+
git blame -M -C lib/git/base.rb
|
|
1745
|
+
```
|
|
1746
|
+
|
|
1747
|
+
5. **Blame specific lines:**
|
|
1748
|
+
|
|
1749
|
+
```bash
|
|
1750
|
+
git blame -L 100,150 lib/git/base.rb
|
|
1751
|
+
```
|
|
1752
|
+
|
|
1753
|
+
## Release Management Workflow
|
|
1754
|
+
|
|
1755
|
+
This workflow guides preparing and publishing new releases of the ruby-git gem.
|
|
1756
|
+
|
|
1757
|
+
### Understanding the Release Process
|
|
1758
|
+
|
|
1759
|
+
ruby-git uses [release-please](https://github.com/googleapis/release-please) for
|
|
1760
|
+
automated release management. Key files:
|
|
1761
|
+
|
|
1762
|
+
- `release-please-config.json` - Release configuration
|
|
1763
|
+
- `lib/git/version.rb` - Version constant
|
|
1764
|
+
- `CHANGELOG.md` - Release history
|
|
1765
|
+
|
|
1766
|
+
### Step 1: Pre-Release Checks
|
|
1767
|
+
|
|
1768
|
+
Before preparing a release:
|
|
1769
|
+
|
|
1770
|
+
1. **Ensure all CI checks pass:**
|
|
1771
|
+
|
|
1772
|
+
```bash
|
|
1773
|
+
bundle exec rake default
|
|
1774
|
+
```
|
|
1775
|
+
|
|
1776
|
+
2. **Review unreleased changes:**
|
|
1777
|
+
|
|
1778
|
+
```bash
|
|
1779
|
+
# List commits since last tag
|
|
1780
|
+
git log $(git describe --tags --abbrev=0)..HEAD --oneline
|
|
1781
|
+
|
|
1782
|
+
# List PRs merged since last release
|
|
1783
|
+
gh pr list --state merged --base main --search "merged:>$(git log -1 --format=%cs $(git describe --tags --abbrev=0))"
|
|
1784
|
+
```
|
|
1785
|
+
|
|
1786
|
+
3. **Check for any outstanding issues:**
|
|
1787
|
+
|
|
1788
|
+
```bash
|
|
1789
|
+
gh issue list --label "bug" --state open
|
|
1790
|
+
gh issue list --label "breaking-change" --state open
|
|
1791
|
+
```
|
|
1792
|
+
|
|
1793
|
+
4. **Verify documentation is current:**
|
|
1794
|
+
|
|
1795
|
+
```bash
|
|
1796
|
+
bundle exec yard doc
|
|
1797
|
+
bundle exec yard stats --list-undoc
|
|
1798
|
+
```
|
|
1799
|
+
|
|
1800
|
+
### Step 2: Version Bump
|
|
1801
|
+
|
|
1802
|
+
Determine the appropriate version bump based on changes:
|
|
1803
|
+
|
|
1804
|
+
- **Patch** (x.y.Z): Bug fixes, documentation, non-breaking changes
|
|
1805
|
+
- **Minor** (x.Y.0): New features, backward-compatible additions
|
|
1806
|
+
- **Major** (X.0.0): Breaking changes
|
|
1807
|
+
|
|
1808
|
+
Update version in `lib/git/version.rb`:
|
|
1809
|
+
|
|
1810
|
+
```ruby
|
|
1811
|
+
module Git
|
|
1812
|
+
VERSION = 'X.Y.Z'
|
|
1813
|
+
end
|
|
1814
|
+
```
|
|
1815
|
+
|
|
1816
|
+
### Step 3: Update Changelog
|
|
1817
|
+
|
|
1818
|
+
1. **Generate release notes from PRs:**
|
|
1819
|
+
|
|
1820
|
+
```bash
|
|
1821
|
+
# List merged PRs since last release
|
|
1822
|
+
gh pr list --state merged --base main --json number,title,labels,mergedAt \
|
|
1823
|
+
--search "merged:>$(git log -1 --format=%cs $(git describe --tags --abbrev=0))" \
|
|
1824
|
+
| jq -r '.[] | "- \(.title) (#\(.number))"'
|
|
1825
|
+
```
|
|
1826
|
+
|
|
1827
|
+
2. **Organize by category in CHANGELOG.md:**
|
|
1828
|
+
|
|
1829
|
+
```markdown
|
|
1830
|
+
## [X.Y.Z] - YYYY-MM-DD
|
|
1831
|
+
|
|
1832
|
+
### Added
|
|
1833
|
+
- New feature description (#PR)
|
|
1834
|
+
|
|
1835
|
+
### Changed
|
|
1836
|
+
- Changed behavior description (#PR)
|
|
1837
|
+
|
|
1838
|
+
### Fixed
|
|
1839
|
+
- Bug fix description (#PR)
|
|
1840
|
+
|
|
1841
|
+
### Deprecated
|
|
1842
|
+
- Deprecated feature description (#PR)
|
|
1843
|
+
|
|
1844
|
+
### Removed
|
|
1845
|
+
- Removed feature description (#PR)
|
|
1846
|
+
|
|
1847
|
+
### Security
|
|
1848
|
+
- Security fix description (#PR)
|
|
1849
|
+
```
|
|
1850
|
+
|
|
1851
|
+
### Step 4: Create Release
|
|
1852
|
+
|
|
1853
|
+
1. **Commit version bump and changelog:**
|
|
1854
|
+
|
|
1855
|
+
```bash
|
|
1856
|
+
git add lib/git/version.rb CHANGELOG.md
|
|
1857
|
+
git commit -m "chore: release X.Y.Z"
|
|
1858
|
+
```
|
|
1859
|
+
|
|
1860
|
+
2. **Create and push tag:**
|
|
1861
|
+
|
|
1862
|
+
```bash
|
|
1863
|
+
git tag -a vX.Y.Z -m "Release X.Y.Z"
|
|
1864
|
+
git push origin main --tags
|
|
1865
|
+
```
|
|
1866
|
+
|
|
1867
|
+
3. **Build and publish gem:**
|
|
1868
|
+
|
|
1869
|
+
```bash
|
|
1870
|
+
bundle exec rake build
|
|
1871
|
+
gem push pkg/git-X.Y.Z.gem
|
|
1872
|
+
```
|
|
1873
|
+
|
|
1874
|
+
4. **Create GitHub release:**
|
|
1875
|
+
|
|
1876
|
+
```bash
|
|
1877
|
+
gh release create vX.Y.Z --title "vX.Y.Z" --notes-file RELEASE_NOTES.md
|
|
1878
|
+
```
|
|
1879
|
+
|
|
1880
|
+
### Step 5: Post-Release Tasks
|
|
1881
|
+
|
|
1882
|
+
1. **Verify gem is available:**
|
|
1883
|
+
|
|
1884
|
+
```bash
|
|
1885
|
+
gem info git --remote
|
|
1886
|
+
```
|
|
1887
|
+
|
|
1888
|
+
2. **Announce release (if applicable):**
|
|
1889
|
+
- Update any external documentation
|
|
1890
|
+
- Notify downstream dependencies
|
|
1891
|
+
|
|
1892
|
+
3. **Close related milestone (if used):**
|
|
1893
|
+
|
|
1894
|
+
```bash
|
|
1895
|
+
gh api repos/{owner}/{repo}/milestones --jq '.[] | select(.title=="vX.Y.Z")'
|
|
1896
|
+
```
|
|
1897
|
+
|
|
1898
|
+
### Release Commands Reference
|
|
1899
|
+
|
|
1900
|
+
```bash
|
|
1901
|
+
# View recent tags
|
|
1902
|
+
git tag -l --sort=-v:refname | head -10
|
|
1903
|
+
|
|
1904
|
+
# Compare with previous release
|
|
1905
|
+
git diff v1.0.0..v1.1.0
|
|
16
1906
|
|
|
17
|
-
|
|
1907
|
+
# List commits since tag
|
|
1908
|
+
git log v1.0.0..HEAD --oneline
|
|
18
1909
|
|
|
19
|
-
|
|
1910
|
+
# View tag details
|
|
1911
|
+
git show v1.0.0
|
|
20
1912
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
support
|
|
25
|
-
- **Git Objects** - Repository objects (Commit, Tree, Blob, Tag) via `Git::Object`
|
|
26
|
-
- **Git::Status** - Working directory status (tracked/untracked/modified files)
|
|
27
|
-
- **Git::Diff** - Diff operations returning file-level patches and statistics
|
|
28
|
-
- **Git::Log** - Enumerable query builder for commit history
|
|
29
|
-
- **Git::Branch/Branches** - Branch management (local and remote)
|
|
30
|
-
- **Git::Remote** - Remote repository references
|
|
31
|
-
- **Git::Worktree/Worktrees** - Git worktree support
|
|
32
|
-
- **Git::Stash/Stashes** - Stash management
|
|
1913
|
+
# Delete tag (if needed)
|
|
1914
|
+
git tag -d vX.Y.Z
|
|
1915
|
+
git push origin :refs/tags/vX.Y.Z
|
|
33
1916
|
|
|
34
|
-
|
|
1917
|
+
# Build gem locally
|
|
1918
|
+
bundle exec rake build
|
|
35
1919
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- `pkg/` - Built gem packages
|
|
40
|
-
- `redesign/` - Architecture redesign documentation
|
|
1920
|
+
# Install gem locally for testing
|
|
1921
|
+
gem install pkg/git-X.Y.Z.gem
|
|
1922
|
+
```
|
|
41
1923
|
|
|
42
|
-
##
|
|
1924
|
+
## Breaking Change Analysis Workflow
|
|
43
1925
|
|
|
44
|
-
|
|
1926
|
+
This workflow helps assess the impact of API changes before implementation to
|
|
1927
|
+
understand what code would break and plan appropriate migration paths.
|
|
45
1928
|
|
|
46
|
-
|
|
47
|
-
- Follow Ruby community style guide (Rubocop-compatible)
|
|
48
|
-
- Require Ruby 3.2.0+ features and idioms
|
|
49
|
-
- Use keyword arguments for methods with multiple parameters
|
|
50
|
-
- Prefer `private` over `private :method_name` for method visibility
|
|
51
|
-
- Use pattern matching for complex conditional logic where appropriate
|
|
1929
|
+
### Understanding Breaking Changes
|
|
52
1930
|
|
|
53
|
-
|
|
1931
|
+
A breaking change is any modification that requires users to update their code:
|
|
54
1932
|
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
1933
|
+
- Removing or renaming public methods/classes
|
|
1934
|
+
- Changing method signatures (required parameters)
|
|
1935
|
+
- Changing return types or values
|
|
1936
|
+
- Changing exception types
|
|
1937
|
+
- Modifying default behavior
|
|
60
1938
|
|
|
61
|
-
###
|
|
1939
|
+
### Step 1: Identify the Change Scope
|
|
62
1940
|
|
|
63
|
-
|
|
64
|
-
- Methods/variables: snake_case (e.g., `current_branch`, `ls_files`, `commit_all`)
|
|
65
|
-
- Constants: UPPER_SNAKE_CASE (e.g., `VERSION`)
|
|
66
|
-
- Predicate methods: end with `?` (e.g., `bare?`, `success?`, `exist?`)
|
|
67
|
-
- Dangerous methods: end with `!` if they modify in place
|
|
68
|
-
- Instance variables: `@variable_name`
|
|
69
|
-
- Avoid class variables; prefer class instance variables or constants
|
|
1941
|
+
1. **Determine what is changing:**
|
|
70
1942
|
|
|
71
|
-
|
|
1943
|
+
- Which class(es) are affected?
|
|
1944
|
+
- Which method(s) are affected?
|
|
1945
|
+
- Is this a public or private API?
|
|
72
1946
|
|
|
73
|
-
|
|
74
|
-
include interface changes to fully align with these principles.
|
|
1947
|
+
2. **Check API visibility:**
|
|
75
1948
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
1949
|
+
```bash
|
|
1950
|
+
# Search for @api tags in documentation
|
|
1951
|
+
grep -n "@api public" lib/git/*.rb
|
|
1952
|
+
grep -n "@api private" lib/git/*.rb
|
|
1953
|
+
```
|
|
79
1954
|
|
|
80
|
-
|
|
1955
|
+
3. **Review current documentation:**
|
|
81
1956
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- Allow users to leverage their existing knowledge of Git
|
|
1957
|
+
```bash
|
|
1958
|
+
bundle exec yard doc
|
|
1959
|
+
open doc/index.html
|
|
1960
|
+
```
|
|
87
1961
|
|
|
88
|
-
###
|
|
1962
|
+
### Step 2: Find All Usages
|
|
89
1963
|
|
|
90
|
-
|
|
91
|
-
- Each method should directly correspond to a `git` command
|
|
92
|
-
- Example: `git add` → `Git::Base#add`, `git ls-files` → `Git::Base#ls_files`
|
|
93
|
-
- When a single Git command serves multiple distinct purposes, use the command name
|
|
94
|
-
as a prefix followed by a descriptive suffix
|
|
95
|
-
- Example: `#ls_files_untracked`, `#ls_files_staged`
|
|
96
|
-
- Introduce aliases to provide more user-friendly method names where appropriate
|
|
1964
|
+
1. **Search within the gem:**
|
|
97
1965
|
|
|
98
|
-
|
|
1966
|
+
```bash
|
|
1967
|
+
# Find internal usages
|
|
1968
|
+
grep -rn "method_name" lib/
|
|
1969
|
+
grep -rn "ClassName" lib/
|
|
1970
|
+
```
|
|
99
1971
|
|
|
100
|
-
|
|
101
|
-
- Ensures familiarity for developers already accustomed to Git
|
|
102
|
-
- Note: Not all Git command options are supported
|
|
1972
|
+
2. **Search in tests:**
|
|
103
1973
|
|
|
104
|
-
|
|
1974
|
+
```bash
|
|
1975
|
+
grep -rn "method_name" tests/
|
|
1976
|
+
```
|
|
105
1977
|
|
|
106
|
-
|
|
107
|
-
- Ruby objects often include methods that allow for further Git operations
|
|
108
|
-
- Provide additional functionality while staying true to underlying Git behavior
|
|
1978
|
+
3. **Use semantic search for broader patterns:**
|
|
109
1979
|
|
|
110
|
-
|
|
1980
|
+
Use the AI's semantic_search to find related usages that might not match exact
|
|
1981
|
+
patterns.
|
|
111
1982
|
|
|
112
|
-
|
|
113
|
-
- Include `@param`, `@return`, `@raise`, `@example` tags
|
|
114
|
-
- Document edge cases, platform differences, and security considerations
|
|
115
|
-
- Keep method documentation up-to-date with implementation
|
|
116
|
-
- Add `@api private` for internal-only methods
|
|
117
|
-
- Document Git version requirements and compatibility
|
|
1983
|
+
4. **Check external usage (if applicable):**
|
|
118
1984
|
|
|
119
|
-
|
|
1985
|
+
```bash
|
|
1986
|
+
# Search GitHub for usage of this gem's API
|
|
1987
|
+
gh search code "Git::Base#method_name language:ruby"
|
|
1988
|
+
```
|
|
120
1989
|
|
|
121
|
-
|
|
122
|
-
# Opens a Git repository
|
|
123
|
-
#
|
|
124
|
-
# @param [String, Pathname] path The path to the working directory or .git directory
|
|
125
|
-
# @param [Hash] options The options for this command (see list of valid options below)
|
|
126
|
-
# @option options [Logger] :log A logger to use for Git operations
|
|
127
|
-
# @option options [Numeric] :timeout Maximum seconds to wait for Git commands (0 for no timeout)
|
|
128
|
-
# @return [Git::Base] an object that can execute git commands in the context of the repository
|
|
129
|
-
# @raise [ArgumentError] if path is not a valid Git repository
|
|
130
|
-
# @example Open a repository
|
|
131
|
-
# git = Git.open('/path/to/repo')
|
|
132
|
-
# puts git.log.first.message
|
|
133
|
-
# @api public
|
|
134
|
-
def self.open(path, options = {})
|
|
135
|
-
# implementation
|
|
136
|
-
end
|
|
137
|
-
```
|
|
1990
|
+
### Step 3: Assess Impact
|
|
138
1991
|
|
|
139
|
-
|
|
1992
|
+
Create an impact assessment:
|
|
140
1993
|
|
|
141
|
-
|
|
1994
|
+
1. **Internal impact:**
|
|
1995
|
+
- Number of files affected within the gem
|
|
1996
|
+
- Test changes required
|
|
1997
|
+
- Documentation updates needed
|
|
142
1998
|
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
- Captures stdout, stderr, and exit status
|
|
148
|
-
- Raises appropriate errors on command failures
|
|
1999
|
+
2. **External impact:**
|
|
2000
|
+
- Likely number of external users affected
|
|
2001
|
+
- Severity (compile error vs. runtime error vs. behavior change)
|
|
2002
|
+
- Ease of migration
|
|
149
2003
|
|
|
150
|
-
|
|
2004
|
+
3. **Document findings:**
|
|
151
2005
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- Delegates to `Git::Lib` for low-level operations
|
|
155
|
-
- Manages working directory, index, and repository references
|
|
156
|
-
- Returns domain objects (Branch, Status, Diff, Log, etc.)
|
|
2006
|
+
```markdown
|
|
2007
|
+
## Breaking Change Impact Assessment
|
|
157
2008
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- Parses Git command output
|
|
161
|
-
- Minimal business logic - focuses on command execution
|
|
2009
|
+
### Change Description
|
|
2010
|
+
[What is being changed]
|
|
162
2011
|
|
|
163
|
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
2012
|
+
### Affected API
|
|
2013
|
+
- Class: `Git::Base`
|
|
2014
|
+
- Method: `#checkout`
|
|
2015
|
+
- Current signature: `def checkout(branch, opts = {})`
|
|
2016
|
+
- Proposed signature: `def checkout(branch, create: false)`
|
|
168
2017
|
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
- Methods for inspecting object properties and relationships
|
|
2018
|
+
### Internal Impact
|
|
2019
|
+
- Files affected: X
|
|
2020
|
+
- Tests to update: Y
|
|
173
2021
|
|
|
174
|
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
- Similar to `git status` command output
|
|
2022
|
+
### External Impact
|
|
2023
|
+
- Severity: [High/Medium/Low]
|
|
2024
|
+
- Migration difficulty: [Easy/Medium/Hard]
|
|
178
2025
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
- Total insertion/deletion statistics
|
|
2026
|
+
### Migration Path
|
|
2027
|
+
[How users should update their code]
|
|
2028
|
+
```
|
|
183
2029
|
|
|
184
|
-
|
|
185
|
-
- Chainable methods for building log queries
|
|
186
|
-
- Enumerable returning `Git::Object::Commit` objects
|
|
187
|
-
- Supports filtering by path, date range, author, etc.
|
|
2030
|
+
### Step 4: Plan Migration Path
|
|
188
2031
|
|
|
189
|
-
|
|
2032
|
+
1. **Deprecation approach (preferred for non-urgent changes):**
|
|
190
2033
|
|
|
191
|
-
ruby
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
2034
|
+
```ruby
|
|
2035
|
+
def old_method(*args)
|
|
2036
|
+
warn "[DEPRECATION] `old_method` is deprecated. Use `new_method` instead."
|
|
2037
|
+
new_method(*args)
|
|
2038
|
+
end
|
|
2039
|
+
```
|
|
195
2040
|
|
|
196
|
-
|
|
197
|
-
|
|
2041
|
+
2. **Version-based migration:**
|
|
2042
|
+
- v2.x: Deprecate with warning
|
|
2043
|
+
- v3.0: Remove deprecated API
|
|
198
2044
|
|
|
199
|
-
|
|
2045
|
+
3. **Document migration in CHANGELOG:**
|
|
200
2046
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- `Git::
|
|
204
|
-
|
|
205
|
-
- `ArgumentError`: Invalid arguments passed to methods
|
|
2047
|
+
```markdown
|
|
2048
|
+
### Deprecated
|
|
2049
|
+
- `Git::Base#old_method` is deprecated, use `Git::Base#new_method` instead
|
|
2050
|
+
```
|
|
206
2051
|
|
|
207
|
-
|
|
2052
|
+
### Step 5: Document the Change
|
|
208
2053
|
|
|
209
|
-
|
|
2054
|
+
1. **Update YARD documentation:**
|
|
210
2055
|
|
|
211
|
-
|
|
2056
|
+
```ruby
|
|
2057
|
+
# @deprecated Use {#new_method} instead. Will be removed in v3.0.
|
|
2058
|
+
def old_method
|
|
2059
|
+
end
|
|
2060
|
+
```
|
|
212
2061
|
|
|
213
|
-
**
|
|
214
|
-
Red-Green-Refactor cycle.**
|
|
2062
|
+
2. **Add to CHANGELOG.md:**
|
|
215
2063
|
|
|
216
|
-
|
|
217
|
-
|
|
2064
|
+
````markdown
|
|
2065
|
+
### Breaking Changes
|
|
2066
|
+
- `Git::Base#checkout` signature changed: `opts` hash replaced with keyword
|
|
2067
|
+
arguments
|
|
218
2068
|
|
|
219
|
-
|
|
2069
|
+
### Migration Guide
|
|
220
2070
|
|
|
221
|
-
|
|
222
|
-
- **Bug Fixes Start with Tests:** Before fixing any bug, write a failing test that
|
|
223
|
-
demonstrates the bug and fails in the expected way. Only then fix the code to make
|
|
224
|
-
the test pass.
|
|
225
|
-
- **Tests Drive Design:** Let the test dictate the API and architecture. If the test
|
|
226
|
-
is hard to write, the design is likely wrong. When this happens, stop and suggest
|
|
227
|
-
one or more design alternatives. Offer to stash any current changes and work on the
|
|
228
|
-
design improvements first before continuing with the original task.
|
|
229
|
-
- **Write Tests Incrementally:** Focus on small, atomic tests that verify exactly one
|
|
230
|
-
logical behavior.
|
|
231
|
-
- **No Implementation in Advance:** Only write the code strictly needed to pass the
|
|
232
|
-
current test.
|
|
2071
|
+
Before:
|
|
233
2072
|
|
|
234
|
-
|
|
2073
|
+
```ruby
|
|
2074
|
+
git.checkout('branch', { create: true })
|
|
2075
|
+
```
|
|
235
2076
|
|
|
236
|
-
|
|
237
|
-
2. Create a checklist of small, isolated implementation steps.
|
|
2077
|
+
After:
|
|
238
2078
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
2079
|
+
```ruby
|
|
2080
|
+
git.checkout('branch', create: true)
|
|
2081
|
+
```
|
|
2082
|
+
````
|
|
242
2083
|
|
|
243
|
-
|
|
2084
|
+
3. **Update README if applicable**
|
|
244
2085
|
|
|
245
|
-
|
|
246
|
-
- All functionality for that item is implemented
|
|
247
|
-
- All related tests pass
|
|
248
|
-
- Code is clean and well-factored
|
|
249
|
-
- Ready to move to the next independent item
|
|
2086
|
+
## Documentation Workflow
|
|
250
2087
|
|
|
251
|
-
|
|
2088
|
+
This workflow guides creating and maintaining documentation for the ruby-git gem.
|
|
252
2089
|
|
|
253
|
-
|
|
254
|
-
checklist item
|
|
255
|
-
- Only write enough of a test to get an expected, failing result (the test should
|
|
256
|
-
fail for the *right* reason)
|
|
257
|
-
- **Execute** the test using the terminal command `bundle exec ruby -I lib:tests
|
|
258
|
-
tests/units/test_name.rb` or `bin/test test_name` and **analyze** the output.
|
|
259
|
-
- Confirm it fails with an _expected_ error (e.g., assertion failure or missing
|
|
260
|
-
definition).
|
|
261
|
-
- **Validation:** If the test passes without implementation, the test is invalid
|
|
262
|
-
or the logic already exists—revise or skip.
|
|
2090
|
+
### Understanding Documentation Standards
|
|
263
2091
|
|
|
264
|
-
|
|
2092
|
+
ruby-git uses YARD for API documentation:
|
|
265
2093
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
- **Execute** the test again using the terminal command `bundle exec ruby -I
|
|
271
|
-
lib:tests tests/units/test_name.rb` or `bin/test test_name` and **verify** it
|
|
272
|
-
passes.
|
|
273
|
-
- _Constraint:_ Do not implement future features or optimizations yet.
|
|
2094
|
+
- All public methods must have YARD documentation
|
|
2095
|
+
- Use standard YARD tags: `@param`, `@return`, `@raise`, `@example`
|
|
2096
|
+
- Include code examples for non-trivial methods
|
|
2097
|
+
- Document edge cases and platform differences
|
|
274
2098
|
|
|
275
|
-
|
|
2099
|
+
### Step 1: Identify Documentation Gaps
|
|
276
2100
|
|
|
277
|
-
|
|
278
|
-
checklist item.
|
|
279
|
-
- Remove duplication, improve variable names, and apply design patterns.
|
|
280
|
-
- Skip this step only if the code is already clean and simple—avoid
|
|
281
|
-
over-engineering.
|
|
282
|
-
- **Execute** all tests using the terminal command `bundle exec rake` and
|
|
283
|
-
**verify** they still pass.
|
|
284
|
-
- **Test Independence:** Verify tests can run independently in any order.
|
|
2101
|
+
1. **Check documentation coverage:**
|
|
285
2102
|
|
|
286
|
-
|
|
2103
|
+
```bash
|
|
2104
|
+
bundle exec yard stats --list-undoc
|
|
2105
|
+
```
|
|
287
2106
|
|
|
288
|
-
|
|
2107
|
+
2. **Find methods without documentation:**
|
|
289
2108
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
step.
|
|
294
|
-
- Stop and ask for clarification if a step is ambiguous.
|
|
2109
|
+
```bash
|
|
2110
|
+
bundle exec yard doc --no-output --no-cache 2>&1 | grep "Undocumented"
|
|
2111
|
+
```
|
|
295
2112
|
|
|
296
|
-
|
|
2113
|
+
3. **Review specific files:**
|
|
297
2114
|
|
|
298
|
-
```
|
|
299
|
-
#
|
|
300
|
-
|
|
2115
|
+
```bash
|
|
2116
|
+
# Check documentation for a specific class
|
|
2117
|
+
bundle exec yard doc lib/git/base.rb --no-output
|
|
2118
|
+
```
|
|
301
2119
|
|
|
302
|
-
|
|
303
|
-
def setup
|
|
304
|
-
@repo = clone_working_repo
|
|
305
|
-
@git = Git.open(@repo)
|
|
306
|
-
end
|
|
2120
|
+
### Step 2: Write Documentation
|
|
307
2121
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
2122
|
+
Follow the YARD documentation template:
|
|
2123
|
+
|
|
2124
|
+
```ruby
|
|
2125
|
+
# Short description of what the method does
|
|
2126
|
+
#
|
|
2127
|
+
# Longer description with more details about behavior,
|
|
2128
|
+
# edge cases, or important notes.
|
|
2129
|
+
#
|
|
2130
|
+
# @param name [Type] Description of parameter
|
|
2131
|
+
# @param options [Hash] Options hash description
|
|
2132
|
+
# @option options [Type] :key Description of option
|
|
2133
|
+
#
|
|
2134
|
+
# @return [Type] Description of return value
|
|
2135
|
+
# @return [nil] When no result is found
|
|
2136
|
+
#
|
|
2137
|
+
# @raise [ArgumentError] When invalid arguments provided
|
|
2138
|
+
# @raise [Git::Error] When git command fails
|
|
2139
|
+
#
|
|
2140
|
+
# @example Basic usage
|
|
2141
|
+
# git = Git.open('/path/to/repo')
|
|
2142
|
+
# result = git.method_name('arg')
|
|
2143
|
+
#
|
|
2144
|
+
# @example With options
|
|
2145
|
+
# git.method_name('arg', option: true)
|
|
2146
|
+
#
|
|
2147
|
+
# @see #related_method
|
|
2148
|
+
# @see Git::RelatedClass
|
|
2149
|
+
#
|
|
2150
|
+
# @since 2.0.0
|
|
2151
|
+
# @api public
|
|
2152
|
+
def method_name(name, options = {})
|
|
312
2153
|
end
|
|
2154
|
+
```
|
|
313
2155
|
|
|
314
|
-
|
|
2156
|
+
### Step 3: Verify Documentation
|
|
315
2157
|
|
|
316
|
-
|
|
317
|
-
class Git::Branch
|
|
318
|
-
def create
|
|
319
|
-
@base.lib.branch_new(@name)
|
|
320
|
-
end
|
|
321
|
-
end
|
|
2158
|
+
1. **Generate and review docs:**
|
|
322
2159
|
|
|
323
|
-
|
|
2160
|
+
```bash
|
|
2161
|
+
bundle exec yard doc
|
|
2162
|
+
open doc/index.html
|
|
2163
|
+
```
|
|
324
2164
|
|
|
325
|
-
|
|
326
|
-
def test_checks_out_new_branch
|
|
327
|
-
branch = @git.branch('feature').create
|
|
328
|
-
@git.checkout(branch)
|
|
329
|
-
assert_equal 'feature', @git.current_branch
|
|
330
|
-
end
|
|
2165
|
+
2. **Check for warnings:**
|
|
331
2166
|
|
|
332
|
-
|
|
2167
|
+
```bash
|
|
2168
|
+
bundle exec yard doc 2>&1 | grep -i "warn"
|
|
2169
|
+
```
|
|
333
2170
|
|
|
334
|
-
|
|
335
|
-
def checkout
|
|
336
|
-
@base.lib.checkout(@name)
|
|
337
|
-
@base.lib.branch_current
|
|
338
|
-
end
|
|
2171
|
+
3. **Verify examples work:**
|
|
339
2172
|
|
|
340
|
-
|
|
2173
|
+
Run code examples in a console to ensure they're correct:
|
|
341
2174
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
2175
|
+
```bash
|
|
2176
|
+
bundle exec bin/console
|
|
2177
|
+
```
|
|
2178
|
+
|
|
2179
|
+
4. **Check cross-references:**
|
|
2180
|
+
|
|
2181
|
+
Verify all `@see` references point to valid targets.
|
|
2182
|
+
|
|
2183
|
+
### Step 4: Update Related Documentation
|
|
2184
|
+
|
|
2185
|
+
1. **README.md updates:**
|
|
2186
|
+
- Ensure examples match current API
|
|
2187
|
+
- Update feature descriptions
|
|
2188
|
+
- Check installation instructions
|
|
2189
|
+
|
|
2190
|
+
2. **CHANGELOG.md entries:**
|
|
2191
|
+
- Document API changes
|
|
2192
|
+
- Note deprecations
|
|
2193
|
+
|
|
2194
|
+
3. **Inline comments:**
|
|
2195
|
+
- Update implementation comments if behavior changed
|
|
2196
|
+
- Remove outdated TODO comments
|
|
2197
|
+
|
|
2198
|
+
### Documentation Commands Reference
|
|
2199
|
+
|
|
2200
|
+
```bash
|
|
2201
|
+
# Generate documentation
|
|
2202
|
+
bundle exec yard doc
|
|
2203
|
+
|
|
2204
|
+
# Generate and serve locally
|
|
2205
|
+
bundle exec yard server --reload
|
|
2206
|
+
|
|
2207
|
+
# Check documentation coverage
|
|
2208
|
+
bundle exec yard stats
|
|
2209
|
+
|
|
2210
|
+
# List undocumented objects
|
|
2211
|
+
bundle exec yard stats --list-undoc
|
|
2212
|
+
|
|
2213
|
+
# Generate docs for specific file
|
|
2214
|
+
bundle exec yard doc lib/git/base.rb
|
|
346
2215
|
|
|
347
|
-
#
|
|
348
|
-
|
|
2216
|
+
# Check for YARD syntax errors
|
|
2217
|
+
bundle exec yard doc --no-output 2>&1
|
|
2218
|
+
|
|
2219
|
+
# View documentation for specific class
|
|
2220
|
+
bundle exec yard ri Git::Base
|
|
349
2221
|
```
|
|
350
2222
|
|
|
351
2223
|
## Testing Requirements
|
|
@@ -403,20 +2275,24 @@ end
|
|
|
403
2275
|
### Test Helpers
|
|
404
2276
|
|
|
405
2277
|
The `Test::Unit::TestCase` base class provides:
|
|
2278
|
+
|
|
406
2279
|
- `clone_working_repo`: Creates a temporary clone of test repository
|
|
407
2280
|
- `create_temp_repo`: Creates a temporary repository for testing
|
|
408
2281
|
- `with_temp_dir`: Provides a temporary directory for tests
|
|
409
2282
|
- `git_teardown`: Automatically cleans up temporary files
|
|
410
2283
|
- Test fixtures in `tests/files/`
|
|
411
2284
|
|
|
412
|
-
|
|
2285
|
+
### Running Tests
|
|
413
2286
|
|
|
414
2287
|
```bash
|
|
415
2288
|
# Run all tests
|
|
416
|
-
bundle exec
|
|
2289
|
+
bundle exec bin/test
|
|
2290
|
+
|
|
2291
|
+
# Run specific test file using bin/test (preferred method)
|
|
2292
|
+
bundle exec bin/test test_base
|
|
417
2293
|
|
|
418
|
-
# Run
|
|
419
|
-
bundle exec
|
|
2294
|
+
# Run multiple test files
|
|
2295
|
+
bundle exec bin/test test_object test_archive
|
|
420
2296
|
|
|
421
2297
|
# Run specific test by name
|
|
422
2298
|
bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_opens_existing_repository
|
|
@@ -448,6 +2324,7 @@ open coverage/index.html
|
|
|
448
2324
|
### Platform Considerations
|
|
449
2325
|
|
|
450
2326
|
**Cross-Platform Compatibility:**
|
|
2327
|
+
|
|
451
2328
|
- Git command execution works on all platforms
|
|
452
2329
|
- Handle Windows path separators and drive letters appropriately
|
|
453
2330
|
- Test Git operations on all platforms
|
|
@@ -455,12 +2332,14 @@ open coverage/index.html
|
|
|
455
2332
|
- Windows has different path handling and file system behavior
|
|
456
2333
|
|
|
457
2334
|
**Git Version Compatibility:**
|
|
2335
|
+
|
|
458
2336
|
- Minimum Git version is 2.28.0
|
|
459
2337
|
- Test with different Git versions when using newer features
|
|
460
2338
|
- Gracefully handle missing Git features on older versions
|
|
461
2339
|
- Document Git version requirements for specific features
|
|
462
2340
|
|
|
463
2341
|
**Encoding Handling:**
|
|
2342
|
+
|
|
464
2343
|
- Handle different default encodings across platforms
|
|
465
2344
|
- Use `rchardet` for automatic encoding detection
|
|
466
2345
|
- Test with UTF-8 and other encodings
|
|
@@ -497,6 +2376,7 @@ Located in `Rakefile`:
|
|
|
497
2376
|
- Use `ArgumentError` for invalid method arguments
|
|
498
2377
|
|
|
499
2378
|
**Error Design Principles:**
|
|
2379
|
+
|
|
500
2380
|
- Inherit from `Git::Error` for all gem-specific errors
|
|
501
2381
|
- `Git::FailedError`: Command failed (non-zero exit)
|
|
502
2382
|
- `Git::SignaledError`: Command killed by signal
|
|
@@ -507,7 +2387,7 @@ Located in `Rakefile`:
|
|
|
507
2387
|
|
|
508
2388
|
## Performance Considerations
|
|
509
2389
|
|
|
510
|
-
### Git
|
|
2390
|
+
### Git Commands
|
|
511
2391
|
|
|
512
2392
|
- Commands execute with configurable timeout (global or per-command)
|
|
513
2393
|
- Clean up resources properly
|
|
@@ -530,9 +2410,10 @@ Located in `Rakefile`:
|
|
|
530
2410
|
|
|
531
2411
|
## Documentation
|
|
532
2412
|
|
|
533
|
-
|
|
2413
|
+
The purpose of this section is to define the standards for maintaining project
|
|
2414
|
+
documentation.
|
|
2415
|
+
|
|
534
2416
|
- Update README.md examples when API changes
|
|
535
|
-
- Document breaking changes prominently in CHANGELOG
|
|
536
2417
|
- Use inline YARD comments for comprehensive API documentation
|
|
537
2418
|
- Generate docs with `bundle exec yard doc`
|
|
538
2419
|
- Ensure examples in documentation actually work
|
|
@@ -546,33 +2427,37 @@ Located in `Rakefile`:
|
|
|
546
2427
|
Always consult these before implementing features:
|
|
547
2428
|
|
|
548
2429
|
- **README.md** - Project overview, usage examples, and getting started
|
|
549
|
-
- **CHANGELOG.md** - Version history
|
|
2430
|
+
- **CHANGELOG.md** - Version history including identification breaking changes
|
|
2431
|
+
managed by the release GitHub Actions workflow
|
|
550
2432
|
- **LICENSE** - MIT License
|
|
551
2433
|
- **CONTRIBUTING.md** - Contribution guidelines
|
|
552
2434
|
- **MAINTAINERS.md** - Maintainer information
|
|
553
2435
|
- **redesign/** - Architecture redesign documentation
|
|
554
|
-
-
|
|
2436
|
+
- [The full YARD documentation page](https://rubydoc.info/gems/git/)
|
|
555
2437
|
|
|
556
2438
|
## Code Quality Checklist
|
|
557
2439
|
|
|
558
2440
|
Before committing, ensure:
|
|
559
2441
|
|
|
560
2442
|
**Testing:**
|
|
2443
|
+
|
|
561
2444
|
- [ ] **TDD process followed** - Tests written before implementation
|
|
562
|
-
- [ ] All tests pass (`bundle exec
|
|
2445
|
+
- [ ] All tests pass (`bundle exec bin/test`)
|
|
563
2446
|
- [ ] No Ruby warnings when running tests
|
|
564
2447
|
|
|
565
2448
|
**Code Style:**
|
|
2449
|
+
|
|
566
2450
|
- [ ] Code follows Ruby style conventions (Rubocop)
|
|
567
2451
|
- [ ] YARD documentation for public methods
|
|
568
2452
|
|
|
569
2453
|
**Compatibility:**
|
|
2454
|
+
|
|
570
2455
|
- [ ] Backward compatibility maintained (unless breaking change)
|
|
571
2456
|
- [ ] Cross-platform compatibility considered (Windows, macOS, Linux)
|
|
572
2457
|
- [ ] Git version compatibility (minimum 2.28.0)
|
|
573
2458
|
|
|
574
2459
|
**Documentation & Safety:**
|
|
575
|
-
|
|
2460
|
+
|
|
576
2461
|
- [ ] Security considerations addressed (command injection, etc.)
|
|
577
2462
|
- [ ] Resource cleanup (file handles, temporary files)
|
|
578
2463
|
|
|
@@ -588,6 +2473,7 @@ non-conventional commits.
|
|
|
588
2473
|
The simplest format: `type: description`
|
|
589
2474
|
|
|
590
2475
|
**Valid types** (see [.commitlintrc.yml](../.commitlintrc.yml) for full list):
|
|
2476
|
+
|
|
591
2477
|
- `feat:` - New user facing functionality
|
|
592
2478
|
- `fix:` - Bug fixes
|
|
593
2479
|
- `docs:` - Documentation only
|
|
@@ -601,20 +2487,36 @@ The simplest format: `type: description`
|
|
|
601
2487
|
- `revert:` - Revert a previous commit
|
|
602
2488
|
|
|
603
2489
|
**Description rules:**
|
|
2490
|
+
|
|
604
2491
|
1. Must NOT start with an upper case letter
|
|
605
2492
|
2. Must be no more than 100 characters
|
|
606
2493
|
3. Must NOT end with punctuation
|
|
607
2494
|
|
|
608
2495
|
**Examples:**
|
|
2496
|
+
|
|
609
2497
|
- `feat: add the --merges option to Git::Lib.log`
|
|
610
2498
|
- `fix: exception thrown by Git::Lib.log when repo has no commits`
|
|
611
2499
|
- `docs: add conventional commit announcement to README.md`
|
|
612
2500
|
|
|
613
|
-
**Breaking changes** must include an exclamation mark before the colon
|
|
2501
|
+
**Breaking changes** must include an exclamation mark before the colon AND a
|
|
2502
|
+
`BREAKING CHANGE: <description>` footer where the `<description>` indicates what was
|
|
2503
|
+
broken:
|
|
2504
|
+
|
|
614
2505
|
- `feat!: removed Git::Base.commit_force`
|
|
615
2506
|
|
|
616
|
-
|
|
2507
|
+
Example with footer:
|
|
2508
|
+
|
|
2509
|
+
```text
|
|
2510
|
+
feat(branch)!: rename create to make
|
|
2511
|
+
|
|
2512
|
+
Implement the new Branch#make method with improved validation.
|
|
2513
|
+
|
|
2514
|
+
BREAKING CHANGE: Branch#create renamed to Branch#make
|
|
617
2515
|
```
|
|
2516
|
+
|
|
2517
|
+
**Full format:**
|
|
2518
|
+
|
|
2519
|
+
```text
|
|
618
2520
|
type[optional scope][!]: description
|
|
619
2521
|
|
|
620
2522
|
[optional body]
|
|
@@ -623,6 +2525,7 @@ type[optional scope][!]: description
|
|
|
623
2525
|
```
|
|
624
2526
|
|
|
625
2527
|
**Version incrementing:**
|
|
2528
|
+
|
|
626
2529
|
- Breaking change → **major** version increment
|
|
627
2530
|
- New feature → **minor** version increment
|
|
628
2531
|
- Neither → **patch** version increment
|
|
@@ -644,6 +2547,24 @@ automated releases based on conventional commits.
|
|
|
644
2547
|
4. Ensure all tests pass and code quality checks pass
|
|
645
2548
|
5. Push the branch and create a PR
|
|
646
2549
|
|
|
2550
|
+
**When Submitting Existing Changes:**
|
|
2551
|
+
|
|
2552
|
+
- Ensure changes are on a feature branch (not `main`), following the naming
|
|
2553
|
+
convention `<type>/<short-description>`
|
|
2554
|
+
- If changes are on the wrong branch, offer to create a new branch from
|
|
2555
|
+
`origin/main` and relocate the user's existing work (commits or uncommitted
|
|
2556
|
+
changes) onto that new branch, choosing an appropriate Git approach (for
|
|
2557
|
+
example, cherry-pick, rebase, or recommitting) based on the situation
|
|
2558
|
+
|
|
2559
|
+
**PR Creation Automation:**
|
|
2560
|
+
|
|
2561
|
+
When asked to create the PR, use the GitHub CLI: `gh pr create --title "feat(scope):
|
|
2562
|
+
description" --body "..."`
|
|
2563
|
+
|
|
2564
|
+
- Read `.github/pull_request_template.md` to structure the body
|
|
2565
|
+
- Ensure the body covers the "PR Description Should Include" points below
|
|
2566
|
+
- Assign the user as the assignee if possible
|
|
2567
|
+
|
|
647
2568
|
**PR Description Should Include:**
|
|
648
2569
|
|
|
649
2570
|
- What problem does this solve?
|
|
@@ -663,15 +2584,17 @@ automated releases based on conventional commits.
|
|
|
663
2584
|
- No breaking changes without major version bump or exclamation mark in commit
|
|
664
2585
|
- At least one approval from a project maintainer required before merge
|
|
665
2586
|
|
|
666
|
-
## Special Considerations
|
|
2587
|
+
## PR Special Considerations
|
|
667
2588
|
|
|
668
2589
|
### Security
|
|
669
2590
|
|
|
670
2591
|
- **Command Injection**: When using single-string commands, be aware of shell
|
|
671
|
-
injection risks
|
|
672
|
-
- **Input Validation**: Validate and sanitize user
|
|
2592
|
+
injection risks. Use `Git::CommandLine` for proper argument escaping.
|
|
2593
|
+
- **Input Validation**: Validate and sanitize user-supplied paths and arguments
|
|
2594
|
+
before passing to commands.
|
|
673
2595
|
- **File Permissions**: Be careful with file descriptors and permissions
|
|
674
2596
|
- **Resource Limits**: Consider timeout and resource consumption
|
|
2597
|
+
- **Git Hooks**: Consider risks associated with Git hook execution
|
|
675
2598
|
- Document security implications in YARD comments
|
|
676
2599
|
|
|
677
2600
|
## Current Priorities
|
|
@@ -695,13 +2618,17 @@ Based on project status and maintenance needs:
|
|
|
695
2618
|
### Feature Enhancements
|
|
696
2619
|
|
|
697
2620
|
Consider these only after TDD test is written:
|
|
2621
|
+
|
|
698
2622
|
- Improved worktree support
|
|
699
2623
|
- Enhanced Git LFS integration
|
|
700
2624
|
- Better handling of large repositories
|
|
701
2625
|
- Performance optimizations for common operations
|
|
702
2626
|
- Additional Git operations as needed
|
|
703
2627
|
|
|
704
|
-
### Documentation
|
|
2628
|
+
### Documentation Priorities
|
|
2629
|
+
|
|
2630
|
+
Focus on these specific documentation improvements to enhance developer experience
|
|
2631
|
+
and project maintainability:
|
|
705
2632
|
|
|
706
2633
|
- Keep README.md examples current and comprehensive
|
|
707
2634
|
- Add more real-world examples
|
|
@@ -711,62 +2638,25 @@ Consider these only after TDD test is written:
|
|
|
711
2638
|
|
|
712
2639
|
## Useful Commands
|
|
713
2640
|
|
|
714
|
-
|
|
715
|
-
# Install dependencies and setup pre-commit hooks
|
|
716
|
-
bin/setup
|
|
717
|
-
|
|
718
|
-
# Or just install dependencies
|
|
719
|
-
bundle install
|
|
720
|
-
|
|
721
|
-
# Run full test suite
|
|
722
|
-
bundle exec rake test
|
|
723
|
-
|
|
724
|
-
# Run specific test file using bin/test (preferred method)
|
|
725
|
-
bin/test test_base
|
|
726
|
-
|
|
727
|
-
# Run multiple test files
|
|
728
|
-
bin/test test_object test_archive
|
|
729
|
-
|
|
730
|
-
# Run all unit tests using bin/test
|
|
731
|
-
bin/test
|
|
732
|
-
|
|
733
|
-
# Run tests with a different Git version
|
|
734
|
-
GIT_PATH=/path/to/git/bin-wrappers bin/test
|
|
735
|
-
|
|
736
|
-
# Alternative: run specific test file directly
|
|
737
|
-
bundle exec ruby -I lib:tests tests/units/test_base.rb
|
|
2641
|
+
See [Project Configuration](#project-configuration) for primary development commands.
|
|
738
2642
|
|
|
739
|
-
|
|
740
|
-
bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_opens_existing_repository
|
|
741
|
-
|
|
742
|
-
# Run tests in Docker
|
|
743
|
-
bin/test-in-docker
|
|
744
|
-
|
|
745
|
-
# Generate YARD documentation
|
|
746
|
-
bundle exec yard doc
|
|
747
|
-
|
|
748
|
-
# Start documentation server
|
|
749
|
-
bundle exec yard server --reload
|
|
2643
|
+
**Additional commands:**
|
|
750
2644
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
bundle exec
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
bundle exec rubocop -a
|
|
759
|
-
|
|
760
|
-
# View coverage report (if configured)
|
|
761
|
-
open coverage/index.html
|
|
762
|
-
```
|
|
2645
|
+
- Run specific test method: `bundle exec ruby -I lib:tests tests/units/test_base.rb -n test_method_name`
|
|
2646
|
+
- Run tests in Docker: `bin/test-in-docker`
|
|
2647
|
+
- Run with different Git: `GIT_PATH=/path/to/git/bin-wrappers bin/test`
|
|
2648
|
+
- Generate docs: `bundle exec yard doc`
|
|
2649
|
+
- Serve docs locally: `bundle exec yard server --reload`
|
|
2650
|
+
- Build gem: `bundle exec rake build`
|
|
2651
|
+
- Auto-fix style: `bundle exec rubocop -a`
|
|
763
2652
|
|
|
764
2653
|
## Getting Help
|
|
765
2654
|
|
|
766
2655
|
- Review README.md for usage examples and architecture
|
|
767
2656
|
- Check CHANGELOG.md for version history and breaking changes
|
|
768
2657
|
- Read inline YARD documentation in source code
|
|
769
|
-
- Browse full API docs
|
|
2658
|
+
- Browse full API docs on [the full YARD documentation
|
|
2659
|
+
page](https://rubydoc.info/gems/git/)
|
|
770
2660
|
- Look at existing tests for testing patterns
|
|
771
2661
|
- Check CI configuration in `.github/workflows/` for supported platforms
|
|
772
2662
|
- Review architecture redesign docs in `redesign/` directory
|
|
@@ -813,11 +2703,3 @@ open coverage/index.html
|
|
|
813
2703
|
- Test timeout behavior with long-running operations
|
|
814
2704
|
- Document timeout implications in YARD comments
|
|
815
2705
|
- Timeout support is built into the command execution layer
|
|
816
|
-
|
|
817
|
-
### Security Considerations
|
|
818
|
-
|
|
819
|
-
- Be careful with user-supplied paths and arguments
|
|
820
|
-
- Validate and sanitize inputs
|
|
821
|
-
- Use proper argument escaping via `Git::CommandLine`
|
|
822
|
-
- Document security implications
|
|
823
|
-
- Consider Git hook execution risks
|