文档

执行 Git 操作(提交、分支、合并、变基、冲突解决与恢复)时强制套用安全规则。

它能做什么

按参考文件分流提交、分支、冲突、历史改写、恢复、报错、追溯、协作、worktree、子模块、大仓库、hooks、密钥、发布与脚本化等场景。强制执行核心规则:只改写未推送历史、force push 必须用 `--force-with-lease`、破坏性命令前先列出会受影响的对象、按爆炸半径升级撤销操作。从 `~/Clawic/data/git/config.yaml` 读取偏好(集成方式、提交风格、分支命名、受保护分支、签名、提交信息语言),给出具体命令

技能文档

User preferences and memory live in ~/Clawic/data/git/ (see setup.md on first use, memory-template.md for the file format). If you have data at an old location (~/git/ or ~/clawic/git/), move it to ~/Clawic/data/git/.

Configuration

User-dependent variables. Defaults apply until the user states a preference; store them in ~/Clawic/data/git/config.yaml.

VariableTypeDefaultEffect
integration_stylerebase | merge | squash | repo-defaultrepo-defaultHow branches get combined and what pull does; repo-default reads the last 20 merges (git log --merges --oneline -20) and follows what the repo already does
commit_styleconventional | plain | repo-defaultrepo-defaultShape of every generated commit subject (Commit Discipline); repo-default copies the style found in git log --oneline -20
branch_namingtext (pattern)type/topicTemplate used when creating branches, lowercase and hierarchical by default
protected_brancheslistmain, masterBranches never committed to, rewritten, or force-pushed (Core Rule 2, Push gate); a request that targets one becomes "branch first, then propose the merge"
force_push_policynever | own-branches | anyown-branchesGoverns the Push gate: never turns every rewrite into a git revert; any still requires --force-with-lease
subject_maxnumber (chars, 50-100)72Hard stop for every generated commit subject (Core Rule 6) and the length any commit-msg gate enforces
message_languagetext (language) | repo-defaultrepo-defaultLanguage of generated commit subjects, bodies, and tag messages; repo-default copies the language already in git log --oneline -20
remote_hostgithub | gitlab | bitbucket | gitea | othergithubSelects PR-vs-MR wording, blob size limits, and squash-merge semantics quoted in review and release guidance
signingoff | ssh | gpgoffAdds signing flags and commit.gpgsign setup to commit and tag flows

Preference areas to record as the user reveals them:

  • tooling — CLI vs GUI vs IDE Git, hosting CLI in use, pre-commit framework, mergetool of choice
  • conventions — subject format, ticket-ID placement, tag scheme, trailers such as Co-authored-by, monorepo tag prefixes
  • thresholds — body-length and file-count limits a commit may reach, the large-file guard's size (--above=), reflog retention (gc.reflogExpireUnreachable), clone depth and filter in CI
  • restrictions — repos, paths, or file types the agent must leave alone; operations banned outright (no rebase, no filter-repo); compliance regimes demanding signed or reviewed commits
  • platform — hosting provider, SSH vs HTTPS, monorepo vs polyrepo, Windows/macOS line-ending and case sensitivity constraints
  • safety posture — whether the agent may commit or push unprompted, confirmation before --hard/clean -f/history rewrites
  • work order — commit granularity, whether to sync before starting, review gates expected before a push
  • cadence — how often to fetch/prune, when to run maintenance on large clones

When To Use

  • Any task touching a Git repository: staging, commits, branches, merges, rebases, tags, stashes, submodules.
  • Something looks lost — deleted branch, bad rebase, hard reset, vanished stash: recovery is a first-class use (→ Recovery Playbook, recovery.md).
  • Git refuses to run and the message is opaque (index.lock, non-fast-forward, dubious ownership, detached HEAD) → errors.md.
  • Before any history rewrite or force push: run the Output Gates below first.
  • Investigating when a behavior broke, who changed a line, or where code came from → forensics.md.
  • Not for CI pipeline configuration — GitHub workflows are github-actions, GitLab pipelines are gitlab; writing the PR description itself is pull-request.

Quick Reference

