Auto-copy files when creating Git worktrees or Jujutsu workspaces
quality 2/10 · low quality
0 net
AI Summary
A guide to automatically copy configuration files (like .env, API keys, local config) when creating new Git worktrees or Jujutsu workspaces using a .worktree-copy manifest file and shell hooks or wrapper functions.
Entities
Git
Jujutsu
Claude Code
Cursor
Lefthook
Husky
Bash
Zsh
Fish shell
Auto-copy files when creating Git worktrees or Jujutsu workspaces â Cretezy Mar 10, 2026 Tutorial Git Jujutsu Auto-copy files when creating Git worktrees or Jujutsu workspaces Worktrees and workspaces are one of the best ways to work across multiple branches simultaneously â and theyâre especially powerful when pairing with AI coding tools like Claude Code or Cursor, where you might spin up a fresh workspace per task or conversation to keep things isolated and clean. The friction point: ignored files donât carry over. Your .env , .env.local , API keys, local config â none of it comes with you. Every new worktree means manually hunting down and copying those files before you can actually get to work. The solution: .worktree-copy Add a .worktree-copy file to the root of your repo listing the paths you want copied every time a new worktree or workspace is created: # Secrets & environment .env .env.local # Local tooling config .secrets .tool-versions.local Lines starting with # are treated as comments. Blank lines are ignored. The file itself should be committed â itâs project config, not a secret. Setup Git â automatic via hook This approach runs transparently every time git worktree add is used, with no change to your normal workflow. Create .git/hooks/post-checkout with the following content, then make it executable with chmod +x .git/hooks/post-checkout : #!/bin/bash MAIN_WORKTREE = $( git worktree list | head -1 | awk '{print $1}' ) COPY_LIST = " $MAIN_WORKTREE /.worktree-copy" [[ ! -f " $COPY_LIST " ]] && exit 0 while IFS = read -r f || [[ -n " $f " ]]; do [[ -z " $f " || " $f " == \#* ]] && continue if [[ -e " $MAIN_WORKTREE / $f " && ! -e " $f " ]]; then cp -r " $MAIN_WORKTREE / $f " " $f " echo "Copied $f " fi done < " $COPY_LIST " Note: Git hooks arenât shared via the repo, so each contributor needs to add this themselves â or you can use a hook manager like Lefthook or Husky to distribute them. Git â shell wrapper command If you prefer an explicit command (or want something more portable across machines without setting up hooks), add a gwt function to your .bashrc or .zshrc : gwt () { git worktree add " $@ " local dest = "${ @: -1 }" local main = $( git worktree list | head -1 | awk '{print $1}' ) local copy_list = " $main /.worktree-copy" [[ ! -f " $copy_list " ]] && return 0 while IFS = read -r f || [[ -n " $f " ]]; do [[ -z " $f " || " $f " == \#* ]] && continue [[ -e " $main / $f " ]] && cp -r " $main / $f " " $dest / $f " && echo "Copied $f " done < " $copy_list " } Usage is identical to git worktree add â just use gwt instead: gwt ../my-project-feature feature-branch For Fish shell, add to ~/.config/fish/functions/gwt.fish : View Fish code function gwt git worktree add $argv set dest $argv [-1] set main ( git worktree list | head -1 | awk '{print $1}' ) set copy_list " $main /.worktree-copy" if not test -f $copy_list return 0 end while read -l f string match -qr '^\s*$|^#' -- $f; and continue if test -e " $main / $f " cp -r " $main / $f " " $dest / $f " echo "Copied $f " end end < $copy_list end Jujutsu â shell wrapper command Jujutsu workspaces share the same underlying store, so thereâs no hook equivalent. Add a jjws function to your .bashrc or .zshrc : jjws () { jj workspace add " $@ " local dest = "${ @: -1 }" local main = $( jj root ) local copy_list = " $main /.worktree-copy" [[ ! -f " $copy_list " ]] && return 0 while IFS = read -r f || [[ -n " $f " ]]; do [[ -z " $f " || " $f " == \#* ]] && continue [[ -e " $main / $f " ]] && cp -r " $main / $f " " $dest / $f " && echo "Copied $f " done < " $copy_list " } Usage mirrors jj workspace add : jjws ../my-project-feature For Fish shell, add to ~/.config/fish/functions/jjws.fish : View Fish code function jjws jj workspace add $argv set dest $argv [-1] set main ( jj root) set copy_list " $main /.worktree-copy" if not test -f $copy_list return 0 end while read -l f string match -qr '^\s*$|^#' -- $f; and continue if test -e " $main / $f " cp -r " $main / $f " " $dest / $f " echo "Copied $f " end end < $copy_list end Tips Install with AI â Ask your AI agent to install this post to your repository or to your shell. Symlink instead of copy â if the file should stay in sync across all worktrees (e.g. a shared .env with no per-branch variation), symlink it instead of copying: ln -s " $main / $f " " $dest / $f " Just swap the cp for ln -s in whichever script youâre using. Donât copy if the file already exists â all examples above skip copying if the destination file is already present, so re-running is safe and wonât clobber local overrides. Who am I? Hello! My name is Cretezy and I am a software developer. I write about programming, personal projects, and more. See more posts here.