Skip to main content

Git Operations

Git Operations Architecture

Core Service Boundary

Separate repository policy from low-level Git command execution and version-tag interpretation.

Commandapp/core/git_ops/

Category

Architecture

Quick Command

consumer -> GitService -> IGitCommandExecutor -> git

GitServiceprotocolexecutordry-run

Overview​

Custy keeps subprocess syntax in GitCommandExecutor and repository decisions in GitService. Callers such as the workflow engine, changelog providers, branch cleanup, branch workflow, and version strategies normally depend on the service instead of assembling git command arguments themselves.


Git Stack

Factory

git/factory.py

Creates GitCommandExecutor, obtains the shared ConfigLoader, and returns a fully wired GitService with optional version strategy context.

Executor Protocol

git/protocol.py

Defines the command-level operations required by the service, including repository, branch, remote, log, tag, commit, stage, and push calls.

Command Executor

git/executor.py

Builds explicit git argument lists, delegates subprocess behavior to Runner, and normalizes results into CommandResult.

Git Service

git/service.py

Applies high-level policy, parses results, resolves remotes, selects tag sorters, logs operations, and raises meaningful operation failures.


Operation Flow

Workflow Timeline

1
Request repository behavior
A workflow, changelog provider, cleanup service, or strategy calls GitService.
completed
2
Apply domain policy
GitService chooses remotes, validates state, selects sorting, or prepares command parameters.
completed
3
Invoke protocol operation
The service calls the injected IGitCommandExecutor interface.
completed
4
Execute or simulate
GitCommandExecutor delegates to Runner, which runs subprocess or reports a dry-run simulation.
current
5
Normalize result
CommandResult carries return code, output, error text, and dry-run skipped state.
pending
6
Return or raise
GitService converts low-level output into values or high-level failures for its caller.
pending

Service Capabilities

Repository and History

GitService→repository checks

Detect repository and commit state.


GitService→branch operations

Inspect, list, compare, and delete local or remote branches.


GitService→history queries

Read hashes, messages, ranges, counts, dates, and structured commits.


GitService→tag ordering

Select and cache a strategy-aware TagSorter.

Mutating Operations

GitService→staging

Stage all, tracked updates, or explicit files and inspect the index.


GitService→commit and tag

Create local history from resolved messages and flags.


GitService→push

Push HEAD or selected tags to one or more resolved remotes.


GitService→branch deletion

Apply local and remote cleanup selected by the branch service.


Dry-Run Boundary

GitCommandExecutor inherits DryRunSupport, which owns a Runner. In dry-run mode, operations explicitly marked as read-only still execute so callers can inspect real repository history, branches, tags, status, and configured remotes. Mutating operations are reported as simulated and return a successful CommandResult whose skipped state distinguishes them from executed discovery.

Higher layers may still resolve configuration, read project files, validate inputs, render previews, or perform other non-mutating work. Custy's normal diagnostic logging can also write to its configured log file. Dry-run is a mutation boundary, not a transaction or rollback mechanism.



Policy Above the Service

The workflow engine still owns release-specific decisions such as whether to push backup remotes, whether a branch is non-critical, when to prompt for a fallback remote, and whether to push the current tag. This keeps GitService reusable, but it means remote behavior is shared between workflow policy and service-level resolution rather than centralized in one object.


Continue