<div align="center">
<p align="center">
<img src="assets/tbdflow-logo.png" alt="tbdflow logo" width="200"/>
</p>
<p align="center">
<i><b>Keep your code flowing</b></i><br/>
</p>
[](https://crates.io/crates/tbdflow)
[](https://crates.io/crates/tbdflow)
</div>
## tbdflow, a Trunk-Based Development CLI
`tbdflow` is a lightweight command-line tool that helps you (and your team) stay in flow with Trunk-Based Development (TBD).
This CLI supports both the default commit-to-main workflow and the structured handling of short-lived branches for features, releases, and hotfixes.

## Philosophy
This tool is built around a specific philosophy of Trunk-Based Development:
* **Main is the default.** The `commit` command is your everyday go-to. It automates pulling the latest changes, committing, and pushing directly to `main`, promoting small, frequent integrations.
* **Branches are the exception.** While branches are supported, they’re treated as short-lived exceptions and not the norm.
* **Cleanup is automatic.** The complete command enforces branch short-livedness by merging and automatically tagging (release) and deleting completed branches, helping keep your repo tidy.
* **Conventional Commits encouraged.** Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/) for clarity and consistency.
### Why not just use Git?
This CLI isn’t a replacement for Git. You’ll still reach for raw `git` when doing advanced work like rebasing, cherry-picking, or running `git bisect`.
This tool is as a **workflow assistant**, `tbdflow` encapsulates a repeatable, opinionated process to support your day-to-day development.
It offers three main benefits:
1. **Consistency across the team**
Everyone follows the same steps for common tasks. Commits, branches, and releases are handled the same way every time, keeping your Git history clean and predictable.
2. **Less to remember**
No need to recall the exact flags or sequences (like `pull --rebase`, `merge --no-ff`, or commit message formats). The CLI handles that, so you can stay focused on writing code.
3. **It supports "the TBD way"**
This tool makes the preferred approach easy by providing a smooth, safe, and efficient path for 80% of everyday tasks. For the other 20%, you can always use Git directly.
### Installation
You need [Rust and Cargo](https://www.rust-lang.org/tools/install) installed.
#### Installing from crates.io
The easiest way to install `tbdflow` is to download it from [crates.io](https://crates.io/crates/tbdflow). You can do it using the following command:
```bash
cargo install tbdflow
```
If you want to update `tbdflow` to the latest version, execute the following command:
```bash
tbdflow update
```
#### Building from source
Alternatively you can build `tbdflow` from source using Cargo:
```bash
git clone https://github.com/cladam/tbdflow.git
cd tbdflow
sudo cargo install --path . --root /usr/local
```
### Monorepo Support
`tbdflow` is "monorepo-aware." It understands that in a monorepo, you often want commands to be scoped to a specific project or subdirectory.
When you run `tbdflow commit`, `tbdflow sync` or `tbdflow status` from the root of a configured monorepo, the tool will intelligently ignore project subdirectories, making sure you only commit changes to root-level files (like `README.md`, `LICENSE`, or `CI configuration`). When run from within a project subdirectory, the commands are automatically scoped to just that directory (**N.B.** you need to run `tbdflow init` from within the subdirectory for this to work).
This is configured in your root `.tbdflow.yml` file:
```
# in .tbdflow.yml
monorepo:
enabled: true
# A list of all directories that are self-contained projects.
# These will be excluded from root-level commits and status checks.
project_dirs:
- "frontend"
- "backend-api"
- "infra"
```
#### Handling Cross-Cutting Changes
For "vertical slice" changes that intentionally touch multiple project directories, you can use the `--include-projects` flag. This flag overrides the default safety mechanism and stages all changes from all directories, allowing you to create a single, cross-cutting commit.
### Configuration
`tbdflow` is configurable via two optional files in the root of your repository. To get started quickly, run `tbdflow init` to generate default versions of these files.
`.tbdflow.yml`
This file controls the core workflow of the tool. You can customise:
- The name of your main branch (e.g. main, trunk).
- Allowed branch types and their prefixes (e.g feat/, chore/)
- A strategy for handling issue references ("branch-name" or "commit-scope")
- The threshold for stale branch warnings.
- Automatic tagging formats.
- Commit message linting rules.
`.dod.yml`
This file controls the interactive Definition of Done checklist for the commit command.
### Features
#### The Definition of Done (DoD) Check
To move beyond just automating process, `tbdflow` integrates an optional pre-commit quality check. If a `.dod.yml` file is present in your repository, the commit command will present an interactive checklist to ensure your work meets the team's agreed-upon standards.
**Example** `.dod.yml`:
```
# .dod.yml in your project root
checklist:
- "All relevant automated tests pass successfully."
- "New features or fixes are covered by new tests."
- "Security implications of this change have been considered."
- "Relevant documentation (code comments, READMEs) is updated."
```
If you try to proceed without checking all items, the tool will offer to add a TODO list to your commit message footer, ensuring the incomplete work is tracked directly in your Git history.
#### Commit Message Linting
If a `.tbdflow.yml` file is present and contains a lint section, the commit command will automatically validate your commit message against the configured rules before the DoD check. This provides immediate feedback on stylistic and structural conventions.
**Default linting rules:**
```yaml
lint:
conventional_commit_type:
enabled: true
allowed_types:
- build
- chore
- ci
- docs
- feat
- fix
- perf
- refactor
- revert
- style
- test
issue_key_missing:
enabled: false
pattern: ^[A-Z]+-\d+$
scope:
enabled: true
enforce_lowercase: true
subject_line_rules:
max_length: 72
enforce_lowercase: true
no_period: true
body_line_rules:
max_line_length: 80
leading_blank: true
```
---
## Global options
| --verbose | Prints the underlying Git commands as they are executed. | No |
| --dry-run | Simulate the command without making any changes. | No |
## Commands
### 1. `commit`
This is the primary command for daily work.
Commits staged changes using a Conventional Commits message. This command is context-aware:
* **On `main`:** It runs the full TBD workflow: pulls the latest changes with rebase, commits, and pushes.
* **On any other branch:** It simply commits and pushes, allowing you to save work-in-progress.
**Usage:**
```bash
tbdflow commit [options]
```
**Options:**
| -t | --type | The type of commit (e.g., feat, fix, chore). | Yes |
| -s | --scope | The scope of the changes (e.g., api, ui). | No |
| -m | --message | The descriptive commit message (subject line). | Yes |
| | --body | Optional multi-line body for the commit message. | No |
| -b | --breaking | Mark the commit as a breaking change. | No |
| | --breaking-description | Provide a description for the 'BREAKING CHANGE:' footer. | No |
| | --tag | Optionally add and push an annotated tag to this commit. | No |
| | --issue | Optionally add an issue reference to the footer. | No |
| | --no-verify | Bypass the interactive DoD checklist. | No |
**Example:**
```bash
# A new feature
tbdflow commit -t feat -s auth -m "add password reset endpoint"
# A bug fix with a breaking change
tbdflow commit -t fix -m "correct user permission logic" -b
tbdflow commit -t refactor -m "rename internal API" --breaking --breaking-description "The `getUser` function has been renamed to `fetchUser`."
# A bug fix with a new tag
tbdflow commit -t fix -m "correct user permission logic" --tag "v1.1.1"
```
### 2. `branch`
Creates and pushes a new, short-lived branch from the latest version of `main`. This is the primary command for starting new work that isn't a direct commit to `main`.
**Usage:**
```bash
tbdflow branch --type <type> --name <name> [--issue <issue-id>] [--from_commit <commit hash>]
```
**Options (release):**
| -t, --type | The type of branch (e.g. feat, fix, chore). See .tbdflow.yml for allowed types. | Yes |
| -n, --name | A short, desriptive name for the branch. | Yes |
| --issue | Optional issue reference to include in the branch name or commit scope. | No |
| -f, --from_commit | Optional commit hash on `main` to branch from. | No |
**Examples:**
```bash
# Create a simple feature branch named "feat/new-dashboard"
tbdflow branch -t feat -n "new-dashboard"
# Create a fix branch with an issue reference in the name
# (This will be named "fix/PROJ-123-login-bug" by default)
tbdflow branch -t fix -n "login-bug" --issue "PROJ-123"
# Create a release branch from a specific commit
tbdflow branch -t release -v "2.1.0" -f "39b68b5"
```
### 3. `complete`
Merges a short-lived branch back into main, then deletes the local and remote copies of the branch.
**Automatic Tagging:**
* When completing a release branch, a tag (e.g. v2.1.0) is automatically created and pushed.
**Usage:**
```bash
tbdflow complete --type <branch-type> --name <branch-name>
```
**Options:**
| -t | --type | The type of branch: feature, release, or hotfix. | Yes |
| -n | --name | The name or version of the branch to complete. | Yes |
**Examples:**
```bash
# Complete a feature branch
tbdflow complete -t feat -n "user-profile-page"
# Complete a release branch (this will be tagged v2.1.0)
tbdflow complete -t release -n "2.1.0"
```
### 4. `changelog`
Generates a changelog in Markdown format from your repository's Conventional Commit history. See `tbdflow` repo for a CHANGELOG.md generated by this command.
**Usage:**
```bash
tbdflow changelog [options]
```
**Options:**
| --unreleased | Generate a changelog for all commits since the last tag. |
| --from | Generate a changelog for commits from a specific tag. |
| --to | Generate a changelog for commits up to a specific tag (defaults to HEAD). |
**Examples:**
```bash
# Generate a changelog for a new version
tbdflow changelog --from v0.12.0 --to v0.13.0
# See what will be in the next release
tbdflow changelog --unreleased
```
### 5. Utility commands
`tbdflow` has a couple of commands that can be beneficial to use but they are not part of the workflow, they are for inspecting the state of the repository.
**Examples:**
```bash
# Does a pull, shows latest changes to main branch, and warns about stale branches.
tbdflow sync
# Checks the status of the working dir
tbdflow status
# Shows the current branch name
tbdflow current-branch
# Explicitly checks for local branches older than one day.
tbdflow check-branches
# Checks for a new version of tbdflow and updates it if available.
tbdflow update
```
### 6. Advanced Usage
#### Shell Completion
To make `tbdflow` even faster to use, you can enable shell completion. Add one of the following lines to your shell's configuration file.
For Zsh (`~/.zshrc`):
```bash
eval "$(tbdflow generate-completion zsh)"
```
For Bash (`~/.bashrc`):
```bash
eval "$(tbdflow generate-completion bash)"
```
For Fish (`~/.config/fish/config.fish`):
```bash
#### Man Page Generation
You can generate a man page for `tbdflow` by running the following command:
```bash
tbdflow generate-man-page > tbdflow.1 && man tbdflow.1
```