> ## Documentation Index
> Fetch the complete documentation index at: https://zerv.wisl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Flow

> How zerv flow turns any Git state into a meaningful pre-release version. Branch patterns, post modes, dirty state, and build context.

`zerv flow` is automated pre-release management: it generates meaningful versions from any
Git state without manual decisions. The [version command](/concepts/version) gives you raw
control; flow layers opinionated, branch-driven logic on top of it.

## Core principles

1. **Semantic state capture** - Extract semantic meaning from ANY Git state (any branch, any
   commit, uncommitted changes)
2. **Multi-format output** - Transform semantic meaning into various version formats with
   customizable format support
3. **semantic-release integration** - Work with semantic release tools while providing
   fully automated pre-release versioning
4. **Build traceability** - Include sufficient context to trace versions back to exact Git
   states

## Version format

**Full example**: `1.0.1-alpha.12345.post.3.dev.1729924622+feature.auth.1.f4a8b9c`

**Structure**: `<BASE>-<PRE_RELEASE>.<POST>[.<DEV>][+BUILD_CONTEXT]`

* **`1.0.1`** - Base version (semantic meaning from tags)
* **`alpha.12345`** - Pre-release type and branch identification
* **`post.3`** - Commits since reference point
* **`[.dev.timestamp]`** - Optional dev timestamp for uncommitted changes
* **`[+BUILD_CONTEXT]`** - Optional build context for traceability

**Key point**: The core version `<BASE>-<PRE_RELEASE>.<POST>[.<DEV>]` contains all semantic
meaning needed to understand Git state. The build context `[+BUILD_CONTEXT]` is optional and
provides additional verbose information for easier interpretation and traceability.

**Version variations**:

* **Tagged release**: `1.0.1`
* **Tagged pre-release**: `2.0.1-rc.1.post.2`
* **Branch from tagged release**: `1.0.1-alpha.54321.post.1+feature.login.1.f4a8b9c`
* **Branch from tagged pre-release**: `2.0.1-alpha.98765.post.3+fix.auth.bug.1.c9d8e7f`
* **Uncommitted changes**: `2.0.1-alpha.98765.post.4.dev.1729924622+fix.auth.bug.1.c9d8e7f`

## Pre-release resolution

**Default behavior**: all branches start as `alpha.<hash-id>` (hash-based identification).

**Configurable branch patterns**: map specific branches to custom pre-release types (alpha,
beta, rc) with optional numbers:

* Example: `feature/user-auth` branch → `beta.12345` (label only, uses hash-based number)
* Example: `develop` branch → `beta.1` (label and custom number for stable branches)
* Any branch can be mapped to any pre-release type with hash-based or custom numbers

**Branch name resolution**: extract pre-release information from branch name patterns:

* Example: `release/1/feature-auth-fix` → `rc.1` (extracts number from branch pattern)
* Simplified GitFlow-inspired naming conventions

