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.
@@ -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
- ## Architecture & Module Organization
1907
+ # List commits since tag
1908
+ git log v1.0.0..HEAD --oneline
18
1909
 
19
- ruby-git follows a modular architecture:
1910
+ # View tag details
1911
+ git show v1.0.0
20
1912
 
21
- - **Git::Base** - Main interface for repository operations (most major actions)
22
- - **Git::Lib** - Low-level Git command execution via system calls
23
- - **Git::CommandLine** - Handles Git command construction and execution with timeout
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
- Key directories:
1917
+ # Build gem locally
1918
+ bundle exec rake build
35
1919
 
36
- - `lib/git/` - Core library code
37
- - `tests/units/` - Test::Unit test suite
38
- - `doc/` - YARD-generated documentation
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
- ## Coding Standards
1924
+ ## Breaking Change Analysis Workflow
43
1925
 
44
- ### Ruby Style
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
- - Use `frozen_string_literal: true` at the top of all Ruby files
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
- ### Code Organization
1931
+ A breaking change is any modification that requires users to update their code:
54
1932
 
55
- - Keep classes focused and single-responsibility
56
- - Use modules for mixins and namespace organization
57
- - Place related classes in the same file only if they're tightly coupled
58
- - One public class per file as a general rule
59
- - Core library code organized in `lib/git/` directory
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
- ### Naming Conventions
1939
+ ### Step 1: Identify the Change Scope
62
1940
 
63
- - Classes/Modules: PascalCase (e.g., `Git::Base`, `Git::Branch`, `Git::CommandLine`)
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
- ## Design Philosophy
1943
+ - Which class(es) are affected?
1944
+ - Which method(s) are affected?
1945
+ - Is this a public or private API?
72
1946
 
73
- **Note:** As of v2.x, this design philosophy is aspirational. Future versions may
74
- include interface changes to fully align with these principles.
1947
+ 2. **Check API visibility:**
75
1948
 
76
- The git gem is designed as a lightweight wrapper around the `git` command-line tool,
77
- providing a simple and intuitive Ruby interface for programmatically interacting with
78
- Git.
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
- ### Principle of Least Surprise
1955
+ 3. **Review current documentation:**
81
1956
 
82
- - Do not introduce unnecessary abstraction layers
83
- - Do not modify Git's core functionality
84
- - Maintain close alignment with the existing `git` command-line interface
85
- - Avoid extensions or alterations that could lead to unexpected behaviors
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
- ### Direct Mapping to Git Commands
1962
+ ### Step 2: Find All Usages
89
1963
 
90
- - Git commands are implemented within the `Git::Base` class
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
- ### Parameter Naming
1966
+ ```bash
1967
+ # Find internal usages
1968
+ grep -rn "method_name" lib/
1969
+ grep -rn "ClassName" lib/
1970
+ ```
99
1971
 
100
- - Parameters are named after their corresponding long command-line options
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
- ### Output Processing
1974
+ ```bash
1975
+ grep -rn "method_name" tests/
1976
+ ```
105
1977
 
106
- - Translate Git command output into Ruby objects for easier programmatic use
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
- ### Documentation
1980
+ Use the AI's semantic_search to find related usages that might not match exact
1981
+ patterns.
111
1982
 
