From 5df63c66d9c5efbbb87670f42dcf7201af489673 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Wed, 1 Apr 2026 15:49:11 -0500 Subject: [PATCH 1/2] Support a .worktreeinclude file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a file which we use to "include" untracked files in new worktree. Disabled by default, this makes it easier to share files between main repo and worktrees. I set mine to: .env .envrc **/.claude/settings.local.json See https://code.claude.com/docs/en/common-workflows#copy-gitignored-files-to-worktrees for how claude’s works. --- agent-shell-worktree.el | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/agent-shell-worktree.el b/agent-shell-worktree.el index 20d5be9c..69290e99 100644 --- a/agent-shell-worktree.el +++ b/agent-shell-worktree.el @@ -106,6 +106,33 @@ Or nil if not in a repo." (unless (string-empty-p trimmed) trimmed)))) +(defcustom agent-shell-worktree-include-filename nil + "When non-nil, file that contains a list of untracked files in repostitory to copy to new worktree. + +This is formatted in \".gitignore\" style, so wildcards and similar are +allowed. See https://git-scm.com/docs/gitignore#_pattern_format for more information." + :type '(choice (const nil) (const ".worktreeinclude") string) + :group 'agent-shell) + +(defun agent-shell-worktree--copy-worktree-include-files (original-repo worktree) + "Copy untracked files matching patterns in +`agent-shell-worktree-include-filename' from ORIGINAL-REPO to WORKTREE. + +If `agent-shell-worktree-include-filename' is unset, does nothing." + (when agent-shell-worktree-include-filename + (let ((file (file-name-concat original-repo agent-shell-worktree-include-filename))) + (when (file-exists-p file) + (let* ((default-directory original-repo) + (output (shell-command-to-string + (format "git ls-files --others --ignored --exclude-from=%s" + (shell-quote-argument file))))) + (dolist (relative-file (split-string output "\n" t)) + (let ((src (file-name-concat original-repo relative-file)) + (dst (file-name-concat worktree relative-file))) + (when (file-exists-p src) + (make-directory (file-name-directory dst) t) + (copy-file src dst t t t t))))))))) + ;;;###autoload (defun agent-shell-new-worktree-shell () "Create a new git worktree and start an agent shell in it. @@ -136,6 +163,7 @@ The user is prompted to confirm or edit the worktree path before creation." (shell-quote-argument worktree-path))))) (unless (file-exists-p worktree-path) (user-error "Failed to create worktree: %s" output)) + (agent-shell-worktree--copy-worktree-include-files repo-root worktree-path) (let ((default-directory worktree-path)) (agent-shell '(4)))))) From 906b5e0913e37e356916ecfc0dd11838afff4009 Mon Sep 17 00:00:00 2001 From: Matthew Bauer Date: Wed, 1 Apr 2026 15:52:32 -0500 Subject: [PATCH 2/2] Update --- agent-shell-worktree.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/agent-shell-worktree.el b/agent-shell-worktree.el index 69290e99..3d65b8c8 100644 --- a/agent-shell-worktree.el +++ b/agent-shell-worktree.el @@ -107,7 +107,8 @@ Or nil if not in a repo." trimmed)))) (defcustom agent-shell-worktree-include-filename nil - "When non-nil, file that contains a list of untracked files in repostitory to copy to new worktree. + "When non-nil, file that contains a list of untracked files in repository +to copy to new worktree. This is formatted in \".gitignore\" style, so wildcards and similar are allowed. See https://git-scm.com/docs/gitignore#_pattern_format for more information."