`homeboy git`
Synopsis
homeboy git <COMMAND>Git operations for Homeboy components, worktrees, portable checkouts, and GitHub issue / pull request workflows.
Most commands emit Homeboy’s structured JSON envelope when appropriate. See the JSON output contract. Git JSON output includes a top-level variant discriminator for the public wrapper shape: single, bulk, issue, pr, pr_refresh, find, policy, or land. Some subcommands also accept --json for bulk input.
Follow-up: git has many subcommand-specific payload shapes inside those wrappers; the current public contract tags the wrapper variants, and per-subcommand golden fixtures can be added incrementally where consumers need stricter fixtures.
Component Resolution
Most core git verbs can run without a positional component ID:
homeboy git status
homeboy git commit -m "Update docs"
homeboy git pushHomeboy resolves the target checkout in this order:
- Explicit component ID plus
--path: trust both values. Use this when a command needs a known component identity but should operate on a specific checkout. --path <path>only: operate on that checkout, discovering the component from a portablehomeboy.jsonat the path or its git root. If no portable config exists, Homeboy derives the component ID from the path basename.- Explicit component ID only: resolve the component from Homeboy’s registry.
- Neither ID nor
--path: auto-detect from the current directory using the registry, then a portablehomeboy.jsonin the current checkout or git root.
Use --path for worktrees, CI runners, ad-hoc clones, or headless scripts where the process CWD is not already the checkout you want:
homeboy git status --path /Users/user/Developer/homeboy@docs-refresh-git-command
homeboy git push --path /tmp/homeboy-ci-checkoutCore Verbs
Status
homeboy git status [component_id] [--path <path>]Shows git status for one checkout. component_id is optional when Homeboy can detect the component from CWD or --path.
Bulk status is available through --json:
homeboy git status --json '{"component_ids":["homeboy","sample-plugin"]}'Commit
homeboy git commit [component_id] [message-or-spec]
homeboy git commit -m "Update docs"
homeboy git commit --staged-only -m "Use staged changes only"
homeboy git commit --files README.md docs/index.md -m "Update docs"
homeboy git commit --exclude Cargo.lock -m "Update docs"By default, commit stages all changes before committing. Use --staged-only, --files, --include, or --exclude for narrower staging.
commit also accepts a JSON spec. The spec can be passed positionally, through --json, from stdin with -, or from a file with @file.json:
homeboy git commit '{"message":"Update docs","include_files":["README.md"]}'
homeboy git commit --json '@commit.json'Homeboy auto-detects single vs bulk commit specs by checking for a top-level components array.
Push
homeboy git push [component_id] [--tags] [--force-with-lease] [--path <path>]push --force-with-lease is the safe post-rebase force-push path. It refuses to overwrite the remote if it has commits the local ref has not seen. Plain --force is intentionally not exposed.
homeboy git push
homeboy git push --tags
homeboy git push --force-with-leaseBulk push is available through --json:
homeboy git push --json '{"component_ids":["homeboy","sample-plugin"],"tags":true}'Pull
homeboy git pull [component_id] [--path <path>]Pulls remote changes for one checkout. Like status, push, and commit, the component ID is optional when CWD or --path can identify the component.
Rebase
homeboy git rebase [component_id] [--onto <ref>] [--continue | --abort] [--path <path>]Without --onto, rebase uses the current branch’s tracked upstream (@{upstream}), matching git pull --rebase semantics. Use --onto <ref> to choose the target explicitly:
homeboy git rebase --onto origin/main
homeboy git rebase --continue
homeboy git rebase --abortOn conflict, Homeboy returns a failed result with git’s stderr. Resolve conflicts manually, then re-run with --continue or --abort.
Cherry-pick
homeboy git cherry-pick [refs...] [--pr <number>...] [--continue | --abort] [--path <path>]cherry-pick accepts SHAs, branch names, ranges such as <a>..<b>, and repeatable --pr <number> flags. PR numbers are resolved with gh pr view <n> --json commits.
homeboy git cherry-pick abc1234 def5678
homeboy git cherry-pick feature-a..feature-b
homeboy git cherry-pick --pr 123 --pr 124
homeboy git cherry-pick --continue
homeboy git cherry-pick --abortUse -c, --component-id <id> when running from outside the target checkout without --path.
Tag
homeboy git tag [component_id] [tag_name] [-m <message>] [--path <path>]If tag_name is omitted, Homeboy tags v<component version> from homeboy version show.
GitHub Issue Workflows
homeboy git issue create <component_id> --title <title> [--body <body> | --body-file <path>] [--label <label>...]
homeboy git issue comment <component_id> --number <n> [--body <body> | --body-file <path>]
homeboy git issue find <component_id> [--title <title>] [--label <label>...] [--state open|closed|all] [--limit <n>]
homeboy git issue close <component_id> --number <n> [--reason completed|not-planned] [--comment <body> | --comment-file <path>]
homeboy git issue edit <component_id> --number <n> [--title <title>] [--body <body> | --body-file <path>] [--add-label <label>...] [--remove-label <label>...]Issue commands require a component ID, but they also accept --path to discover component metadata from a portable checkout:
homeboy git issue find homeboy --state open --limit 10
homeboy git issue create homeboy --path /tmp/homeboy --title "docs: clarify git workflow" --body-file /tmp/body.mdUse close --reason not-planned for intentional wontfix decisions. Homeboy’s reconciliation tooling treats GitHub’s not-planned state as the durable signal not to re-file the issue.
GitHub Pull Request Workflows
homeboy git pr create <component_id> --base <base> --head <head> --title <title> [--body <body> | --body-file <path>] [--draft]
homeboy git pr edit <component_id> --number <n> [--title <title>] [--body <body> | --body-file <path>]
homeboy git pr find <component_id> [--base <base>] [--head <head>] [--state open|closed|merged|all] [--limit <n>]
homeboy git pr readiness <component_id> --number <n>
homeboy git pr comment <component_id> --number <n> [comment mode flags]
homeboy git pr refresh <component_id> <number-or-url> [--strategy auto|rebase|merge|ff-only] [--check <cmd>...] [--push]
homeboy git pr land <repo> <pr>... [--merge-method squash|merge|rebase]Like issue commands, PR commands accept --path to discover component metadata from a portable checkout:
homeboy git pr create homeboy --base main --head docs-refresh-git-command --title "docs: refresh git command workflows" --body-file /tmp/pr.md
homeboy git pr find homeboy --head docs-refresh-git-command --state open
homeboy git pr readiness homeboy --number 123 --output /tmp/pr-readiness.jsonPR Merge Readiness
homeboy git pr readiness is a read-only explanation command. It fetches GitHub PR metadata with gh pr view, reports GitHub’s raw mergeStateStatus, and adds a Homeboy interpretation without attempting a merge as the discovery mechanism.
The command exits 0 only when the interpreted state is mergeable_now and no blockers are present. Other interpreted states exit nonzero so automation can gate on readiness while still reading the structured JSON result from --output.
Interpreted states:
| State | Meaning | Usual guidance |
|---|---|---|
mergeable_now | GitHub reports CLEAN, the PR is not draft, and checks are terminal green. | Merge policy may proceed. |
conflicted | GitHub reports DIRTY or the branch is BEHIND. | Rebase or update the PR branch, resolve conflicts, push, then re-run readiness. |
waiting_on_required_checks | Required checks are pending, or GitHub reports CLEAN before checks have appeared on a new head. | Wait for checks to report on the current head. |
failing_required_checks | Branch protection or required checks block merge. | Fix failing required checks or branch-rule blockers. |
waiting_on_optional_checks | GitHub reports UNSTABLE while checks are still pending. | Wait for non-blocking checks if your workflow treats them as merge evidence. |
failing_optional_checks | GitHub reports UNSTABLE with failed or inconclusive checks. | Inspect optional check failures and decide whether they are acceptable. |
unknown | GitHub reports UNKNOWN, no raw merge state, hooks are still settling, or Homeboy does not recognize the combination. | Wait briefly and re-run readiness; do not probe by attempting a merge. |
Machine-readable output includes the raw state, interpreted state, blockers, and guidance:
{
"variant": "pr_readiness",
"action": "pr.readiness",
"number": 123,
"ci_state": "terminal_green",
"ci_summary": "1 check(s): 1 terminal-green, 0 failed/unknown, 0 pending",
"readiness": {
"raw_merge_state": "UNKNOWN",
"interpreted_state": "unknown",
"mergeable": false,
"blockers": [
{
"kind": "mergeability_unknown",
"message": "GitHub has not computed mergeability for the current PR head yet.",
"guidance": "Wait briefly and re-run readiness; do not attempt a merge just to discover state."
}
],
"check_guidance": "Check state alone is insufficient while mergeability is UNKNOWN. 1 check(s): 1 terminal-green, 0 failed/unknown, 0 pending",
"conflict_guidance": "Conflict state is unknown until GitHub recomputes mergeability."
}
}PR Refresh
homeboy git pr refresh updates a PR branch from its current base and emits a structured summary for merge-train recovery after sibling PRs land.
homeboy git pr refresh homeboy 5806
homeboy git pr refresh homeboy https://github.com/Extra-Chill/homeboy/pull/5806 --strategy rebase
homeboy git pr refresh homeboy 5806 --check "git diff --check" --pushSafety behavior:
- Refuses to start when the worktree is already dirty.
- Checks out the PR through
gh pr checkout, fetches the current base, then applies the selected strategy. --strategy autohonorsbranch.<name>.rebaseorpull.rebase, falling back torebase.- Reports conflicted files from
git status --porcelainand exits non-zero when blockers remain. - Runs lightweight checks only after a clean refresh. When no
--checkis supplied, it runsgit diff --check. - Never pushes by default.
--pushpublishes only a clean, check-passing branch and usesgit push --force-with-lease; plain destructive force-push is not exposed.
PR Landing Train
homeboy git pr land lands a list of PRs one at a time. It inspects the next PR immediately before merging, merges only clean PRs with successful reported checks, then rechecks the next PR after each merge. The command pauses at the first blocker and emits a final fleet status table.
homeboy git pr land Extra-Chill/homeboy 123 124 125
homeboy git pr land Extra-Chill/homeboy https://github.com/Extra-Chill/homeboy/pull/123 --dry-runSafety behavior:
- PRs merge sequentially by default; there is no parallel landing mode.
- A PR with failing, pending, or unreported required checks blocks the train.
- A
CLEANmerge state without reported successful checks is not considered ready. - If GitHub reports a base-branch-modified merge race, Homeboy recomputes readiness and retries within
--max-base-retries. - Dirty dependent PRs are refreshed only when an explicit helper program is supplied with
--refresh-helper; helper arguments are passed directly, not through a shell.
Refresh helper example:
homeboy git pr land Extra-Chill/homeboy 123 124
--refresh-helper homeboy-pr-refresh
--refresh-helper-arg {repo}
--refresh-helper-arg {number}Supported helper placeholders are {repo}, {number}, {url}, and {head_sha}.
PR Comments
homeboy git pr comment supports three comment modes:
- Plain comment: no marker flags. Homeboy appends a fresh comment.
- Sticky whole-body comment:
--key <key>finds or updates one comment tagged with<!-- homeboy:key=<key> -->. The provided body replaces the whole managed comment body. - Sectioned managed comment:
--comment-key <outer> --section-key <inner>updates one section inside a shared comment tagged with<!-- homeboy:comment-key=<outer> -->. Other sections are preserved.
Sectioned comments are used by Homeboy Action to keep lint, test, audit, and tooling metadata in one managed PR comment without clobbering sibling sections:
homeboy git pr comment homeboy
--number 123
--comment-key homeboy-ci-results
--section-key lint
--section-order lint,test,audit
--header "## Homeboy Results"
--footer-file /tmp/tooling.md
--body-file /tmp/lint.md--key mode and --comment-key / --section-key mode are mutually exclusive. In sectioned mode, existing headers and footers are preserved when omitted; passing --footer or --footer-file replaces the stored footer.
JSON Input Schemas
SingleCommitSpec
{
"id": "homeboy",
"message": "Update git docs",
"staged_only": false,
"include_files": ["docs/commands/git.md"]
}Notes:
idis optional when the component is supplied positionally or auto-detected from CWD.staged_onlydefaults tofalse.include_filesstages only the listed paths.exclude_filesstages all changes and then unstages the excluded paths.
BulkCommitInput
{
"components": [
{ "id": "homeboy", "message": "Update git docs" },
{ "id": "sample-plugin", "message": "Update workflow docs" }
]
}BulkIdsInput
{
"component_ids": ["homeboy", "sample-plugin"],
"tags": true,
"force_with_lease": false
}tags and force_with_lease are only used by push.
JSON Output
Note: command output is wrapped in the global JSON envelope described in the JSON output contract. The examples below show the
datapayload.
Single Component Output
{
"component_id": "homeboy",
"path": "/Users/user/Developer/homeboy@docs-refresh-git-command",
"action": "status|commit|push|pull|tag|rebase|cherry-pick",
"success": true,
"exit_code": 0,
"stdout": "<stdout>",
"stderr": "<stderr>"
}Bulk Output
{
"action": "status|commit|push|pull",
"results": [
{
"component_id": "homeboy",
"path": "/path/to/homeboy",
"action": "commit",
"success": true,
"exit_code": 0,
"stdout": "[main abc1234] Update git docsn 1 file changed",
"stderr": ""
}
],
"summary": {
"total": 1,
"succeeded": 1,
"failed": 0
}
}Note: command output is wrapped in the global JSON envelope described in the JSON output contract. The examples below show the data payload.
commitreturns a successful result withstdoutset toNothing to commit, working tree cleanwhen there are no changes.- Bulk operations continue processing all components even if some fail; the summary reports total, succeeded, and failed counts.
- Bulk outputs are
BulkGitOutput { action, results, summary }, whereresultsis a list ofGitOutputobjects.
Exit Code
- Single mode: exit code matches the underlying
gitorghcommand. - Bulk mode (
--json):0if all components succeeded;1if any failed.
Examples
# Auto-detect the component from the current checkout
homeboy git status
homeboy git commit -m "Update docs"
homeboy git push
# Operate on a worktree or CI checkout without changing CWD
homeboy git status --path /Users/user/Developer/homeboy@docs-refresh-git-command
homeboy git commit --path /Users/user/Developer/homeboy@docs-refresh-git-command -m "Update docs"
# Use explicit component IDs when operating outside a component checkout
homeboy git status homeboy
homeboy git pull homeboy
homeboy git tag homeboy v1.0.0 -m "Release 1.0.0"
# Rebase, then safely update the remote branch
homeboy git rebase --onto origin/main
homeboy git push --force-with-lease
# Pick commits by ref or by GitHub PR number
homeboy git cherry-pick abc1234
homeboy git cherry-pick --pr 123
# GitHub issue and PR helpers
homeboy git issue find homeboy --label audit --state open
homeboy git pr create homeboy --base main --head docs-refresh-git-command --title "docs: refresh git command workflows" --body-file /tmp/pr.md
homeboy git pr comment homeboy --number 123 --key docs-check --body-file /tmp/comment.md