agentleFS
SWEStashSWEStash/swe-workflow-skills/skills/git-workflow/SKILL.md

git-workflow

Skill1 starsChanged 4 days agoMITView on GitHub

Write commit messages, PR descriptions, and manage branching strategy following conventional commits.

188 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use squad-commands, ci-cd-pipelines and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • Microsoft AzureSkill

    squad-commands

    Categorized catalog of common Squad operations. Coordinator reads this file and presents it as an interactive menu when the user asks for available commands or help.

    Also in 5 projects that use this

  • harrissohail6Skill

    ci-cd-pipelines

    CI/CD pipeline design and implementation. Auto-activates when discussing deployment, automation, or pipelines.

    Also in 6 projects that use this

  • Microsoft AzureSkill

    architectural-proposals

    How to write comprehensive architectural proposals that drive alignment before code is written

    Also in 4 projects that use this

  • GitHubSkill

    e2e-template-testing

    End-to-end validation of coordinator and agent template changes

    Also in 3 projects that use this

  • GitHubSkill

    notification-routing

    Route agent notifications to specific channels by type — prevent alert fatigue from single-channel flooding

    Also in 3 projects that use this

  • frostneySkill

    native-nostalgia-stack

    Applies the user's FreePascal toolchain and its build, formatting, hook, and test contracts while leaving project-specific mechanics local. Use when scaffolding or working in a FreePascal project that follows this toolchain.

    Also in 3 projects that use this

  • +5 more from Azure
  • +1 more from github

The file

Show its rules and text

We split this skill into the rules it gives an agent

14 rules. 0 are common, 11 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 165 edited versions we read keep these.

  • 11

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Start from git diff --staged --stat for what's staged.

    line 15
  2. Distinctive:

    Is this one logical change or multiple?: If multiple, suggest splitting into separate commits.

    line 21
  3. Distinctive:

    This step is not a gate on writing the message: Read the diff and draft in the same response — "write me a commit message" is a request for …

    line 23
  4. Distinctive:

    The diff is the basis, not an optional cross-check: When you genuinely cannot read it, still deliver the message, and carry the requirement …

    line 31
  5. Distinctive:

    Use the Conventional Commits format — see references/conventions.md:

    line 45
  6. Very specific:

    Commit types are not just style — in automated release flows they drive the version: fix → PATCH, feat → MINOR, feat!/BREAKING CHANGE: → …

    line 108
  7. Distinctive:

    Not a checklist to nod at: read the drafted message back against the rules above, line by line, before you commit.

    line 114
  8. Distinctive:

    Don't substitute your own reading of the diff for the call.

    line 139
  9. Very specific:

    Start from the branch state vs the default branch (main, or master in older repos): git log <base>..HEAD --oneline and git diff …

    line 146
  10. Distinctive:

    Use the template at templates/pull-request.md.

    line 153
  11. Very specific:

    Before requesting review, invoke verification-before-completion — opening a PR is a completion claim, and that skill owns the evidence gate.

    line 174
  12. Distinctive:

    If the PR is too large, suggest splitting it into stacked PRs or smaller logical units.

    line 185
  13. Distinctive:

    Consider trunk-based development with feature flags

    line 206
  14. Distinctive:

    DRY: If you're writing the same commit message pattern repeatedly, you might be making commits too granular or too broad.

    line 215

“Common” is measured: kept by at least 6 in 10 of the 165 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Git Workflow

Help write clear commit messages, structured PR descriptions, and manage branching conventions. Good git history is documentation — it tells the story of why the codebase evolved the way it did.

Workflow: Commit Messages

Step 1: Analyze the Changes

Start from git diff --staged --stat for what's staged. If the summary is empty or not enough to understand the change, run git diff --staged for the full diff.

Identify:

  • What changed? (files modified, functions added/removed, logic altered)
  • Why did it change? (feature, bugfix, refactor, dependency update)
  • Is this one logical change or multiple? If multiple, suggest splitting into separate commits.

This step is not a gate on writing the message. Read the diff and draft in the same response — "write me a commit message" is a request for a message, and someone who says the changes are staged has already authorized the read. Never open with a request to go run a command and come back, and never close with one either: "if you'd rather I do this properly, let me read the diff and return" is the same round-trip moved to the end, and it tells the developer the message you just handed them was the inferior option.

The diff is the basis, not an optional cross-check. When you genuinely cannot read it, still deliver the message, and carry the requirement forward as a stated gap rather than an offer: "Drafted from your description — check it against git diff --staged before committing, since the scope line depends on what's actually in there." That is a deferred requirement. "Want me to look?" is not.

