`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 release 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 ready <component_id> --number <n>
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.
homeboy git pr ready performs the explicit draft-to-ready-for-review transition. It observes an already-ready PR without changing it, so retries do not issue another GitHub mutation.
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 binds the next PR to its exact head SHA, waits up to 15 minutes for every reported head check to become terminal, and merges only a clean PR with no unwaived failures. The command pauses at the first blocker and emits a resumable check report with each check’s conclusion and link.
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 checks blocks the train, including non-required checks.
- A head change while checks are being observed blocks the train; rerun the emitted resume command against the new head.
--check-waiver HEAD_SHA|CHECK_NAME|APPROVERrecords an explicit waiver for one named non-required failure on exactly one head SHA.--max-check-wait-secondsbounds waiting; a timeout preserves the PR and reports the exact resume command.- 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