Files
JuliaFEM.jl/.github/prompts/commit.prompt.md
T
Jukka Aho 0182fc7566 docs(git): add tracked AI commit workflow prompt
Introduce `.github/prompts/commit.prompt.md` as the contributor-facing description
of how assistants should stage, review, propose, and record commits.

- Document defaults: one file per commit, rare justified pairs, no blanket `git add`.
- Describe optional `.githooks/pre-commit` cap at two staged paths.
- Require reading the full `git diff --staged` (no truncation) before messaging.
- Spell out approval-before-commit flow and Conventional Commits subject lines.
- Scale the body to the patch: short summaries for small edits; large or
  multi-concern diffs need grouped, substantive bullets so history stays readable.
- Keep checklist items aligned with that depth expectation.
2026-05-09 16:44:31 +03:00

176 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Git Commit Workflow for AI Assistants
## Goals
- Git history should read as a **story**: small steps, one clear intent per commit.
- **Default:** one file per commit (smallest practical unit).
- **Exception:** several files in **one** commit only when they share the **same logical entity / same story** (incomplete or misleading if split). This should be **unusual**—always prefer smaller commits when in doubt.
## When to combine files (exception)
Combine only when splitting would:
- leave the tree broken or the feature half-wired, or
- tell an incoherent story (e.g. rename without updating the only call site).
**Always** state **why** those paths belong together in one commit when proposing a multi-file commit.
## User initiation
```
❌ AI: "Should I commit these files?"
❌ AI: "Let me commit this..."
✅ Human: "Commit the changed files"
✅ Human: "Do the commits now"
```
**Rule:** Do not suggest or initiate commits. Only run this workflow after an explicit user command.
## Staging
```bash
git add path/to/file.jl
# or, only when justified:
git add path/a.jl path/b.jl
```
- Avoid `git add .` and `git add -A` unless the user explicitly wants everything (still read the full staged diff after).
- Never stage unrelated changes into the same commit.
## Optional git hook (max two staged paths)
The repo ships `.githooks/pre-commit`. After `git config core.hooksPath .githooks`, commits with **more than two** staged files are rejected. This supports the common “impl + test” or “snippet + verifier” pair without allowing large batches. Split bigger changes across commits or adjust the hook deliberately.
## Read the full staged diff
```bash
git diff --staged
```
**Critical:**
- Do not pipe through `head`, `tail`, `less`, or otherwise truncate.
- Read every line; the commit message must reflect the actual diff.
**Exception:** machine-generated or binary files—review only as far as is practical.
## Approval before `git commit`
**Before** running `git commit`, present to the user:
1. **File(s)** to be committed (exact paths).
2. **Full proposed commit message** (subject + body in the format below).
3. If **more than one file:** a **short justification** why one commit is appropriate.
**Wait** for explicit approval. Only then:
```bash
git commit -F- <<'EOF'
<paste full message>
EOF
```
(or equivalent multi-line `-m` usage). Do not commit silently.
## Commit message structure
**1. Subject line (first line)** — Conventional Commits:
`type(scope): specific description from the diff`
- Types include `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, etc.
- `scope` is optional but recommended when it clarifies the area.
- Imperative mood; specific; no vague "update" / "fix things".
**2. Blank line**
**3. Summary** — one short paragraph, **one to three sentences**: what changed and why, for this commit only.
**4. Body detail (scale with the diff)** — after the summary:
- **Small / localized change:** optional bullets only when they add real value; often the summary is enough.
- **Large file, large diff, or several concerns in one commit:** expand with **substantive bullets**. Prefer **grouped sections** (short headings or bullet groups) that mirror the patch: major types/functions added, behavior changes, wiring/exports, migrations, risks, or follow-ups. A few vague bullets are not sufficient when the diff is hundreds of lines or touches multiple subsystems—the message should let a reviewer reconstruct *why* the patch looks the way it does without re-reading every hunk.
Use `-` bullet lists; omit sections that do not apply.
### Example (single file)
```
refactor(basis): Replace per-element lagrange includes with generator entrypoints
The basis tree previously listed seven separate lagrange_*.jl includes; they are
folded behind lagrange_generator.jl and lagrange_generated.jl so new elements
register in one place.
- Drop redundant includes from JuliaFEM.jl
- Document the 'Basis' suffix convention in the include comment
```
### Example (multi-file — requires justification to user)
When proposing:
> **Files:** `src/foo.jl`, `test/foo/test_foo.jl`
> **Why one commit:** adds `compute_bar` and the regression test that locks its behavior; splitting would leave the feature untested in history.
> **Message:** …
## Cycle per commit
1. Stage the smallest set (usually one file).
2. `git diff --staged` — read all of it.
3. Propose message + paths (+ multi-file justification if needed).
4. Wait for approval.
5. Commit.
6. Repeat for remaining work.
## Common mistakes
### Vague or mismatched messages
```bash
# ❌ WRONG
git commit -m "Update documentation"
# ✅ RIGHT — subject + summary (+ bullets if needed), from the real diff
```
### Bundling unrelated files
```bash
# ❌ WRONG — two different stories
git add docs/CONTRIBUTING.md src/unrelated_fix.jl
# ✅ RIGHT — two commits, or ask user to split worktrees if mixed in one working tree
```
### Committing without approval
Never run `git commit` until the user has approved the proposed paths and message.
### Truncating the diff
Never use `git diff --staged | head` (etc.). Read the full diff.
## Checklist before each commit
- [ ] Did the user explicitly ask to commit?
- [ ] Is the staged set as **small** as it reasonably can be?
- [ ] If multiple files: is there a **clear single story**, and will you **justify** it to the user?
- [ ] If `.githooks` is active: are there **at most two** staged paths?
- [ ] Did I read the **full** `git diff --staged`?
- [ ] Subject line: Conventional Commits, specific, matches diff?
- [ ] Body: blank line, then **13 sentence** summary, then **bullets scaled to diff size** (rich, grouped bullets for large / multi-concern commits)?
- [ ] Did I **propose** the commit and wait for **approval** before `git commit`?
## Why this matters
1. **Story:** History is easy to read and bisect.
2. **Review:** Each commit is reviewable in isolation.
3. **Honesty:** Messages match what the diff actually does.
4. **Control:** The author approves each step.
---
Git history is long-lived. Prefer small, well-explained commits and explicit approval before each `git commit`.