# Git Commit

> Use this skill whenever the user wants to commit, push, or ship changes in a git repository. This skill is intended to run with the developer's configured default Haiku model. Triggers include: "commit changes", "push my changes", "ship it", "commit and push", "create a branch and commit", "make a PR", "open a pull request", "create draft PR", or any variation of committing/pushing work. Always use this skill when the user mentions committing — even casually — as it handles the full cycle: branch → add → commit → push → (optionally) PR, with Conventional Commits format and automatic area detection.

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

---


# Git Commit Skill

Full cycle: checkout new branch from `development` → stage → commit (Conventional Commits) → push → optional PR.

---

## Step 0 — Detect mode (new branch vs. update existing)

First figure out which mode you're in. This decides whether you create a branch/PR or just push to what already exists.

```bash
git rev-parse --abbrev-ref HEAD          # current branch
gh pr view --json number,url,state 2>/dev/null   # open PR for current branch (if any)
```

- **New-branch mode** — current branch is `development` (or another base branch), or there's no PR for it.
  Run the full cycle: Steps 1–6 as written (create branch → commit → push → optional PR).
- **Update-existing mode** — you're already on a feature branch **and** it has an open PR (or the user
  says "push to the existing PR" / "update my PR"). **Do not** create a new branch and **do not** run
  `gh pr create`. Stay on the current branch, then:
  1. Step 2 — review the changes.
  2. Step 4 — generate the commit message (reuse the existing PR's ticket; keep the same `area`/type style).
  3. Step 5 — **skip the `git checkout` lines**; just `git add` → `git commit` → `git push` to the current branch.
  4. Skip Step 6's `gh pr create`. Pushing updates the open PR automatically. Only refresh the PR body
     (`gh pr edit --body`) if the user asks or the description is now stale/missing.
  5. Step 7 — report the existing PR link, not a new one.

---

## Step 1 — Gather required context

Before doing anything, ensure you have:

- **Ticket number** — use the `ticket` argument if passed. Else look in conversation context (e.g. from
  OpenSpec explore, recent messages). If still not found, ask: _"What is the ticket number?"_
- **Area** — if the `area` argument is passed, use it directly in Step 3 (skip detection).
- **Draft PR?** — if the user said "draft" or "draft PR", note it for Step 5.

> This skill runs in a forked context (`context: fork`), so it does **not** see the main conversation.
> Prefer passing `ticket` (and optionally `area`) as arguments: `/git-commit 3642 Deployments/Images`.

---

## Step 2 — Understand the changes

```bash
git status
git diff HEAD
```

If there are no changes at all — report and stop.

---

## Step 3 — Determine `area`

Resolve the `area` with this 3-tier fallback (project-agnostic — works in any repo):

1. **`area` argument given** → use it verbatim. Done.
2. **Project defines an area taxonomy** → if `.claude/reference/areas.md` exists, read it and map the changed
   files to an area using the rules in that file (`Parent/Child` for one leaf, `Parent` for several
   under one parent, most-changed parent across many, technical area for infra/config).
3. **Neither** → infer a sensible area from the **top-level directory** of the changed files
   (e.g. most changes under `src/auth/**` → `auth`). For pure tooling/config with no feature home, use a
   technical area: `infra`, `config`, `api`.

### Step 3a — Self-extend `.claude/reference/areas.md` (only if the file exists)

If the resolved area is **not already listed** in `.claude/reference/areas.md`, append it so the taxonomy grows
over time. Do this for both a new arg-supplied area and a tier-3 inferred area.

Rules — be conservative, append-only, never rewrite or reorder existing rows:

1. **Confirm it's new** — `grep -F "<area>" .claude/reference/areas.md`. If the exact area string is already
   present, skip; do nothing.
2. **Pick the right section:**
   - New leaf under an existing parent (e.g. `Deployments/Foo`) → add a row to that parent's table.
   - New top-level feature with a route/component but no parent → add a row under
     **Cross-cutting feature areas**.
   - New non-UI concern → add a row under **Technical areas** with a short "Covers" note.
3. **Fill the evidence columns** from the actual change — the route slug (`app/[lang]/<slug>`) and/or
   the component folder (`src/components/<Folder>`) the change touched. Leave a cell as `—` only if it
   genuinely has none.
4. **Only one new row per run**, matching the single resolved area. Don't bulk-invent areas.
5. The edit is staged by `git add` in Step 5, so the taxonomy update ships **in the same commit** as the
   change that introduced it. Mention the added area in the Step 7 summary.

If `.claude/reference/areas.md` does **not** exist, skip 3a entirely (don't create it — that's a deliberate
project-setup choice, not something this skill bootstraps).

---

## Step 4 — Generate commit message

Format:
```
<type>(<area>): <short description> (Issue #<ticket>)
```

**Type selection** — pick the most accurate:

| Type | When to use |
|------|-------------|
| `feat` | New feature or capability |
| `fix` | Bug fix |
| `chore` | Maintenance, deps, config, tooling |
| `refactor` | Restructuring without behavior change |
| `docs` | Documentation only |
| `test` | Tests only |
| `style` | Formatting, no logic change |

**Message rules:**
- Analyze the diff to understand *what* changed and *why*
- Keep the description concise and imperative (add, fix, update, remove, extract...)
- If ticket context is available (e.g. from OpenSpec), use it to improve accuracy

**Branch name** is derived from the commit message slug:
`feat/<short-slug>` — lowercase, hyphens only, no ticket number.

Example:
- Commit: `feat(Deployments/Images): add image version selector (Issue #42)`
- Branch: `feat/add-image-version-selector`

---

## Step 5 — Execute

```bash
# 1. Create branch from development
git checkout development
git checkout -b feat/<short-slug>

# 2. Stage all changes
git add .

# 3. Commit
git commit -m "<type>(<area>): <description> (Issue #<ticket>)"

# 4. Push
git push origin feat/<short-slug>
```

If push fails for any reason (no permissions, rejected, conflict) — **report the error with the full output and stop**. Do not attempt force push or rebase automatically.

---

## Step 6 — Pull Request (if requested)

If the user requested a PR or draft PR **Always follow that template** — fill every placeholder,
never leave `<SHORT_DESCRIPTION>` or `<TICKET_ID>` unreplaced.

```markdown
**Description:**

<2-4 sentences: what changed and why. Use the diff + ticket context. Explain the *why*, not just the *what*.>

Issues:

- Issue #<ticket>

**Key Changes:**

- [path/to/file.tsx](<github-file-link>) — short description
- [path/to/file.tsx](<github-file-link>) — short description

**New Components:**

<List of newly created React components or reusable modules with a one-line description each.>
<Omit this section entirely if no new components were added.>

**Breaking Changes:**

<Describe any breaking changes to APIs, props, or component interfaces.>
<Omit this section entirely if there are no breaking changes.>


**Checklist:**

- [x] the pull request name complies with [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
- [x] the pull request name ends with `(Issue #<ticket>)` (comma-separated list of issues)
```

Rules for filling the template:
- **Description**: required — always write a real summary, even for small chores. Explain the *why*,
  not just the *what*; use ticket title/description for context.
- **Issues**: one `- Issue #<ticket>` line per ticket. If there is genuinely no ticket, **remove the
  whole `Issues:` block** and leave the second checklist item **unchecked** (`[ ]`), since the title
  can't end with `(Issue #…)`.
- **Summary**: explain the *why*, not just the *what*; use ticket description for context.
- **Key Changes**: most impactful files only (max ~10); skip trivial files like formatting-only changes.
- **New Components**: newly created React components or shared modules only. Omit the section if none.
- **Breaking Changes**: only if interfaces, props, or contracts changed non-backward-compatibly;
  otherwise omit the section.
- **Checklist**: tick `[x]` the boxes this skill actually satisfies — the title is Conventional Commits
  (always checked) and ends with `(Issue #<ticket>)` (checked only when a ticket exists).

Then create the PR:

```bash
# Regular PR
gh pr create \
  --base development \
  --head feat/<short-slug> \
  --title "<type>(<area>): <description> (Issue #<ticket>)" \
  --body "<generated body>"

# Draft PR (if user said "draft")
gh pr create \
  --base development \
  --head feat/<short-slug> \
  --title "<type>(<area>): <description> (Issue #<ticket>)" \
  --body "<generated body>" \
  --draft
```

If `gh` CLI is not available — provide the GitHub compare URL for manual PR creation:
```
https://github.com/<org>/<repo>/compare/development...feat/<short-slug>
```

---

## Step 7 — Summary

Finish with a concise confirmation:

```
Branch:  feat/<short-slug>
Commit:  <type>(<area>): <description> (Issue #<ticket>)
Push:    ✅ succeeded  /  ❌ failed — <reason>
PR:      <link> (created)  /  <link> (updated existing)  /  skipped
```

