Skip to content

Latest commit

 

History

75 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

feature-per-worktree

Orchestrate multi-repo feature branches with isolated git worktrees and dependency isolation for Java projects using Maven and Gradle.

Built for Quarkus and Hibernate development, where a single feature often spans multiple repositories with interdependent SNAPSHOT artifacts.

Problem

When working across multiple Java repositories (e.g., Quarkus and its Hibernate dependencies), feature branches pollute each other's build artifacts. You change a dependency, rebuild, and suddenly your "clean" main branch has stale SNAPSHOTs in your local Maven repository. A/B comparison between upstream and your feature becomes unreliable.

Solution

Each feature gets its own directory with:

  • Git worktrees for every repo involved (not full clones — lightweight and instant)
  • An isolated .m2 local Maven repository, seeded from main/.m2 via hardlinks (instant, near-zero disk overhead)
  • Maven config that ensures builds never touch ~/.m2

A main/ directory always tracks upstream and has pre-built SNAPSHOTs ready for comparison.

Directory Structure

~/git/hibernate/
├── main/                        # "real" clones, always at upstream/main
│   ├── quarkus/
│   ├── hibernate-orm/
│   ├── hibernate-reactive/
│   ├── hibernate-tools/
│   ├── hibernate-models/
│   ├── hibernate-search/
│   └── quarkus-wiki/            # reference only
├── 3223/                        # feature QUARKUS-3223
│   ├── quarkus/                 # worktree from main/quarkus
│   ├── hibernate-orm/           # worktree, added on demand
│   ├── .m2/                     # seeded from ~/.m2 via hardlinks
│   └── journal/                 # daily work journal
├── journal/                     # archived journals from completed features
├── 4567/                        # another feature
│   └── ...

How It Works

Dependency Isolation via Hardlinked .m2

When a feature directory is created, its .m2 is seeded from ~/.m2/repository using rsync --link-dest. This creates hardlinks — the copy is instant and uses near-zero extra disk space. When you rebuild a SNAPSHOT in your feature, only the changed jars diverge and consume real space.

Every worktree has a .mvn/maven.config with -Dmaven.repo.local pointing to its feature's .m2, so Maven never touches ~/.m2.

A/B Comparison

  1. Open main/quarkus — pre-built upstream SNAPSHOTs, always clean
  2. Open 3223/quarkus — your feature branch with its own SNAPSHOTs
  3. Both are independently buildable and testable, no interference

Refresh Loop

A background script (scripts/refresh-main.sh) keeps main/ in sync: fetch upstream, reset all repos, rebuild SNAPSHOTs, sleep 1 hour, repeat.

Prerequisites

  • Java (JDK 17+)
  • mvnd (Maven Daemon) and Gradle
  • Git
  • $GITHUB_USERNAME environment variable set to your GitHub username (for fork URLs)
  • Forks of the upstream repositories under your GitHub account

Usage with Claude Code

This repo is designed to be used with Claude Code. The .claude/skills/ directory contains skills that automate the workflow:

Skill Description
/init-workspace Clone all repos into main/, set up remotes, do builds
/create-feature <number> Create a feature directory with worktree and isolated .m2
/add-repo-to-feature <repo> <number> Add another repo's worktree to a feature
/delete-feature <number> Clean up worktrees and delete a feature directory
/refresh-main Start the hourly upstream refresh loop
/hibernate-update Bump Hibernate ORM/Reactive/Search/Tools versions in Quarkus
/migration-guide Generate a Quarkus migration guide entry for a Hibernate upgrade
/write-journal Write a daily work journal entry for the current feature
/today-journal Quick summary of today's work from journal entries

Agents

The .agents/ directory contains agent skills for use with AI coding assistants beyond Claude Code. See AGENTS.md for details.

Adapting to Your Projects

This workspace is currently configured for Quarkus/Hibernate development, but the pattern works for any multi-repo setup:

  1. Fork the upstream repos to your GitHub account
  2. Set $GITHUB_USERNAME to your GitHub username
  3. Update CLAUDE.md with your repos and upstream URLs
  4. Update the skills to reference your repos
  5. Run /init-workspace to set everything up

About

Orchestrate multi-repo feature branches with isolated git worktrees and dependency isolation

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages