dev10x:git
/dev10x:git
Use before running git push or git rebase — so force-pushes to protected branches are blocked and non-interactive rebases run unattended without manual editor approval prompts. TRIGGER when: running git push or git rebase operations. DO NOT TRIGGER when: other git operations (commit, status, log, diff) that don't need push/rebase safety.
- Author
- dev10x-guru ↗
- Repository
- dev10x-claude ↗
- Licence
- MIT
- Last repository change
- 12.10.2026
Assessment and security
- Files in this package
- 5
- Scripts
- 4
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 12.10.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
- 4 scripts in this package. Review them before installing, as Claude may execute them.
Scripts: scripts/git-push-safe.sh, scripts/git-rebase-groom.sh, scripts/git-seq-editor.sh, scripts/protected-branches.sh
What it does and when to use it
Use before running git push or git rebase — so force-pushes to protected branches are blocked and non-interactive rebases run unattended without manual editor approval prompts. TRIGGER when: running git push or git rebase operations. DO NOT TRIGGER when: other git operations (commit, status, log, diff) that don't need push/rebase safety.
Original author description
Use before running git push or git rebase — so force-pushes to protected branches are blocked and non-interactive rebases run unattended without manual editor approval prompts. TRIGGER when: running git push or git rebase operations. DO NOT TRIGGER when: other git operations (commit, status, log, diff) that don't need push/rebase safety.
How it works
- Orchestration
- Safe Push
- Non-Interactive Rebase
- Branch Comparison Aliases
- settings.local.json wiring
SKILL.md preview
---
name: dev10x:git
description: >
Use before running git push or git rebase — so force-pushes to
protected branches are blocked and non-interactive rebases run unattended
without manual editor approval prompts.
TRIGGER when: running git push or git rebase operations.
DO NOT TRIGGER when: other git operations (commit, status, log, diff)
that don't need push/rebase safety.
user-invocable: true
invocation-name: dev10x:git
allowed-tools:
- mcp__plugin_dev10x_cli__push_safe
- Skill(dev10x:gh-pr-monitor)
- Bash(${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-rebase-groom.sh:*)
- Bash(${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-seq-editor.sh:*)
- Bash(git reset --soft:*)
- Bash(git push --force-with-lease:*)
- Bash(/tmp/Dev10x/bin/mktmp.sh:*)
- Edit(/tmp/Dev10x/git/**)
---
**Announce:** "Using dev10x:git to [push / groom commits]."
# dev10x:git — Hardened Git Operations
Provides hardened scripts for safe git push and non-interactive rebase.
Add the `allowed-tools` entries to your project's `settings.local.json`
to pre-approve the scripts without per-call prompts.
## Orchestration
This skill follows `references/task-orchestration.md` patterns.
Create a task at invocation, mark completed when done:
**REQUIRED: Create a task at invocation.** Execute at startup:
1. `TaskCreate(subject="Safe git push", activeForm="Pushing safely")`
Mark completed when done: `TaskUpdate(taskId, status="completed")`
## Safe Push
**Primary: MCP tool call** (no permission friction):
```
mcp__plugin_dev10x_cli__push_safe(args=["origin", "branch"])
```
MCP calls avoid `Bash()` allow-rule matching and provide
structured responses. Use the MCP tool as the default for
all push operations.
### Configuring `protected_branches`
`push_safe` blocks **`--force`** to a protected branch, and an ordinary
push is always allowed. A `--force-with-lease` is allowed on any branch
too, with one condition on a protected one: the remote tip must already
be an ancestor of what you are pushing (GH-1270). Protection resolves in
three tiers (GH-1031):
1. The `protected_branches` call parameter, when non-empty.
2. Else the project's durable `protected_branches` key in the
matching `projects[]` entry of `~/.config/Dev10x/friction.yaml`.
3. Else `git-push-safe.sh`'s own default set:
`main master develop development staging trunk`.
Each tier REPLACES the one below it rather than adding to it, so a
list that names `release/*` must re-list the integration branches it
still wants covered. Glob patterns are supported at every tier.
Prefer tier 2 for anything durable: an unattended agent never passes
a per-call list, which is exactly when an unprotected force-push
costs the most.
```yaml
# ~/.config/Dev10x/friction.yaml
projects:
- match: ["*/my-repo", "*/my-repo-*"]
protected_branches: [main, release/*, staging]
```
| Recipe | Call | When |
|---|---|---|
| Default (any workflow) | `push_safe(args=["origin","feature"])` | Feature branches; the six-branch default set applies |
| Protect only `main` for this call | `push_safe(args=["origin","develop"], protected_branches=["main"])` | Solo flow that force-pushes `develop` as integration |
| Add a release branch | `push_safe(args=["origin","feature"], protected_branches=["main","develop","release/*"])` | Long-lived release branches that must never be force-pushed |
| Protect a non-standard branch everywhere | durable `protected_branches` (above) | The project's integration branch is not in the default set |
**`protected_branches=[]` does NOT disable protection.** An empty
list reads as "no override" and falls through to the tiers below, so
the default set still applies. To force-push a branch in the default
set, pass a list that omits it (`protected_branches=["main"]` to
force-push `develop`). Turning protection off entirely is
deliberately not expressible — the shell layer has no such flag.
**Solo-maintainer rule of thumb:** when a hook denial says
`Skill: dev10x:git`, the fix is almost always to re-invoke
`push_safe` with the right `protected_branches` list. Reach for
the skill's documented escape paths — not env-level bypasses —
when the wrapper itself blocks: hook overrides live in the hook
layer (see `.claude/rules/hook-patterns.md`), not at the caller.
If the call still blocks after adjusting `protected_branches`,
read the returned `blocked_reason` field — it names the exact
flag (`--force` on a protected branch, divergent ref, etc.) so
you can adjust the call rather than escalating.
**MCP server unavailable.** If `mcp__plugin_dev10x_cli__push_safe`
is listed as "no longer available" in system-reminders, STOP and
ask the user to reconnect via `/mcp` or a session restart. Do NOT
fall back to the wrapper script (blocked by
`validate-bash-command.py`) or env-level bypasses — see
`references/mcp-unavailable-escape-hatch.md` for the documented
recovery path.
### Post-push CI monitoring (GH-117 #2)
**On successful push to a branch with an open PR, the next
action is `Skill(dev10x:gh-pr-monitor)` — not "wait and see".**
A push to a PR branch retriggers CI; failing to monitor it
turns a deviation into an oversight.
### `push_safe` return shape
On success, `push_safe` returns a structured payload:
```json
{
"pushed": true,
"ref": "<branch>",
"remote": "origin",
"sha": "<short-sha>",
"tracking": "origin/<branch>",
"ci_run_url": null
}
```
On a blocked or failed push, `pushed` is `false` and `blocked_reason`
names the cause (`protected_branch_force_push`, `push_failed`, …).
A returned `{"error": "..."}` payload signals an MCP-level failure
distinct from `pushed: false`.
> **Historical note (GH-188):** earlier versions returned `{}` on
> success and required a separate `git ls-remote` round-trip to
> confirm the remote accepted the ref. New callers should branch on
> the `pushed` field; existing callers tolerating `{}` continue to
> work because the new payload is strictly additive.
After `push_safe` returns:
1. Resolve PR state for the pushed branch via
`mcp__plugin_dev10x_cli__pr_detect`.
2. If a PR exists and is OPEN, immediately invoke
`Skill(dev10x:gh-pr-monitor)` so the supervisor's CI-poll
micro-agent dispatches before the user has to ask.
3. If no PR exists (push is the first push of a new branch),
skip this auto-chain — the next step is `dev10x:gh-pr-create`
in the work-on plan.
When this skill is invoked from inside `dev10x:work-on`,
work-on's pr-continuation play moves `Monitor CI` to
`in_progress` automatically (see work-on instructions §
Post-push auto-advance). When invoked standalone, the user is
responsible for the chain, but this skill's success message
should still surface a "Next: `Skill(dev10x:gh-pr-monitor)`"
hint so the next move is unambiguous.
**There is no wrapper-script fallback (GH-1025).** Earlier versions of
this skill documented
`${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-push-safe.sh` as a
fallback, but the `git-push-safe-script` rule in
`command-skill-map.yaml` hard-blocks that path with "use the MCP tool
instead" — so following the instruction produced a guaranteed block.
A skill must never instruct an action its own guardrail forbids. The
script still ships (other tooling shells out to it); it is not an
agent-facing entry point.
`push_safe` blocks bare `--force` / `-f` on protected branches. The
resolved protected set is the one documented above — the shell script's
own default is the last tier, not a separate list.
`--force-with-lease` is allowed everywhere else, but a **protected**
target is fetched first and refused with `blocked_reason:
"base_behind_remote"` unless its remote tip is already an ancestor of
the pushed ref (GH-1270). A lease is not the protection it reads as
here: it compares the remote against the local remote-tracking ref, so
a `develop` last fetched hours ago leases cleanly against its own stale
copy and overwrites every merge landed since — seven PRs were erased
that way in eleven minutes, with git reporting success and `git diff`
showing nothing, because the two tips shared a tree. The refusal names
the commits that would be dropped; rebase onto `origin/<base>` and push
again. When the fetch itself fails the push is refused as
`base_fetch_failed` rather than attempted blind — unless the branch
does not exist on the remote yet, which has nothing to lose.
## Non-Interactive Rebase
Two scripts power fully automated rebases:
- **`git-seq-editor.sh`** — replaces `GIT_SEQUENCE_EDITOR`; reads the
rebase todo from the path in `GROOM_SEQ_FILE` env var.
- **`git-rebase-groom.sh`** — convenience wrapper that sets
`GIT_SEQUENCE_EDITOR` and `GIT_EDITOR=true`, then runs
`git rebase -i <base-ref>`. Takes `<seq-file> <base-ref>` args.
### Usage
1. Create a unique temp file for the rebase sequence:
```bash
/tmp/Dev10x/bin/mktmp.sh git rebase-seq .txt
```
Store the returned path (e.g., `/tmp/Dev10x/git/rebase-seq.a7b3c9.txt`).
2. Write the rebase todo (oldest commit first) to that file using
the Write tool:
```
Write <unique-path>:
pick abc1234 First commit
pick def5678 Second commit
fixup fed9876 fixup! Second commit
```
**Note:** The Write tool requires reading a file before writing to it.
For a new file, `mktmp.sh` already created it (empty), so Read it first,
then Write the sequence content.
3. Run the rebase with the sequence file as the first argument:
```bash
${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-rebase-groom.sh <unique-path> <base-ref>
```
### Sequence file ordering
The sequence file must list commits **oldest at the top, newest at the
bottom** — the same order `git rebase -i` expects. Use `tac` to
reverse `git log` output:
```bash
git log --oneline <base>..HEAD | tac
```
### SHA staleness
After each rebase pass all commit SHAs change. Always re-run
`git log --oneline <base>..HEAD` after each pass and use fresh SHAs
when writing the next sequence file.
## Branch Comparison Aliases
Use git aliases instead of embedding `$(git merge-base ...)` in
commands. The `$(...)` substitution creates compound commands that
break Claude Code permission prefix matching, causing unnecessary
permission prompts.
| Alias | Equivalent |
|----------------------|----------------------------------------------------------------|
| `git develop-log` | `git log --oneline $(git merge-base develop HEAD)..HEAD` |
| `git develop-diff` | `git diff $(git merge-base develop HEAD)..HEAD` |
| `git develop-rebase` | `git rebase -i --autosquash $(git merge-base develop HEAD)` |
The alias name includes the base branch. When a different base is
needed (e.g., `trunk`), add a parallel set: `trunk-log`, `trunk-diff`,
`trunk-rebase`.
**Never use `$(git merge-base ...)` inline** — always use the alias.
`{base}-rebase` grooms `fixup!` commits back to the merge-base. It is
interactive and resolves the merge-base against the **local** `{base}`
ref, so it is unusable by an unattended agent — it hangs without an
editor, and a stale local ref makes it report success without moving
HEAD (GH-964). Groom non-interactively with `rebase_groom`. To catch
up with a base that moved, no alias applies: run `git fetch origin`,
then `git rebase origin/<base>`, then assert
`git merge-base --is-ancestor origin/<base> HEAD` exits 0.
## settings.local.json wiring
Add to your project's `.claude/settings.local.json`:
```json
{
"permissions": {
"allow": [
"Bash(${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-rebase-groom.sh:*)",
"Bash(${CLAUDE_PLUGIN_ROOT}/skills/git/scripts/git-seq-editor.sh:*)",
"Bash(git reset --soft:*)",
"Bash(git push --force-with-lease:*)",
"Bash(/tmp/Dev10x/bin/mktmp.sh:*)",
"Edit(/tmp/Dev10x/git/**)"
]
}
}
```
Files in this package (5)
- SKILL.md 12 KB
- scripts/git-push-safe.sh 12 KB
- scripts/git-rebase-groom.sh 5 KB
- scripts/git-seq-editor.sh 1 KB
- scripts/protected-branches.sh 1 KB
Versions
The database has no other skills named dev10x:git.
Database snapshot: 13.11.2026 · package version b23bfa34b6ae (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100push
AI-assisted safety layer for git push operations with quality gates and collaboration guardrails. Use when: pushing commits, force pushing, pushing to protected branches, pushing feature branches. Not for: composing the commit — use /commit; branch and merge strategy decisions —… - 100git-feature-branch-sync
Rebase vs merge a feature branch; force-push safely. TRIGGER when: syncing a feature branch with the default branch or deciding whether and how to force-push. DO NOT TRIGGER when: routine work on a clean branch, operating on shared/default branches (never force-push them), or… - 100git-workflow
Writes commit messages, manages branches, and opens pull requests with summaries. Use when the user asks to commit, push, branch, or create a PR, and before any destructive git operation such as reset, rebase, or force-push. - 100push
AI 辅助的 git push 安全层,提供质量关卡与协作护栏。 Use when: 推送 commit、强制推送、推送到受保护分支、推送 feature 分支。 Not for: 撰写 commit 内容——请用 /commit;分支与合并策略的决策——请用 /git-workflow-guide。 Keywords: git push, force push, protected branch, quality gate, push receipt, PR automation, 推送, 保护分支, 质量门禁, 强制推送. - 100git-ops
Git + worktree orchestrator: status survey, per-worktree triage, commits, PRs, branches, releases, rebases — reads inline, writes to a background agent. Triggers on: git status, anything to commit, anything to push, commit, push, create PR, rebase, release, tag, changelog, worktree, land worktrees. - 90git-safety
Git safety rules. INVOKE WHEN: git push, force push, git reset, git clean, destructive git, push force, reset hard. NEVER force push or do destructive git operations.