"Enforce a strict Gitflow-based workflow with conventional commits, semantic versioning, and issue-driven branching. Use when the user asks to commit, create a branch, open a PR, tag a release, or perform any git operation. Also applies when mentions 'commit', 'branch', 'merge', 'release', 'hotfix', 'gitflow', 'conventional commit', 'semantic versioning', or 'semver'."
Resources
7Install
npx skillscat add qubernetic-org/git-workflow-agent-skill Install via the SkillsCat registry.
Git Workflow Skill
Enforce a disciplined Gitflow-based development workflow. Every git operation follows strict rules: conventional commits, atomic logical changes, semantic versioning, issue-driven branching, and PR-only merges to protected branches.
When This Skill Applies
- User asks to commit changes
- User asks to create a branch, open a PR, or merge
- User asks to tag a release or create a hotfix
- User mentions "commit", "branch", "merge", "release", "hotfix", "gitflow", "conventional commit", "semver"
- User asks about branching strategy or version management
- Any git operation that affects the repository history
Core Principles
- Atomic logical commits — one commit = one logical change, never mix concerns
- Conventional Commits — structured commit messages with type prefixes
- No AI signatures — never add "Co-Authored-By", "Generated by", or similar lines
- Semantic Versioning —
MAJOR.MINOR.PATCHfor all releases - Issue-driven workflow — every branch starts from a GitHub Issue and closes it
- PR-only merges —
mainanddevelopare never committed to directly - Always
--no-ff— all merges into protected branches use--no-ffto preserve branch topology - Discipline over tooling — follow all workflow rules even when branch protection is not configured or when operating as an admin user who can bypass it. Branch protection is a safety net, not a substitute for discipline. Early-stage repositories may lack protection rules, and admin users are often exempt — neither case permits direct commits to protected branches or merging without a PR.
Branch Model (Gitflow)
Protected Branches
| Branch | Purpose | Merge via |
|---|---|---|
main |
Production-ready code | PR only (from release/* or hotfix/*) |
develop |
Integration branch for next release | PR only (from feature/* or fix/*) |
Working Branches
| Pattern | Base branch | Merges into | Purpose |
|---|---|---|---|
feature/<issue>-<slug> |
develop |
develop |
New features |
fix/<issue>-<slug> |
develop |
develop |
Bug fixes on develop |
hotfix/<issue>-<slug> |
main |
main AND develop |
Urgent production fixes |
release/<version> |
develop |
main AND develop |
Release preparation |
Merge Strategy
- Always use
--no-fffor merges intomainanddevelop— this preserves the branch topology and groups commits visually - Never squash merge into protected branches — squashing destroys the atomic commit history you carefully crafted
- Never rebase merge into protected branches — rebase rewrites hashes and removes merge commit markers
GitHub settings: In repository settings, only enable "Allow merge commits" and disable "Allow squash merging" and "Allow rebase merging". When using
gh pr merge, always pass--merge --delete-branch.
Keeping Feature Branches Up to Date
- Not yet pushed: rebase onto
developis acceptable (git rebase develop) - Already pushed or PR open: merge
developinto the feature branch (git merge develop) — never force-push a rebased shared branch
Branch Naming Convention
- Always lowercase, hyphen-separated
- Working branches (
feature/*,fix/*,hotfix/*) are prefixed with the issue number - Release branches use version number only:
release/<version> - Examples:
feature/42-add-search,fix/17-broken-navbar,hotfix/89-auth-crash,release/1.2.0
Commit Message Format (Conventional Commits)
Structure
<type>(<optional scope>): <description>
<optional body>
<optional footer>Types
| Type | When to use | Semver impact |
|---|---|---|
feat |
New feature or capability | MINOR bump |
fix |
Bug fix | PATCH bump |
docs |
Documentation only | None |
chore |
Maintenance, config, dependencies | None |
refactor |
Code change that neither fixes nor adds | None |
test |
Adding or updating tests | None |
style |
Formatting, whitespace (no logic change) | None |
perf |
Performance improvement | PATCH bump |
ci |
CI/CD configuration changes | None |
build |
Build system or external dependency changes | None |
revert |
Reverting a previous commit | Depends on the original commit type |
Revert semver note: The impact mirrors the reverted commit's type. Reverting a
featremoves a capability (potentially MAJOR if it was public API), reverting afixreintroduces a bug (PATCH when re-fixed). Evaluate the user-facing effect at release time.
Breaking Changes
Append ! after the type or add BREAKING CHANGE: in the footer:
feat!: replace authentication system
BREAKING CHANGE: OAuth tokens from v1 are no longer valid.Breaking changes trigger a MAJOR version bump.
Rules
- Imperative mood in description: "add feature" not "added feature" or "adds feature"
- Lowercase description start (no capital after colon)
- No period at the end of the description line
- 72 character limit on the description line
- Body wraps at 80 characters, separated by a blank line
- One logical change per commit — if you need "and" in the description, split it
Examples
feat(auth): add OAuth2 login flow
fix: resolve race condition in websocket reconnect
docs: translate design language to English
chore: add MIT license and gitignore
refactor(api): extract validation into middleware
feat!: drop support for Node 16Issue-Driven Workflow
The Flow
Issue created (including release issues)
↓
Branch created from issue (feature/42-slug, fix/17-slug, etc.)
↓
Atomic commits on branch
↓
PR opened with Conventional Commits title
↓
Review + merge (--no-ff)
↓
Issue closed (manually or auto-closed — see note below)
↓
Branch deleted (remote + local)Rules
- Every branch starts from a GitHub Issue — no branch without an issue, including releases (create a lightweight "Release v1.2.0" issue with
chorelabel) - One PR per issue — the PR closes exactly one issue
- PR title follows Conventional Commits format:
<type>(<scope>): <description> (#<issue>)— e.g.,feat(auth): add OAuth2 login flow (#42) - PR body references the issue:
Closes #42 - Branch is deleted after merge — both remote (enable GitHub's "Automatically delete head branches") and local (
git fetch --prune && git branch -d <branch>)
GitHub Auto-Close Limitation
Important: GitHub only auto-closes issues via
Closes #Xwhen the PR targets the repository's default branch (usuallymain). In Gitflow, feature and fix PRs targetdevelop, so issues will not auto-close.Workarounds:
- Close manually after merging to
develop— usegh issue close <number>or close via GitHub UI- Use GitHub Actions — add a workflow that auto-closes the referenced issue when a PR is merged to
developAlways include
Closes #Xin PR bodies for traceability, even though it won't trigger auto-close ondevelopmerges.
Issue Labels
| Label | Used for |
|---|---|
bug |
Something is broken |
enhancement |
New feature request |
documentation |
Docs improvement |
hotfix |
Urgent production fix |
chore |
Maintenance task |
Semantic Versioning
Format: MAJOR.MINOR.PATCH
| Component | Incremented when | Example |
|---|---|---|
| MAJOR | Breaking changes (feat!, BREAKING CHANGE) |
1.0.0 → 2.0.0 |
| MINOR | New features (feat) |
1.0.0 → 1.1.0 |
| PATCH | Bug fixes, performance (fix, perf) |
1.0.0 → 1.0.1 |
Pre-release Tags
- Release candidates:
1.2.0-rc.1,1.2.0-rc.2 - Beta:
1.2.0-beta.1
Version Locations
Keep version in sync across:
- Git tags (
v1.2.0) package.json/Cargo.toml/pyproject.toml(if applicable)CHANGELOG.md
Repository Bootstrap (One-Time Setup)
The initial setup is the only allowed direct commit to main. This is a one-time exception to bootstrap the Gitflow structure.
1. Create empty repo on GitHub
2. Clone and make the first commit directly to main:
git clone <repo-url> && cd <repo>
# Add initial files (README, LICENSE, .gitignore)
git add README.md LICENSE .gitignore
git commit -m "chore: initialize repository"
git push origin main
3. Create and push develop:
git checkout -b develop
git push -u origin develop
4. Set up branch protection rules on main and develop
5. Normal workflow applies from here — no more direct commitsRelease Process
Standard Release
1. Create a "Release v1.2.0" issue (label: chore)
2. Create release branch from develop:
git checkout develop
git checkout -b release/1.2.0
3. On release branch:
- Bump version numbers
- Update CHANGELOG.md
- Fix release-only issues
- Commit: "chore(release): prepare 1.2.0"
4. PR: release/1.2.0 → main
- Title: "chore(release): prepare 1.2.0"
- Body: "Closes #<release-issue>"
- Review and merge with --no-ff
5. Tag on main:
git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0
6. Create GitHub Release from the tag (see Release Notes Template below)
7. PR: main → develop (back-merge)
- No code review required (content already reviewed for main)
- Exists for CI validation and audit trail only
- Merge with --no-ff
8. Delete release branch (remote + local)Hotfix Release
1. Create hotfix issue (label: hotfix)
2. Create hotfix branch from main:
git checkout main
git checkout -b hotfix/89-auth-crash
3. Fix the issue with atomic commits
4. Bump PATCH version:
- Commit: "chore(release): prepare 1.2.1"
5. PR: hotfix/89-auth-crash → main
- Merge with --no-ff
6. Tag on main:
git tag -a v1.2.1 -m "Release 1.2.1"
git push origin v1.2.1
7. Create GitHub Release from the tag (see Release Notes Template below)
8. PR: main → develop (back-merge)
- No code review required (content already reviewed for main)
- Exists for CI validation and audit trail only
- Merge with --no-ff
9. Delete hotfix branch (remote + local)Release Notes Template
Every tag must have a corresponding GitHub Release. Use gh release create or the GitHub UI. The release notes follow this template:
<changelog ### sections from CHANGELOG.md for this version>
**Full Changelog**: https://github.com/<owner>/<repo>/compare/v<prev>...v<version>- Title:
v<version>(e.g.,v1.2.0) — do not repeat the version in the body, GitHub already displays it prominently - Body: Copy the
###sections (Added, Fixed, Changed, etc.) from CHANGELOG.md for this version — skip the## [version] - dateheading - Full Changelog link: Use
/compare/v<prev>...v<version>, or/commits/v<version>for the initial release
CHANGELOG Format
Follow Keep a Changelog:
## [1.2.0] - 2026-03-18
### Added
- OAuth2 login flow (#42)
- Search autocomplete (#45)
### Fixed
- Race condition in websocket reconnect (#38)
### Changed
- Validation extracted to middleware (#50)Rules
- Group by: Added, Changed, Deprecated, Removed, Fixed, Security
- Reference issue numbers
- Most recent version at the top
- Use
## [Unreleased]section for in-progress work on develop
Forbidden (NEVER Do)
- Commit directly to
mainordevelop(sole exception: repository bootstrap) - Add AI/copilot co-author signatures to commits
- Create a branch without a backing issue
- Mix multiple logical changes in one commit
- Use past tense in commit messages ("added", "fixed")
- Force-push to
mainordevelop - Merge without a PR
- Squash merge or rebase merge into protected branches
- Fast-forward merge into protected branches (always use
--no-ff) - Skip version bump on release
- Delete
mainordevelopbranches - Tag a release without updating CHANGELOG.md
- Tag a release without creating a GitHub Release
- Use
git commit --amendon pushed commits - Use
git rebaseon shared/published branches
Decision Guide
"What branch do I create?"
| Situation | Branch type | Base |
|---|---|---|
| New feature | feature/* |
develop |
| Bug found during development | fix/* |
develop |
| Bug found in production | hotfix/* |
main |
| Preparing a release | release/* |
develop |
"What commit type do I use?"
| Change | Type |
|---|---|
| Added a new user-facing capability | feat |
| Fixed something that was broken | fix |
| Changed docs, README, comments | docs |
| Updated config, CI, dependencies | chore |
| Restructured code without behavior change | refactor |
| Added or updated tests | test |
| Improved performance | perf |
"Do I bump the version?"
| Situation | Action |
|---|---|
| Merging feature/fix to develop | No version bump yet |
| Creating a release branch | Bump version on release branch |
| Merging hotfix to main | Bump PATCH version on hotfix branch |
| Breaking change anywhere | MAJOR bump at release time |