Skip to main content
aapp-hacks
← Back to articles
Author
app-hacks
Published

Git / Conventional Commits / Workflow

Conventional Commits and Practical Commit Scope for Solo Development

Use Conventional Commits prefixes, reviewable change boundaries, and short-lived branches to keep a solo project's history understandable and reversible.

Even in solo development, your future self becomes a reviewer who no longer remembers why a change was made. A history of “update” and “fix” cannot reconstruct intent. Conventional Commits add a change type at the start of each message so people and tools can interpret the history.

Start with a small format

Use type: description, adding an optional scope only when it clarifies the affected area.

feat(blog): add article tag list
fix(seo): generate canonical URL from site origin
refactor(content): extract post sorting helper
docs: document required Node.js version
chore: update development dependencies
  • feat: user-visible behavior or functionality
  • fix: correction of unintended behavior
  • refactor: internal change without altered external behavior
  • docs: documentation-only work
  • test: test additions or corrections
  • chore: tooling, configuration, or dependency maintenance

Classify by meaning, not file type. A new card is a feature; correcting its mobile overflow is a fix. The description may use concise imperative English or a consistent local language. Add a body when the reason cannot be recovered from the diff:

fix(content): reject empty article tags

Empty tags render blank pills in the article list, so the schema now
requires every tag to contain at least one character.

Put one decision in one commit

A useful boundary is independently explainable, testable, and reversible—not a fixed file count. A schema and the page consuming it may be one coherent feature, while an unrelated dependency update should stay separate.

git status --short
git diff
git add src/content.config.ts src/pages/blog/index.astro
git diff --staged
git commit -m "feat(content): add typed blog collection"

Stage explicit files and review the staged diff before committing. git add -p can split concerns within a file, but each resulting commit should still build. A commit that adds only an import while its component arrives later leaves an unverifiable point in history.

Keep branches short-lived

git switch main
git pull --ff-only
git switch -c feat/article-layout

npm run build
git push -u origin feat/article-layout

Branch prefixes may resemble commit types, but do not need to match every commit. A feature branch can contain preparatory refactors and docs. Integrate small complete changes before the branch accumulates unrelated work. Pull requests remain useful in a solo repository because they collect CI results, rationale, and final diff.

Restrict force pushes to private working branches. Rewriting main or a shared branch breaks other working copies. Check collaboration status before interactive rebase.

Prepare for changelog automation

Consistent types allow future tools to classify feat and fix. Mark breaking changes with ! or a footer:

feat(content)!: require publication date on every article

BREAKING CHANGE: Existing Markdown files must define pubDate.

The convention alone does not generate a changelog; release tooling, tags, and version policy are separate. First create a history humans can read. When adding CI linting, consider existing history and external contributors, document examples, and apply the rule to new commits rather than imposing strict automation before the vocabulary is understood.

The real value is not the prefix’s appearance. It is the habit of short-lived purpose branches, verifiable commits, and recorded reasons that make fixes, reverts, and release notes less costly.