# Hodios paste pack: Git and version control

Everything in Git and version control from Hodios, the open prompt library by Hermes IDE: 9 entries, catalog 2026.1003.0.

Every entry is dedicated to the public domain under CC0 1.0. Copy, change and share them freely, no attribution needed.

Browse and search the library at https://hermes-ide.com/prompts

## How to use

Find an entry below and copy the text inside its block into ChatGPT, claude.ai or any chat. Replace each [PLACEHOLDER] with your own material. Personas, rules and styles work best as custom instructions or project instructions.

## Contents

- Git and version control
  - [Choose a branching strategy](#choose-branching-strategy) (prompt)
  - [Clean up a branch's commit history](#clean-up-commit-history) (prompt)
  - [Conventional Commits rules](#conventional-commits-rules) (rule)
  - [Purge a file from git history](#purge-file-from-git-history) (prompt)
  - [Recover lost Git work](#recover-lost-git-work) (prompt)
  - [Resolve a merge conflict](#resolve-merge-conflict) (prompt)
  - [Split a large pull request into a stack](#split-large-pull-request) (prompt)
  - [Write a commit message](#write-commit-message) (prompt)
  - [Write a pull request description](#write-pr-description) (prompt)

---

<a id="choose-branching-strategy"></a>

## Choose a branching strategy

`choose-branching-strategy` · prompt · Git and version control · https://hermes-ide.com/prompts/choose-branching-strategy

Recommends a branching and release strategy such as trunk-based, GitHub flow or release branches for a team's size, cadence and environments, with rules, protections and migration steps.

````markdown
<context>
A branching strategy is a delivery decision disguised as a git decision. Long-lived branches feel safe but delay integration, so merges get bigger, conflicts get worse and releases get riskier; research on delivery performance (the DORA programme) consistently associates trunk-based development with better outcomes. But trunk-based development only works with fast CI, small changes and a way to hide unfinished work. Teams shipping to app stores, supporting several released versions, or under formal change control genuinely need release branches. The right strategy is the simplest one the team's release model and engineering practices can support today, with a path to simpler.
</context>

<task>
Recommend a branching and release strategy for this team.

<team>
[TEAM]
</team>

Release cadence: [RELEASE_CADENCE]

1. Identify the deciding factors: how often and how code reaches production, whether more than one released version must be maintained, whether releases need a stabilisation period, the team's CI speed and test confidence, use of feature flags, and regulatory or approval steps. If a deciding factor is missing, state your assumption.
2. Compare the candidates that fit: trunk-based development (short-lived branches or direct commits, merged at least daily), GitHub flow (feature branches merged to an always-deployable main), trunk plus release branches cut for each release, and Git Flow (develop, release and hotfix branches). Recommend one and say in one line each why the others lose for this team. Recommend Git Flow only when several released versions must be supported in parallel and nothing simpler works.
3. Write the branch rules: branch types and naming, maximum branch lifetime, where branches start and merge, merge method (squash, rebase or merge commit) and why, how unfinished work is hidden (feature flags, branch by abstraction, dark launches), and how environments map to branches or, preferably, to build artifacts promoted between environments.
4. Write the release and hotfix flow step by step: how a release is cut and versioned, how it is tagged, how fixes reach a release branch (fix on main first, then cherry-pick), and how a hotfix goes to production and back to main without regressing.
5. List protections and automation for the code host: required reviews and status checks on main and release branches, linear history if chosen, who may push or force-push, CODEOWNERS, automatic deletion of merged branches, merge queues for busy repos, and release tagging and changelog automation.
6. Write migration steps from the current way of working, in order, with a checkpoint for each: what to change first, how to drain or merge existing long-lived branches, and the practices (CI speed, flags, PR size) that must be in place before shortening branch lifetimes further.
7. Say what would make the team revisit the choice (for example adding a mobile app, a second supported version, or CI getting slower than a set time).
</task>

<constraints>
- Fit the recommendation to the stated release model. Do not recommend continuous trunk deploys for a product released through an app store review without explaining how releases are cut.
- Do not prescribe practices the team cannot support yet; put them in the migration steps as prerequisites.
- Commands and settings must be specific to the code host if one was named, and generic otherwise.
- Separate what you verified from what you inferred. Mark inferences as such.
- When you do not know, say "I don't know" once and state what would settle it.
</constraints>

<output_format>
## Recommendation
The strategy and the three main reasons, in at most 5 lines, plus a Mermaid gitGraph showing a typical feature, release and hotfix.
## Why not the alternatives
One line per alternative.
## Branch rules
Table: branch type, naming, created from, merged into, lifetime, merge method.
## Release and hotfix flow
Numbered steps for each.
## Protections and automation
Checklist per protected branch.
## Migration steps
Numbered, each with its checkpoint.
## When to revisit
Bullets.
</output_format>
````

---

<a id="clean-up-commit-history"></a>

## Clean up a branch's commit history

`clean-up-commit-history` · prompt · Git and version control · https://hermes-ide.com/prompts/clean-up-commit-history

Plans an interactive rebase that turns a messy branch into logical, reviewable commits, with a backup, the exact todo list and a check that the code is unchanged. Use before merging a WIP branch.

````markdown
<context>
Reviewers read history commit by commit, and `git bisect` and `git revert` work on commits, so each commit should be one logical change that builds on its own. Work-in-progress history ("wip", "fix typo", "address review") is normal while working and should be reshaped before merge. Interactive rebase is the tool, but it rewrites commits: the risks are losing work, breaking a shared branch, and ending with a final tree that differs from what was tested. A backup and a tree comparison remove those risks.
</context>

<task>
Plan the clean-up of this branch:
[LOG]


1. Read the log and the files each commit touches. Group the changes into logical commits: one purpose each, ordered so every commit builds and passes tests (refactors and moves before the behaviour that depends on them; tests with the code they test unless the target shape says otherwise). If the log is missing the base branch or file stats, ask for them.
2. Write the target history: the list of final commits with a subject line in the team's convention (imperative mood, under about 72 characters if no convention is given) and which original commits feed each one.
3. Map every original commit to a rebase action: `pick`, `reword`, `squash`, `fixup`, `drop` or `edit` (to split). Reorder lines as needed. Point out where reordering will likely conflict, because a later commit touches the same lines as an earlier one.
4. For commits that mix two purposes, give the split procedure: mark `edit`, `git reset HEAD~`, stage by purpose with `git add -p` or by path, commit each part, then `git rebase --continue`.
5. Mention the fixup alternative for future work: `git commit --fixup=<sha>` plus `git rebase -i --autosquash`.
6. Keep the reshape and any update to a newer base apart. Rebase onto the branch's current merge base (`git rebase -i --keep-base <base>`, Git 2.24 or newer, or `git rebase -i $(git merge-base <base> HEAD)`), so the final tree can be compared with the backup. Moving onto the latest base is a separate, later step.
7. Give the verification: the final tree must equal the backup's tree, `git range-diff` shows each old commit's fate, and each commit should build and test.
</task>

<constraints>
- The first step is always a backup branch. Never suggest `git reset --hard` or `git push --force` without `--force-with-lease`.
- If the branch is already pushed and others may have based work on it, say so, and recommend agreeing with them before rewriting.
- Never drop a commit whose changes are not present elsewhere in the target history; if a change looks accidental, list it and ask.
- Use only commit hashes and messages from the log. Do not invent commits.
</constraints>

<output_format>
## Target history
Numbered final commits: subject, then the original commits it absorbs.
## Before you start
The backup command (`git branch backup/<branch>-<date>`) and a check that the working tree is clean.
## Rebase todo
The `git rebase -i --keep-base <base>` command and the full todo list exactly as it should be edited, oldest first.
## Splitting and rewording
Step-by-step commands for each `edit` and the new messages for each `reword` or `squash`.
## Verify
`git diff backup/<branch>-<date> HEAD` must be empty (any difference is lost or extra work), `git range-diff <base> backup/<branch>-<date> HEAD` to review the mapping, and `git rebase -x "<test command>" --keep-base <base>` to build and test each commit.
## Publish
`git push --force-with-lease` and when it is safe.
## Undo
How to return to the backup (or find the old head in `git reflog`) if anything goes wrong.
</output_format>
````

---

<a id="conventional-commits-rules"></a>

## Conventional Commits rules

`conventional-commits-rules` · rule · Git and version control · https://hermes-ide.com/prompts/conventional-commits-rules

Makes the assistant write every commit in Conventional Commits 1.0.0 format, one logical change per commit, with honest breaking-change footers. Use in repos that release from commits.

````markdown
Follow these rules for the rest of this conversation.

When you write a commit message, follow Conventional Commits 1.0.0.

- Write the header as `type(scope): description`. The scope is optional; leave it out unless the repo already uses scopes, and then use the same scope names.
- Use one of these types: `feat` (new behaviour for users), `fix` (a bug fix), `docs`, `style` (formatting only), `refactor` (no behaviour change), `perf`, `test`, `build`, `ci`, `chore`, `revert`. Do not invent new types unless the repo's commitlint config lists them.
- Write the type and scope in lowercase. Write the description in the imperative mood ("add", not "added"), with no trailing period.
- Keep the header under 72 characters.
- Put one logical change in each commit. If the staged changes do two things, say so and suggest splitting them instead of writing a header that joins them with "and".
- After a blank line, add a body that explains why the change was made when the header does not make that obvious. Wrap it at 72 characters. Do not narrate the diff.
- Mark a breaking change in two places: an exclamation mark before the colon (`feat(api)!: drop the v1 endpoints`) and a `BREAKING CHANGE:` footer that says what users must change. Write `BREAKING CHANGE` in uppercase.
- A change is breaking when existing users must change code, configuration or data to keep working. Removing a public function, renaming a CLI flag and changing a default are breaking; internal refactors are not.
- Put footers after the body, one per line, in `Token: value` form (`Refs: #123`, `Reviewed-by: Name`). Only reference issues that exist in the task or the branch; never invent an issue number.
- For a revert, use `revert: ` followed by the reverted header, and a body of `This reverts commit SHA.` with the real sha.
- Remember how release tools read these: `fix` produces a patch release, `feat` a minor release and any breaking change a major release. Choose the type by its effect on users, not by the size of the diff.
- Do not add tool or assistant attribution trailers unless the user asks for them.
````

---

<a id="purge-file-from-git-history"></a>

## Purge a file from git history

`purge-file-from-git-history` · prompt · Git and version control · https://hermes-ide.com/prompts/purge-file-from-git-history

Removes a large file or committed secret from all git history with git filter-repo, with a backup first, exact commands, force-push coordination and what every collaborator must do.

````markdown
<context>
Deleting a file in a new commit does not remove it from history: every clone, fork and cached view still has it. Removing it for real means rewriting every commit since it was added, which changes their hashes, invalidates open pull requests and breaks every collaborator's clone. git filter-repo is the tool the Git project recommends for this (git filter-branch is slow and error-prone, and BFG Repo-Cleaner is an older alternative). For a secret, the rewrite is cleanup, not the fix: anyone who cloned, forked or scraped the repository already has it, so the credential must be revoked and rotated first.
</context>

<task>
Write a step-by-step plan to remove this from the repository's entire history:

<what_to_remove>
[WHAT_TO_REMOVE]
</what_to_remove>

Hosting: github
Is a secret or sensitive data: false
Treat it as a secret even if this says false when the description shows a credential, token, key, private certificate or personal data, and say that you did.

1. **Before you start.** If it is a secret, the first step is to revoke and rotate the credential and check its access logs for misuse, before touching history; say this plainly and do not let the rewrite delay it. For any rewrite: name the window when nobody may push, list the open pull requests and branches that will need recreating, check whether the file should instead stay in history through Git LFS (`git lfs migrate import --include="<pattern>" --everything`) if it is a large asset the project still needs, and note that every commit hash after the first affected commit will change, breaking links and signatures on rewritten commits and tags.
2. **Back up.** A mirror clone (`git clone --mirror <url> backup.git`) stored somewhere safe and access-controlled, because for a secret the backup contains it too; say when to delete the backup.
3. **Rewrite.** Install git filter-repo with the platform's package manager or pip, make a fresh mirror clone to work in, and give the exact command for this case:
   - a path: `git filter-repo --invert-paths --path <path>` (repeat `--path`, or use `--path-glob` for patterns);
   - large files by size: `git filter-repo --strip-blobs-bigger-than <size>`, after listing the biggest blobs so the user can choose the threshold;
   - a secret string inside files that must stay: `git filter-repo --replace-text <expressions-file>`, with the file format (`literal:<secret>==>***REMOVED***` or `regex:<pattern>==>***REMOVED***`) and a warning not to commit or share that file.
   For sensitive data, mention the `--sensitive-data-removal` option that recent git filter-repo versions provide (it also fetches and rewrites refs such as pull request refs and reports the first changed commits) and tell the user to check `git filter-repo --help` for their version.
4. **Verify** before pushing, with commands that must return nothing: `git log --all --oneline -- <path>` for a path, `git log --all -S '<secret>' --oneline` for a string (run it locally only and keep it out of shell history), and the largest-blobs listing again for size cleanups. Also check the tags.
5. **Push.** Re-add the remote if filter-repo removed it, temporarily allow force pushes on protected branches, then force-push all branches and tags (`git push --force --mirror origin` from the mirror clone, or `git push origin --force --all` and `git push origin --force --tags`). Explain that rejections of read-only refs such as pull request refs are expected on some hosts. Restore branch protection immediately afterwards.
6. **Host cleanup** for github: the host still serves old commits through pull request refs, caches and forks. For GitHub, explain that pull request refs and cached views keep the old commits and that GitHub Support can remove cached views and run garbage collection on request, with the affected commit hashes; forks are separate repositories the owner must handle. For GitLab, use the Repository cleanup setting with the `commit-map` file that filter-repo writes under `.git/filter-repo/`. For other hosts, say to check the host's documentation or support for purging unreachable objects. Also clear CI caches, artifacts and mirrors that may hold the old history.
7. **Tell collaborators.** Write the message to send: stop pushing; after the rewrite, re-clone (the safest option); anyone with unpushed work saves it as patches or rebases it onto the new history with `git rebase --onto`, never merges an old branch, because that brings the purged file back; recreate open pull requests; delete old local clones and forks that contain the file.
8. **Afterwards.** Add the path or pattern to `.gitignore`, add a pre-commit or server-side check (secret scanning or a file-size limit), and for a secret confirm the rotated credential works everywhere.
</task>

<constraints>
- Do not run any command yourself. Give commands for the user to run, and label each one read-only or rewrites history or force-pushes.
- Never print, echo or repeat the secret value in the plan; use a placeholder like `<secret>`.
- If it is a secret, rotation comes before every other step, and say that a history rewrite alone does not make the secret safe.
- Do not claim the data is gone from the host until the host cleanup step is done; say what may still hold it.
- If you are unsure an option exists in the user's tool version, say how to check instead of asserting it.
</constraints>

<output_format>
## Before you start
## Back up
## Rewrite
## Verify
## Push
## Host cleanup
## Tell collaborators
Include the ready-to-send message in a quote block.
## Afterwards
Each section uses numbered steps with commands in fenced blocks, each command labelled read-only, rewrites history or force-pushes.
</output_format>
````

---

<a id="recover-lost-git-work"></a>

## Recover lost Git work

`recover-lost-git-work` · prompt · Git and version control · https://hermes-ide.com/prompts/recover-lost-git-work

Recovers commits, branches, stashes and staged files lost to a reset, rebase or dropped stash, using reflog and fsck after a backup, explaining each command. Use right after a git mistake.

````markdown
<context>
Git rarely deletes committed work immediately. A reset, rebase, amend or deleted branch only moves references; the old commits stay in the object store and in the reflog until garbage collection removes them (by default reflog entries last 90 days, or 30 for commits no branch can reach). A dropped stash is a dangling commit. Staged but uncommitted files exist as blobs. Only changes that were never committed or staged are outside Git's reach. The danger during recovery is panic: more resets, `git gc`, or re-cloning can destroy what is still recoverable.
</context>

<task>
Help recover lost work.

What happened:
[WHAT_HAPPENED]


1. Classify the loss: commits lost by reset, rebase or amend; a deleted branch; a dropped or cleared stash; staged files lost by reset or checkout; uncommitted, unstaged changes overwritten; a force-pushed remote branch; or something else. If the description is ambiguous, ask the one question that decides it, and give the read-only commands that will show it.
2. Start with safety: stop running write commands, do not run `git gc` or `git prune`, and make a full copy of the repository directory (including `.git`) before changing anything.
3. Give read-only commands to locate the work, explaining what each one shows:
   - `git reflog` and `git reflog show <branch>` for previous positions of HEAD and branches; `ORIG_HEAD` after a reset, rebase or merge;
   - `git fsck --lost-found` or `git fsck --unreachable --no-reflogs` for dangling commits and blobs, including dropped stashes (stash commits have messages starting "WIP on" or "On <branch>"); list them readably with `git fsck --unreachable --no-reflogs | grep commit | cut -d' ' -f3 | xargs git log --no-walk --format='%h %ci %s'`;
   - `git show <sha>` and `git log -p <sha>` to confirm a candidate is the lost work.
   If you can run commands in the repository yourself, run only these read-only ones and show their output; otherwise give them to the user and wait for the output.
4. List the candidates with sha, date, subject and a `git show --stat <sha>` summary so the user can recognise their work, ranked by how well each matches the description.
5. Restore without overwriting anything: create a new branch at the found commit (`git branch recovered/<name> <sha>`), apply a stash commit with `git stash apply <sha>`, or write a blob to a new file with `git show <sha> > recovered-file`. Only then compare and merge into the working branch.
6. If the lost changes were never committed or staged, say so plainly and list the places that might still hold them: editor or IDE local history, editor swap or backup files, OS snapshots or backups, a copy in another clone, CI artifacts, or an open pull request.
7. If the work was pushed before it was lost, the remote or a teammate's clone still has it: fetch it from there. If the remote branch was force-pushed, check other clones and the reflog of whoever pushed, and the hosting service's pull request or activity views for the old head commit.
</task>

<constraints>
- Every command you give is read-only until the user has a backup. Label each command read-only or writes.
- Never suggest `git reset --hard`, `git checkout -- .`, `git clean`, `git gc` or `git prune` during recovery.
- Do not claim a commit is the lost work until its contents have been checked with `git show`.
- If you need output you do not have, ask for it with the exact command, and wait.
- Separate what you verified from what you inferred. Mark inferences as such.
- When you do not know, say "I don't know" once and state what would settle it.
</constraints>

<output_format>
## What likely happened
Two or three sentences, and the one question to ask if unsure.
## Stop and back up
The backup command for the user's platform.
## Candidates
Numbered read-only commands, each with what to look for in the output, then a table: sha | date | subject | files changed | match (high, medium, low).
## Restore it
Commands to restore onto a new branch or file, then how to bring it back into the working branch.
## If it is not there
Where else the work may survive, in order of likelihood.
</output_format>
````

---

<a id="resolve-merge-conflict"></a>

## Resolve a merge conflict

`resolve-merge-conflict` · prompt · Git and version control · https://hermes-ide.com/prompts/resolve-merge-conflict

Resolves merge, rebase or cherry-pick conflicts by reading both sides and their common base, keeps the intent of each, and asks when the intents contradict. Use when git stops on a conflict.

````markdown
<context>
A conflict means two changes touched the same lines. Picking one side wholesale silently deletes the other person's work, and keeping both blindly often produces code that compiles but is wrong. A correct resolution keeps the intent of both changes, which you can only know by comparing each side with their common ancestor. Conflicts can also be semantic and outside the markers: one side renames a function while the other adds a new call to the old name.
</context>

<task>
Resolve the conflicts in the current repository.

1. Run `git status` to see the operation (merge, rebase, cherry-pick, revert or stash pop) and the conflicted files. Remember that during a rebase "ours" is the branch being rebased onto and "theirs" is the commit being replayed, the reverse of a merge.
2. For each conflicted file, read the three versions: base (`git show :1:path`), ours (`:2:path`) and theirs (`:3:path`). Read the commits that touched the file on each side (`git log --oneline --left-right --merge -- path`) to learn the intent of each change.
3. Classify every conflicting hunk:
   - independent: both changes can coexist; combine them.
   - same intent: both made an equivalent change; keep one, preferring the more complete one.
   - contradictory: the changes want different behaviour; do not guess. Leave the markers in that hunk and put it under "Needs your decision".
4. Remove every conflict marker you resolved. Search the whole file for leftover `<<<<<<<`, `=======` and `>>>>>>>`.
5. Look for semantic conflicts beyond the markers: renamed or removed symbols, changed signatures, moved files. Search for usages of anything either side renamed or deleted.
6. For lockfiles and generated files, do not hand-merge. Take one side, then regenerate with the project's own command (for example the package manager's install) and say which command you ran.
7. Run the project's build and the tests nearest to the touched code. Stage the files you resolved with `git add`.
</task>

<constraints>
- Do not run `git commit`, `git merge --continue`, `git rebase --continue`, `git push`, or any command that discards work (`reset --hard`, `checkout -- .`, `merge --abort`, `rebase --abort`, `clean`). Stop after staging and let the user continue.
- Never resolve a whole file with `--ours` or `--theirs` unless your hunk analysis shows that one side's changes are fully contained in the other's, and say so.
- Read the relevant code before making a claim about it. Do not guess what a file, function or config contains.
- If the information you need is not available, say what is missing and how to get it instead of inventing it.
- Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
- If you could not run a check, say so plainly and say which one.
</constraints>

<output_format>
## Resolutions
A table with one row per hunk: `path:line` | ours intended | theirs intended | resolution | confidence (high, medium, low).
## Verification
The build and test commands you ran and their real results, plus any semantic conflicts you found outside the markers.
## Needs your decision
Each contradictory hunk: the two behaviours in one sentence each, and the question to answer. Write "None" if there are none.
End with the command the user should run next (for example `git rebase --continue`).
</output_format>
````

---

<a id="split-large-pull-request"></a>

## Split a large pull request into a stack

`split-large-pull-request` · prompt · Git and version control · https://hermes-ide.com/prompts/split-large-pull-request

Splits a large pull request into a stack of small, independently reviewable PRs with their order, dependencies and the branch commands to build them. Use when a PR is too big to review well.

````markdown
<context>
Review quality drops sharply as pull requests grow: big PRs get skimmed and approved, and their defects ship. Most large PRs combine several kinds of change that can be reviewed separately: mechanical changes (renames, moves, formatting, generated code), preparatory refactors, new code that is not yet called, schema or infrastructure changes, and the behaviour change itself. Split along those lines, each PR has one purpose, builds and passes tests on its own, and can merge independently or as a short stack.
</context>

<task>
Propose how to split this pull request:
[DIFF_SUMMARY]


1. Inventory the changes, grouping files and hunks by kind: mechanical, preparatory refactor, new isolated code (not yet wired in), schema or migration, configuration or infrastructure, behaviour change, tests, docs. Note which groups depend on which.
2. Propose the stack, usually in this order: mechanical changes; preparatory refactors with no behaviour change; additive schema changes (expand) and new code behind a flag or not yet called; the behaviour change that wires it in; clean-up and contract steps. Each PR must compile and pass tests on its own, contain the tests for its own code, and have a single purpose stated in its title. Aim for each PR to be reviewable in under 30 minutes; say when a PR stays large and why that is acceptable (for example a generated file or a pure rename).
3. Mark which PRs are independent (can branch from main and merge in any order) and which must stack.
4. Give the commands to build the branches from the existing one without rewriting it: create each branch from the right base and bring over files with `git restore --source=<big-branch> -- <paths>` or hunks with `git checkout -p <big-branch> -- <path>`, then commit. For stacked branches, show how to keep them in sync when an earlier PR changes: `git rebase --update-refs` (Git 2.38 or newer) or `git rebase --onto`.
5. Describe how to verify the split lost nothing: the tip of the stack must have no diff against the original branch.
6. Write the merge plan: order, what each reviewer should focus on, and whether to retarget each PR to main after its parent merges.
</task>

<constraints>
- Base the plan on the files and changes in the input. If you only have a file list, say which groupings are guesses and ask for the diff of the files that matter.
- Keep anything that must change atomically in the same PR (a schema change and the code that requires it in the same deploy, a public API change and its callers in the same repository) and say why.
- Do not suggest splitting tests from the code they verify unless the team asks for it.
</constraints>

<output_format>
## Change inventory
Table: Group | Kind | Files | Approx. lines | Depends on.
## Proposed stack
Table: Order | PR title | Contents | Base branch | Independent or stacked | Reviewer focus.
## Branch commands
Code block with the commands to create each branch, plus the final check that nothing was lost.
## Merge plan
Numbered merge order and retargeting steps.
## What stays together
Bullets: changes that must stay in one PR and why.
</output_format>
````

---

<a id="write-commit-message"></a>

## Write a commit message

`write-commit-message` · prompt · Git and version control · https://hermes-ide.com/prompts/write-commit-message

Writes a commit message that states what changed and why, in the repo's own convention, and flags staged changes that should be split. Use before committing.

````markdown
<context>
A commit message is read months later by someone running `git log`, `git blame` or `git bisect` who needs to know why a line exists. The subject says what changed in words a reader can scan; the body says why, because the diff already shows how. A message that narrates the diff, or one that bundles unrelated changes behind "and", fails that reader.
</context>

<task>
Write a commit message for this change:
If no change is given above, read the staged changes (`git diff --staged`). If nothing is staged, say so in one line and stop.

1. Read the whole diff and name its single purpose in one sentence. If the diff mixes unrelated purposes (a fix plus a refactor, two features), do not write one message. Propose a split instead: list each commit with its files or hunks and its subject line.
2. Pick the convention: match-repo.
   - `match-repo`: read the last 20 subjects (`git log --format=%s -20`) and copy their pattern: type prefixes, scopes, capitalisation, ticket references. If there is no history or no clear pattern, use `plain`.
   - `conventional`: Conventional Commits 1.0.0. `type(scope): description`, with type one of feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert. Use the scope only if the repo has clear modules. Mark a breaking change with an exclamation mark before the colon (`feat(api)!: ...`) and a `BREAKING CHANGE:` footer that says what users must do.
   - `plain`: a capitalised imperative subject with no prefix.
3. Subject: imperative mood ("Fix", not "Fixed" or "Fixes"), names the thing that changed, no trailing period, at most 72 characters and ideally under 50.
4. Body, after one blank line, wrapped at 72 characters: the problem, why this approach, and any side effect or follow-up a reviewer must know. Skip the body when the subject says everything (typo fixes, version bumps).
5. Footers only for facts you have: issue references from the input, `BREAKING CHANGE:`, or trailers the repo already uses.
</task>

<constraints>
- Never invent a reason, ticket number, issue link, benchmark or test result. If the motivation is not in the diff or the input, write a body with only what the diff proves and add one line after the message asking for the reason.
- Do not add tool or assistant attribution trailers (such as `Co-authored-by`) unless the author asks.
- Do not run `git commit` or change the index. Output the message only.
- Describe behaviour, not files: "Reject expired tokens at login" beats "Update auth.ts".
</constraints>

<output_format>
The message inside one fenced `text` block, exactly as it should be committed.
After the block, at most two lines starting with `Note:` for a proposed split or missing information. Nothing else.
For a split, output one fenced block per proposed commit, each preceded by the files or hunks it contains.
</output_format>

<examples>
Input: a diff that changes `retry.ts` so that `fetchWithRetry` stops retrying on HTTP 4xx responses, with a new test.

```text
Stop retrying client errors in fetchWithRetry

A 4xx response means the request itself is wrong, so retrying it only
adds latency and load: a bad token was retried 5 times per call before
failing. Retry only network errors and 5xx responses, and add a test
that a 401 fails on the first attempt.
```
</examples>
````

---

<a id="write-pr-description"></a>

## Write a pull request description

`write-pr-description` · prompt · Git and version control · https://hermes-ide.com/prompts/write-pr-description

Writes a pull request description that tells reviewers why the change exists, what to look at first, how to test it and what could break. Use when opening a PR.

````markdown
<context>
A PR description is for the reviewer, who has less context than the author and limited time. A good one answers, in order: what does this do, why now, where should I look first, how do I know it works, and what could go wrong. It is not a changelog of every file and not a sales pitch. Its length should follow the size and risk of the change: two lines for a typo fix, a full page for a migration.
</context>

<task>
Write the description for . If no change is given, diff the current branch against the default branch (`git merge-base` with `origin/HEAD`, then `git diff` and `git log` from there).

1. Read every commit message and the full diff before writing. Check the repo for a PR template (`.github/pull_request_template.md`, `.github/PULL_REQUEST_TEMPLATE/`, `docs/`) and use it if one exists.
2. State the purpose in one or two sentences a reviewer could repeat.
3. Group the changes by intent, not by file. Point to the one or two places that carry the risk ("start with `billing/proration.ts`; the rest is wiring").
4. Write test steps a reviewer can follow: commands, inputs and expected results. Include only tests and checks you can see in the diff or the input.
5. List what could break: behaviour changes, migrations, config or environment changes, feature flags, performance, and how to roll back.
</task>

<constraints>
- Never claim that tests pass, that something was tested manually, or that metrics improved unless the input says so. Write `TODO(author): ...` for anything only the author can confirm.
- Link issues only when the id appears in the branch name, commits or input. Never invent one.
- Call out breaking changes and required deploy steps (migrations, new env vars) at the top of Risks, in bold.
- No filler ("This PR aims to..."), no restating the title, no emoji unless the template uses them.
- Do not create or edit the PR yourself; output the text.
</constraints>

<output_format>
First line: a proposed PR title in the repo's commit style, under 72 characters.
Then, unless a template replaces them, these sections, omitting any that would be empty for a small change:
## Summary
One or two sentences.
## Why
The problem or ticket, with the link if known.
## Changes
Bullets grouped by intent. Name the files to review first.
## How to test
Numbered steps with expected results.
## Risks
Breaking changes, migrations, rollout and rollback, or "Low: ..." with the reason.
</output_format>
````
