DEV Community

Rizwan Saleem
Rizwan Saleem

Posted on

A Practical Git Worktree Workflow for Large, Multirepo Projects

A Practical Git Worktree Workflow for Large, Multirepo Projects

A Practical Git Worktree Workflow for Large, Multirepo Projects

If you work on a software project that spans multiple repositories, components, or microservices, standard branching and submodules can become brittle and painful. A worktree-based workflow lets you check out multiple branches or even multiple repositories in parallel, share a single Git history where it makes sense, and keep your workspace clean and fast. This guide walks you through a complete, opinionated workflow using git worktree, plus practical patterns for testing, automation, and collaboration.

Why a worktree workflow

  • Parallel focus: Work on several related repos or features without juggling dozens of clones or nested submodules.
  • Clean histories: Each feature or component gets a distinct branch while still sharing a central base.
  • Flexible isolation: Easily switch between active development streams without reconfiguring remotes or submodules.
  • Speed and simplicity: Reduced repo boilerplate and fewer crufted configurations.

    Core concepts

  • worktree: A separate checkout linked to a single Git repository. You can have multiple worktrees checked out from the same repository, each with its own HEAD, index, and working tree.

  • reference: A shared object database in .git/objects that all worktrees reuse, reducing disk space.

  • maintenance: You can add, remove, or switch worktrees on the fly; Git keeps them synchronized with the main repo.

Key benefits for large, multi-repo projects:

  • You can pin each component to its own branch while keeping a central integration branch for end-to-end validation.
  • You can test changes in one component with another component checked out in its own worktree, avoiding full clone cycles.

    Prerequisites

  • Git 2.15+ (worktrees have matured a lot since then; modern versions are recommended)

  • A main repository workspace that logically represents your project (even if you’ll link to multiple repos from a single “root” workflow)

  • A plan for how components map to branches or separate repos (discussed below)

    Setup: your baseline repository

  1. Create a canonical “integration” repo that will serve as the anchor for worktrees.

    • This repo contains the primary workflow files, CI configuration, and references to subcomponents via submodules or remotes if needed.
    • Alternatively, you can use a lightweight orchestrator repository that points to multiple repos via remotes or submodules as appropriate.
  2. Ensure you have a consistent git user configuration:

    • git config user.name
    • git config user.email
    • git config core.editor
  3. Decide on a naming convention:

    • worktree names: feature-, fix-, chore-, or component-
    • mappings: choose a convention for which components belong to which worktrees
  4. Initialize your baseline repository (if not already):

    • git init
    • Add remotes for any shared components if your workflow relies on them
    • Create an initial integration branch: git checkout -b integration ### Step-by-step: creating and managing worktrees

1) Create a new worktree for a feature

  • Suppose you’re adding a feature “analytics-dashboard” that affects a shared component repo.
  • From the integration repo root:
    • git worktree add ../analytics-dashboard analytics-dashboard
    • This creates a new working directory at ../analytics-dashboard bound to the same .git repository.
    • cd ../analytics-dashboard
    • git switch -c feature/analytics-dashboard

2) Maintain a shared base and isolated worktrees

  • In the integration repo, you can keep a central branch like integration, and each feature worktree can rebase onto it as needed:
    • In the feature worktree: git fetch origin; git rebase origin/integration
  • If you need to integrate a component that lives in another repo, you can:
    • Use a dedicated remote in the feature worktree, or
    • Use a submodule or subtree where appropriate, but prefer worktrees to minimize coupling.

3) Update the integration points

  • When a feature is ready to integrate, you can push its changes from its worktree and then merge into integration:
    • In feature worktree: git push origin feature/analytics-dashboard
    • In integration repo: git fetch origin; git merge origin/feature/analytics-dashboard

4) Remove a completed worktree

  • From the main repo:
    • git worktree prune
    • rm -rf path/to/worktree
  • The main repository remains intact; only the working directory is removed.

5) List current worktrees

  • git worktree list

    Branching strategy that fits worktrees

  • Central integration branch: integration

  • Feature branches: feature/xxx

  • Realtime hotfix branches: hotfix/xxx

  • Component-specific branches can exist within their own worktree checkout and be merged back into integration when ready

