GSD-Build Branching Strategies: How Branches Are Created During Execution
GSD-Build supports three Git branching strategies—none, phase, and milestone—which control whether branches are created per milestone, per phase, or not at all during gsd execute-phase workflows.
The gsd-build/get-shit-done repository provides a structured CLI for managing software milestones through Git-based workflows. Understanding the available GSD-Build branching strategies is essential for teams configuring their development pipeline, as these settings determine exactly when and how Git branches are created during phase execution.
Supported Branching Strategies in GSD-Build
GSD-Build implements three distinct branching strategies, controlled via the git.branching_strategy configuration setting. According to the source code in get-shit-done/bin/gsd-tools.cjs, the default configuration is:
defaults = {
branching_strategy: 'none',
phase_branch_template: 'gsd/phase-{phase}-{slug}',
milestone_branch_template: 'gsd/{milestone}-{slug}',
}
The three strategies work as follows:
none(default): All commits occur on the current branch (typicallymain). No new branches are created during execution.phase: Creates a separate branch for each phase of a milestone. The branch is created when the firstgsd execute-phasecommand runs for that specific phase.milestone: Creates a single branch shared across all phases belonging to the same milestone. The branch is created at the start of the first phase in the milestone.
The branch naming templates use placeholder variables that are resolved at runtime:
{phase}: The phase number (zero-padded to two digits){milestone}: The milestone version identifier{slug}: A URL-friendly identifier for the phase or milestone
How GSD-Build Creates Branches During Execution
Configuration Initialization
When a workflow starts via gsd execute-phase, the CLI reads the configuration to determine the branching_strategy, phase_branch_template, and milestone_branch_template values. This initialization logic is implemented in get-shit-done/bin/gsd-tools.cjs at lines 199-202.
The Handle Branching Step
Inside get-shit-done/workflows/execute-phase.md, the handle_branching step executes the following logic:
- Strategy Check: If
branching_strategyis set to"none", the step skips branch handling and remains on the current branch. - Branch Name Computation: For
"phase"or"milestone"strategies, the system computes thebranch_nameusing the appropriate template. - Branch Creation: Executes
git checkout -b $branch_nameorgit switch -c $branch_nameif the branch does not yet exist.
# Conceptual implementation from handle_branching
if [ -n "$BRANCH_NAME" ]; then
git switch -c "$BRANCH_NAME"
fi
# Subsequent commits target $BRANCH_NAME
Commit Phase Work
Once the branch is created and checked out, all plan and documentation commits generated during that phase execution are applied to this branch rather than the default branch.
Milestone Completion Handling
When gsd complete-milestone runs, the handle_branches step in get-shit-done/workflows/complete-milestone.md inspects the strategy, lists created branches using git branch --list "${BRANCH_PREFIX}*", and presents merge options to the user:
- Squash merge: Consolidates all branch commits into a single commit
- Merge with history: Preserves the complete commit history
- Delete: Removes the branch after merging
- Keep: Retains the branch without merging
# Example squash merge from complete-milestone.md
git merge --squash "$branch"
git commit -m "feat: $branch for v${VERSION}"
Branch Lifecycle by Strategy
The branch lifecycle varies significantly based on the chosen strategy:
none: No branch lifecycle exists. All work commits directly to the current branch.
phase: One branch per phase lifecycle. Created at the start of each phase via execute-phase, optionally merged or deleted when complete-milestone runs.
milestone: Single branch per milestone lifecycle. Created at the first phase of the milestone, reused for subsequent phases, and handled collectively at milestone completion.
Configuration Examples
To configure the phase branching strategy in your project settings:
{
"git": {
"branching_strategy": "phase",
"phase_branch_template": "gsd/phase-{phase}-{slug}",
"milestone_branch_template": "gsd/{milestone}-{slug}"
}
}
The branch name generation logic extracted from gsd-tools.cjs works as follows:
function getBranchName({ phaseInfo, milestoneInfo, config }) {
if (config.branching_strategy === 'phase' && phaseInfo) {
return config.phase_branch_template
.replace('{phase}', String(phaseInfo.number).padStart(2, '0'))
.replace('{slug}', phaseInfo.slug);
}
if (config.branching_strategy === 'milestone' && milestoneInfo) {
return config.milestone_branch_template
.replace('{milestone}', milestoneInfo.version)
.replace('{slug}', milestoneInfo.slug);
}
return null; // "none" strategy
}
Summary
- GSD-Build offers three branching strategies configured via
git.branching_strategy:none,phase, andmilestone. - Default values are defined in
get-shit-done/bin/gsd-tools.cjs, withnoneas the default strategy. - Branches are created during the
handle_branchingstep ofexecute-phaseworkflows, not during planning or configuration. - Branch names follow configurable templates using
{phase},{milestone}, and{slug}placeholders. - The
complete-milestonecommand handles branch cleanup through squash merges, standard merges, or deletion based on user selection.
Frequently Asked Questions
What is the default branching strategy in GSD-Build?
The default branching strategy is none, meaning all commits are made directly to the current branch without creating additional Git branches. This default is explicitly set in get-shit-done/bin/gsd-tools.cjs within the defaults configuration object.
How does the phase strategy differ from the milestone strategy?
The phase strategy creates a new branch for every individual phase within a milestone (e.g., gsd/phase-03-authentication), while the milestone strategy creates one branch shared across all phases in a milestone (e.g., gsd/v1.0-mvp). The phase strategy provides granular isolation per phase, whereas the milestone strategy groups related work together.
Can I customize branch naming templates?
Yes, you can customize branch naming by modifying the phase_branch_template and milestone_branch_template settings in your configuration file. These templates support the placeholders {phase}, {milestone}, and {slug}, which are dynamically replaced during execution based on the current milestone and phase metadata.
When exactly are branches created during execution?
Branches are created at the beginning of phase execution, specifically within the handle_branching step documented in get-shit-done/workflows/execute-phase.md. If the branch already exists, the CLI switches to it; otherwise, it creates the branch using git switch -c before any plan-execution commits occur.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →