Skip to content
Community content. Review instructions before giving them to an AI agent — treat modules like open-source code.

Git Workflow Rules

Git workflow rules for teams: small atomic commits with imperative messages, branch naming, rebase versus merge policy, pull request size caps, never force-pushing shared branches, why-focused commit bodies, and .gitignore hygiene.

Mby @markdownersPublished August 21, 2026 · ~4 min read

0 downloads · Used by 0 stacks

Every commit should be one atomic, reviewable change with a message that explains why it exists — a history of small, well-described commits is a debugging tool; a history of "wip" and "fix" commits is not.

Atomic commits

  • Make each commit a single logical change (one bug fix, one small feature slice, one refactor) that could be reverted on its own without breaking unrelated things — never bundle an unrelated formatting pass, a dependency bump, and a feature change into one commit.
  • Ensure the codebase builds and tests pass at every individual commit, not just at the tip of the branch — a broken intermediate commit defeats git bisect and makes cherry-picking dangerous.
  • Split a large change into a sequence of small commits that each make sense in isolation (e.g., "add the new field," then "backfill it," then "start using it") rather than one enormous commit.

Imperative commit messages

  • Write the commit subject line in the imperative mood ("Add rate limiting," not "Added rate limiting" or "Adds rate limiting") — it reads naturally as "this commit will ___" and matches Git's own generated messages (merges, reverts).
  • Keep the subject line short (roughly 50–72 characters) and capitalized, with no trailing period; use a blank line before the body if more explanation is needed.
  • Use a conventional prefix (feat:, fix:, chore:, refactor:, docs:, test:) when the project has adopted conventional commits, and stay consistent with whatever the project already uses — don't introduce a second convention mid-project.

Commit body explains why

  • Use the commit body to explain why the change was made and what alternatives were considered/rejected, not to restate what the diff already shows — the diff is the authoritative "what"; the prose should carry context a diff can't.
  • Reference the issue/ticket a commit addresses when one exists, and note any follow-up work deliberately left out of this commit so a future reader isn't left wondering if it was forgotten.

Branch naming

  • Name branches with a consistent, greppable pattern (e.g., type/short-description or type/ticket-id-short-description, such as fix/login-redirect-loop) so branch purpose is legible from git branch output alone.
  • Keep branch names short and hyphenated, in lowercase, without spaces or special characters beyond hyphens and slashes.

Rebase vs. merge policy

  • Rebase a personal, not-yet-shared feature branch onto the latest target branch to keep history linear and avoid noise merge commits — this is safe because no one else has based work on your branch's current commits.
  • Never rebase a branch that others have already pulled or based work on — rewriting shared history forces everyone downstream to reconcile diverged histories, which is far more disruptive than an extra merge commit.
  • Use a merge commit (or squash-merge, per project convention) when integrating a finished feature branch into the main line, so the integration point is visible in history.

Pull request size caps

  • Keep a pull request small enough for a reviewer to hold the whole change in their head — as a rough guide, a few hundred changed lines excluding generated/lockfiles; split anything larger into a sequence of dependent PRs.
  • Never mix a large refactor with a behavior change in the same PR — land the refactor (no behavior change, easy to verify) first, then the behavior change on top of it, as two reviewable PRs.
  • Open a PR as a draft early for large or exploratory work to get directional feedback before investing in polish, rather than surprising reviewers with a large, finished PR.

Never force-push shared branches

  • Never force-push to a branch other people are actively working from (main/master, a shared release branch, any branch listed as protected) — it can silently discard others' commits and desyncs everyone's local history.
  • Force-push only to your own personal, not-yet-reviewed feature branch, and only after confirming no one else has pulled it; prefer --force-with-lease over a bare --force even then, since it refuses if the remote has commits you don't have locally.

.gitignore hygiene

  • Commit a .gitignore from the start of a project covering the language/framework's standard build artifacts, dependency directories, and local environment files — don't wait until a large binary or a secret is accidentally committed.
  • Never rely on .gitignore alone to keep a secret out of history — if a secret is ever committed, rotate it; removing the file in a later commit does not remove it from history.
  • Keep generated/build output and dependency lockfile caches out of the repository unless the project has a specific reason to vendor them (e.g., reproducible builds); if in doubt, don't commit generated files.
Badge

Link back to this module from your own README.

Get it on Markdowners
[![Get it on Markdowners](https://markdowners.com/mdstack-badge.svg)](https://markdowners.com/m/markdowners/git-workflow-rules)

Comments (0)

Sign in to comment. Sign in

No comments yet. Be the first to add one.

Discussions about this module

No discussions about this module yet.

Start a discussion