**Note**: Branch names are conventions, not strict requirements. zerv provides flexible
pattern matching and user configuration. See the
[branch rules on the flow CLI page](/cli/flow#branch-rules).

**Clean branches**: `main`, `master` → no pre-release (clean releases).

## Post-release resolution

**Configurable post representation** with two options:

* **Tag distance** *(default)*: count commits from the last tag
* **Commit distance**: count commits from the branch creation point
* **`post.0`**: exactly on reference point (no commits since)
* **`post.N`**: N commits since reference point
* Consistent across all branch types (alpha, beta, rc, etc.)

**Tag distance (release branches):**

```
main: v1.0.0 (tag)
└── release/1 (created) → create tag v1.0.1-rc.1.post.1
    └── 1 commit → 1.0.1-rc.1.post.1.dev.1729924622  (same post, dev timestamp)
    └── 2 commits → 1.0.1-rc.1.post.1.dev.1729924623  (same post, dev timestamp)
    └── create tag → 1.0.1-rc.1.post.2  (new tag increments post)
    └── more commits → 1.0.1-rc.1.post.2.dev.1729924624  (new post, dev timestamp)
```

**Commit distance (develop branch):**

```
main: v1.0.0 (tag)
└── develop (created from v1.0.0) → commit 1.0.1-beta.1.post.1  (1 commits since branch creation)
    └── 5 commits later → 1.0.1-beta.1.post.6  (6 commits since branch creation)
    └── 1 more commit → 1.0.1-beta.1.post.7  (7 commits since branch creation)
```

## Workflow examples

These diagrams show how flow behaves across branching strategies. To keep them readable,
build context is omitted from version strings; dirty state (`.dev.timestamp`) is shown where
relevant.

A commit shown as `1.0.1-alpha.12345.post.3.dev.1729924622` here reads
`1.0.1-alpha.12345.post.3.dev.1729924622+feature.user-auth.3.a1b2c3d` with build context
enabled.

### Trunk-based development

Complex trunk-based workflow with parallel features, nested branches, and synchronization.

**Scenario**: development from `v1.0.0` with parallel feature branches, synchronization, and
nested development.

```mermaid theme={null}
---
config:
  logLevel: 'debug'
  theme: 'base'
---
gitGraph
    %% Step 1: Initial commit on main with v1.0.0 tag
    commit id: "1.0.0"

    %% Step 2: Create parallel feature branches feature-1 and feature-2 from main
    branch feature-1 order: 2
    branch feature-2 order: 3

    %% Step 3: feature-2: Start development with dirty state
    checkout feature-2
    commit type:REVERSE id: "1.0.1-alpha.68031.post.0.dev.{timestamp}" tag: "uncommitted"

    %% Step 4: feature-2: Create first commit
    commit id: "1.0.1-alpha.68031.post.1"

    %% Step 5: feature-1: Create commits (parallel development)
    checkout feature-1
    commit id: "1.0.1-alpha.42954.post.1"
    commit id: "1.0.1-alpha.42954.post.2"

    %% Step 6: feature-1: Merge to main and release v1.0.1
    checkout main
    merge feature-1 id: "1.0.1" tag: "feature-1 released"

    %% Step 7: feature-2: Sync with main to get feature-1 changes
    checkout feature-2
    merge main id: "1.0.2-alpha.68031.post.2"

    %% Step 8: feature-2: Create additional commit
    commit id: "1.0.2-alpha.68031.post.3"

    %% Step 9: feature-3: Branch from feature-2 for sub-feature development
    branch feature-3 order: 4
    checkout feature-3
    commit id: "1.0.2-alpha.14698.post.4"

    %% Step 10: feature-3: Continue development with dirty state
    commit type:REVERSE id: "1.0.2-alpha.14698.post.4.dev.{timestamp}" tag: "uncommitted"

    %% Step 11: feature-3: Continue development with commits
    commit id: "1.0.2-alpha.14698.post.5"
    commit id: "1.0.2-alpha.14698.post.6"

    %% Step 12: feature-2: Merge feature-3 back to continue development
    checkout feature-2
    merge feature-3 id: "1.0.2-alpha.68031.post.6" tag: "feature-3 merged"

    %% Step 13: feature-2: Final development before release
    commit id: "1.0.2-alpha.68031.post.7"

    %% Step 14: Final release: feature-2 merges to main and releases v1.1.0
    checkout main
    merge feature-2 id: "1.1.0" tag: "feature-2 released"
```

**Key behaviors demonstrated**:

* **Parallel development**: `feature-1` and `feature-2` get unique hash IDs (`42954`, `68031`)
* **Version progression**: base version updates when syncing (`1.0.1` → `1.0.2`)
* **Dirty state**: uncommitted changes show `.dev.timestamp` suffix
* **Nested branches**: `feature-3` branches from `feature-2` with independent versioning
* **Clean releases**: main branch maintains semantic versions on merges

### GitFlow

GitFlow methodology with proper pre-release type mapping and merge patterns.

**Scenario**: main branch with `v1.0.0`, develop branch integration, feature development,
hotfix emergency flow, and release preparation.

```mermaid theme={null}
---
config:
  logLevel: 'debug'
  theme: 'base'
---
gitGraph
    %% Step 1: Initial state: main and develop branches
    commit id: "1.0.0"

    %% Step 2: Create develop branch with initial development commit
    branch develop order: 3
    checkout develop
    commit id: "1.0.1-beta.1.post.1"

    %% Step 3: Feature development from develop branch
    branch feature/auth order: 4
    checkout feature/auth
    commit id: "1.0.1-alpha.92409.post.2"
    commit id: "1.0.1-alpha.92409.post.3"

    checkout develop
    %% Step 4: Merge feature/auth back to develop
    merge feature/auth id: "1.0.1-beta.1.post.3" tag: "feature merged"

    %% Step 5: Hotfix emergency flow from main
    checkout main
    branch hotfix/critical order: 1
    checkout hotfix/critical
    commit id: "1.0.1-alpha.11477.post.1"

    checkout main
    %% Step 6: Merge hotfix to main and release v1.0.1
    merge hotfix/critical id: "1.0.1" tag: "hotfix released"

    %% Step 7: Sync develop with main changes and continue development
    checkout develop
    merge main id: "1.0.2-beta.1.post.4" tag: "sync main"

    %% Step 8: Continue development on develop branch
    commit id: "1.0.2-beta.1.post.5"

    %% Step 9: Release branch preparation
    branch release/1 order: 2
    checkout release/1
    commit id: "1.0.2-rc.1.post.1"
    commit id: "1.0.2-rc.1.post.2"
    commit type:REVERSE id: "1.0.2-rc.1.post.3.dev.{timestamp}" tag: "uncommitted"
    commit id: "1.0.2-rc.1.post.3"

    checkout main
    %% Step 10: Final release: merge release/1 to main
    merge release/1 id: "1.1.0" tag: "release 1.1.0"

    %% Step 11: Sync develop with release and prepare for next cycle
    checkout develop
    merge main id: "1.1.1-beta.1.post.1" tag: "sync release"
```

**Key behaviors demonstrated**:

* **Beta pre-releases**: develop branch uses `beta` for integration builds
* **Alpha pre-releases**: feature branches use `alpha` with hash-based identification
* **RC pre-releases**: release branches use `rc` for release candidates
* **Clean releases**: main branch maintains clean versions without pre-release suffixes
* **Hotfix flow**: emergency fixes from main with proper version propagation
* **Branch synchronization**: develop branch syncs with main releases

### Complex release management

Release branch scenarios including branch abandonment and cascading release preparation.

**Scenario**: main branch with `v1.0.0`, release branch preparation with critical issues
leading to abandonment, and selective branch creation for successful release.

```mermaid theme={null}
---
config:
  logLevel: 'debug'
  theme: 'base'
---
gitGraph
    %% Step 1: Initial state: main branch with v1.0.0 tag
    commit id: "1.0.0" tag: "v1.0.0"

    %% Step 2: Create release/1 from main for next release preparation
    branch release/1 order: 2
    checkout release/1
    commit id: "1.0.1-rc.1.post.1"
    commit id: "1.0.1-rc.1.post.2"

    %% Step 3: Create release/2 from the second commit of release/1 (before issues)
    %% release/1 at this point: 1.0.1-rc.1.post.2, so release/2 continues from there
    checkout release/1
    branch release/2 order: 1
    checkout release/2
    commit id: "1.0.1-rc.2.post.3"

    %% Step 4: Go back to release/1 and add the problematic third commit (issues found)
    checkout release/1
    commit id: "1.0.1-rc.1.post.3" tag: "issues found"

    %% Step 5: release/2 completes preparation successfully
    checkout release/2
    commit id: "1.0.1-rc.2.post.4"

    %% Step 6: Merge release/2 to main and release v1.1.0
    checkout main
    merge release/2 id: "1.1.0" tag: "v1.1.0"
```

**Version progression details**:

* **release/1**: `1.0.1-rc.1.post.1` → `1.0.1-rc.1.post.2` → `1.0.1-rc.1.post.3` (abandoned)
* **release/2**: created from `release/1`'s second commit (`1.0.1-rc.1.post.2`), continues as
  `1.0.1-rc.2.post.3` → `1.0.1-rc.2.post.4`
* **Main**: clean progression `1.0.0` → `1.1.0` (only from the successful `release/2` merge)

**Key behaviors demonstrated**:

* **Branch isolation**: each release branch maintains independent versioning regardless of
  parent/child relationships
* **Selective branching**: flow correctly handles branches created from specific historical
  commits
* **Abandonment handling**: unmerged branches don't affect final release versions on main
* **Cascade management**: complex branching scenarios where releases feed into other releases
  are handled transparently
* **Clean main branch**: main only receives versions from successfully merged releases,
  maintaining clean semantic versioning

## Where to go next

* [Flow CLI](/cli/flow) - schema presets, `--branch-rules`, and override flags
* [Schema system](/concepts/schema-system) - what `core`, `extra_core`, and `build` mean
* [Why zerv](/getting-started/why-zerv) - how flow differs from release automation
