Git operations guidance including branching strategies, commit conventions, merge workflows, conflict resolution, and worktree management.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add cosmix/loom --skill loom-git-workflow --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Loom Git Workflow?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/cosmix-loom-git-workflow)More formats (shields.io, HTML) on the badges page.
---
name: loom-git-workflow
description: Git operations guidance including branching strategies, commit conventions, merge workflows, conflict resolution, and worktree management.
allowed-tools:
- Read
- Grep
- Glob
- Bash
triggers:
- git
- branch
- commit
- merge
- rebase
- pull request
- PR
- cherry-pick
- stash
- reset
- revert
- checkout
- switch
- worktree
- conflict
- GitFlow
- trunk-based
- feature branch
- release branch
- version control
- squash
- amend
- history
- tag
- remote
- push
- pull
- fetch
- clone
- rerere
- reflog
- bisect
---
# Git Workflow
## Overview
Git operations with an eye to a clean, bisectable history and safe collaboration. Canonical home for **commit hygiene and conventional commits** (referenced by `/loom-code-review` and `/loom-refactoring`).
## The golden rule
**Never rewrite history that others have based work on.** `rebase`, `commit --amend`, `reset --hard`, and `push --force` on a shared/public branch orphan collaborators' commits and force painful recovery. Rewrite freely on your *own* un-pushed / unshared branch; treat anything pushed to a shared branch as immutable.
- Force-push only your own feature branch, and prefer `--force-with-lease` (aborts if someone else pushed since your last fetch) over `--force`.
- Never force-push `main`/`master`/`release/*` — protect them server-side.
## Commit hygiene (conventional commits)
Format: `type(scope): description` — `feat`, `fix`, `docs`, `refactor`, `test`, `chore` (+ `perf`, `build`, `ci`, `style`). `!` or a `BREAKING CHANGE:` footer marks an incompatible change.
- **Atomic:** one logical change per commit. It should build and pass tests on its own — a green history is a bisectable history.
- **Separate refactor from behavior change** (see `/loom-refactoring`): a `refactor:` commit is a runtime no-op; a `fix:` commit changes behavior. Mixing them hides the fix from reviewers and poisons `git bisect`.
- **Message = what + why, not how.** The diff shows how. Body explains motivation, tradeoffs, and links issues.
- **Group by concern:** 5 files across 3 concerns → 3 commits (module / its tests / wiring), not 1 monolith or 5 fragments.
```bash
git commit -m "fix(cart): resolve race in quantity update
Rapid add/remove let the count go negative via unsynchronized state.
Guard with an atomic compare-and-swap.
Fixes #234"
```
⚠ Loom stages: never `git add -A` / `git add .` — that stages the `.loom/work/` symlink (or the legacy `.work/` symlink). Stage specific files only.
## Rebase vs. merge — pick deliberately
| Situation | Use | Why |
| -------------------------------------------------- | -------------------------------- | ---------------------------------------------------------- |
| Update your local feature branch with `main` | `rebase` | Linear history; your commits replay on top, no merge noise |
| Integrate a reviewed feature into `main` | `merge` (often `--no-ff`) | Preserves the branch as a reviewable unit; never rewrites shared history |
| Branch already pushed & others pulled it | `merge` (NOT rebase) | Golden rule — rebasing rewrites shared commits |
| Clean up messy local WIP commits before a PR | `rebase -i` (before pushing) | Squash/reorder/reword while still private |
| Long-lived branch, want to record integration points | `merge` | Merge commits document when integration happened |
Rule of thumb: **rebase to keep *your private* branch current; merge to *share*.** Rebasing public branches is the most common way teams lose work.
### Interactive rebase hygiene
`git rebase -i origin/main` — `pick`/`reword`/`squash`/`fixup`/`edit`/`drop`. Squash WIP noise, keep meaningful commits distinct (don't collapse a real feature into one opaque blob — you lose bisect granularity). `git commit --fixup=<sha>` + `git rebase -i --autosquash` targets fixups automatically. Abort anytime with `git rebase --abort`.
## Conflict resolution
```bash
git merge feature/new-api # CONFLICT in src/api.rs
git status # list conflicted files
git diff src/api.rs # see both sides in context (<<<<<<< ======= >>>>>>>)
# resolve by understanding BOTH intents — not blindly picking a side:
git checkout --ours path # keep current-branch version wholesale
git checkout --theirs path # take incoming version wholesale
git add src/api.rs # mark resolved
cargo test # ALWAYS re-test: a clean textual merge can be a semantic conflict
git merge --continue
git merge --abort # bail out if it's the wrong approach
```
- ⚠ **A conflict-free merge is not a correct merge.** Two branches editing different lines can still break each other's assumptions. Run tests after every resolution.
- Document non-obvious resolutions in the merge commit body.
- ⚠ `--ours`/`--theirs` mean *opposite things* under `rebase` vs `merge` (during rebase, "ours" is the branch you're rebasing *onto*). Check which operation you're in.
### `git rerere` — resolve once, reuse forever
`git config --global rerere.enabled true`. Git records how you resolved a conflict and **replays the same resolution automatically** next time the identical conflict appears — invaluable for long-lived branches repeatedly rebased/merged, and for loom's progressive merges where the same worktree conflict can recur. Combine with periodic `git rerere diff` to sanity-check recorded resolutions.
## Worktrees
Multiple working directories sharing one `.git` — parallel branches without stashing/switching. This is the mechanism loom uses for parallel stages.
```bash
git worktree list
git worktree add ../feat-auth feature/user-auth # new dir on a branch
git worktree add --detach ../test-v1.2 v1.2.0 # detached, for testing a tag
git worktree remove ../feat-auth # clean removal (must be clean, on another branch)
git worktree prune # after a dir was deleted by hand
# Loom: each stage runs in .worktrees/<stage-id>/ on branch loom/<stage-id>
ls .worktrees/
```
⚠ You cannot check out the same branch in two worktrees. ⚠ A `worktree remove` on a dirty tree fails — commit or discard first.
## Recovery (nothing is truly lost for ~90 days)
`git reflog` is the undo history for `HEAD` movements — the escape hatch for "I `reset --hard`'d / rebased / deleted a branch and lost commits."
```bash
git reflog # find the sha you were at before the mistake
git reset --hard HEAD@{2} # jump back to that state
git branch recovered <sha> # or resurrect a lost branch/commit
git cherry-pick <sha> # pull back a single lost commit
```
`reset` variants: `--soft` (keep changes staged) · `--mixed`/default (keep unstaged) · `--hard` (discard — the only destructive one). `git revert <sha>` undoes a commit *with a new commit* — the safe choice on shared history (no rewrite).
## Bisect (find the commit that introduced a bug)
```bash
git bisect start && git bisect bad && git bisect good v1.2.0
# git checks out the midpoint; test it, then:
git bisect good # or: git bisect bad
git bisect run ./test.sh # fully automated: script exits 0=good, non-0=bad
git bisect reset
```
Bisect is only reliable if history is bisectable — every commit builds/tests. See `/loom-debugging` for using bisect within a root-cause investigation.
## Gotchas
- ⚠ `reset --hard` and `checkout -- <file>` discard uncommitted work with **no reflog entry** — it's gone. `git stash` first if unsure.
- ⚠ `git clean -fd` deletes untracked files irreversibly; always `git clean -n` (dry run) first.
- ⚠ `pull` defaults to merge, creating noise commits on feature branches. `git pull --rebase` (or set `pull.rebase = true`) keeps them linear — but only on unshared branches.
- ⚠ `cherry-pick` duplicates a commit under a new sha; cherry-picking across branches you'll later merge causes "already applied" conflicts.
- ⚠ `commit --amend` rewrites the last commit — safe only if unpushed.
## Verify before done
- [ ] No history rewrite (`rebase`/`amend`/`force`) on a shared/public branch
- [ ] Force-push, if any, is `--force-with-lease` on your own branch only
- [ ] Commits atomic, conventional-format, refactor separated from behavior change
- [ ] Tests run after every conflict resolution (textual merge ≠ semantic correctness)
- [ ] Loom: staged specific files (never `git add -A`/`.`); stayed within the worktree
- [ ] `rerere` enabled for repeated/long-lived merge work
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!