# Git

> Git rules for modern frontend - trunk-based branching, conventional commits, PRs, stacked PRs, hooks, merge policy, debugging, versioning, permission matrix for agents

- Skill: `14bryanespinoza/git` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 14bryanespinoza/git`
- Raw SKILL.md: https://api.skillmd.com/api/skills/14bryanespinoza/git/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: 14BryanEspinoza (https://skillmd.com/u/14bryanespinoza)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/14bryanespinoza/git

---


# Git — Rules and Conventions

---

## 1. Philosophy

1. **Atomic commits** — One commit = one logical change. Small, descriptive, reviewable. Stage selectively, never `git add .` blindly.
2. **Clean history** — `main` stays linear and deployable: every PR lands as one squash commit. No merge bubbles, no WIP commits, no empty messages.
3. **Ephemeral branches** — Feature branches are short-lived, derived from `main`, deleted after merge. `main` is the only permanent branch.
4. **Trunk-based development** — `main` is always stable and deployable. Every change reaches `main` through a PR with code review. Never push directly to `main`.
5. **Conventional Commits** — Mandatory standard for messages. Enables changelog generation, semantic versioning, automated releases.

---

## 2. Minimum Versions

| Technology | Minimum Version |
| ---------- | --------------- |
| Git        | 2.43+           |
| GitHub CLI | 2.40+           |

---

## 3. Branching Strategy (Trunk-Based)

**One permanent branch: `main`.** Everything else is ephemeral and merges into `main` via PR.

| Branch           | Base   | Merge into  | Lifetime  | Purpose                        |
| ---------------- | ------ | ----------- | --------- | ------------------------------ |
| `main`           | —      | —           | permanent | Stable, always deployable      |
| `feature/<name>` | `main` | `main` (PR) | short     | New feature                    |
| `fix/<name>`     | `main` | `main` (PR) | short     | Bug fix                        |
| `chore/<name>`   | `main` | `main` (PR) | short     | Tooling, CI, dependencies      |
| `docs/<name>`    | `main` | `main` (PR) | short     | Documentation                  |
| `epic/<name>`    | `main` | `main` (PR) | long      | Tracker branch for stacked PRs |

> **No `develop`, `release/*`, or `hotfix/*` branches.** A hotfix is a `fix/<name>` branch from `main` with priority. A release is a tag + GitHub Release from `main`, not a branch.

### Naming Convention

```text
feature/<issue-id>-<short-description>
fix/<issue-id>-<short-description>
chore/<issue-id>-<short-description>
docs/<issue-id>-<short-description>
epic/<short-description>
```

### Examples

```text
feature/42-add-user-auth
fix/53-fix-login-redirect
chore/58-bump-dependencies
docs/12-update-readme
epic/billing-refactor
```

---

## 4. Commits

### Format (Conventional Commits)

```text
<type>(<optional scope>): <description>

<optional body>

<optional footer>
```

### Types

| Type       | Use                                               |
| ---------- | ------------------------------------------------- |
| `feat`     | New feature                                       |
| `fix`      | Bug fix                                           |
| `docs`     | Documentation                                     |
| `style`    | Formatting, linting, whitespace (no logic change) |
| `refactor` | Refactor without changing functionality           |
| `perf`     | Performance improvement                           |
| `test`     | New or updated tests                              |
| `build`    | Build system, dependencies, bundler config        |
| `ci`       | CI/CD configuration, scripts, workflow files      |
| `chore`    | Other maintenance (tooling, tasks)                |
| `revert`   | Revert a change                                   |

> Full spec is default. `build` and `ci` can map to `chore` if team prefers,
> but commit-msg hook must match.

### Breaking Changes

```text
feat(api)!: change user endpoint response format

BREAKING CHANGE: The /api/users endpoint now returns { data: [...] }
instead of the previous flat array format.
```

### Rules

- **Language**: English by default (matches orchestrator contract:
  generated technical artifacts are English). Spanish/other only when
  explicitly requested.
- Description: imperative present tense, no final period
- Body: explain **what** and **why**, not how
- Footer: reference issues (`Closes #42`, `Fixes #53`)
- Atomic: one logical change per commit; stage specific files
  (`git add <files>` or `git add -p`), never `git add .`
- No AI attribution: never add `Co-Authored-By` or AI-generated trailers

```text
# ❌ Bad
fix stuff
update
WIP
asdf

# ✅ Good
feat(auth): add login form validation
Closes #42
```

### Commit Signing (GPG or SSH)

```bash
# GPG
gpg --full-generate-key
git config --global user.signingkey <KEY_ID>
git config --global commit.gpgsign true
git commit -S -m "feat: add secure endpoint"

# SSH (simpler, reuses SSH key)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git commit -S -m "feat: add secure endpoint"
```

---

## 5. Pull Requests

### Title

Same format as commits:

```text
feat(auth): add login form validation
```

### Checklist before opening PR

- [ ] Branch rebased on `main` (not merged)
- [ ] Code follows project conventions
- [ ] Tests pass locally (`pnpm test`) — see `package-manager` skill
- [ ] Linter passes (`pnpm lint`) — see `linting` skill
- [ ] `git diff --check` reports no whitespace errors
- [ ] No `console.log` / `debugger`
- [ ] No commented-out code
- [ ] Documentation updated if applicable
- [ ] No merge conflicts with target branch

### Draft PRs

Open a draft PR (`gh pr create --draft`) for early feedback or WIP slices. Cannot be merged until marked ready.

---

## 6. Merge Policy

One clear policy — no ambiguity:

| Strategy            | Use                                                                                       |
| ------------------- | ----------------------------------------------------------------------------------------- |
| **Squash**          | **Default** for every PR into `main`: each PR = one commit. Keeps `main` linear.          |
| **Rebase**          | Local workflow: sync your branch with `main` before PR. Never rebase `main`.              |
| **Merge `--no-ff`** | Exception only, explicitly documented: very large PR whose commits have standalone value. |

### Synchronizing before PR (standard)

```bash
git switch feature/42-add-user-auth
git fetch origin
git rebase origin/main
# Resolve conflicts if any, then re-test before pushing
```

### Exception: merge commit (rare, documented)

```bash
git switch main
git merge --no-ff feature/42-add-user-auth
```

---

## 7. Workflow

### Feature

```bash
git switch main
git pull origin main
git switch -c feature/42-add-user-auth
# ... work in small, atomic commits ...
git add src/auth/login.ts src/auth/validation.ts
git commit -m "feat(auth): add login form validation"
git push
gh pr create --title "feat(auth): add login form validation" --body "Closes #42"
```

### Bug fix / hotfix (same flow, higher priority)

```bash
git switch main
git pull origin main
git switch -c fix/58-patch-security-vuln
git commit -m "fix: patch XSS vulnerability in search input"
git push
gh pr create --title "fix: patch XSS vulnerability in search input"
# After merge, tag a patch release if it must ship immediately (§10)
```

### Release (tag from main, no release branch)

```bash
git switch main
git pull origin main
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin v1.2.0
gh release create v1.2.0 --generate-notes
```

### Keep long-lived branch in sync

```bash
git fetch origin
git rebase origin/main
# If rewrites already-pushed commits:
git push --force-with-lease
```

---

## 8. Stacked / Chained PRs

Large changes must be split into reviewable slices. Pick one strategy per
delivery plan and state it explicitly.

### stacked-to-main

Each PR targets `main`; branches derive from each other. Merge bottom-up.

```bash
# Slice 1
git switch -c feature/42-auth-base main
# ... commits ...
git push
gh pr create --base main --head feature/42-auth-base

# Slice 2 (derived from slice 1)
git switch -c feature/42-auth-validation feature/42-auth-base
# ... commits ...
git push
gh pr create --base main --head feature/42-auth-validation
```

When base PR merges, rebase child on updated `main`:

```bash
git fetch origin
git switch feature/42-auth-validation
git rebase origin/main
git push --force-with-lease
```

### feature-branch-chain (tracker branch)

Tracker (`epic/<name>`) accumulates integration; PRs target previous
branch. Only tracker merges to `main`.

```bash
# Tracker
git switch -c epic/billing-refactor main
git push
gh pr create --base main --head epic/billing-refactor --draft

# PR #1 targets tracker
git switch -c feature/10-billing-model epic/billing-refactor
git push
gh pr create --base epic/billing-refactor --head feature/10-billing-model

# PR #2 targets previous PR branch
git switch -c feature/11-billing-api feature/10-billing-model
git push
gh pr create --base feature/10-billing-model --head feature/11-billing-api
```

### Rules for chained PRs

1. Merge bottom-up, always in dependency order.
2. After any parent merge/edit, rebase descendants and verify with
   `git range-diff` (§12).
3. Only `--force-with-lease`, never plain `--force`.
4. Review incremental diff (`gh pr diff` against PR base), not whole chain.
5. Delete branches after merge; for tracker chain, delete all children
   when tracker merges.

---

## 9. .gitignore

### Essential patterns (modern frontend)

```gitignore
# Dependencies
node_modules/

# Build output
dist/
build/
.next/
out/
.astro/
.vite/

# Caches
.cache/
.eslintcache
.parcel-cache/
.turbo/
.nx/

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Env (commit .env.example as template)
.env
.env.local
.env.*.local

# Logs
*.log
pnpm-debug.log*

# Testing (coverage only — snapshots ARE committed for PR review)
coverage/
.vitest/

# Platform folders
.vercel/
.netlify/

# Temp
*.tmp
*.temp
*.tsbuildinfo
```

> ⚠️ **Do NOT ignore snapshots** (`__snapshots__/`, `*.snap`). Jest/Vitest commit snapshots by default for PR review.
> **Secrets**: `.env*` patterns above are minimum. Add secret scanning — see `security` skill.

---

## 10. Tags and Semantic Versioning

### SemVer

```text
MAJOR.MINOR.PATCH
MAJOR: incompatible changes (breaking)
MINOR: new features (backward compatible)
PATCH: bug fixes (backward compatible)
```

### Create tags

```bash
# Annotated (recommended — includes metadata)
git tag -a v1.2.0 -m "Release v1.2.0"

# Signed
git tag -s v1.2.0 -m "Release v1.2.0"
```

### Publish tags

```bash
git push origin v1.2.0
git push origin --tags
```

---

## 11. Git Hooks

> Production path for frontend repos is **husky + lint-staged** (see `linting` skill). `commitlint` is the maintainable alternative to hand-rolled commit-msg hook.

### Husky + lint-staged (reference)

Husky manages git hooks without touching `.git/hooks` directly. lint-staged runs linters only on staged files. See `linting` skill for full setup.

### commitlint (recommended)

```bash
pnpm add -D @commitlint/cli @commitlint/config-conventional
echo "export default { extends: ['@commitlint/config-conventional'] }" > commitlint.config.js
# Wire into husky: echo "pnpm commitlint --edit \$1" > .husky/commit-msg
```

---

## 12. Daily Commands + Recovery

### Modern day-to-day

```bash
git switch main                    # instead of: git checkout main
git switch -c feature/x            # instead of: git checkout -b feature/x
git restore --staged file.ts       # unstage
git restore file.ts                # discard working-tree changes of one file
git diff --check                   # whitespace errors before committing
```

### Stash

```bash
git stash push -u -m "WIP: login form"  # -u includes untracked
git stash list
git stash pop
git stash apply stash@{2}
git stash drop stash@{2}
git stash branch feature/new-branch     # create branch from stash
```

### Cherry-pick

```bash
git cherry-pick abc1234               # apply specific commit
git cherry-pick abc1234 def5678       # multiple
git cherry-pick -n abc1234            # without committing
```

### Reflog (disaster recovery)

```bash
git reflog                            # HEAD movement history
git reflog show feature/42            # specific branch
git cherry-pick <hash>                # recover "lost" commit after reset
```

### Bisect (binary debugging)

```bash
git bisect start
git bisect bad                        # current is bad
git bisect good v1.0.0                # tag where it worked
# Test each step: git bisect bad / good
git bisect reset                      # exit

# Automated
git bisect start HEAD v1.0.0
git bisect run pnpm test
git bisect reset
```

### Incorporate review feedback

```bash
git commit --fixup <hash>
git rebase -i --autosquash <base>
```

### range-diff (verify rebases and force-pushes)

```bash
git range-diff origin/main...HEAD
git range-diff <sha-before>...<sha-after>  # after force-push
```

### Pickaxe (find when string introduced)

```bash
git log -S "functionName" --oneline -- src/
git blame src/auth/login.ts
```

### Worktrees (parallel branches)

```bash
git worktree add ../project-feature feature/42
git worktree list
git worktree remove ../project-feature
```

### Submodules (rare — prefer pnpm workspaces)

```bash
git submodule add https://github.com/user/lib.git libs/shared
git clone --recurse-submodules <url>
git submodule update --init --recursive
```

### Git LFS (rare)

```bash
git lfs install
git lfs track "*.psd" "*.zip" "*.mp4"
git lfs ls-files
```

---

## 13. GitHub CLI

### Essential commands

```bash
gh auth login
gh pr create --title "feat(auth): add login" --body "Closes #42"
gh pr create --draft --title "feat(auth): add login" --body "WIP"
gh pr create --base epic/xxx --head feature/yyy  # stacked PRs
gh pr list
gh pr checkout 42
gh pr view 42
gh pr diff 42
gh pr checks 42 --watch
gh pr merge 42 --squash
```

> ⚠️ `gh pr merge`, `gh pr close`, `gh pr review --approve` require explicit user authorization. Never run without confirmation.

---

## 14. Permission Matrix and User Authorization

### Command categories (agent / orchestrator contract)

| Category            | Commands                                                                                                                                 | Authorization                           |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| **Read-only**       | `status`, `diff`, `log`, `show`, `fetch`, `branch -l`, `tag -l`, `remote -v`, `worktree list`, `reflog`, `blame`, `log -S`, `range-diff` | ✅ Always allowed                       |
| **Local prep**      | `switch`, `switch -c`, `restore` (single file), selective `add`, `diff --cached`                                                         | ✅ Allowed within delegated task scope  |
| **Local history**   | `commit`, `rebase`, `amend`, `reset`, `merge`, `cherry-pick`, `revert`, `stash`, `clean`, `restore .`                                    | ⚠️ Requires explicit authorization      |
| **Remote-mutating** | `push`, `push --force*`, `push --delete`, tag push, `gh pr merge`, `gh pr close`, `gh pr review --approve`, `gh release`                 | ⚠️ Requires explicit user authorization |

### Workflow (step by step)

```text
1. Explain the plan
   → "I will commit changes to skills/git/SKILL.md and skills/package-manager/SKILL.md"
   → "Message: feat: modernize git and package-manager skills to v2.0"

2. Show evidence
   → "Files changed: skills/git/SKILL.md, skills/package-manager/SKILL.md"
   → Show exact command to execute

3. Ask for confirmation
   → "Should I run: git add skills/git/SKILL.md skills/package-manager/SKILL.md && git commit -m 'feat: modernize git and package-manager skills to v2.0'?"

4. Only then execute
   → If user confirms, execute
   → If not, stop and wait
```

### Rules Git

1. **Never** run `git add`, `git commit`, `git push` without user permission.
2. **Never** merge, close, or approve a PR without explicit user permission.
3. **Always** show exact command before asking.
4. **Always** wait for explicit yes/no.
5. **Never** assume consent from silence.
6. **Never** chain commands without permission.
7. Agent/subagent approval ≠ authorization — only human user authorizes.

---

## 15. Prohibitions

- ❌ NEVER commit or push directly to `main`
- ❌ NEVER use `git push --force` on shared branches (use `--force-with-lease`)
- ❌ No giant commits (+200 lines without justification)
- ❌ No empty/meaningless commit messages
- ❌ NEVER merge a PR without explicit user authorization
- ❌ NEVER close a PR without explicit user authorization
- ❌ NEVER self-approve a PR without explicit user authorization
- ❌ No `WIP` or `fix` in final commits
- ❌ Do not ignore `.gitignore` (no node_modules, .env, dist/)
- ❌ Do not use `git commit --no-verify` except justified emergency
- ❌ Do not push `.env` or secrets
- ❌ Do not rebase/force-push branches shared with other developers
- ❌ Do not delete tags without team consensus

---

## 16. Methodology

Before using ANY Git command/config/pattern not documented in this skill:

1. **MCP Context7** (priority): `context7_resolve-library-id` +
   `context7_query-docs` for the specific tool.
2. **Official docs**: git-scm.com — verify current behavior + options.
3. **Project config**: `.git/config`, `.github/workflows/`
   — verify against actual setup.
4. **HARD RULE**: If not in this skill AND cannot be verified against
   2 authoritative sources → DO NOT USE IT. Document as assumption or risk in
   report to orchestrator.

---

## 17. References

> **Note:** For husky + lint-staged and commitlint wiring, see [Linting](../linting/SKILL.md)
> **Note:** For CI/CD workflow templates, see [Deploy](../deploy/SKILL.md)
> **Note:** For package manager conventions, see [Package Manager](../package-manager/SKILL.md)
> **Note:** For secret scanning, see [Security](../security/SKILL.md)

---

Last updated: 2026-08