SituationFile
Staging surgery, splitting a mixed change, wording a message, stashingcommits.md
Creating or switching branches, merge vs rebase, stacked branchesbranching.md
A merge or rebase stopped on conflictsconflicts.md
Undoing: reset, revert, amend, rewriting a branch before reviewhistory.md
Work looks lost: bad reset, dropped stash, deleted branch, detached commitsrecovery.md
Git printed an error and refuses to proceederrors.md
"When did this break", "who wrote this line", "where did this code go"forensics.md
Push/pull friction, review flow, force-pushing on a shared branchcollaboration.md
Forks, upstreams, mirrors, moving or splitting a repositoryremotes.md
Two checkouts at once: hotfix mid-refactor, parallel agent tasksworktrees.md
Nested repositories: submodules, subtrees, vendored codesubmodules.md
Slow clone or status, monorepo scale, huge files, LFSlarge-repos.md
Pre-commit/pre-push automation, lint gates, a hook that never runshooks.md
A credential or a giant blob reached the historysecrets.md
Wrong author identity, auth failures, ignore rules, CRLF churnconfig.md
Tags, version bumps, backports, release branches, changelogsreleases.md
A flag or one-time config that removes a whole trap classcommands.md
Git driven from a script, a CI job, or a non-interactive agentscripting.md
User states a workflow preferencesetup.md + memory-template.md
Anything elseStay here — Core Rules, Revision Syntax, and the Recovery Playbook cover the default path

Core Rules

  1. Rewrite only unpushed history. Check: git log @{u}.. lists exactly the commits safe to amend/rebase/squash. A commit missing from that output is published — fix forward with git revert instead.
  2. Force push = --force-with-lease, own branch only, never a branch in protected_branches. The lease is void if anything fetched after the remote moved — IDE auto-fetch does this without warning — so add --force-if-includes (git >=2.30) to close that hole.
  3. Destructive command → name the casualties first. git status before reset --hard, git clean -n before git clean -f, git diff @{u} before force push. If you cannot list what dies, you are not ready to run it. Cheap insurance when you are unsure: git branch backup/$(date +%F-%H%M) costs one ref and zero bytes.
  4. git reflog before panic. Committed work survives 90 days (reachable) / 30 days (unreachable) — those are reflog-entry lifetimes, and a commit some reflog entry still names does not count as unreachable, so gc's shorter two-week prune window never applies to it (→ recovery.md). The only truly unrecoverable losses: never-staged edits killed by reset --hard/restore, and untracked files killed by clean -f.
  5. Conflicts repeat per commit in rebase, once in merge. Same region conflicting across 3+ replayed commits → abort and merge instead (one resolution), or enable rerere so each resolution is recorded once.
  6. Commit = one reviewable change. Mixed changes → git add -p to split. Subject: aim ≤50 chars (convention), hard stop subject_max, default 72 because git log indents bodies by four spaces inside an 80-column terminal — hosts truncate around the same width in list views. Body explains why, not what; subject and body both follow message_language.
  7. A pushed secret is a leaked secret. Rotate the credential first; history rewrite (filter-repo) is cleanup, not containment — forks, clones, and CI caches keep the old objects.
  8. Escalate undo by blast radius; stop at the first tool that reaches the goal. git restore (one file, nothing else moves) → git revert (one commit, safe on shared branches) → git reset (moves your branch pointer only) → git rebase (new SHAs, everyone tracking the branch pays) → git filter-repo (every clone in existence is now wrong). Reaching for the right-hand tools when a left-hand one suffices is the single most common self-inflicted Git incident.

Revision Syntax

Most "Git did something I did not ask for" reports are a misread revision expression. Decoder:

