Subject: Re: bug#79024: 31.0.50; Multiple working trees support for VC

From: Spencer Baugh <[email-masked]>
Date: Thu, 17 Jul 2025 13:24:36 -0400

Sean Whitton <[email-masked]> writes:

> X-debbugs-cc: [email-masked], [email-masked]
>
> Hello,
>
> I would like to add support for multiple working trees to VC.  This is
> 'git worktree' for Git and 'hg share' for Mercurial.  It may or may not
> map onto trunk/ vs. branch/ in SVN; see below.

Exciting!

> TERMINOLOGY
>
> VC's documentation consistently uses "working tree" to refer to what we
> often also call the "working directory", "clone", "checkout".
>
> I think that we can introduce the idea of "other working trees" and
> commands that operate on them.  I don't believe we need to distinguish
> between primary and secondary working trees, which is a VCS-specific
> concept.  If a Git user tries to delete the primary worktree from a
> secondary worktree, for example, it's just an error, signalled by the
> relevant backend-specific function.

Yes, that sounds good to me.  This is ideal because this already matches
up well with the "worktree" terminology in Git.

I briefly considered proposing that command names use "vc-worktree"
instead of "vc-working-tree", but I actually think "vc-working-tree" is
better than "vc-worktree" because tab completion will expand "vc-w-t"
unambiguously to vc-working-tree but "vc-w" can't expand to vc-worktree.

> These commands would probably be meaningful only for changeset-based
> VCS, not file-based VCS.
>
> COMMANDS
>
> - C-x v w c: Add a new working tree.
>
>   The user must specify what branch, revision or tag to check out there.
>   Probably the prompting should be as similar as possible to C-x v r
>   and/or C-x v b s (which we might want to improve and/or unify first).

Sounds good to me.

> - C-x v w w: Switch to another working tree.
>
>   This is a contextual command.  When used in a file-visiting or dired
>   buffer, it means visit that same file name under one of the other
>   working trees.
>
>   E.g. if you have worktrees for the Emacs master and release branches,
>   you can use it to hop between vc.el on master and vc.el on emacs-30.
>   In *vc-dir* it means to switch to *vc-dir* for the other worktree.
>
>   Each working tree is already a separate project.el project, which is
>   what we want.

This will be great!  This is like project-find-matching-file but I think
this worktree-specific version will be much more useful, since worktrees
give us the knowledge that two projects are related and that lets us
have the prompt be populated with much fewer options.

>   + If we keep the list of other working trees sorted by recency, then
>     C-x v w w RET would allow you to switch back and forth between (the
>     same file name in) your two most recently used working trees.
>
> - C-x v w s: A wrapper around C-x p p but with selection limited to
>   other working trees of this project.

Sounds great.  I suggest this should be done by let-binding
project-prompter to a function which only prompts for the working trees
related to the current project.

Though: how are you thinking about prompting for working trees?  At my
site:
- project-name is a short and sometimes-ambiguous name (since it's
used widely in project.el in places that expect it to be short,
e.g. project-prefixed-buffer-name), so just prompting with project-name
would be undesirable.
- And the directory of the worktree is also not very informative at my
site.

For this reason, I have a custom project-prompter configured at my site.
Maybe vc backends should also be able to customize the prompting
function used to prompt for working trees?

> - C-x v w x: Delete a working tree.
>
> - C-x v w R: Relocate a working tree.
>
>   Move or rename it, updating VC and project.el metadata as appropriate.
>
> BACKEND FUNCTIONS
>
> - other-working-trees: Return a list of all other working trees.
>
> - add-working-tree, delete-working-tree, move-working-tree.
>
> SVN BRANCHES
>
> Adding a new working tree is the same as creating a new branch, I think?
> I think there are two ways we could go here:
>
> 1. Decide that SVN does not support other working trees in the sense of
>    these new commands, such that they are no-ops.
> 2. Make the new commands effectively synonyms of existing branch-related
>    commands for SVN.

IMO we should do 1 now until/unless someone requests 2.  We can always
do 2 later if we do 1 now, but if we do 2 now then we can never take it
back if we decide it's wrong.

> QUESTIONS
>
> - Are there other things that we might want to support that wouldn't be
>   covered by this API?

I think this is a great start, I don't think this locks us into anything
too bad.

Later possible additions: the operation "make a new branch and worktree,
and transfer the uncommitted changes from the current worktree to that
new branch" (as we've discussed off-list) might be neat.

Actually, in general, transferring uncommitted (or committed?) changes
between worktrees would be a cool thing to support.  I often find myself
making vc-diff buffers and M-x cding in the buffer to other worktrees so
that I can apply the changes in that buffer to the other worktree.  Some
first-class support might be cool.  But I think we don't need to design
that yet.

> - Does project.el need to know about these relationships between trees,
>   or do we leave it all up to VC?  I think the latter.  I.e., from
>   project.el's point of view, each working tree is its own project.

I agree.  Adding support for "related projects" has often come up for
project.el, but it's unclear how to design it.  Keeping the worktree
concept in vc avoids this, and we can always expose the knowledge to
project.el later if we figure out a reason to do it.

> - What shall we do with CVS/SVN branches?  I've made two suggestions.
>
> - How are the bindings I've suggested?  Intuitive enough?

Yes - I particularly like C-x v w w; I think giving that an easy binding
(the duplicated w) is very helpful, since I think for worktree users
it's a fairly common operation.

> Thank you in advance for any feedback.