How Worktrunk Handles Branch Naming Conventions to Prevent Errors

Worktrunk prevents filesystem and database errors by automatically normalizing Git branch names through built-in sanitize and sanitize_db filters that strip illegal characters before using names in file paths, Docker containers, or hook scripts.

Worktrunk is a Rust-based Git worktree management tool that treats branch names as structured data rather than raw strings. Because Git branch names can legally contain slashes, spaces, and other characters that are illegal in file paths or database identifiers, Worktrunk enforces strict branch naming conventions through automatic sanitization rules applied across all templating contexts.

Built-in Jinja-like Sanitization Filters

Worktrunk ships with two template filters that are automatically applied to the {{ branch }} variable in its internal templating engine. These filters ensure that branch names are safe for their intended destinations.

The sanitize Filter for Filesystem Safety

The sanitize filter makes branch names safe for file-system paths, including worktree directories and log files. It replaces forward slashes (/) and backslashes (\) with hyphens (-), while preserving other characters unchanged. This prevents directory traversal bugs and invalid path errors when Worktrunk creates directories or writes files.

The sanitize_db Filter for Database Identifiers

The sanitize_db filter prepares branch names for use as database identifiers, such as Docker container names or PostgreSQL database names. This filter performs four transformations:

  1. Converts the string to lowercase
  2. Replaces any non-alphanumeric character with an underscore (_)
  3. Prefixes the result with an underscore if it would start with a digit
  4. Truncates to 48 characters and appends a short hash-suffix for uniqueness

This prevents naming collisions where two distinct branches might otherwise map to the same identifier.

Core Implementation Files

The sanitization pipeline is implemented in two key source files within the max-sixty/worktrunk repository.

src/path.rs

The core sanitization routine is defined in src/path.rs as the sanitize_for_filename function. This function implements the slash-to-dash replacement logic used by the sanitize filter and is called directly when Worktrunk constructs internal log file paths.

src/template.rs

During startup, Worktrunk registers the filters with the minijinja template engine in src/template.rs. The registration code maps the filter names (sanitize, sanitize_db) to the Rust functions that perform the transformations, making them available in every Worktrunk template including config.toml and hook scripts.

Contexts Where Sanitization Is Applied

Worktrunk applies these filters automatically across multiple contexts to prevent runtime errors.

Worktree Path Templates – The worktree-path configuration uses {{ branch | sanitize }} to create directories. For example, a branch named feature/auth/login becomes .worktrees/feature-auth-login. This is demonstrated in tests/integration_tests/config_show.rs at lines 168-173.

Hook Variables – Hooks receive a sanitized branch variable when the script needs a safe filename, though the raw branch name remains available for logic operations. See tests/integration_tests/user_hooks.rs at lines 3790-3840 for implementation details.

Docker and Database Names – Configuration templates for Docker containers use {{ branch | sanitize_db }} to generate valid container names. For a branch 123/feature-xyz, the output resembles _123_feature_xyz_ab12, conforming to Docker's naming rules.

Log File Paths – When the logger writes to paths containing branch names, the branch component is passed through sanitize_for_filename to guarantee valid filenames, as shown in tests/integration_tests/config_state.rs at lines 7-15.

Symbolic Switch Arguments – When a user runs wt switch @ (referring to the current branch), Worktrunk resolves the symbolic reference first, then passes the resolved name through the sanitization pipeline before any hook executes, as implemented in tests/integration_tests/user_hooks.rs at lines 3417-3424.

Practical Configuration Examples

Configuring Worktree Paths


# dev/config.example.toml

worktree-path = ".worktrees/{{ branch | sanitize }}"

When switching to a branch called feature/auth/login, Worktrunk creates the directory .worktrees/feature-auth-login.

Using the Branch in a Hook


# .github/worktrunk/hooks/pre-start

#!/usr/bin/env sh

# Log the sanitized branch name for diagnostics

echo "Running on branch {{ branch | sanitize }}" >> "$WT_LOG/pre-start.log"

Running wt switch feature/auth/login writes a line containing feature-auth-login to the log.

Database-Safe Names


# dev/docker-compose.yml (template)

services:
  db:
    container_name: "{{ repo }}-{{ branch | sanitize_db }}"

For a branch 123/feature-xyz, the container name becomes something like myrepo-_123_feature_xyz_ab12.

Summary

  • Worktrunk uses sanitize and sanitize_db filters to normalize branch names for different contexts
  • The sanitize_for_filename function in src/path.rs handles filesystem safety by replacing slashes with hyphens
  • Templates automatically apply these filters in worktree-path configurations, hook scripts, and Docker templates
  • The sanitize_db filter prevents collisions and ensures valid identifiers by lowercasing, underscoring non-alphanumeric characters, and appending hash suffixes
  • All sanitization is registered in src/template.rs using the minijinja template engine

Frequently Asked Questions

What characters does Worktrunk remove from branch names?

For filesystem paths, Worktrunk replaces forward slashes (/) and backslashes (\) with hyphens using the sanitize filter. For database identifiers, the sanitize_db filter replaces any non-alphanumeric character with an underscore.

How does Worktrunk handle branch names that start with numbers for database identifiers?

The sanitize_db filter automatically prefixes the sanitized string with an underscore (_) if the result would start with a digit. This ensures compliance with Docker and PostgreSQL naming rules that prohibit identifiers beginning with numbers.

Where is the branch sanitization logic implemented in the Worktrunk source code?

The core logic resides in src/path.rs within the sanitize_for_filename function, while the template filter registration occurs in src/template.rs using the minijinja template engine. Integration tests in tests/integration_tests/config_show.rs and user_hooks.rs demonstrate the filters in action.

Can I use raw branch names in Worktrunk hooks?

Yes, hooks receive the raw branch name via the branch variable for comparison logic and conditional operations. However, you should apply the {{ branch | sanitize }} filter when using the branch name in file paths, commands, or any context where filesystem-safe strings are required.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →