{"thread":{"id":"62141","subject":"\"git worktree repair\" modifies the wrong repository","startedAt":"2024-09-19T01:27:37Z","lastAt":"2024-10-04T15:50:28Z","messageCount":11,"participants":["Russell Stuart","Eric Sunshine","Phillip Wood","phillip.wood123@gmail.com","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"503046","messageId":"E1sr5iF-0007zV-2k@binarylane-bailey.stuart.id.au","threadId":"62141","inReplyTo":null,"subject":"\"git worktree repair\" modifies the wrong repository","fromName":"Russell Stuart","fromEmail":"russell+git.vger.kernel.org@stuart.id.au","sentAt":"2024-09-19T01:12:03Z","receivedAt":"2024-09-19T01:27:37Z","isPatch":false,"sender":{"key":"russell+git.vger.kernel.org@stuart.id.au","avatar":null},"body":"What did you do before the bug happened? (Steps to reproduce your issue)\n    /tmp$ mkdir -p gb/a gb/b\n    /tmp$ cd gb/a\n    /tmp/gb/a$ git init r\n    Initialized empty Git repository in /tmp/gb/a/r/.git/\n    /tmp/gb/a$ cd r\n    /tmp/gb/a/r$ touch x\n    /tmp/gb/a/r$ git add x\n    /tmp/gb/a/r$ git commit -am .\n    [main (root-commit) 6323b04] .\n    1 file changed, 0 insertions(+), 0 deletions(-)\n    create mode 100644 x\n    /tmp/gb/a/r$ git branch foo\n    /tmp/gb/a/r$ git worktree add ../r.foo\n    Preparing worktree (new branch 'r.foo')\n    HEAD is now at 6323b04 .\n    /tmp/gb/a/r$ -r cp ../* ../../b/.\n    -bash: -r: command not found\n    /tmp/gb/a/r$ cp -a ../* ../../b/.\n    /tmp/gb/a/r$ cd ../../b/r\n    /tmp/gb/b/r$ git worktree repair ../r.foo\n    repair: gitdir incorrect: /tmp/gb/a/r/.git/worktrees/r.foo/gitdir\n    repair: .git file incorrect: /tmp/gb/a/r.foo\n    /tmp/gb/b/r$ cat .git/worktrees/r.foo/gitdir \n    /tmp/gb/a/r.foo/.git\n    /tmp/gb/b/r$ cat ../r.foo/.git\n    gitdir: /tmp/gb/a/r/.git/worktrees/r.foo\n    /tmp/gb/b/r$ cat ../../a/.git/worktrees/r.foo/gitdir \n    cat: ../../a/.git/worktrees/r.foo/gitdir: No such file or directory\n    /tmp/gb/b/r$ cat ../../a/r/.git/worktrees/r.foo/gitdir \n    /tmp/gb/b/r.foo/.git\n    /tmp/gb/b/r$ cat ../../a/r.foo/.git\n    gitdir: /tmp/gb/b/r/.git/worktrees/r.foo\n    /tmp/gb/b/r$ \n\nWhat did you expect to happen? (Expected behavior)\n    I expected \"/tmp/gb/b/r$ git worktree repair ../r.foo\" to alter the\n    repositories it was run from, ie those under the directory \"/tmp/gb/b\".\n\nWhat happened instead? (Actual behavior)\n    \"/tmp/gb/b/r$ git worktree repair ../r.foo\" modified the repositories\n    under the directory \"/tmp/gb/a\".\n\n[System Info]\ngit version:\ngit version 2.39.3 (Apple Git-146)\ncpu: arm64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nfeature: fsmonitor--daemon\nuname: Darwin 23.6.0 Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:21 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T8103 arm64\ncompiler info: clang: 15.0.0 (clang-1500.3.9.4)\nlibc info: no libc information available\n$SHELL (typically, interactive shell): /opt/homebrew/bin/bash\n\n\n--\nRegards,\nRussell Stuart\n"},{"id":"503050","messageId":"CAPig+cQ8=Y6sVvN_dBo_GQ5nLkQ4GJ7AM6mE2kt_2QV7CR0omg@mail.gmail.com","threadId":"62141","inReplyTo":"E1sr5iF-0007zV-2k@binarylane-bailey.stuart.id.au","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-09-19T08:58:26Z","receivedAt":"2024-09-19T08:58:38Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Sep 18, 2024 at 9:27 PM Russell Stuart\n<russell+git.vger.kernel.org@stuart.id.au> wrote:\n> What did you do before the bug happened? (Steps to reproduce your issue)\n>     /tmp/gb/a$ git init r\n>     /tmp/gb/a/r$ git worktree add ../r.foo\n\nHad you run `git worktree list` at this point in /tmp/gb/a/r/, you\nwould have seen:\n\n    /tmp/gb/a/r      3699610 [main]\n    /tmp/gb/a/r.foo  3699610 [r.foo]\n\n>     /tmp/gb/a/r$ cp -a ../* ../../b/.\n>     /tmp/gb/a/r$ cd ../../b/r\n\nHad you run `git worktree list` at this point in /tmp/gb/b/r/, you\nwould have seen:\n\n    /tmp/gb/b/r      3699610 [main]\n    /tmp/gb/a/r.foo  3699610 [r.foo]\n\nfrom which it can be seen that /tmp/gb/b/r/.git/worktree/r.foo/gitdir\nis pointing at /tmp/gb/a/r.foo, which makes sense since that gitdir\nfile is an exact copy of /tmp/gb/a/r/.git/worktree/r.foo/gitdir. So\n/tmp/gb/a/r.foo is being shared by both repositories, /tmp/gb/a/ and\n/tmp/gb/b/, and neither one knows about /tmp/gb/b/r.foo.\n\n>     /tmp/gb/b/r$ git worktree repair ../r.foo\n>     repair: gitdir incorrect: /tmp/gb/a/r/.git/worktrees/r.foo/gitdir\n>     repair: .git file incorrect: /tmp/gb/a/r.foo\n>     /tmp/gb/b/r$ cat .git/worktrees/r.foo/gitdir\n>     /tmp/gb/a/r.foo/.git\n>     /tmp/gb/b/r$ cat ../r.foo/.git\n>     gitdir: /tmp/gb/a/r/.git/worktrees/r.foo\n>     /tmp/gb/b/r$ cat ../../a/r/.git/worktrees/r.foo/gitdir\n>     /tmp/gb/b/r.foo/.git\n>     /tmp/gb/b/r$ cat ../../a/r.foo/.git\n>     gitdir: /tmp/gb/b/r/.git/worktrees/r.foo\n\nThe implementation of `git worktree repair` started out (relatively)\nsimple, handling the most common cases, and has been extended to\nhandle additional cases when identified and reported. The case of\nmerely copying a repository and its worktrees (and leaving the\noriginals intact) is not yet implemented, so the above all makes sense\ngiven the current implementation.\n\n> What did you expect to happen? (Expected behavior)\n>     I expected \"/tmp/gb/b/r$ git worktree repair ../r.foo\" to alter the\n>     repositories it was run from, ie those under the directory \"/tmp/gb/b\".\n>\n> What happened instead? (Actual behavior)\n>     \"/tmp/gb/b/r$ git worktree repair ../r.foo\" modified the repositories\n>     under the directory \"/tmp/gb/a\".\n\nI have a tentative fix implemented which seems to handle this case\ncorrectly. Once I've finished polishing it and formalizing the related\ntest, I'll send out a patch.\n"},{"id":"503051","messageId":"3b579ddd-b386-4daa-ad63-1e75522b7462@stuart.id.au","threadId":"62141","inReplyTo":"CAPig+cQ8=Y6sVvN_dBo_GQ5nLkQ4GJ7AM6mE2kt_2QV7CR0omg@mail.gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Russell Stuart","fromEmail":"russell+git.vger.kernel.org@stuart.id.au","sentAt":"2024-09-19T10:16:26Z","receivedAt":"2024-09-19T10:16:30Z","isPatch":false,"sender":{"key":"russell+git.vger.kernel.org@stuart.id.au","avatar":null},"body":"On 19/9/24 18:58, Eric Sunshine wrote:\n> I have a tentative fix implemented which seems to handle this case \n> correctly. Once I've finished polishing it and formalizing the\n> related test, I'll send out a patch.\n\nFantastic.\n\nI noticed repair hadn't changed the directories I thought it had, but\nhad said it was changing something.  Pondering what on earth could of\nhappened, my first thought \"surely not\" - and then checked the\noriginals.  It caught me totally by surprise.  Everyone I showed it to\nexpressed the same surprise.\n\nI can't resist pointing out if \"git worktree add\" had of preserved the\nrelative paths I gave it, it would not have happened.\n\n\n-- \nRegards,\nRussell Stuart\n"},{"id":"503053","messageId":"CAPig+cTkpLLoTxTa-8xfycNGFibN_M71+kkHtT-wgp6HRPi-aw@mail.gmail.com","threadId":"62141","inReplyTo":"3b579ddd-b386-4daa-ad63-1e75522b7462@stuart.id.au","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-09-19T10:47:43Z","receivedAt":"2024-09-19T10:47:55Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Sep 19, 2024 at 6:16 AM Russell Stuart\n<russell+git.vger.kernel.org@stuart.id.au> wrote:\n> I can't resist pointing out if \"git worktree add\" had of preserved the\n> relative paths I gave it, it would not have happened.\n\nThe idea of relative paths has been discussed previously[*] but was\nnever implemented; although they may help some cases, they break other\ncases or at least make the other cases more difficult. For instance,\nrelative paths only help if the main and linked worktrees move\ntogether in some uniform fashion, but don't help if they move in\ndistinct ways. Storing *both* the absolute and relative paths rather\nthan only the absolute path was also discussed and seemed promising,\nbut concerns were raised that doing so could break other Git-related\ntools or non-canonical Git implementations (or even perhaps older\nversions of Git itself), thus was never pursued.\n\nFOOTNOTES\n\n[*] The previous discussion was in the context of an earlier\nimplementation of git-worktree, long before there was a \"repair\"\nsubcommand. In fact, the very original implementation of linked\nworktrees (which was actually `git checkout --to=<path>` would attempt\nto automatically repair itself whenever any Git command discovered\nsome sort of breakage, however, that initial implementation was buggy\nin some fashion (I don't have the details at hand), so the auto-repair\nfeature was removed very early on. The \"repair\" subcommand came much\nlater and took the conservative approach of addressing common problems\npeople were reporting at the time, and was extended as new reports\ncame in, rather than trying to tackle every possible way in which\nsomeone could wield a foot-gun.\n"},{"id":"503054","messageId":"4781ff6e-c20a-4340-851b-c9d324d1fac8@stuart.id.au","threadId":"62141","inReplyTo":"CAPig+cTkpLLoTxTa-8xfycNGFibN_M71+kkHtT-wgp6HRPi-aw@mail.gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Russell Stuart","fromEmail":"russell+git.vger.kernel.org@stuart.id.au","sentAt":"2024-09-19T11:40:30Z","receivedAt":"2024-09-19T11:40:33Z","isPatch":false,"sender":{"key":"russell+git.vger.kernel.org@stuart.id.au","avatar":null},"body":"On 19/9/24 20:47, Eric Sunshine wrote:\n> The idea of relative paths has been discussed previously[*] but was \n> never implemented; although they may help some cases, they break \n> other cases or at least make the other cases more difficult. For \n> instance, relative paths only help if the main and linked worktrees \n> move together in some uniform fashion, but don't help if they move in\n> distinct ways.\n\nIf breaking when moved is the criteria, then absolute paths always\nbreak.  Relative paths break slightly less often.  So it seems to me\nrelative paths are an improvement - but not a fix.\n\nIt's always possible to break something by moving the wrong thing.  For\nexample moving the .git directory in a normal repository would create a\nmess.  Yet, unlike moving worktrees (most?) people do not attempt to\nmove the .git directory in illegal ways.  They always copy/more copy the\nentire repository.  It's intuitively obvious if you keep the .git\ndirectory in the same relative position, it will work.\n\nSo my uniformed guess on how to \"fix\" the problem of people\nmoving/copying worktrees is to make equally obvious they must remain in\nthe same relative position to the parent.  One way to do that is to use\nthe same structure hg uses, which is the child worktrees must all be in\nthe one common parent directory, and the parent directory contains the\n.git metadata.  It then becomes self-evident you can only more/copy the\nentire thing - not bits of it.\n\n> [*] The previous discussion was in the context of an earlier \n> implementation of git-worktree, long before there was a \"repair\" \n> subcommand. In fact, the very original implementation of linked \n> worktrees\n\nThanks.  The starting point of \"linked git directories\" (I presume to\nsave on metadata storage?) explains a how worktrees ended up where they\nhave.\n\nInterestingly, people (including me as it happens) start out by trying\nto emulate the hg approach using a single parent directory to hold a\nbare repository, and the child worktree directories.  Then they discover\nbare repositories mangle the remote links, and give up on the idea.  In\nmy case I then tried moving/copying the worktrees as a group using \"git\nworktree repair\" to fix the mess, which eventually lead to this email :)\n\nOthers have published of hacks / tricks that try to solve problem in\nother ways, eg: https://github.com/Kristian-Tan/git-worktree-relative\n\nNone of them work very well.  Going on what Google throws up, moving\nworktrees remains a commonly felt pain point.\n\n\n-- \nRegards,\nRussell Stuart\n"},{"id":"503275","messageId":"CAPig+cTop=2+k0XbqYbsCTbJVo77evY+_a+FqDV_ziKf2q+Dzw@mail.gmail.com","threadId":"62141","inReplyTo":"4781ff6e-c20a-4340-851b-c9d324d1fac8@stuart.id.au","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-09-23T18:52:04Z","receivedAt":"2024-09-23T18:52:16Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Sep 19, 2024 at 7:40 AM Russell Stuart\n<russell+git.vger.kernel.org@stuart.id.au> wrote:\n> On 19/9/24 20:47, Eric Sunshine wrote:\n> > The idea of relative paths has been discussed previously[*] but was\n> > never implemented; although they may help some cases, they break\n> > other cases or at least make the other cases more difficult. For\n> > instance, relative paths only help if the main and linked worktrees\n> > move together in some uniform fashion, but don't help if they move in\n> > distinct ways.\n>\n> If breaking when moved is the criteria, then absolute paths always\n> break.  Relative paths break slightly less often.  So it seems to me\n> relative paths are an improvement - but not a fix.\n\nIndeed, I don't think anyone has argued against relative paths\noutright, but only pointed out that absolute and relative paths each\nhave their strengths with regards to making the repair process\n(whether automatic or not) more robust. It was for this reason that\nthe previous discussion[1] eventually settled on the idea of storing\nboth absolute and relative paths.\n\n[1]: The discussion begins at the \"Also Eric\" paragraph of this email\nand continues in emails following it:\nhttps://lore.kernel.org/git/CACsJy8CXEKG+WNdSPOWF7JDzPXidSRWZZ5zkdMW3N3Dg8SGW_Q@mail.gmail.com/\n\n> It's always possible to break something by moving the wrong thing.  For\n> example moving the .git directory in a normal repository would create a\n> mess.  Yet, unlike moving worktrees (most?) people do not attempt to\n> move the .git directory in illegal ways.  They always copy/more copy the\n> entire repository.  It's intuitively obvious if you keep the .git\n> directory in the same relative position, it will work.\n\nThis intuition perhaps arises from your background with \"hg\", but I\nhave not formed any such intuition.\n\n> So my uniformed guess on how to \"fix\" the problem of people\n> moving/copying worktrees is to make equally obvious they must remain in\n> the same relative position to the parent.  One way to do that is to use\n> the same structure hg uses, which is the child worktrees must all be in\n> the one common parent directory, and the parent directory contains the\n> .git metadata.  It then becomes self-evident you can only more/copy the\n> entire thing - not bits of it.\n\nThat's a very restrictive and limiting organization. As I understand\nit, one of the design goals of Git's linked worktrees was to allow\nworktrees to be placed anywhere, including on removable media or\nnot-always-mounted network drives. (Yes, you may be able to do\nsomething similar with \"hg\" and symbolic links, but that doesn't play\nwell with Windows users, at least not in the era when Git's worktree\nsupport was implemented.)\n\n> Interestingly, people (including me as it happens) start out by trying\n> to emulate the hg approach using a single parent directory to hold a\n> bare repository, and the child worktree directories.  Then they discover\n> bare repositories mangle the remote links, and give up on the idea.\n\nCan you provide more details about this \"mangling\"? Although the\nuse-case you describe was not directly considered in the initial\ndesign, worktrees hanging off a bare repository became an\nexplicitly-supported use-case not long after worktrees were\nintroduced. So, it should work properly and we know that people use\nworktrees this way, but we haven't had any reports of mangling in this\nscenario.\n\n> In\n> my case I then tried moving/copying the worktrees as a group using \"git\n> worktree repair\" to fix the mess, which eventually lead to this email :)\n\nMoving should have worked, either using \"git worktree move\" or by\nusing \"git worktree repair\" after moving them manually. The copy case\nwas broken as you reported. By the way, I posted a fix[2].\n\n[2]: https://lore.kernel.org/git/20240923075416.54289-1-ericsunshine@charter.net/\n\n> Others have published of hacks / tricks that try to solve problem in\n> other ways, eg: https://github.com/Kristian-Tan/git-worktree-relative\n\nInteresting reading.\n\n> None of them work very well.  Going on what Google throws up, moving\n> worktrees remains a commonly felt pain point.\n\nI suspect that the best way forward is to store both absolute and\nrelative paths, but this needs to be done with care so as to not break\nexisting tooling or other implementations of Git or Git libraries\n(including older versions of Git itself).\n\nBy the way, have you seen the patch recently posted[3] to explicitly\nsupport relative paths for worktrees?\n\n[3]: https://lore.kernel.org/git/pull.1783.git.git.1726880551891.gitgitgadget@gmail.com/\n"},{"id":"503357","messageId":"87afa860-52f4-414a-82da-09e7eeac1301@gmail.com","threadId":"62141","inReplyTo":"CAPig+cTop=2+k0XbqYbsCTbJVo77evY+_a+FqDV_ziKf2q+Dzw@mail.gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-09-24T13:53:44Z","receivedAt":"2024-09-24T13:53:47Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 23/09/2024 19:52, Eric Sunshine wrote:\n> On Thu, Sep 19, 2024 at 7:40 AM Russell Stuart\n> <russell+git.vger.kernel.org@stuart.id.au> wrote:\n>> Interestingly, people (including me as it happens) start out by trying\n>> to emulate the hg approach using a single parent directory to hold a\n>> bare repository, and the child worktree directories.  Then they discover\n>> bare repositories mangle the remote links, and give up on the idea.\n> \n> Can you provide more details about this \"mangling\"? Although the\n> use-case you describe was not directly considered in the initial\n> design, worktrees hanging off a bare repository became an\n> explicitly-supported use-case not long after worktrees were\n> introduced. So, it should work properly and we know that people use\n> worktrees this way, but we haven't had any reports of mangling in this\n> scenario.\n\nI can't speak for Russell but a while ago when I added a worktree to an \nexisting bare repository I had to update remote.origin.fetch and \nremote.origin.mirror because \"git clone --bare\" implies \"--mirror\". I \nalso needed to enable extensions.worktreeConfig and ensure core.bare was \nset appropriately.\n\nBest Wishes\n\nPhillip\n"},{"id":"503461","messageId":"b9f55058-354d-4a61-ac3b-92ea56026693@stuart.id.au","threadId":"62141","inReplyTo":"CAPig+cTop=2+k0XbqYbsCTbJVo77evY+_a+FqDV_ziKf2q+Dzw@mail.gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Russell Stuart","fromEmail":"russell@stuart.id.au","sentAt":"2024-09-25T09:31:39Z","receivedAt":"2024-09-25T09:31:48Z","isPatch":false,"sender":{"key":"russell@stuart.id.au","avatar":null},"body":"Sorry, I missed this reply.\n\nOn 24/9/24 04:52, Eric Sunshine wrote:\n> [1]: The discussion begins at the \"Also Eric\" paragraph of this email\n> and continues in emails following it:\n> https://lore.kernel.org/git/CACsJy8CXEKG+WNdSPOWF7JDzPXidSRWZZ5zkdMW3N3Dg8SGW_Q@mail.gmail.com/\n\nYes, Duh's comments pretty much sums it up.\n\n> This intuition perhaps arises from your background with \"hg\", but I\n> have not formed any such intuition.\n\nNot only from hg.  You can freely move the parent directory of all CVS \nsystems I'm aware of - hg, svn, cvs, rcs, sccs and yes git too.  It only \nbreaks when you add worktrees to git.\n\n> That's a very restrictive and limiting organization. As I understand\n> it, one of the design goals of Git's linked worktrees was to allow\n> worktrees to be placed anywhere, including on removable media or\n> not-always-mounted network drives. (Yes, you may be able to do\n> something similar with \"hg\" and symbolic links, but that doesn't play\n> well with Windows users, at least not in the era when Git's worktree\n> support was implemented.)\n\nYes, it is far more restrictive than git worktrees are now.  It \nsimplifies the users the mental model of what is going on, but that \nsimplification comes at a cost.  I only mentioned it because relative \npaths in worktrees would allow you to pretend it works that way.\n\n> Can you provide more details about this \"mangling\"? Although the\n> use-case you describe was not directly considered in the initial\n> design, worktrees hanging off a bare repository became an\n> explicitly-supported use-case not long after worktrees were\n> introduced. So, it should work properly and we know that people use\n> worktrees this way, but we haven't had any reports of mangling in this\n> scenario.\n\nPhillip's reply was spot on: \nhttps://lore.kernel.org/git/87afa860-52f4-414a-82da-09e7eeac1301@gmail.com/\n\n> By the way, have you seen the patch recently posted[3] to explicitly\n> support relative paths for worktrees?\n> \n> [3]: https://lore.kernel.org/git/pull.1783.git.git.1726880551891.gitgitgadget@gmail.com/\n\nAhh, now I see why using both is attractive\n\n"},{"id":"504016","messageId":"CAPig+cSSDnq_kh9ERuYZmUCNrVvWmGFF8OSfBCy8bHrkx6fz3g@mail.gmail.com","threadId":"62141","inReplyTo":"87afa860-52f4-414a-82da-09e7eeac1301@gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2024-10-03T06:28:57Z","receivedAt":"2024-10-03T06:29:10Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Sep 24, 2024 at 9:53 AM Phillip Wood <phillip.wood123@gmail.com> wrote:\n> On 23/09/2024 19:52, Eric Sunshine wrote:\n> > On Thu, Sep 19, 2024 at 7:40 AM Russell Stuart\n> > <russell+git.vger.kernel.org@stuart.id.au> wrote:\n> >> Interestingly, people (including me as it happens) start out by trying\n> >> to emulate the hg approach using a single parent directory to hold a\n> >> bare repository, and the child worktree directories.  Then they discover\n> >> bare repositories mangle the remote links, and give up on the idea.\n> >\n> > Can you provide more details about this \"mangling\"? Although the\n> > use-case you describe was not directly considered in the initial\n> > design, worktrees hanging off a bare repository became an\n> > explicitly-supported use-case not long after worktrees were\n> > introduced. So, it should work properly and we know that people use\n> > worktrees this way, but we haven't had any reports of mangling in this\n> > scenario.\n>\n> I can't speak for Russell but a while ago when I added a worktree to an\n> existing bare repository I had to update remote.origin.fetch and\n> remote.origin.mirror because \"git clone --bare\" implies \"--mirror\". I\n> also needed to enable extensions.worktreeConfig and ensure core.bare was\n> set appropriately.\n\nThanks, Phillip. This is interesting information, but I'm not sure I\nunderstand what the actual problems are that you encountered. When you\nsay that --bare implies --mirror, do you mean the other way around?\nThe documentation states the opposite; that --mirror implies --bare,\nand my own testing seems to confirm that.\n\nThat aside, I played around a bit again with bare and mirror\nrepositories with worktrees hanging off them, but didn't encounter any\nanomalous behavior, which (almost certainly) indicates that I'm not\nexercising it thoroughly enough. Thus, can you provide more detail\nabout the actual problems you encountered which required the manual\nadjustments you made to the configuration? (Does this also imply that\nDocumentation/git-worktree.txt could use an update to discuss how to\nuse them with a bare repository?)\n\nRegarding core.bare: That's one of the settings which is special-cased\n(hard-coded) to work \"properly\" when extensions.worktreeConfig is not\nenabled, so it's not clear what problem you were experiencing in that\nregard. In my testing, `git rev-parse --is-bare-repository` correctly\nreported \"true\" in the bare repository, and \"false\" in a worktree\nhanging off the bare repository even when extensions.worktreeConfig\nwas not enabled.\n"},{"id":"504078","messageId":"6c0b8681-95ca-4224-ba89-7582fd731565@gmail.com","threadId":"62141","inReplyTo":"CAPig+cSSDnq_kh9ERuYZmUCNrVvWmGFF8OSfBCy8bHrkx6fz3g@mail.gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"","fromEmail":"phillip.wood123@gmail.com","sentAt":"2024-10-04T09:15:55Z","receivedAt":"2024-10-04T09:15:58Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Eric\n\nOn 03/10/2024 07:28, Eric Sunshine wrote:\n> On Tue, Sep 24, 2024 at 9:53 AM Phillip Wood <phillip.wood123@gmail.com> wrote:\n>> On 23/09/2024 19:52, Eric Sunshine wrote:\n>>> On Thu, Sep 19, 2024 at 7:40 AM Russell Stuart\n>>> <russell+git.vger.kernel.org@stuart.id.au> wrote:\n>>>> Interestingly, people (including me as it happens) start out by trying\n>>>> to emulate the hg approach using a single parent directory to hold a\n>>>> bare repository, and the child worktree directories.  Then they discover\n>>>> bare repositories mangle the remote links, and give up on the idea.\n>>>\n>>> Can you provide more details about this \"mangling\"? Although the\n>>> use-case you describe was not directly considered in the initial\n>>> design, worktrees hanging off a bare repository became an\n>>> explicitly-supported use-case not long after worktrees were\n>>> introduced. So, it should work properly and we know that people use\n>>> worktrees this way, but we haven't had any reports of mangling in this\n>>> scenario.\n>>\n>> I can't speak for Russell but a while ago when I added a worktree to an\n>> existing bare repository I had to update remote.origin.fetch and\n>> remote.origin.mirror because \"git clone --bare\" implies \"--mirror\". I\n>> also needed to enable extensions.worktreeConfig and ensure core.bare was\n>> set appropriately.\n> \n> Thanks, Phillip. This is interesting information, but I'm not sure I\n> understand what the actual problems are that you encountered. When you\n> say that --bare implies --mirror, do you mean the other way around?\n> The documentation states the opposite; that --mirror implies --bare,\n> and my own testing seems to confirm that.\n\nSorry I must have mis-remembered - it was quite a while ago. In my case \nthe bare repository was set up with --mirror.\n\n> That aside, I played around a bit again with bare and mirror\n> repositories with worktrees hanging off them, but didn't encounter any\n> anomalous behavior, which (almost certainly) indicates that I'm not\n> exercising it thoroughly enough. Thus, can you provide more detail\n> about the actual problems you encountered which required the manual\n> adjustments you made to the configuration? (Does this also imply that\n> Documentation/git-worktree.txt could use an update to discuss how to\n> use them with a bare repository?)\n\n\"git clone --mirror\" sets up a fetch refspec that forcibly update \n\"refs/heads/*\" when fetching. This means fetching overwrites your local \nbranches and I think the fetch fails if you have a branch checked out \nthat it wants to update. \"git clone --bare\" does not set up any fetch \nrefspec. In both cases there are no remote tracking branches to base \nyour local work on.\n\n> Regarding core.bare: That's one of the settings which is special-cased\n> (hard-coded) to work \"properly\" when extensions.worktreeConfig is not\n> enabled, so it's not clear what problem you were experiencing in that\n> regard. In my testing, `git rev-parse --is-bare-repository` correctly\n> reported \"true\" in the bare repository, and \"false\" in a worktree\n> hanging off the bare repository even when extensions.worktreeConfig\n> was not enabled.\n\nI've a feeling I thought I needed to set it because I didn't realize \nthat core.bare was special cased rather than doing so in response to a \nparticular problem but I can't remember for sure.\n\nBest Wishes\n\nPhillip\n"},{"id":"504092","messageId":"xmqqo73zg94t.fsf@gitster.g","threadId":"62141","inReplyTo":"6c0b8681-95ca-4224-ba89-7582fd731565@gmail.com","subject":"Re: \"git worktree repair\" modifies the wrong repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-10-04T15:50:26Z","receivedAt":"2024-10-04T15:50:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"phillip.wood123@gmail.com writes:\n\n> \"git clone --mirror\" sets up a fetch refspec that forcibly update\n> \"refs/heads/*\" when fetching. This means fetching overwrites your\n> local branches and I think the fetch fails if you have a branch\n> checked out that it wants to update. \"git clone --bare\" does not set\n> up any fetch refspec. In both cases there are no remote tracking\n> branches to base your local work on.\n>\n>> Regarding core.bare: That's one of the settings which is special-cased\n>> (hard-coded) to work \"properly\" when extensions.worktreeConfig is not\n>> enabled, so it's not clear what problem you were experiencing in that\n>> regard. In my testing, `git rev-parse --is-bare-repository` correctly\n>> reported \"true\" in the bare repository, and \"false\" in a worktree\n>> hanging off the bare repository even when extensions.worktreeConfig\n>> was not enabled.\n>\n> I've a feeling I thought I needed to set it because I didn't realize\n> that core.bare was special cased rather than doing so in response to a\n> particular problem but I can't remember for sure.\n\nI recently encountered a funny behaviour in a worktree linked to a\nbare repository.\n\n    $ git clone --bare file://$(pwd)/git.git victim-00.git\n    $ git -C victim-00.git worktree add ../victim-01\n    $ cd victim-01\n    $ git grep -i -e subscribe\n    fatal: this operation must be run in a work tree\n\nOf course, \"git grep -i subscribe HEAD\" works (as it does not\nrequire a working tree and works on a proper bare repository).\n\nWhat is curious is that this also works:\n\n    $ git grep -i -e subscribe --cached\n\nThat mode of operation can work only when the index exists,\nwhich means it needs a working tree.  Perhaps the working tree\nversion is written in a more strict way to avoid unexpected\nbehaviour (and gets the implementation of strictness wrong), while\nthe index version has no such protection?  Running the index version\nin the bare repository\n\n    $ git -C ../victim-00.git -i -e subscribe --cached; echo $?\n    1\n\nseems to confirm.  The command does not fail, but in a bare\nrepository, the in-core the_index has 0 elements, so it thinks it\nsuccessfully looked for the needle in the haystack and found\nnothing, without complaining \"hey, there is no haystack\".\n\nWith the extensions.worktreeConfig things work as expected in the\nworktree linked to the bare repository, like so:\n\n    $ cd ../victim-01\n    $ git config set extensions.worktreeConfig true\n    $ git config set core.bare false\n    $ git grep -i -e subscribe\n\nSo, I dunno.  Is core.bare really \"special cased\"?  It seems to me\nthat any halfway special case harms users more than helps.\n\n\n"}]}