112
- - Use YARD syntax for all public methods
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
- Example:
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
- ```ruby
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
- ## Key Technical Details
1992
+ Create an impact assessment:
140
1993
 
141
- ### Git Command Execution
1994
+ 1. **Internal impact:**
1995
+ - Number of files affected within the gem
1996
+ - Test changes required
1997
+ - Documentation updates needed
142
1998
 
143
- All Git commands are executed through the `Git::CommandLine` class which:
144
- - Constructs Git commands with proper argument escaping
145
- - Handles environment variables and working directory context
146
- - Manages command execution with timeout support
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
- ### Major Classes and Their Responsibilities
2004
+ 3. **Document findings:**
151
2005
 
152
- 1. **Git::Base**: The main repository interface
153
- - Entry point for most Git operations
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
- 2. **Git::Lib**: Low-level command execution
159
- - Executes Git commands via `Git::CommandLine`
160
- - Parses Git command output
161
- - Minimal business logic - focuses on command execution
2009
+ ### Change Description
2010
+ [What is being changed]
162
2011
 
163
- 3. **Git::CommandLine**: Command execution layer
164
- - Builds Git command arrays with proper escaping
165
- - Manages subprocess execution with timeout support
166
- - Handles timeout and error conditions
167
- - Returns `Git::CommandLineResult` with output and status
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
- 4. **Git Objects** (Commit, Tree, Blob, Tag)
170
- - Immutable representations of Git objects
171
- - Lazy-loaded from repository
172
- - Methods for inspecting object properties and relationships
2018
+ ### Internal Impact
2019
+ - Files affected: X
2020
+ - Tests to update: Y
173
2021
 
174
- 5. **Git::Status**: Working directory status
175
- - Enumerable collection of `Git::Status::StatusFile`
176
- - Tracks added, changed, deleted, and untracked files
177
- - Similar to `git status` command output
2022
+ ### External Impact
2023
+ - Severity: [High/Medium/Low]
2024
+ - Migration difficulty: [Easy/Medium/Hard]
178
2025
 
179
- 6. **Git::Diff**: Diff operations
180
- - Enumerable collection of `Git::Diff::DiffFile`
181
- - Per-file patches and statistics
182
- - Total insertion/deletion statistics
2026
+ ### Migration Path
2027
+ [How users should update their code]
2028
+ ```
183
2029
 
184
- 7. **Git::Log**: Commit history query builder
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
- ### Path Handling
2032
+ 1. **Deprecation approach (preferred for non-urgent changes):**
190
2033
 
191
- ruby-git handles three types of paths:
192
- - **Working directory paths**: Relative to repository working directory
193
- - **Git directory paths**: The `.git` directory location
194
- - **Object paths**: Paths within Git tree objects
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
- The gem provides `Git::Path` and `Git::EscapedPath` for handling paths with special
197
- characters.
2041
+ 2. **Version-based migration:**
2042
+ - v2.x: Deprecate with warning
2043
+ - v3.0: Remove deprecated API
198
2044
 
199
- ### Error Handling
2045
+ 3. **Document migration in CHANGELOG:**
200
2046
 
201
- The gem raises errors that inherit from `Git::Error`:
202
- - `Git::FailedError`: Git command exited with non-zero status
203
- - `Git::SignaledError`: Git command was killed by a signal
204
- - `Git::TimeoutError`: Git command exceeded timeout (subclass of SignaledError)
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
- All Git command errors include the command, output, and status for debugging.
2052
+ ### Step 5: Document the Change
208
2053
 
209
- ## Development Methodology
2054
+ 1. **Update YARD documentation:**
210
2055
 
211
- ### Test Driven Development (TDD)
2056
+ ```ruby
2057
+ # @deprecated Use {#new_method} instead. Will be removed in v3.0.
2058
+ def old_method
2059
+ end
2060
+ ```
212
2061
 
213
- **This project strictly follows TDD practices. All code MUST be written using the
214
- Red-Green-Refactor cycle.**
2062
+ 2. **Add to CHANGELOG.md:**
215
2063
 
216
- You are an expert software engineer following a strict Test-Driven Development (TDD)
217
- workflow.
2064
+ ````markdown
2065
+ ### Breaking Changes
2066
+ - `Git::Base#checkout` signature changed: `opts` hash replaced with keyword
2067
+ arguments
218
2068
 
219
- **Core TDD Principles**
2069
+ ### Migration Guide
220
2070
 
221
- - **Never write production code without a failing test first.**
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
- **Phase 1: Analysis & Planning** Before writing any code:
2073
+ ```ruby
2074
+ git.checkout('branch', { create: true })
2075
+ ```
235
2076
 
236
- 1. Analyze the request.
237
- 2. Create a checklist of small, isolated implementation steps.
2077
+ After:
238
2078
 
239
- **Phase 2: The RED-GREEN-REFACTOR Cycle** Execute the checklist items one by one.
240
- Build each checklist item using multiple RED-GREEN iterations if needed. Follow with
241
- a REFACTOR step before moving to the next checklist item.
2079
+ ```ruby
2080
+ git.checkout('branch', create: true)
2081
+ ```
2082
+ ````
242
2083
 
