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

From: Spencer Baugh <[email-masked]>
Date: Thu, 24 Jul 2025 16:40:05 -0400

Sean Whitton <[email-masked]> writes:
> Hello,
>
> On Thu 24 Jul 2025 at 11:38am -04, Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of text editors" wrote:
>
>>> So far in my WIP code other-working-trees is indeed used only to prompt
>>> for another working tree.  Looking to the future, though, giving Lisp
>>> programs a way to obtain a list of all other working trees seems like
>>> something we, or someone else, will want at some point.
>>
>> Naturally, but maybe we can wait until a use case appears?  (I do think
>> there's some chance one never will appear)
>
> This is a good question to ask, though as I'll argue below, unless I'm
> missing something, the options are actually all closely equivalent and
> so have roughly the same use cases.
>
>> They would not avoid the performance problems - but if all we're going
>> to do is pass a predicate to project-prompter which filters
>> project--list, they would be better suited to that, since they're less
>> powerful.  We would not need to mention project--list in vc at all then.
>
> You can define vc-is-other-working-tree-p and other-working-trees in
> terms of each other with only a little code:
>
> (defun vc-is-other-working-tree-p (dir1 dir2)
>   (member dir2 (vc-call-backend (vc-responsible-backend dir1)
>                                 'other-working-trees)))
>
> (defun vc-other-working-trees (dir1)
>   (cl-remove-if-not (apply-partially #'vc-is-other-working-tree-p dir1)
>                     (project-known-project-roots)))
>
> I think this means they are equivalently powerful.  I think you could
> make a similar argument for vc-working-tree-identity.

I don't think so: if hg's other-working-trees is implemented by
filtering project-known-project-roots (as we were considering earlier),
then your implementation of vc-is-other-working-tree-p will erroneously
return nil if dir2 is an hg share which is not in
project-known-project-roots.

For hg, a correct implementation would would be something like:

(defun vc-hg-is-other-working-tree-p (dir1 dir2)
  (string-equal (vc-hg-share-file-contents dir1)
                (vc-hg-share-file-contents dir2)))

This would return the right answer every time, even if dir1 or dir2 is
not in project--list.

> Then the question is, which is the better one to ask backend authors to
> implement -- return a list of all other working trees, answer whether
> two given trees are related, or return an identifying string for a
> working tree?
>
> For Git and Jujutsu, other-working-trees is extremely simple to
> implement because they have a command to list all working trees.
> The other two will be more complicated, but not very much more.
>
> For Mercurial, returning an identifying string is easier to implement,
> but again, the difference is fairly small.

I don't think that's right, because for Mercurial it's simply impossible
to reliably implement other-working-trees.  We've considered
implementing it with project--list, but that has the issue I mentioned
above.

Though, for what it's worth, I'm ultimately not that concerned about
this.  My VC backend will not have a problem implementing
other-working-trees, so I don't care that much about the vc-hg
implementation.

> So then I think we are left with considering overall simplicity and ease
> of understanding, writing documentation, etc..  I think a backend
> function that just returns a list of all other working trees is a bit
> simpler than your two suggestions, but there's not much in it.