Reference guide for ruby-git architecture, coding standards, design philosophy, key technical details, and compatibility requirements. Use when answering architecture questions, deciding where new code belongs, reviewing coding standards, or understanding the layered command/parser/facade design.
70
86%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Reference for ruby-git's architecture, coding standards, design philosophy, and technical constraints. Load this skill when answering questions about code structure, where logic belongs, or how the layers interact.
Attach this file to your Copilot Chat context when you need architecture guidance, coding standard details, or implementation constraints.
Git::Repository::* facade methods, the gem's public API layerKey modules and their roles:
| Class | Role |
|---|---|
Git::Repository | Main facade — entry point for all user-facing operations; methods live in Git::Repository::* topic modules under lib/git/repository/, included into the class |
Git::ExecutionContext::* | Configured subprocess runner; holds binary path, env vars, and global opts; provides #command_capturing/#command_streaming to command classes |
Git::Commands::* | Command classes: define CLI API, bind args, execute → return CommandLineResult |
Git::CommandLine | Subprocess execution: escaping, timeout, stdout/stderr capture |
Git::Parsers::* | Transform raw stdout into structured data |
Git::Object::* | Immutable Git objects (Commit, Tree, Blob, Tag) |
Git::Status | Working-directory status (enumerable StatusFile collection) |
Git::Diff | Diff operations (enumerable DiffFile collection) |
Git::Log | Chainable commit-history query builder |
Git::Branch/Branches | Branch management (local + remote) |
Git::Remote | Remote repository references |
Git::Worktree/Worktrees | Worktree support |
Git::Stash/Stashes | Stash management |
Key directories:
lib/git/ — Core library codelib/git/commands/ — Command classes (new architecture)lib/git/repository/ — Facade topic modules (Git::Repository::*)spec/unit/ — RSpec unit tests (mocked execution context)spec/integration/ — RSpec integration tests (real git repositories)spec/support/ — Shared test contexts and helpersredesign/ — Architecture redesign documentation
redesign/3_architecture_implementation.md is a living migration tracker.
When command migrations land, keep checklist states, "Next Task", and Phase 2
progress counts synchronized with lib/git/commands/ and current spec paths.The three-layer architecture separates concerns cleanly:
Git::Repository (facade — topic modules under lib/git/repository/)
└── Git::Commands::* (defines CLI API, binds args, executes via execution_context)
└── Git::ExecutionContext::* (configured subprocess runner: env, binary, global opts)
└── Git::CommandLine (subprocess execution)Git::Commands::*): Owns the git CLI contract. Declares
arguments via DSL, executes command, returns CommandLineResult. No parsing.
literal entries are only for operation selectors (subcommand names,
mode flags like --delete that define what the class does). Output-format
flags, parser-contract options, and other caller-controlled options belong as
flag_option / value_option — not as literal entries.--patch, --numstat, --raw, --format=…) are options
declared in the DSL; the facade chooses which to pass. Separate subclasses
for the same operation with different output modes are an anti-pattern.Git::Parsers::*): Transforms raw stdout/stderr into structured
Ruby data. No execution.Git::Repository::*): Pre-processes caller arguments, invokes
the right command class, calls parsers, constructs rich response objects.
Parser-contract options (e.g. no_color: true, pretty: 'raw',
format: FORMAT_STRING) are passed explicitly at the facade call site — this makes
the parser contract auditable by reading the topic module method.Git::Commands::Base provides default #initialize(execution_context) and #call.
Command classes that need non-zero successful exits declare
allow_exit_status <Range> with a rationale comment.
Command classes are neutral, faithful representations of the git CLI. They declare
options via the DSL but never embed policy choices (output-control flags, editor
suppression, progress, verbose mode). The facade (Git::Repository::*) sets safe defaults
at each call site. Some defaults are fixed (not in ALLOWED_OPTS — rejected by
assert_valid_opts! before reaching the command); others are overridable (in
ALLOWED_OPTS, placed before the caller's **opts so the caller's value wins).
The execution layer (GIT_EDITOR='true') is an unconditional safety net.
Anti-pattern:
literal '--no-edit',literal '--verbose',literal '--no-progress'inside a command class.Correct pattern:
flag_option :edit, negatable: truein the command;no_edit: truepassed from the facade call site.
Command classes use per-argument validation parameters (required:, type:,
allow_nil:, etc.) and operand format validation. They generally do not declare
cross-argument constraint methods (conflicts, requires, requires_one_of,
requires_exactly_one_of, forbid_values, allowed_values) — git is the single source of truth for its
own option semantics. The narrow exception is arguments git cannot observe in
its argv: if an argument is skip_cli: true, git never sees it and cannot detect
incompatibilities — conflicts and/or requires_one_of are appropriate. Example:
cat-file --batch uses both because :objects is skip_cli: true:
| Validated by Commands | Mechanism |
|---|---|
| Unknown options | validate_unsupported_options! in Arguments DSL |
| Required options | required: true in Arguments DSL |
| Type checking | type: in Arguments DSL |
| Option-like operand rejection | Automatic for operands before -- |
| Delegated to git (semantic) | Surfaced as |
|---|---|
Option conflicts (--soft vs --hard) | Git::FailedError |
Option dependencies (--all-match requires --grep) | Git::FailedError |
| At-least-one-of groups | Git::FailedError |
| Value-set membership | Git::FailedError |
| Forbidden value combinations | Git::FailedError |
The constraint DSL infrastructure (conflicts, requires, requires_one_of,
requires_exactly_one_of, forbid_values, allowed_values) remains available in Git::Commands::Arguments
and is used only for skip_cli: true argument constraints, and in narrow documented cases for
git-visible arguments whose combination causes silent data loss (no error, wrong result).
See redesign/3_architecture_implementation.md Insight 6 for the full policy and exception criteria.
frozen_string_literal: true at the top of every Ruby fileprivate keyword form (not private :method_name)| Kind | Convention | Example |
|---|---|---|
| Class/Module | PascalCase | Git::CommandLine |
| Method/variable | snake_case | current_branch |
| Constant | UPPER_SNAKE_CASE | VERSION |
| Predicate | ends with ? | bare? |
| Mutating method | ends with ! | reset! |
Parsed metadata struct (top-level Git::) | *Info suffix | BranchInfo, TagInfo, StashInfo |
Mutating-operation outcome struct (top-level Git::) | *Result suffix | BranchDeleteResult, TagDeleteResult |
Result class constraints:
*Info / *Result suffixes are reserved for top-level Git:: data structs.
Never apply them to Git::Commands::* classes — command classes are subprocess
runners, not data structs, and a name like Commands::Foo::BarInfo misleads
readers.Object — it shadows Ruby's ::Object.lib/git/; command classes in lib/git/commands/@param, @return, @raise, @example@overload with explicit keyword params when methods use **@api private on internal methodsSee CONTRIBUTING.md for authoritative, complete guidelines.
Summary:
git CLIgit add → Git::Repository#add; use prefix + suffix for
multi-purpose commands (#ls_files_untracked, #ls_files_staged)All gem errors inherit from Git::Error:
Git::FailedError — non-zero exit statusGit::SignaledError — killed by signalGit::TimeoutError — exceeded timeout (subclass of SignaledError)ArgumentError — invalid argumentsAll errors include structured data (command, output, status) for debugging. Never swallow exceptions silently.
Pathname objects on Git::RepositoryGit::EscapedPath for paths with special charactersrchardet for automatic encoding detectionGit::TimeoutError is raised on expiryGit::CommandLine; document implications in YARDactivesupport (≥ 5.0) — utilities and deprecation handlingaddressable (~> 2.8) — URI parsingprocess_executer (~> 4.0) — subprocess execution with timeoutrchardet (~> 1.9) — character encoding detectionFile.join and forward slashes; avoid platform-specific paths in testsGit::CommandLine; do not shell out directlyFollow the three-layer pattern: command class (CLI contract) → parser (output
transform) → Git::Repository::* facade method (orchestration + rich object). See
Command Implementation.
Pathname; use Git::EscapedPath for special charsGit::CommandLine for all command execution — it handles proper escaping8887679
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.