Project Branching¶
Project branches let you create isolated snapshots of a project's artifact pins and configuration, experiment freely, and merge changes back into the main line when you are ready. This is separate from artifact-level DAG branching, which tracks individual artifact version history.
Feature flag required. Project branching is gated behind the
dvcs_branching_enabledfeature flag. See Enabling the feature flag below.
Overview: Project branches vs. artifact branches¶
| Concept | Scope | What it tracks |
|---|---|---|
| Project branch | Whole project | Which artifact versions are pinned per project; project-level config |
| Artifact branch (DAG) | Single artifact | Individual artifact content versions and merge history |
Project branches are coarse-grained: switching a project branch swaps the entire set of artifact pins in one operation. Artifact branches are fine-grained: they track content changes inside a single artifact. The two systems compose — artifact-level version resolution happens inside the ProjectGraphService during a project merge.
Enabling the feature flag¶
Project branching is disabled by default. Enable it in your deployment:
When the flag is off, all branch API endpoints return 404 and the CLI prints:
Branching is disabled (dvcs_branching_enabled=false). Enable the feature flag to use project branches.
The implicit main branch¶
Every project automatically has a main branch. It is created lazily on the first project mutation after the flag is enabled; existing projects are backfilled with a main branch row during the feature migration. The main branch:
- Is marked
is_default: true. - Cannot be deleted.
- Is the target for most merge operations.
Managing branches via the web UI¶
Viewing branches¶
Open a project's detail page. When dvcs_branching_enabled is on, a branch picker appears in the project header showing the current branch (default: main).
Creating a branch¶
- Open the branch picker dropdown.
- Select New branch at the bottom of the list.
- Enter a branch name and optionally choose a parent branch.
- Click Create.
Switching branches¶
Select a branch from the branch picker. The page re-fetches project artifacts filtered to that branch's head state. The ?branch=<name> query parameter is reflected in the URL.
Merging branches¶
- Click the Merge button (visible on non-default branches).
- In the Merge dialog, confirm the source and target branches.
- Click Merge. The merge saga runs server-side.
If the merge is partial (some artifacts could not be resolved automatically), the dialog shows:
Merge partially complete — some artifacts could not be resolved automatically.
Retry the merge with the same token to resume. See Known limitation: partial merge recovery.
Deleting a branch¶
Use the branch picker overflow menu to delete a branch. You will be asked to confirm. The main branch cannot be deleted.
Managing branches via the CLI¶
All branch subcommands require dvcs_branching_enabled=true. They work in both local and enterprise editions; enterprise calls authenticate via the configured PAT.
List branches¶
Output is a table with columns: Branch Name, Default, Visibility, Created At.
Create a branch¶
# Fork from the project default branch
skillmeat project branch create <project_id> experimental
# Fork from a specific parent
skillmeat project branch create <project_id> hotfix --parent main
# Create a private (user-only) branch
skillmeat project branch create <project_id> draft --private
Switch branches (local CLI context)¶
This writes projects.<project_id>.current_branch = experimental to ~/.skillmeat/config.toml so subsequent CLI commands that accept a --branch option default to that branch.
Merge branches¶
# Merge experimental into main
skillmeat project branch merge <project_id> --source experimental --target main
# Idempotent retry with a fixed token
skillmeat project branch merge <project_id> --source experimental --target main \
--token 550e8400-e29b-41d4-a716-446655440000
If the merge is partial, the CLI outputs a warning and exits 0. Rerun with the same --token to resume.
Delete a branch¶
# With confirmation prompt
skillmeat project branch delete <project_id> old-feature
# Skip prompt
skillmeat project branch delete <project_id> old-feature --yes
Branch visibility¶
Branches have a visibility field:
| Value | Meaning |
|---|---|
team_shared |
Visible to all project members (default) |
user_private |
Visible only to the branch creator |
User-private branch management UI is minimal in the current release. Full private-branch UX is planned as a follow-on. See Known limitation: user-private branch UX.
Known limitations¶
Partial merge recovery¶
When a project merge saga fails partway through (for example, one artifact's merge produces a conflict), the project is left in a partial state. The idempotency token allows safe retry:
skillmeat project branch merge <project_id> \
--source experimental --target main \
--token <uuid-from-first-attempt>
A formal recovery workflow (resume endpoint) is being designed and will be available in a future release.
User-private branch UX¶
The schema supports user_private branches, but the filter logic and management surface are minimal in this release. Private branches can be created via --private flag but do not yet have a dedicated management page.
Related¶
- DAG Branching & Merge-Back — artifact-level version branching
- Version History & Restore — per-artifact version timeline
- Edition Feature Matrix — which features require enterprise