243
- You must complete the _entire_ cycle for a checklist item before moving to the next.
2084
+ 3. **Update README if applicable**
244
2085
 
245
- **Completion Criteria for a Checklist Item:**
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
- 1. **RED (The Failing Test):**
2088
+ This workflow guides creating and maintaining documentation for the ruby-git gem.
252
2089
 
253
- - Write a single, focused, failing test or extend an existing test for the current
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
- 2. **GREEN (Make it Pass):**
2092
+ ruby-git uses YARD for API documentation:
265
2093
 
266
- - Write the _minimum amount of code_ required to make the test pass.
267
- - It is acceptable to use hardcoded values or "quick and dirty" logic here just to
268
- get to green, even if this means intentionally writing clearly suboptimal code
269
- that you will improve during the REFACTOR step.
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
- 3. **REFACTOR (Make it Right):**
2099
+ ### Step 1: Identify Documentation Gaps
276
2100
 
277
- - **Critical Step:** You must consider refactoring _before_ starting the next
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
- **Additional Guidelines**
2103
+ ```bash
2104
+ bundle exec yard stats --list-undoc
2105
+ ```
287
2106
 
288
- These supplement the RED-GREEN-REFACTOR cycle:
2107
+ 2. **Find methods without documentation:**
289
2108
 
290
- - If the implementation reveals a complex logic gap, add it to your checklist, but
291
- finish the current cycle first.
292
- - Do not generate a "wall of text." Keep code blocks small and focused on the current
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
- #### Example TDD Session
2113
+ 3. **Review specific files:**
297
2114
 
298
- ```ruby
299
- # Step 1: Write first failing test
300
- require_relative '../test_helper'
2115
+ ```bash
2116
+ # Check documentation for a specific class
2117
+ bundle exec yard doc lib/git/base.rb --no-output
2118
+ ```
301
2119
 
302
- class TestGitBranch < Test::Unit::TestCase
303
- def setup
304
- @repo = clone_working_repo
305
- @git = Git.open(@repo)
306
- end
2120
+ ### Step 2: Write Documentation
307
2121
 
308
- def test_creates_new_branch
309
- @git.branch('feature').create
310
- assert @git.branches.local.map(&:name).include?('feature')
311
- end
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
- # Run test RED (method doesn't exist or doesn't work)
2156
+ ### Step 3: Verify Documentation
315
2157
 
316
- # Step 2: Minimal code to pass
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
- # Run test → GREEN
2160
+ ```bash
2161
+ bundle exec yard doc
2162
+ open doc/index.html
2163
+ ```
324
2164
 
325
- # Step 3: Write next failing test
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
- # Run test → RED (checkout doesn't work correctly)
2167
+ ```bash
2168
+ bundle exec yard doc 2>&1 | grep -i "warn"
2169
+ ```
333
2170
 
334
- # Step 4: Implement actual functionality
335
- def checkout
336
- @base.lib.checkout(@name)
337
- @base.lib.branch_current
338
- end
2171
+ 3. **Verify examples work:**
339
2172
 
340
- # Run test GREEN
2173
+ Run code examples in a console to ensure they're correct:
341
2174
 
342
- # Step 5: REFACTOR - Improve code organization
343
- def checkout
344
- @base.checkout(@name)
345
- end
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
- # Run all tests Still GREEN
348
- # Checklist item complete, move to next item...
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
- ## Running Tests
2285
+ ### Running Tests
413
2286
 
414
2287
  ```bash
415
2288
  # Run all tests
416
- bundle exec rake test
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 specific test file
419
- bundle exec ruby -I lib:tests tests/units/test_base.rb
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 Command Execution
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
- - Keep CHANGELOG.md updated with all user-facing changes
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, breaking changes, and migration guides
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
- - Full YARD documentation at https://rubydoc.info/gems/git/
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 rake test`)
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
- - [ ] CHANGELOG.md updated for user-facing changes
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
- **Full format:**
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 input before passing to commands
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
- ```bash
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
- # Run specific test by name
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
- # Build gem
752
- bundle exec rake build
753
-
754
- # Check code style
755
- bundle exec rubocop
756
-
757
- # Auto-fix code style issues
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 at https://rubydoc.info/gems/git/
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