Brevity applies to the message, not to the judgment. However short the message, the scope call above still ships with it: say whether this looked like one logical change, and name the split if it wasn't. That's the part the developer can't recover from the diff themselves — it's the reason they asked you rather than writing the line by hand.

Step 2: Write the Commit Message

Use the Conventional Commits format — see references/conventions.md:

<type>(<scope>): <short description>

<body — explain WHY, not WHAT>

<footer — references, breaking changes>

The subject line (first line):

  • Type: feat, fix, refactor, test, docs, chore, perf, ci, build
  • Scope: The module, component, or area affected (optional but recommended)
  • Description: Present tense, lowercase, no period, 72 characters total including the type(scope): prefix — the commitlint default, and what keeps git log --oneline readable in an 80-column terminal. (The older 50-char rule predates Conventional Commits: a fix(skills): prefix spends 13 characters before you write a word.)
  • It should complete the sentence: "If applied, this commit will..."

Where a tool generates the changelog (release-please, changesets, semantic-release), this line is the changelog entry a consumer reads at upgrade time — and on a squash-merge repo, that means the PR title is. Write it for the person deciding whether to upgrade, not for yourself: fix(api): reject expired tokens on refresh tells them something; fix(api): address review feedback is true and useless. The type prefix picks the changelog section too, so a mislabeled type hides the entry or files it under the wrong heading.

The body — governed by one test:

Delete any sentence a reader could reconstruct from the diff.

The diff is attached to the message. Every line spent restating it is a line the reviewer must read to discover it says nothing, which is why over-long messages make review worse, not more thorough. What survives the test is what the diff cannot show:

  • Why now — the trigger, the bug report, the constraint that forced it
  • What was rejected — the approach you didn't take, and what ruled it out
  • The non-obvious consequence — what this breaks, enables, or quietly changes
  • Why nobody noticed — for bugs, often the most valuable sentence in the message

And what fails it: file-by-file enumerations, "renamed X to Y", "added a test for Z", restating the type signature, narrating the steps you took.

Length follows from that, not from the size of the change:

ChangeBody
Mechanical — rename, format, dep bump, generated file, typoNone. The subject is the whole message.
Ordinary — a feature or fix whose reasoning is visible in the codeA sentence or two, or none.
Subtle — a non-obvious bug, a rejected alternative, a surprising constraintHowever long the reasoning actually is.

A long message is not a failure. An unearned long message is. Do not compress a message that carries real reasoning just to make it short — that loses the only part worth keeping.

Wrap at 72 characters.

The footer (optional):

  • Reference issues: Closes #123, Fixes #456
  • Breaking changes: BREAKING CHANGE: description
  • Co-authors: Co-authored-by: Name <email>

Commit types are not just style — in automated release flows they drive the version: fix → PATCH, feat → MINOR, feat!/BREAKING CHANGE: → MAJOR. A mislabeled type mis-versions the next release (see release-management).

Step 3: Validate — Re-read the Message You Just Wrote

Not a checklist to nod at: read the drafted message back against the rules above, line by line, before you commit. These constraints are trivially easy to state and trivially easy to skip — a subject line drifts past its limit, a body accumulates a restatement paragraph, and nothing ever catches it because the message is never re-read.

  • Read the subject as a stranger. Does it name the behavior change on its own? That's the real test; 72 characters is the ceiling, not the goal. Over it, cut words — and if it can't be cut, ask whether it's more than one change.
  • Apply the recoverability test to each body sentence. Could the reader get this from the diff? Then delete it. Whatever's left is the message.
  • Is this a single logical change? (If not, split it)
  • Does the subject describe the behavior change, not the implementation?
  • Would someone understand why this commit exists 6 months from now?
  • Are related issue numbers referenced?
  • Does the message use vocabulary a reader can resolve? Phase names, checkpoint IDs, and task codes belong in a commit only when a tracked document defines them — otherwise write what they mean.

Then invoke verification-before-completion — committing is publishing, and that skill owns the publish gate.

Exit condition — name it, by name, in the response where you commit: "Invoking verification-before-completion on the staged diff before this commit."

Don't substitute your own reading of the diff for the call. Knowing roughly what that gate looks for is precisely what makes skipping it feel harmless.

Workflow: PR Descriptions

Step 1: Analyze the Branch

Start from the branch state vs the default branch (main, or master in older repos): git log <base>..HEAD --oneline and git diff <base>...HEAD --stat. Understand the full scope of changes across all commits — run the full git diff <base>...HEAD when the stat summary isn't enough.

Step 2: Write the PR Description

