Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Guides safe, professional Git usage — branching strategies, atomic clean commits, conventional commit messages, interactive rebase (squash/fixup/reword/reorder), merge vs rebase decisions, conflict resolution, and recovery of lost work via reflog. Use this skill when the user asks to create or clean up a branch, write or amend commits, squash or reorder history, rebase onto main, resolve merge conflicts, undo a bad commit/merge/reset, recover deleted commits or branches, find lost work, fix a de
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 90% | 0% |
| case-23 | ✗→✓ | ▲ Improved | 138% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 81% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 99% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 123% | 0% |
This skill provides a disciplined, safe workflow for everyday Git: branching, crafting clean atomic commits, rewriting history with interactive rebase, resolving conflicts, and recovering from mistakes using the reflog. The guiding principle is safety first — never destroy work you cannot recover, always know your escape hatch before running a history-rewriting command.
Keywords: git, branch, commit, rebase, interactive rebase, squash, fixup, reword, cherry-pick, merge, conflict, conflict resolution, reflog, recover lost commits, undo, reset, revert, detached HEAD, force-push, stash, clean history, conventional commits, PR prep.
Golden rules
main/develop). Rewrite only your own unmerged feature branches.rebase, reset --hard, or force-push, note the current commit: git rev-parse HEAD or just trust the reflog — it remembers.git push --force-with-lease over --force. It refuses to clobber commits you haven't seen.git reflog (see references/reflog-recovery.md).Always understand current state first:
git status # working tree + branch
git log --oneline -10 # recent history
git branch -vv # branches + trackinggit switch main && git pull --ff-only.git switch -c feat/short-description.<type>/<slug> e.g. feat/oauth-login, fix/null-deref, chore/bump-deps, docs/readme. See references/branch-naming.md.git add -p to split a working tree into focused hunks. feat(auth): add OAuth2 PKCE login flow
Body explaining WHY, wrapped at ~72 cols. Reference issues.
git diff --staged.Choose merge vs rebase intentionally (see decision framework below). For a private feature branch, rebasing keeps history linear:
git fetch origin
git rebase origin/mainSquash noise ("wip", "fix typo"), reword unclear messages, reorder for logical flow:
git rebase -i origin/mainFull guidance and the command cheat sheet: references/interactive-rebase.md. Validate the result before pushing: scripts/rebase-safety-check.sh.
When a rebase/merge stops on a conflict, follow the step-by-step protocol in references/conflict-resolution.md. Summary:
git status # see conflicted files
# edit files, remove <<<<<<< ======= >>>>>>> markers
git add <resolved-files>
git rebase --continue # or: git merge --continue
# abort anytime: git rebase --abort / git merge --abortgit push -u origin feat/short-description # first push
git push --force-with-lease # after a rebase/amendNothing is lost until garbage collection runs (default ~30–90 days). See references/reflog-recovery.md and run scripts/git-recover.sh to surface candidate lost commits.
| Situation | Use | |-----------|-----| | Updating your private, unpushed feature branch with latest main | git rebase origin/main (linear history) | | Branch is shared / others have it checked out | git merge origin/main (don't rewrite shared history) | | Combining a finished feature into main (team prefers linear) | rebase then fast-forward / squash-merge | | Combining a feature, preserving full context & merge point | git merge --no-ff | | You just want to grab one commit from another branch | git cherry-pick <sha> |
Rule of thumb: rebase local, merge shared.
In the git rebase -i todo list, set the action keyword on each line:
| Keyword | Effect | |---------|--------| | pick | keep the commit as-is | | reword (r) | keep changes, edit the message | | edit (e) | stop to amend the commit (split, add files) | | squash (s) | merge into previous commit, combine messages | | fixup (f) | merge into previous commit, discard this message | | drop (d) | remove the commit entirely | | reorder | move lines up/down to reorder commits |
Targeted fixup workflow (best for PR review fixes):
git commit --fixup=<sha> # creates "fixup! ..." commit
git rebase -i --autosquash origin/main # auto-positions & marks it fixup| Problem | Fix | |---------|-----| | Bad last commit, want to redo message | git commit --amend | | Undo last commit, keep changes staged | git reset --soft HEAD~1 | | Undo last commit, keep changes unstaged | git reset HEAD~1 | | Discard last commit AND its changes | git reset --hard HEAD~1 (recoverable via reflog) | | Revert a commit already pushed/shared | git revert <sha> (new commit, safe) | | Lost commits after bad reset/rebase | git reflog then git reset --hard <sha> | | Deleted a branch by accident | git reflog → find tip sha → git branch <name> <sha> | | Detached HEAD with work to keep | git switch -c rescue-branch immediately | | Accidentally committed to main | branch it off, then reset main: see references/reflog-recovery.md | | Drop unstaged local changes | git restore <file> / git restore . | | Stash WIP to switch context | git stash push -m "msg" → git stash pop |
scripts/rebase-safety-check.sh after a rebase to confirm no commits were silently dropped and the tree still matches expectations.git add -p to keep commits atomic instead of git add ..git switch/git restore over the overloaded git checkout.git tag backup-before-rebase. Delete it when done.git config rerere.enabled true to let Git remember conflict resolutions across repeated rebases.--force-with-lease, and never on main.main/develop — rewriting public history breaks everyone. Use revert instead.git reset --hard without checking — you lose uncommitted working-tree changes permanently (these are NOT in the reflog). Stash first.<<<<<<< HEAD (current/your side during merge) vs >>>>>>> branch (incoming). During rebase the sides are swapped — see references/conflict-resolution.md.git diff --staged; use .gitignore.git reflog before doing anything else.references/interactive-rebase.md — complete interactive rebase guide with worked scenarios.references/conflict-resolution.md — step-by-step conflict protocol, marker semantics, rerere, tools.references/reflog-recovery.md — recover lost commits, branches, resets, detached HEAD, wrong-branch commits.references/conventional-commits.md — message format, types, scopes, breaking changes, examples.references/branch-naming.md — naming conventions and branching models.scripts/git-recover.sh — list recently dangling/unreachable commits with previews to aid recovery.scripts/rebase-safety-check.sh — sanity-check history after a rebase against the upstream base.examples/squash-feature-branch.md — end-to-end worked example of cleaning a messy branch.Other measured skills in the registry, with their headline benchmark lift.