Tips:

  • Keep each worktree focused on a single feature or component; this minimizes conflicts across worktrees.
  • For cross-worktree dependencies, consider a dedicated integration test harness that fetches the latest from all relevant worktrees.

    Practical patterns for multi-repo coordination

  • Pattern A: Component-centric worktrees

    • Each component has its own worktree tied to a feature branch
    • You test all components together in the integration worktree
    • When a component’s worktree updates, you trigger a CI job that builds the integration image/activity
  • Pattern B: End-to-end testing with an orchestration script

    • Maintain a test harness script (Python, Bash, or Node) that:
    • Checks out latest integration
    • Spins up required worktrees for components that require updates
    • Runs end-to-end tests
    • Reports results
    • This reduces manual steps between local development and local validation
  • Pattern C: Lightweight automation with Git hooks

    • Use pre-commit or pre-push hooks to enforce consistency:
    • Ensure each feature worktree has a descriptive commit message
    • Validate that worktree branches are named per convention
    • Run a quick local test suite before pushing ### Code examples
  • Creating a new worktree for a feature

    • From the integration repo root:
    • git worktree add ../analytics-dashboard feature/analytics-dashboard
    • cd ../analytics-dashboard
    • git switch -c feature/analytics-dashboard
  • Syncing a worktree with integration

    • In the feature worktree:
    • git fetch origin
    • git rebase origin/integration
  • Pushing a finished worktree

    • In the feature worktree:
    • git push origin feature/analytics-dashboard
  • Integrating back into integration

    • In the integration repo:
    • git fetch origin
    • git merge origin/feature/analytics-dashboard
    • Run CI to verify end-to-end
  • Cleaning up a completed worktree

    • In the integration repo:
    • git worktree prune
    • Remove the directory manually:
    • rm -rf ../analytics-dashboard ### Testing strategy within worktrees
  • Local tests per component:

    • Each worktree runs its unit tests for the specific component
  • Integration tests:

    • A dedicated integration worktree or a separate test runner in the integration repo
    • Use a deterministic test environment (mock services or docker-compose)
  • End-to-end tests:

    • Spin up all relevant worktrees in a test harness
    • Validate pipelines or service interactions
  • Rollback plan:

    • If a feature breaks the integration, revert the merge in the integration branch and re-run tests

Example docker-compose approach:

  • docker-compose.yml defines services for components
  • Each component’s code is mounted into its service
  • The integration test suite runs as a separate service that calls each component’s API

    Collaboration and review tips

  • Use pull requests (PRs) to review worktree changes before merging into integration

    • PRs should reference the worktree name and feature
    • Include a brief description of cross-component impact
  • Keep PR scopes small; prefer incremental work

  • Encourage pair programming on cross-cutting features to reduce integration friction

    Common pitfalls and how to avoid them

  • Pitfall: Too many parallel worktrees strain your environment

    • Solution: Limit the number of active worktrees; retire stale ones
  • Pitfall: Conflicting dependencies across components

    • Solution: Agree on a shared API contract and a stable versioning scheme for components
  • Pitfall: Diverging histories across worktrees

    • Solution: Regularly rebase worktrees onto integration to minimize drift ### Automation blueprint (minimal starter)
  • Script: harness.sh

    • Purpose: bootstrap integration, create feature worktrees, run tests
    • Pseudo-steps:
    • ensure git is installed
    • pull latest integration
    • create or update required worktrees
    • run unit tests in each worktree
    • run integration tests
    • report results
  • GitHub Actions workflow

    • Workflow triggers on push to feature branches or PRs
    • Jobs:
    • Checkout integration repo
    • Create ephemeral worktrees for affected components
    • Install dependencies
    • Run unit and integration tests
    • Tear down ephemeral worktrees
    • Outputs: test results and a summary status badge ### When to choose this workflow
  • You work across multiple components or repos that need coordinated testing

  • You want fast iteration in local development without heavy submodule management

  • You value simple, repeatable integration testing with minimal boilerplate

If your project is already heavy with monorepo tooling or you rely on complex submodules, adapt the approach to your context:

  • For purely monorepo setups, you can still benefit from worktree-based feature isolation within the same repository
  • For multi-repo ecosystems, use a central orchestration repo as anchor and create per-component worktrees as described

    Quick-start checklist

  • [ ] Decide on integration branch naming and feature branch naming conventions

  • [ ] Set up a baseline integration repository

  • [ ] Verify your Git version supports worktrees (git version build-options should show worktree)

  • [ ] Create your first feature worktree and confirm you can switch between worktrees

  • [ ] Implement a lightweight test harness for end-to-end validation

  • [ ] Establish PR review and CI integration for worktree-based changes

  • [ ] Document the workflow for your team and enforce conventions
    Would you like a concrete starter script (bash or Python) tailored to your exact repo structure, including a sample docker-compose-based end-to-end test setup? If so, tell me your main components or repos and your preferred language for the automation script, and I’ll draft it.

-

Rizwan Saleem | https://rizwansaleem.co

Top comments (0)