Use the template at templates/pull-request.md. Key sections:

  • What: What this PR does (1-2 sentences)
  • Why: Why this change is needed (link to issue/task)
  • How: Brief description of the approach taken and key decisions
  • Testing: How the changes were tested
  • Screenshots: For UI changes (before/after)
  • Checklist: Standard items (tests pass, docs updated, etc.)

The PR description should let a reviewer understand the change without reading every line of code first.

The same recoverability test governs here, and it bites hardest on Changes: that section is for the handful of changes a reviewer would otherwise miss, not a transcription of the file list they can already see. If a bullet only names a file and what obviously happened to it, cut the bullet. Why, How, and the reviewer notes are where a PR description earns its length — a reviewer who reads three paragraphs of restatement before reaching the one real trade-off is worse off than one who read nothing.

Step 3: Self-Review

Before requesting review, invoke verification-before-completion — opening a PR is a completion claim, and that skill owns the evidence gate. Then:

  • Read through the entire diff one more time
  • Does anything here change what the docs describe? A renamed flag, env var, endpoint, config key, script, or install step means the README and docs/ are part of this diff — grep them for what you changed
  • Are there any debugging leftovers?
  • Any stray working artifacts (PLAN.md, NOTES.md, scratch files, one-off test scripts) that shouldn't ship?
  • Are there any changes that don't belong in this PR?
  • Is the PR a reasonable size? (Under 400 lines changed is ideal. Over 800 is a red flag.)

If the PR is too large, suggest splitting it into stacked PRs or smaller logical units.

Workflow: Branching Strategy

Help set up or improve branching conventions. Ask about team size and release cadence, then recommend:

For small teams (1-5 devs) or continuous deployment:

  • main — always deployable
  • Branch naming: feat/<description>, fix/<description> — short-lived (1-3 days)
  • Merge to main via PR — squash-merge by default (one clean commit per logical change on main); one approval is the right review bar at this size
  • Deploy from main

For medium teams (5-15 devs) or scheduled releases:

  • main — production
  • develop — integration branch
  • feat/description, fix/description — branch from develop
  • release/x.y.z — stabilization branch before release
  • hotfix/description — urgent fixes branching from main

For large teams or complex release cycles:

  • Consider trunk-based development with feature flags
  • Short-lived branches (< 1 day) merged to main
  • Feature flags control what's visible to users

See references/conventions.md for branch naming conventions.

Principles Applied

  • KISS: One commit = one logical change. Don't bundle unrelated changes.
  • DRY: If you're writing the same commit message pattern repeatedly, you might be making commits too granular or too broad.
  • Functional Independence: Each PR should be independently deployable when possible. Avoid PRs that depend on other unmerged PRs.

Rationalizations to Reject

ExcuseReality
"A thorough message is better than a short one"Thorough about the reasoning, yes. Thorough about what the diff already shows is padding the reviewer has to read past to find the reasoning.
"The subject needs all of this to be clear"If the change can't be named in 72 characters, that's usually a signal it's more than one change. Split it, or move the detail to the body.
"I'll list the changes so reviewers know what to look at"They have the diff and the file list. Point at the non-obvious change; enumerating the rest buries it.
"This is a big change, so it needs a big message"Length tracks unrecoverable reasoning, not lines touched. A 2,000-line mechanical rename needs one line.
"Documenting the decision here saves writing an ADR"A commit message is the worst place to look up a decision — nobody greps git log. Write the ADR (architecture-design) and reference it.
"The phase/task ID gives it traceability"Only if a tracked doc defines it. Otherwise it traces to a conversation the reader wasn't in.
"I'll just commit and fix the message later"Amending after a push rewrites history others have pulled. The message is part of the commit, not a follow-up.
"I should read the diff before I can write anything"Read it and draft, in the same reply. Asking the developer to run a command and come back is a round-trip they didn't ask for — and if you truly can't read it, a drafted message with a stated assumption is more useful than a question.

Red Flags — Stop and Re-Read

  • You wrote the body without re-reading the subject line's character count.
  • A body paragraph could be reconstructed by anyone with the diff open.
  • The message enumerates files or functions that changed.
  • You're about to commit without having read git diff --staged this session.
  • The message contains a phase, checkpoint, task code, or finding number, and no tracked document defines it.
  • You're writing a commit body for a rename, a formatting pass, or a dep bump.
  • Your reply to "write me a commit message" contains no commit message.

Cross-Skill References

  • release-management — cutting the release these commits accumulate into: semver, changelog, tagging, publishing
  • code-reviewing — reviewing the PR the description introduces
  • code-slop-cleanup — tighten the diff (AI artifacts, debug leftovers, stray files) before the self-review
  • verification-before-completion — run the proving commands before pushing or opening the PR

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.