ExpressionMeansTrap
HEAD~2Two commits back along first parentsFollows the mainline through merges, skipping the merged branch
HEAD^2The SECOND PARENT of a merge commitNot "two back": ^ selects a parent, ~ walks generations
HEAD@{2}Where HEAD pointed two reflog moves agoTime, not ancestry — and local to this clone only
@{u} / @{push}The tracked upstream / where a push would landThey differ in triangular setups (fork: pull from upstream, push to origin)
A..BCommits reachable from B but not AIn git diff, the same expression means the plain A-to-B diff
A...Blog: commits on either side but not both. diff: B against the MERGE-BASEThe one expression whose meaning changes between log and diff — the source of "my diff shows unrelated files"
:/fix loginMost recent commit whose message contains that textSearches all reachable history, not just this branch
:1:file :2:file :3:fileDuring a conflict: base, ours, theirsNumbering is fixed; "ours/theirs" inverts under rebase (→ Conflict Basics)
main@{yesterday}Branch tip as of yesterdayReflog-based: empty in a fresh clone, and gone after reflog expiry
v1.2^{}The commit an annotated tag points atWithout peeling, a tag is its own object — git diff v1.2 compares against the tag object's target, scripts that assume a commit break

Ambiguity between a branch and a path is resolved with --: git checkout -- config is always the file.

Recovery Playbook

SymptomPlay
Just finished a bad rebase/merge/resetgit reset --hard ORIG_HEAD — Git saved your pre-operation position
Commits vanished after a rewritegit refloggit reset --hard HEAD@{n} (the entry just before the damage)
Deleted a branchgit refloggit branch restored
Committed on the wrong branch (unpushed)git switch right-branch && git cherry-pick , then git switch - && git reset --hard HEAD~1
Committed on detached HEAD, then switched awayCommit stays in git reflog for 30 days → git branch rescue
Need one file as it was N commits agogit restore --source HEAD~N -- path — nothing else moves
reset --hard ate staged-but-uncommitted workgit fsck --lost-found — staged content survives as dangling blobs; never-staged edits are gone
Dropped a stashgit fsck --unreachable | grep commitgit stash apply
Bad commit already on a shared branchgit revert — never rewrite shared history
Unsure what happened / anything elsegit reflog first; before experimenting, git branch backup — a branch is free insurance

Deeper chains (deleted file archaeology, corrupted index, post-filter-repo rescue, what expiry actually deletes): recovery.md.

Commit Discipline

  • One reviewable change per commit; git add -p splits mixed work. git commit --fixup + git rebase -i --autosquash batches corrections without "fix typo" noise.
  • Match the repo's existing message style before imposing one — check git log --oneline -20, or follow commit_style and message_language when the user set them. Conventional commits (type(scope): description) only where the log or release tooling already uses them.
  • git pull --rebase --autostash before push: no surprise merge commits, works with a dirty tree.
  • First push: git push -u origin HEAD, or set push.autoSetupRemote (git >=2.37) once and never type -u again.

Conflict Basics

  • Set merge.conflictStyle zdiff3 (git >=2.35) once: markers include the base version, so you see what each side changed instead of guessing intent.
  • Ours/theirs invert during rebase: "ours" = the branch you are rebasing onto, "theirs" = your own commit being replayed — rebase checks out upstream and applies your commits as patches on top.
  • After resolving: git grep -nE '^(<{7}|={7}|>{7})' must return nothing, then build/tests, then --continue.
  • Everything else → conflicts.md.

Output Gates

Before declaring Git work done:

  • Rewrite gate: every amended/rebased commit appeared in git log @{u}.. before I touched it
  • Deletion gate: I listed the casualties (git status, git clean -n) before any --hard / -f
  • Push gate: target is not in protected_branches and not a shared branch; if forcing at all, --force-with-lease minimum, and within force_push_policy
  • Conflict gate: marker grep is clean AND the project builds after resolution
  • Identity gate: git config user.email is the right identity for this repo (work vs personal)
  • Content gate: git diff --cached --stat reviewed — no credential, no build artifact, no blob the host will reject

Traps

