Skip to main content
GSD Core can manage git branching automatically as part of the execute-and-ship workflow. By default it works entirely on your current branch, but you can configure it to create a dedicated branch for each phase or each milestone, giving you clean separation for code review and rollback. All branching settings live in the git section of .planning/config.json.

Configuration reference

{
  "git": {
    "branching_strategy": "none",
    "base_branch": "main",
    "phase_branch_template": "gsd/phase-{phase}-{slug}",
    "milestone_branch_template": "gsd/{milestone}-{slug}"
  }
}
Configure these settings interactively with /gsd-config --advanced (Git Customization section) or by editing config.json directly.

Branching strategies

All work happens on your current branch. GSD makes no branch decisions — it commits directly to whatever branch you are on when you invoke /gsd-execute-phase. This is the right choice for solo development, simple projects, or when you manage branching yourself.
{ "git": { "branching_strategy": "none" } }

Strategy comparison

StrategyBranch createdScopeMerge pointBest for
noneNeverCurrent branchN/ASolo development, simple projects
phaseAt execute-phase startOne phaseUser merges after each phaseCode review per phase, granular rollback
milestoneAt first execute-phase in the milestoneAll phases in the milestoneAt complete-milestoneRelease branches, PR per version

Template variables

Customize the branch name format by editing the template strings in config.json.
VariableAvailable inExample output
{phase}phase_branch_template03 (zero-padded)
{slug}Both templatesuser-authentication (lowercase, hyphenated from phase name)
{milestone}milestone_branch_templatev1.0
Use any combination of variables and literal text:
{
  "git": {
    "branching_strategy": "phase",
    "phase_branch_template": "feature/gsd-{phase}-{slug}"
  }
}
With the above template, phase 2 named “API layer” produces: feature/gsd-02-api-layerFor milestone strategy with a custom format:
{
  "git": {
    "branching_strategy": "milestone",
    "milestone_branch_template": "release/{milestone}"
  }
}
This produces: release/v1.0

Base branch

Set git.base_branch to the integration branch that phase and milestone branches are created from and eventually merged back into. Override this when your repository uses master, develop, or a named release branch rather than main.
{
  "git": {
    "base_branch": "develop"
  }
}
GSD also reads git.base_branch to determine where to target the pull request created by /gsd-ship. Make sure this matches the default branch in your GitHub repository settings.

Milestone completion merge options

When using the milestone strategy, /gsd-complete-milestone offers you a choice of how to merge the milestone branch back into base_branch:
OptionGit commandResult
Squash merge (recommended)git merge --squashSingle clean commit representing the entire milestone
Merge with historygit merge --no-ffPreserves all individual phase commits
Delete without merginggit branch -DDiscards the branch; useful if you shipped via individual phase PRs
Keep branches(none)Leaves branches in place for manual handling

Tags on milestone completion

By default, GSD creates a git tag (v[X.Y]) when a milestone completes. Disable this if you have your own release tagging workflow:
{
  "git": {
    "create_tag": false
  }
}

/gsd-quick branch template

Optionally configure an automatic branching strategy for /gsd-quick ad-hoc tasks:
{
  "git": {
    "quick_branch_template": "gsd/quick-{num}-{slug}"
  }
}
When set, /gsd-quick creates a branch named with the task ID and a slug derived from the task description before running. When null (the default), /gsd-quick works on your current branch.
Use the phase strategy with a short review cycle to get clean, reviewable PRs for each unit of work. Use the milestone strategy when your team reviews releases as a whole rather than individual phases.