git-flow-master

SkillDev tools

End-to-end Git operator for any branching strategy. Auto-detects the project's strategy (solo-main, main+integration, enterprise multi-branch, trunk-based, GitFlow, GitHub Flow, GitLab Flow, SDET integration-trunk for chained test-automation suites) from .git config, branches, and the `git_strategy:` block in `.agents/project.yaml`, then adapts every commit, branch, push, PR, conflict-fix, and chained-PR action to that strategy. Use this skill whenever the user wants to: create a branch (`crear branch`, `new feature branch`, `start work on UPEX-123`), commit changes (`commit this`, `commitear esto`, `make a commit`, `commit and push`), push code (`push`, `push to main`, `push to staging`, `subir cambios`), open a pull request (`create PR`, `open PR`, `abrir PR`, `crear pull request`, `gh pr create`), fix merge conflicts (`fix conflict`, `resolver conflicto`, `merge conflict`, `rebase conflict`, `push rejected`), plan stacked or chained PRs (`stack of PRs`, `chained PRs`, `split this PR`, `PR demasiado grande`), set up an isolated git worktree (`worktree`, `work in a worktree`, `isolate this work`, `parallel session`, `aislar el trabajo`, `trabajar aislado`), set up or bootstrap a branching strategy on a fresh repo (`set up our git strategy`, `bootstrap branching`, `configura el flujo de git`, `git strategy setup`, `materialize the git flow`, `create the staging branch and write the runbook`), or pick / change / set up a branching strategy (`git flow`, `git strategy`, `branching strategy`, `which git flow do we use`, `set up our git strategy`, `bootstrap branching`, `configura el flujo de git`). Trigger even when the user does not say `git-flow-master` literally — if the work is git-or-PR-shaped, this is the right tool. Do NOT use for: testing tickets (use /sprint-testing), authoring test cases in TMS (use /test-documentation), writing automated tests (use /test-automation), running regression suites (use /regression-testing), or general code editing — git-flow-master operates strictly on the version-control layer.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the git-flow-master skill

What this skill tells your AI

The instructions your AI receives, as published by upex-galaxy/agentic-qa-boilerplate in .agents/skills/git-flow-master/SKILL.md and read by ahel’s review.

Git Flow Master — One Skill for Branches, Commits, Pushes, PRs, and Conflicts

This skill is the project's single entry point for everything that happens on the version-control layer: creating branches, writing commits, pushing safely, opening pull requests, resolving conflicts, and planning chained / stacked PRs when a change outgrows the review budget.

It does not assume one branching model. The project may run on main only, on main + staging, on a multi-branch enterprise layout, or on any of the well-known flows (trunk-based, GitFlow, GitHub Flow, GitLab Flow). The skill detects which one is active and adapts every command accordingly. The detection is sticky: once resolved, the strategy is recorded in the git_strategy: block of .agents/project.yaml so future invocations skip the prompt.


When to use

Trigger on any of these intents — even without literal keywords:

  • "I want to start work on UPEX-123" → branch creation
  • "commit and push", "subir cambios", "push to main" → commit + push flow
  • "abrí un PR contra staging" → PR creation
  • "tengo conflictos al hacer pull" → conflict resolution
  • "este PR va a quedar enorme" → chained-PR planning hand-off
  • "qué estrategia de git usamos en este repo" → strategy detection / persistence
  • "el push fue rechazado" → diagnostic + recovery flow

If the user is asking about testing a ticket, authoring test cases, writing automated tests, or running regression suites — that is not this skill. Hand back to /sprint-testing, /test-documentation, /test-automation, or /regression-testing.


The six operations

Every git-flow-master invocation maps to one (or a sequence) of these six operations. Operation choice is driven by the user's request; strategy resolution shapes how each operation runs.