TrapWhy it failsDo instead
git stash before a risky operation, expecting untracked files savedPlain stash skips untracked filesgit stash -u
Assuming stash pop dropped the stash after a conflictPop only drops on clean apply; on conflict the entry staysResolve, then git stash drop
git clean -fdx to "clean build artifacts"-x also deletes ignored files: .env, IDE config, local secretsgit clean -fd, always preview with -n
Renaming Foo.jsfoo.js works locally, breaks CImacOS/Windows filesystems are case-insensitive, Linux is notgit mv Foo.js tmp && git mv tmp foo.js
git branch -d refuses to delete after squash-mergeSquashed commits are unreachable from main, so Git thinks the branch is unmergedVerify the PR merged, then -D
Committing a large binary "just this once"GitHub warns >50 MB, blocks >100 MB — and history keeps the blob foreverGit LFS before first commit; after the fact, git filter-repo (secrets.md)
"Sharing" hooks via .git/hooks.git/hooks is never versionedCommit a hooks dir + git config core.hooksPath (hooks.md)
Cloned repo has empty submodule directoriesSubmodules need explicit initializationgit clone --recurse-submodules, or git submodule update --init
Adding a path to .gitignore to stop tracking itIgnore rules never apply to already-tracked files — the file keeps showing up in every diffgit rm --cached , commit the removal, then ignore it
git reset --hard when the intent was "unstage this"--hard also throws away the working tree; unstaging needs no destructive flaggit restore --staged (index only)
Marking a config file --assume-unchanged so local edits stop appearingGit now lies in status, and any incoming change to that file breaks pull with a confusing errorCommit a .example template, gitignore the real file (config.md)

Where Experts Disagree

  • Squash-merge vs preserve commits. Squash school treats PR commits as WIP noise (small PRs, GitHub-centric teams); preserve school needs atomic commits for bisect and surgical reverts (long-lived repos, kernel-style review). Follow the repo's existing merge style — mixing styles hurts more than either choice.
  • Trunk-based vs long-lived branches. DORA research associates branches merged within about a day with higher delivery performance; git-flow-style release branches pay off only when you maintain multiple released versions in parallel.
  • Conventional commits. Pay off when tooling consumes them (changelog generation, semver automation); pure ceremony otherwise. Detect: release automation in the repo → use them.
  • Mandatory commit signing. Provenance school signs everything (supply-chain audits, OSS releases, regulated code). Skeptics note that a signature proves a key was present, not that the author was — a compromised laptop signs happily. Boundary: sign what outsiders consume; internal application repos gain little beyond noise.

More Clawic skills, get them at https://clawic.com/skills/git (install if the user confirms):

  • pull-request — when the branch is ready and the PR itself has to be written and validated
  • review-code — when the job is judging someone else's diff, not producing it
  • github-actions — when the failure is in workflow YAML rather than in the repository
  • gitlab — GitLab CI/CD pipelines and merge-request settings
  • code — planning, implementing, and verifying the change the commits will carry

Feedback

Part of Clawic, the verified skill library. Get this skill: https://clawic.com/skills/git.

相关技能

让分支名、worktree 目录与提交信息都符合 Conventional Commits v1.0.0,便于自动生成 changelog 与 SemVer 升级。

20 次安装

Git高级操作:smart-commit/rebase/bisect/worktree/reflog/conflict-resolution/submodule/PR流程

Diagnose a tangled git situation and give the exact, safe commands to fix it. Use when asked to undo a commit, recover lost work, fix a bad merge or rebase,...

MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED Use with session_send/session_spwan to save context. Triggers by 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.

2 次安装

Scan for orphaned worktrees and stale branches after crashes or abandoned sessions. Offers safe cleanup options.

1 次安装

Use when the user explicitly asks to prepare, review, or create a Git commit, including "提交", "提交代码", "帮我提交", "commit", "git commit", "确认提交", or requests a commit message.

23 次安装1 星标

Iván 的更多技能

浏览全部技能

在本地磁盘以分类纯 Markdown 文件保存需要长期留存的事实,与智能体内置记忆并存。

作者 Iván554 次安装18 星标

给出具体到 flag、文件、行号的 Docker 诊断与排错指引。

作者 Iván1 次安装

按配置的 JDK 版本诊断 Java 与 JVM 问题(从 NPE 到容器 OOM),给出可直接套用的代码与配置。

作者 Iván131 次安装9 星标

用可量化的层级、间距、字号、配色与版式规则,绘制并诊断视觉作品。

作者 Iván139 次安装6 星标

区分检索失败与生成失败,先定位再动手修 RAG 流水线。

作者 Iván