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
.claude/skills/jayrha-git-workflow/SKILL.md| 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.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 16,574 | 18,133 | +9% | 1 | 1 | 0% | 1,927 | 3,771 | +96% | 0 | 0 | — |
case-02 | pass→pass | 9,471 | 7,683 | -19% | 1 | 1 | 0% | 1,915 | 3,457 | +81% | 0 | 0 | — |
case-03 | pass→pass | 9,254 | 7,694 | -17% | 1 | 1 | 0% | 1,833 | 3,643 | +99% | 0 | 0 | — |
case-04 | pass→pass | 8,635 | 8,101 | -6% | 1 | 1 | 0% | 1,649 | 3,672 | +123% | 0 | 0 | — |
case-05 | pass→pass | 6,561 | 4,876 | -26% | 1 | 1 | 0% | 1,297 | 3,035 | +134% | 0 | 0 | — |
case-06 | pass→pass | 8,101 | 4,175 | -48% | 1 | 1 | 0% | 1,496 | 2,899 | +94% | 0 | 0 | — |
case-07 | pass→pass | 9,743 | 6,646 | -32% | 1 | 1 | 0% | 1,633 | 3,314 | +103% | 0 | 0 | — |
case-08 | pass→pass | 3,722 | 2,602 | -30% | 1 | 1 | 0% | 798 | 2,535 | +218% | 0 | 0 | — |
case-09 | fail→pass | 9,504 | 6,570 | -31% | 1 | 1 | 0% | 1,687 | 3,200 | +90% | 0 | 0 | — |
case-10 | pass→pass | 15,620 | 3,966 | -75% | 1 | 1 | 0% | 1,500 | 2,841 | +89% | 0 | 0 | — |
case-11 | pass→pass | 7,776 | 5,232 | -33% | 1 | 1 | 0% | 1,376 | 3,032 | +120% | 0 | 0 | — |
case-12 | pass→pass | 9,330 | 5,972 | -36% | 1 | 1 | 0% | 1,731 | 3,055 | +76% | 0 | 0 | — |
case-13 | pass→pass | 3,863 | 5,703 | +48% | 1 | 1 | 0% | 696 | 2,510 | +261% | 0 | 0 | — |
case-14 | pass→pass | 8,294 | 5,468 | -34% | 1 | 1 | 0% | 1,518 | 3,076 | +103% | 0 | 0 | — |
case-15 | pass→pass | 8,279 | 5,389 | -35% | 1 | 1 | 0% | 1,500 | 3,067 | +104% | 0 | 0 | — |
case-16 | pass→pass | 3,116 | 2,239 | -28% | 1 | 1 | 0% | 539 | 2,412 | +347% | 0 | 0 | — |
case-17 | pass→pass | 3,313 | 6,322 | +91% | 1 | 1 | 0% | 627 | 2,861 | +356% | 0 | 0 | — |
case-18 | pass→pass | 5,796 | 5,301 | -9% | 1 | 1 | 0% | 1,143 | 3,024 | +165% | 0 | 0 | — |
case-19 | pass→pass | 7,754 | 5,719 | -26% | 1 | 1 | 0% | 1,413 | 3,269 | +131% | 0 | 0 | — |
case-20 | pass→pass | 7,050 | 4,471 | -37% | 1 | 1 | 0% | 1,344 | 2,743 | +104% | 0 | 0 | — |
case-21 | pass→pass | 3,990 | 3,458 | -13% | 1 | 1 | 0% | 773 | 2,699 | +249% | 0 | 0 | — |
case-22 | pass→pass | 3,040 | 2,210 | -27% | 1 | 1 | 0% | 511 | 2,443 | +378% | 0 | 0 | — |
case-23 | fail→pass | 6,912 | 24,192 | +250% | 1 | 1 | 0% | 1,319 | 3,140 | +138% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/3/2026 | +5% |
Other measured skills in the registry, with their headline benchmark lift.