My git-worktree setup using worktrunk and caddy
Deep in a feature but need to fix a quick bug? See how I use git-worktree, Worktrunk, and a dynamic Caddyfile to seamlessly switch contexts and environments.
Author
Divyendu SinghDate published
Imagine you are building a large feature and find yourself deep in the context of a problem when you receive a request to solve a minor bug.
While you know how to fix this bug instantly, this is still a major context switch as you have to
- stash or temporarily commit your current changes
- open a new branch
- make the “minor” change
- re-create the context
git-worktree aims to address this issue by allowing you to work on multiple branches in the same repository.
However, it only provides the ability to quickly switch a branch without losing context. To have a working project where you can test changes end to end, you need some additional things like
- the environment variables, as the .env files are usually git ignored, they aren’t copied over in the git-worktree folder.
- ability to run multiple versions of the codebase (if it is a web server for example)
Enter my setup
Worktrunk
Although, you can use git-worktree commands directly, worktrunk provides nicer APIs to achieve the same goals (copying .env files over, less typing).
It is a very thin wrapper, here is an example:
See their docs for other examples but you get the idea.
Copying .env files
This is very project specific so it would vary from project to project but usually my projects are powered by .env files. You can run a git hook using lefthook to generate an env file (by getting the relevant secrets from 1password or locally encrypted env files using dotenvx for example). In fact, this is what I was doing until a week or so ago before I ran into worktrunk.
Worktrunk has a concept of .worktreeinclude file which is a .gitignore style file for copying files over, here is what it looks like for a web project that I work on:
Just this file is not enough, you need a way to run worktrunk hooks on each work tree, here is my config currently:
So essentially, when a git-worktree is created via worktrunk, we install the dependencies and copy over the .env files (yes this works for nested files too). With this, you are already ready to work on the project and run a dev server (but what about port clashes?).
Clash of the dev servers
You are usually testing things end to end in a web server, I usually like to even run projects with https on a custom URL. To power this, I use caddy, here is what my Caddyfile usually looks.
But when using multiple git-worktrees, I didn’t want to stop the dev server so port 5173 (vite default) gets free. I wanted to create a predictable pattern so the next available port is used (and is addressable with https).
Luckily, vite does half the job of running the dev server at 5174, if 5173 is not available but depending on your application, you might have to get a random port and run your application there.
For the other half, I use caddy, here is the modified Caddyfile
Essentially, this allows the following scheme to work:
You might have to change some other things in your application for this to work for you or change the URL scheme to suit your application needs.
For example, this setup also supports local ‘login’ locally for me because the cookie domain is set to .trackfootball.localhost.
Bonus - AI agents
Is it 2026 without a post mentioning AI agents? While this post is 100% handwritten, you might have noticed by now that the above setup would make AI agents have access to isolated environment with git-worktree easily (depending on what all do you need to / want to isolate in your environment).
In fact, worktrunk supports running any binary command with a single command while creating the git-worktree. Here is how you would boot the claude in one go:
You might also need isolated instances of other things in your development environment like a database. Luckily, Xata provides ability to create a Postgres database branches quickly and it even supports Agent Skills for your AI agent to be able to create branches autonomously.
If you want to experiment with Xata branching in your own repo, the CLI docs and branching workflow are the place to start.
Conclusion
This post described my current git-worktree setup, this hasn’t stood the test of time yet but I wanted to share it already to get feedback from the wider community.
Thanks for reading this and please share tips and your setup with me.
Related Posts
Teaching Claude Code to use isolated database branches with Agent Skills
Learn how to set up the Xata Agent Skill in minutes. Enable Claude Code to access realistic data using isolated database branches for safer, faster debugging.
What is database branching? A complete guide for development teams
Learn what database branching is, how copy-on-write works, and how to use it to create isolated databases without conflicts or long copy times.