OpTrigger phrases (examples)Skill behaviour
Branch"create branch", "new feature branch", "start UPEX-123"Resolve strategy → propose name with prefix + issue key → wait for OK → checkout
Commit"commit this", "commit and push", "make atomic commits"Group by responsibility → propose conventional commits → wait for OK → execute one-by-one
Push"push", "push to main", "subir cambios"Diagnose upstream → confirm if pushing to a protected branch → never --force without explicit user opt-in
PR"create PR", "abrir PR", "gh pr create"Pick base branch from strategy → render body inline → ask labels/reviewers → call gh pr create
Conflict"fix conflict", "rebase failed", "push rejected"Diagnose first (see references/conflict-resolution.md) → present options → guide resolution → verify clean state
Strategy Setup"set up our git strategy", "bootstrap branching", "configura el flujo de git", "materialize the flow"Resolve strategy → run decision questionnaire (Q1-Q4) → conditionally create/ff-sync long-lived branches (never force) → write the git_strategy: block in .agents/project.yaml. Skips questions already answered by non-n/a git_strategy.decisions.* fields. See references/strategy-setup.md.

When the operation is ambiguous (user just says "git-flow-master" or "let's do the git stuff"), report the current repo state (Step 1 below) and ask what they need.


Step 1 — Always: read the repo state

Run these silently every invocation. Do not act until the picture is clear:

git status
git branch --show-current
git branch -a
git diff --stat
git log --oneline -5
git fetch origin
git status -sb
git remote -v

Summarise to the user:

  • Current branch.
  • Dirty / clean working tree (staged / unstaged / untracked counts).
  • Unpushed / unpulled commits (ahead / behind upstream).
  • Upstream status (no upstream, up-to-date, diverged).
  • Remote name(s) — most repos have one (origin); some have a fork + upstream.

This summary is cheap, prevents 90% of mistakes, and is the input to every subsequent decision.


Step 1b — Reconcile the declared policy against the host (once per session)

git_strategy.policy.* in .agents/project.yaml records what the team DECIDED. The hosting platform records what is actually ENFORCED. These drift, and the drift only surfaces at the worst moment: a merge that stalls on an approval nobody expected, or a "protected" branch that was never protected.

Run this ONCE per session, at the first push / PR / merge intent (not on read-only operations), and cache the result for the rest of the session.

Run the tool; do not perform the queries by hand:

bun run git:policy verify          # read-only; exit 1 on drift
bun run git:policy verify --stamp  # same, and records the reconciliation when clean

It queries BOTH GitHub protection mechanisms for every branch in git_strategy.branches / protected, compares the union against the declared policy, and prints each divergence as declared vs enforced. The strategy-to-ruleset mapping and what the tool deliberately does not manage: references/ruleset-parity.md.

Why a tool rather than a checklist. This reconciliation existed only as prose in the sibling boilerplate and kept not happening — that repo shipped require_pr_reviews: 0 against a host demanding one approval plus a code-owner review, and it surfaced months later as a refused merge. This repo had the identical divergence. A script performs every query on every run; a procedure performs the ones the reader remembered.

Facts that still bind you when reading its output:

  • A 404 from branches/{b}/protection does NOT mean the branch is unprotected. A repo governed by rulesets returns 404 there while enforcing PR requirements, approvals, signed commits and non-fast-forward bans through rules/branches/{b}. Stopping at the classic endpoint produces a confident "unprotected" reading on a branch that requires a reviewed pull request.
  • A push that succeeds is not evidence of an absent rule. Org owners and anyone on the ruleset bypass list push through while the rule still binds everyone else. When a push prints Changes must be made through a pull request, that was a BYPASS: report it as one, never as permission. With git_strategy.policy.admin_bypass: true (or the divergence listed in git_strategy.policy.accepted_divergences), the Bypassed rule violations remote line is the DOCUMENTED norm — mention it in the report as expected, do NOT treat it as an anomaly, do NOT stall asking for confirmation, and NEVER open a PR to "satisfy" the rule.
  • require_code_owner_review: true with no CODEOWNERS file is unsatisfiable, not strict. Nobody outside the bypass list can clear it, so every merge becomes a bypass.

On drift, report — never auto-correct. Three legitimate resolutions: update .agents/project.yaml to match the host, change the host (bun run git:policy apply, dry run until --yes), or accept the divergence and record WHY in this project's own AGENTS.md. Editing either side needs the user's choice.


Step 2 — Resolve the branching strategy

The skill supports eight strategies (see references/branching-strategies.md for the full catalogue, detection signals, and trade-offs):

StrategyOne-line description
solo-mainSingle long-lived branch (main). All work lands directly. Best for solo projects, scratch repos, prototypes.
main-integrationmain (production) + a single integration branch (staging / dev / develop). Features merge to integration, release-promote to main.
enterprisemain + integration + many short-lived feature/*, fix/*, release/*, hotfix/* branches. Adds environment branches when needed.
trunk-basedTrunk (main) is the only long-lived branch. Short-lived feature branches (<1 day) merge fast, behind feature flags. CI gate is non-negotiable.
gitflowVincent Driessen's classic. main (releases) + develop (integration) + feature/* + release/* + hotfix/*. Heavyweight; mostly legacy.
github-flowmain always deployable. feature/* branches → PR → merge → deploy. No staging/develop branch.
gitlab-flowGitHub Flow + environment branches (pre-production, production) to model deployment promotion.
sdetSDET Gitflow. main (confirmed tests) + ephemeral per-suite integration trunk test/<module>-suite. Test tickets chain through the trunk (--no-ff); one final PR → main. For chained test-automation suites. Opt-in; see references/sdet-integration-trunk.md.

Detection algorithm

Apply in order; stop at the first definitive answer:

  1. git_strategy: block in .agents/project.yaml — read it. If git_strategy.strategy is non-null (one of the eight slugs), it + git_strategy.branches (production / integration / ephemeral_pattern) + git_strategy.decisions (promote_method / feature_merge / hotfix_policy) ARE the persisted decision — use them. Each git_strategy.decisions.* field whose value is NOT n/a/empty means Strategy Setup SKIPS that question on re-run (idempotent — idempotency is keyed off the git_strategy.decisions.* fields, not markers). Inherited-template guard: the boilerplate ships the block FILLED (strategy: solo-main) and a scaffolded project INHERITS it verbatim (the scaffolder only patches project.project_name / project.project_key). So a non-null git_strategy.strategy is only authoritative when the project is actually onboarded. Read project.project_name in the SAME file: if git_strategy.strategy is non-null BUT project.project_name is null, the block was INHERITED from the template (not chosen for THIS project) — treat the strategy as UNCONFIRMED and route to the Bootstrap trigger's inherited case (it still operates under the inherited strategy if the offer is declined). If project.project_name is set, the block is confirmed → use it normally, no nudge.
  2. Single-branch heuristicgit branch -a shows only main (or master) and no integration branch in the remote → solo-main.
  3. Two-branch heuristic — exactly main (or master) + one of {staging, dev, develop, integration} exists upstream → main-integration (record the integration branch name).
  4. Multi-branch heuristicmain + integration + active feature/* or release/* branches in git branch -aenterprise.
  5. Project hints — look for .gitlab-ci.yml (suggests gitlab-flow), release/* and hotfix/* long-lived branches (suggests gitflow).
  6. Fallback — ask the user. Show the options with one-line descriptions; mirror their language. Do NOT pick silently. On a test-automation repo (KATA / Playwright / /test-automation), surface sdet as the recommended option. sdet is opt-in only — never inferred silently from layout; a live test/<module>-suite trunk with test/{KEY}-* PRs targeting it confirms an already-active sdet suite.

Persist the decision

Once resolved (whether by detection or by asking), write/update the git_strategy: block in place inside .agents/project.yaml (preserve the rest of the file — it holds project identity, env config, etc.; create the block if it is missing). NEVER write a separate file. It is the single source of truth. At minimum the first five operations need git_strategy.strategy + git_strategy.branches; the full schema (with git_strategy.decisions, git_strategy.protected, git_strategy.policy, git_strategy.branch_prefixes, git_strategy.meta) is populated by Strategy Setup (3.6).

# .agents/project.yaml — git_strategy block (only the fields that apply shown)
git_strategy:
  strategy: main-integration
  branches:
    production: main
    integration: staging
    ephemeral_pattern: null

The block is the source of truth; its git_strategy.description field is the one-paragraph human summary. The user can edit it; the next invocation re-reads it.

AGENTS.md's ## Git Strategy section is just a pointer to .agents/project.yaml (git_strategy: block) — NEVER write strategy policy or branch decisions into AGENTS.md.

If the strategy uses an integration branch with a non-default name (anything other than staging), record it under git_strategy.branches.integration so commits don't have to re-detect.

Block fields and idempotent setup. git_strategy.strategy + git_strategy.branches are the minimum the first five operations need. Strategy Setup (3.6) additionally populates the three git_strategy.decisions.* fields (promote_method, feature_merge, hotfix_policy) plus the git_strategy.policy.* fields (Q4); these gate questionnaire skips. On any later invocation, detection reads the block and treats each git_strategy.decisions.* field that is NOT n/a/empty as an already-answered questionnaire question — Strategy Setup re-run only asks the questions whose git_strategy.decisions.* fields are still n/a, and never recreates a branch that already exists.

Bootstrap trigger — offer setup on a fresh repo (never auto-run)

At the top of any git intent, after Step 1 (repo state) and Step 2 detection have run, evaluate the gate — it fires on EITHER of two conditions:

(a) Unsetgit_strategy.strategy in .agents/project.yaml is null (or the git_strategy: block is absent) AND the repo looks fresh — any of: only main/master exists locally and on the remote; fewer than ~3 commits; or a boilerplate sentinel file is present (e.g. .agents/project.yaml).

(b) Inheritedgit_strategy.strategy is non-null BUT project.project_name (same file) is null. The block was INHERITED from the boilerplate template (this project has not been onboarded yet) — it was NOT chosen for THIS project. Treat it as UNCONFIRMED.

If EITHER condition is true, OFFER (do not auto-execute, do not silently pick a strategy), using the matching prompt:

(unset case (a)) "No git strategy is set up yet. Want me to run Strategy Setup — pick the flow, create the branches it needs, and write the git_strategy: block in .agents/project.yaml? (Y/N)"

(inherited case (b)) "This project's git_strategy looks inherited from the boilerplate (project not onboarded yet — project.project_name is null). Want to run Strategy Setup to define this project's own flow? (Y/N)"

Rules:

  • Offer once per session, then cache the answer. Do not re-prompt every git intent in the same session.
  • Never auto-run. A No proceeds with the requested operation under the detected (case a) or inherited (case b) strategy without writing the block.
  • A Yes enters Strategy Setup (3.6) before continuing with the original git intent.
  • The boilerplate ships .agents/project.yaml with the git_strategy: block FILLED (strategy: solo-main); a scaffolded project INHERITS it verbatim (the scaffolder patches only project.project_name / project.project_key, and the updater freezes the file via bootstrapOnlyPaths). So the unset case (a) and the inherited case (b) are the two ways a project reaches a real git intent without having confirmed its own flow → the offer fires on first real use — by design (template-trap guard). If project.project_name is set, the strategy is confirmed and NEITHER case fires.

Step 3 — Operation-specific runbooks

3.1 Branch creation

Decide the prefix from the dominant change. Use this fixed vocabulary (mixed-changes precedence: feat > fix > refactor > test > docs > chore):

PrefixWhen the dominant change is…
feat/new feature or capability
fix/bug fix
test/adding or updating automated tests (no product code)
docs/docs only
refactor/code change without behaviour change
chore/tooling, deps, housekeeping

For enterprise and gitflow strategies, also consider release/X.Y.Z and hotfix/X.Y.Z when appropriate.

In a QA repo most work lands as test/, fix/, or chore/ branches. Feature branches (feat/) are rare here — a feat/ in this repo usually means a change to the test framework itself (new fixture, new Page component layer, new reporter).

Issue key extraction (in order):

  1. Current branch name regex: (?:feat|feature|fix|test|docs|refactor|chore)/([A-Z]+-\d+)-.
  2. $ARGUMENTS for [A-Z]+-\d+.
  3. Ask the user once: "Is there an issue key for this work?" — accept "no" gracefully.

Branch name format — read git_strategy.branch_prefixes in .agents/project.yaml (naming_with_key / naming_without_key / precedence); the patterns below are the shipped defaults, used verbatim when the block is absent:

  • With key: {prefix}/{ISSUE-KEY}-{kebab-slug} (e.g. test/UPEX-123-bulk-assign-coverage).
  • Without key: {prefix}/{kebab-slug} (e.g. refactor/split-kata-fixtures).
  • Keep slugs lowercase, hyphen-separated, ≤50 chars.

Strategy-specific source branch:

  • solo-main, github-flow, trunk-based → branch off main.
  • main-integration, gitlab-flow → branch off the integration branch (staging / dev / equivalent).
  • enterprise → branch off the integration branch unless it is a hotfix/*, which branches off main.
  • gitflowfeature/* branches off develop; hotfix/* off main; release/* off develop.
  • sdettest/{KEY}-* ticket branches + Plus Branches (docs/*/chore/*/fix/*) branch off the ephemeral integration trunk test/<module>-suite; the trunk itself is cut from main on demand when a suite begins. Never stack a ticket on the previous ticket branch. See references/sdet-integration-trunk.md.

Always propose the name and ask for OK before git checkout -b. Never create silently.

3.2 Commits

Group changes by responsibility, not by file type:

GroupTypical paths
Test codetests/, tests/components/, tests/e2e/, tests/integration/
API schemasapi/schemas/, codegen output, OpenAPI types
Test datatests/data/
Skills/Docs.agents/skills/, .agents/, AGENTS.md, docs/, README.md
Configpackage.json, tsconfig.json, playwright.config.ts, lint/format configs

Test data and fixtures stay with the tests they support. If a test commit ships its own fixture, they belong in the same commit, not in a separate chore: commit.

Conventional commit format:

  • With issue key: {type}({ISSUE-KEY}): {description} (e.g. test(UPEX-123): cover bulk-assign empty states).
  • Without key: {type}: {description}.
  • Breaking changes: append ! after type/scope and add BREAKING CHANGE: footer.

Vocabulary: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert (full list in references/conventional-commits.md).

Hard rules (apply on every commit):

  • One commit = one responsibility. Never bundle unrelated changes.
  • Never git add -A or git add . — list explicit paths to avoid leaking secrets (.env, credentials) or unrelated work.
  • No AI attribution. No Generated with Claude Code, no Co-Authored-By: Claude, no equivalent line. Commits look human-authored. (Critical Reminder #3 in AGENTS.md.)
  • If a pre-commit hook fails, stop, fix the underlying issue, create a NEW commit. Never --amend a commit the hook rejected — --amend operates on the previous commit, which destroys context.

Present all proposed commits as one block. Wait for OK / modify / reject before executing.

3.3 Push

Push command depends on Step 1 output:

  • No upstream → git push -u origin {branch}.
  • Upstream behind → git push.
  • Upstream diverged → stop. Do not force. Hand to conflict resolution (3.5).

Protected branches per strategy — the branches the policy gate below guards (union with git_strategy.protected):

  • solo-mainmain is protected.
  • main-integration → both main and the integration branch are protected.
  • gitflowmain and develop are protected.
  • github-flow / trunk-basedmain is protected.
  • enterprisemain, integration, and any release/* are protected.
  • sdetmain is protected (only the final suite PR lands, reviewed + green CI). The integration trunk is protected-by-convention but its ticket/Plus PRs are self-merged by the maintainer with no ruleset friction.

Policy gate (consult git_strategy.policy.direct_push_to_protected before any direct push to a protected branch):

git_strategy.policy.direct_push_to_protectedBehaviour
allowedStanding authorization — push WITHOUT a per-push confirm. The recorded value IS the authorization (stamped by Strategy Setup with the user); asking anyway collapses allowed into confirm and empties the third state.
confirm (default)Always ask. Wait for explicit yes.
forbiddenRefuse the direct push. Redirect to the PR flow (3.4): propose a work branch + gh pr create.

For confirm, ask: "You are about to push directly to the protected branch {branch} in a {strategy} flow. Confirm?" Wait for explicit yes. Missing or null git_strategy block (fresh scaffold, project never onboarded) → behave as confirm: the safe default is to ask, never to assume standing authorization.

Admin bypass (only when contemplating skipping PR/protection for an urgent change): only when git_strategy.policy.admin_bypass: true may the skill OFFER a bypass — and it MUST re-confirm at runtime BOTH: (a) the operator actually holds admin rights on the repo (ASK — the skill cannot know the GitHub role; admin_bypass is a team POLICY intent, not a capability check), AND (b) the irreversible action itself. If git_strategy.policy.admin_bypass: false, NEVER offer a bypass regardless of the operator's role.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
21
Forks
12
Last commit
Sep 2026

ahel review

  • K4blow
    destructive-scoped (in references/conflict-resolution.md)

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Catalog kind
skill
Gateway key
git-flow-master
Source
github.com/upex-galaxy/agentic-qa-boilerplate