{"thread":{"id":"63551","subject":"[BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","startedAt":"2025-05-30T19:00:40Z","lastAt":"2025-06-02T19:49:17Z","messageCount":21,"participants":["kristofferhaugsbakk@fastmail.com","Eric Sunshine","shejialuo","Kristoffer Haugsbakk","Junio C Hamano","Phillip Wood","Patrick Steinhardt","phillip.wood123@gmail.com"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"519288","messageId":"1d8f471b6dcb7e952afea834490be195189492a7.1748629208.git.code@khaugsbakk.name","threadId":"63551","inReplyTo":null,"subject":"[BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2025-05-30T19:00:06Z","receivedAt":"2025-05-30T19:00:40Z","isPatch":false,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"From: Kristoffer Haugsbakk <code@khaugsbakk.name>\n\n(regular git-bugreport(1) follows after this, then a demo patch)\n\ngit-refs-verify(1) checks worktree refs since v2.47.0-111-g7c78d819e6a\n(ref: support multiple worktrees check for refs, 2024-11-20).  This\ncauses the command to always exit with code `255` and stderr output\nlines for each worktree created on v2.43.0 or older that does not have\nworktree refs:\n\n    error: cannot open directory .git/worktrees/<worktree name>/refs: No such file or directory\n\nThis is apparently caused by worktrees created on Git v2.43.0 or older.\nApparently these worktrees don’t have this directory unless there exist\nworktree refs:\n\n    .git/worktrees/<worktree name>/refs\n\nAgain: any such worktrees work fine if you for example have bisect refs.\nBut the command will always fail if you have one or more v2.43.0 or\nolder worktrees with no worktree refs.\n\ngit-fsck(1) also now prints the same warnings because of the default\n`--reference`.  But the operation of the command seems unaffected.\n\nSo to reproduce (also see patch at the end)\n\n1. Make a worktree on v2.43.0 or just make a worktree and delete the\n   `refs/` directory for the worktree\n2. Run `git refs verify`\n   • On your regular git(1): not on v2.43.0\n3. Expected: succeeds without output\n4. Actual: exit code `255`, `cannot open directory` on stderr\n\nOr reproduce with this script (replace with clone with worktree if\nyou prefer):\n\n    git config set --global safe.directory /tmp &&\n    cd /tmp &&\n    dir=$(mktemp -d)\n    cd $dir\n    git clone https://github.com/git/git git-older &&\n    cd git-older &&\n    git checkout v2.43.0 &&\n    make &&\n    # use Git v2.43.0\n    ./git worktree add --detach worktree1234 &&\n    # will fail\n    git refs verify\n    # Cleanup\n    git config unset --global safe.directory\n\n§ Testing on `seen` and `next`\n\n• seen: bfa90786bc5 (Merge branch 'jk/diff-no-index-with-pathspec' into\n  seen, 2025-05-29)\n• next: d4ff7b7c865 (Sync with 'master', 2025-05-29)\n\n§ Regular report\n\n> Thank you for filling out a Git bug report!\n> Please answer the following questions to help us understand your issue.\n>\n> What did you do before the bug happened? (Steps to reproduce your issue)\n\nUsing a repository with worktrees that were apparently made on v2.43.0\nor older, based on testing.  Some of them have no worktree refs which is\nwhat triggers this behavior.\n\n> What did you expect to happen? (Expected behavior)\n\n`git refs verify` with exit code `0` and no output.\n\n> What happened instead? (Actual behavior)\n\nThe same command exits with exit code `255` and output like\n\n    error: cannot open directory .git/worktrees/<worktree name>/refs: No such file or directory\n\nWhat's different between what you expected and what actually happened?\n\nSee above.\n\n> Anything else you want to add:\n>\n> Please review the rest of the bug report below.\n> You can delete any lines you don't wish to share.\n\n[System Info]\ngit version:\ngit version 2.50.0.rc0\ncpu: x86_64\nbuilt from commit: b32feae0f1b21faaf8e191e8d3314a32470a536b\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nlibcurl: 7.81.0\nOpenSSL: OpenSSL 3.0.2 15 Mar 2022\nzlib: 1.2.11\nSHA-1: SHA1_DC\nSHA-256: SHA256_BLK\nuname: Linux 6.8.0-59-generic #61~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:03:15 UTC 2 x86_64\ncompiler info: gnuc: 11.4\nlibc info: glibc: 2.35\n$SHELL (typically, interactive shell): /bin/bash\n\n[Enabled Hooks]\npost-rewrite\nsendemail-validate\n\n-- 8< --\nFrom: Kristoffer Haugsbakk <code@khaugsbakk.name>\nSubject: [PATCH] t0602: demo v2.43.0 worktree problem\n\nSigned-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n---\n t/t0602-reffiles-fsck.sh | 43 ++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 43 insertions(+)\ndiff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\nindex f671ac4d3ab..90b68f6561e 100755\n--- a/t/t0602-reffiles-fsck.sh\n+++ b/t/t0602-reffiles-fsck.sh\n@@ -886,4 +886,47 @@ test_expect_success '--[no-]references option should apply to fsck' '\n \t)\n '\n \n+# These worktrees will not have a refs/ directory unless there\n+# actually exist worktree refs\n+test_expect_failure 'works with worktrees from v2.43.0 or older without worktree refs' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\ttest_commit initial &&\n+\t\tgit checkout -b default-branch &&\n+\t\tgit worktree add --detach ./worktree &&\n+\t\t# Simulate old directory layout\n+\t\trmdir .git/worktrees/worktree/refs &&\n+\t\tgit refs verify 2>err &&\n+\t\ttest_must_be_empty err\n+\t)\n+'\n+\n+test_expect_success 'works with worktrees from v2.43.0 or older with worktree refs' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\ttest_commit initial &&\n+\t\ttest_commit second &&\n+\t\tgit checkout -b default-branch &&\n+\t\tgit worktree add --detach ./worktree &&\n+\t\t(\n+\t\t\tcd worktree &&\n+\t\t\tgit bisect start &&\n+\t\t\tgit bisect bad HEAD &&\n+\t\t\tgit bisect good initial &&\n+\t\t\t# Simulate old directory layout: delete if empty\n+\t\t\t# But there should exist a refs/bisect/ directory now\n+\t\t\tif [ ! -e ../.git/worktrees/worktree/refs/bisect ]\n+\t\t\tthen\n+\t\t\t\trmdir ../.git/worktrees/worktree/refs\n+\t\t\tfi &&\n+\t\t\tgit refs verify 2>err &&\n+\t\t\ttest_must_be_empty err\n+\t\t)\n+\t)\n+'\n+\n test_done\n-- \nDon’t cry because the bug is fixed. Smile because it happened.\n"},{"id":"519298","messageId":"CAPig+cQiw03qfwwE9Md+LdKeS-6BGx0M1+0YYDUDXO9UPVo+wg@mail.gmail.com","threadId":"63551","inReplyTo":"1d8f471b6dcb7e952afea834490be195189492a7.1748629208.git.code@khaugsbakk.name","subject":"Re: [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2025-05-30T22:23:25Z","receivedAt":"2025-05-30T22:23:37Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, May 30, 2025 at 3:00 PM <kristofferhaugsbakk@fastmail.com> wrote:\n> git-refs-verify(1) checks worktree refs since v2.47.0-111-g7c78d819e6a\n> (ref: support multiple worktrees check for refs, 2024-11-20).  This\n> causes the command to always exit with code `255` and stderr output\n> lines for each worktree created on v2.43.0 or older that does not have\n> worktree refs:\n>\n>     error: cannot open directory .git/worktrees/<worktree name>/refs: No such file or directory\n\nInteresting. I didn't follow the topic which introduced 7c78d819e6\n(ref: support multiple worktrees check for refs, 2024-11-20), but I\ncan confirm that this is a problem.\n\n> This is apparently caused by worktrees created on Git v2.43.0 or older.\n> Apparently these worktrees don’t have this directory unless there exist\n> worktree refs:\n>\n>     .git/worktrees/<worktree name>/refs\n\nIndeed, the \"refs\" subdirectory was not present by default in older\nGit versions. Were you able to track down which commit is responsible\nfor that directory getting created automatically when the worktree\ngets created?\n\n> -- 8< --\n> From: Kristoffer Haugsbakk <code@khaugsbakk.name>\n> Subject: [PATCH] t0602: demo v2.43.0 worktree problem\n>\n> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n\nEven though this is a bug report and the patch you included doesn't\nprovide a fix, you did craft a couple tests, presumably with the\nintention that they should be used by whomever fixes the problem. As\nsuch, I'll give them a bit of a critique...\n\n>  t/t0602-reffiles-fsck.sh | 43 ++++++++++++++++++++++++++++++++++++++++\n> @@ -886,4 +886,47 @@ test_expect_success '--[no-]references option should apply to fsck' '\n> +# These worktrees will not have a refs/ directory unless there\n> +# actually exist worktree refs\n> +test_expect_failure 'works with worktrees from v2.43.0 or older without worktree refs' '\n> +       test_when_finished \"rm -rf repo\" &&\n> +       git init repo &&\n> +       (\n> +               cd repo &&\n> +               test_commit initial &&\n> +               git checkout -b default-branch &&\n\nThis `git checkout -b` seems unnecessary. The expected test failure\noccurs without this step. As such, it's probably just noise which will\nconfuse readers rather than help them. I suggest omitting it.\n\n> +               git worktree add --detach ./worktree &&\n> +               # Simulate old directory layout\n> +               rmdir .git/worktrees/worktree/refs &&\n> +               git refs verify 2>err &&\n> +               test_must_be_empty err\n> +       )\n> +'\n> +\n> +test_expect_success 'works with worktrees from v2.43.0 or older with worktree refs' '\n> +       test_when_finished \"rm -rf repo\" &&\n> +       git init repo &&\n> +       (\n> +               cd repo &&\n> +               test_commit initial &&\n> +               test_commit second &&\n> +               git checkout -b default-branch &&\n\nUnnecessary branch creation?\n\n> +               git worktree add --detach ./worktree &&\n> +               (\n> +                       cd worktree &&\n> +                       git bisect start &&\n> +                       git bisect bad HEAD &&\n> +                       git bisect good initial &&\n> +                       # Simulate old directory layout: delete if empty\n> +                       # But there should exist a refs/bisect/ directory now\n> +                       if [ ! -e ../.git/worktrees/worktree/refs/bisect ]\n> +                       then\n> +                               rmdir ../.git/worktrees/worktree/refs\n> +                       fi &&\n\nA few comments...\n\nFirst, I'm having trouble understanding what the intention is here;\nthe comment does not illuminate. Even with v2.43.0,\n.git/worktrees/worktree/refs/bisect exists after \"git bisect bad\nHEAD\", so it seems that the `if` condition can never fail, and the\n`rmdir` is dead code.\n\nSecond, this project uses `test` rather than `[` in shell scripts.\n\nFinally, I see that other parts of the script are already (perhaps)\ntoo intimate with the structure of the .git/ directory, and you may\nhave simply been following suit, but these days we often want to\nabstract away such familiarity. Hence, rather than hardcoding the path\n\"../.git/worktrees/<worktree>/refs\", you could do this:\n\n    refs=\"$(git rev-parse --git-dir)/refs\" &&\n    if test ! -e \"$refs/bisect\"\n    then\n        rmdir \"$refs\"\n    fi &&\n\n> +                       git refs verify 2>err &&\n> +                       test_must_be_empty err\n> +               )\n> +       )\n> +'\n\nOverall, although the first new test makes sense, it is not at all\nclear to me what the second test is checking or what its purpose is.\n"},{"id":"519301","messageId":"aDpVd8J-TfhvTyA3@ArchLinux","threadId":"63551","inReplyTo":"CAPig+cQiw03qfwwE9Md+LdKeS-6BGx0M1+0YYDUDXO9UPVo+wg@mail.gmail.com","subject":"Re: [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-05-31T01:03:51Z","receivedAt":"2025-05-31T01:03:42Z","isPatch":false,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Fri, May 30, 2025 at 06:23:25PM -0400, Eric Sunshine wrote:\n> On Fri, May 30, 2025 at 3:00 PM <kristofferhaugsbakk@fastmail.com> wrote:\n> > git-refs-verify(1) checks worktree refs since v2.47.0-111-g7c78d819e6a\n> > (ref: support multiple worktrees check for refs, 2024-11-20).  This\n> > causes the command to always exit with code `255` and stderr output\n> > lines for each worktree created on v2.43.0 or older that does not have\n> > worktree refs:\n> >\n> >     error: cannot open directory .git/worktrees/<worktree name>/refs: No such file or directory\n> \n> Interesting. I didn't follow the topic which introduced 7c78d819e6\n> (ref: support multiple worktrees check for refs, 2024-11-20), but I\n> can confirm that this is a problem.\n> \n\nYes, I didn't realize about this. Thank Kristoffer for reporting this\nissue and you for confirming this. I would write a patch today to fix\nthis issue. And hope that this fix would land in this release.\n\n> > This is apparently caused by worktrees created on Git v2.43.0 or older.\n> > Apparently these worktrees don’t have this directory unless there exist\n> > worktree refs:\n> >\n> >     .git/worktrees/<worktree name>/refs\n> \n> Indeed, the \"refs\" subdirectory was not present by default in older\n> Git versions. Were you able to track down which commit is responsible\n> for that directory getting created automatically when the worktree\n> gets created?\n> \n\nI find out that; in 8f4c00de95 (builtin/worktree: create refdb via ref\nbackend, 2024-01-08)\n"},{"id":"519303","messageId":"aDp55upE6AhYunz7@ArchLinux","threadId":"63551","inReplyTo":"1d8f471b6dcb7e952afea834490be195189492a7.1748629208.git.code@khaugsbakk.name","subject":"[PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-05-31T03:39:18Z","receivedAt":"2025-05-31T03:39:10Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"It is reported that \"git refs verify\" would fail when encountering\nworktrees created on Git v2.43.0 or older versions. These versions\ndon't automatically create the \"refs\" directory, causing the error:\n\n    error: cannot open directory .git/worktrees/<worktree name>/refs:\n    No such file or directory\n\nSince 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n2024-01-08), we automatically create the \"refs\" directory for new\nworktrees. However, the fsck code incorrectly assumes all linked\nworktrees have this directory, thus introducing compatibility issue.\n\nCheck for ENOENT errno before reporting directory access errors for\nlinked worktrees to maintain backward compatibility.\n\nReported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\nSigned-off-by: shejialuo <shejialuo@gmail.com>\n---\n refs/files-backend.c     |  3 +++\n t/t0602-reffiles-fsck.sh | 15 +++++++++++++++\n 2 files changed, 18 insertions(+)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4d1f65a57a..bf6f89b1d1 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n \n \titer = dir_iterator_begin(sb.buf, 0);\n \tif (!iter) {\n+\t\tif (errno == ENOENT && !is_main_worktree(wt))\n+\t\t\tgoto out;\n+\n \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n \t\tgoto out;\n \t}\ndiff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\nindex f671ac4d3a..615b7c0683 100755\n--- a/t/t0602-reffiles-fsck.sh\n+++ b/t/t0602-reffiles-fsck.sh\n@@ -110,6 +110,21 @@ test_expect_success 'ref name check should be adapted into fsck messages' '\n \t)\n '\n \n+test_expect_success 'no refs directory of worktree should not cause problems' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\ttest_commit initial &&\n+\n+\t\tgit worktree add --detach ./worktree &&\n+\t\t# Simulate old directory layout\n+\t\trm -rf ./git/worktrees/worktree/refs &&\n+\t\tgit refs verify 2>err &&\n+\t\ttest_must_be_empty err\n+\t)\n+'\n+\n test_expect_success 'ref name check should work for multiple worktrees' '\n \ttest_when_finished \"rm -rf repo\" &&\n \tgit init repo &&\n-- \n2.49.0\n\n"},{"id":"519308","messageId":"a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com","threadId":"63551","inReplyTo":"CAPig+cQiw03qfwwE9Md+LdKeS-6BGx0M1+0YYDUDXO9UPVo+wg@mail.gmail.com","subject":"Re: [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2025-05-31T09:52:33Z","receivedAt":"2025-05-31T09:52:55Z","isPatch":false,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"On Sat, May 31, 2025, at 00:23, Eric Sunshine wrote:\n>> From: Kristoffer Haugsbakk <code@khaugsbakk.name>\n>> Subject: [PATCH] t0602: demo v2.43.0 worktree problem\n>>\n>> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n>\n> Even though this is a bug report and the patch you included doesn't\n> provide a fix, you did craft a couple tests, presumably with the\n> intention that they should be used by whomever fixes the problem. As\n> such, I'll give them a bit of a critique...\n\nYes if s/should/could.[1]  These are reproduction scripts as patches.  So\nthey can be applied and show the current state (first test is\nexpect-failed, the second is expect-success) of the code.\n\nMy previous reproduction script with the git-clone(1) is inconvenient\nbut either cloning or using a worktree is necessary in order to truly\nreproduce the problem (as opposed to simulating it).\n\nA `-subject-prefix='PATCH THROWAWAY'` would have been in order.\n\nOn the other hand I did write the first test (the second is ugly) as if\nI was doing a quote-unquote real patch. In that light learning more\nabout the proper style is useful for me. So thanks for the review!\n\n> Overall, although the first new test makes sense, it is not at all\n> clear to me what the second test is checking or what its purpose is.\n\nThe idea behind the second test was to show a case where it does work\nwith old worktrees.  But simulating the old worktree didn’t make sense\nsince it looks just like a new worktree when there *are* indeed worktree\nrefs.  So it just ended up being confusing.\n\n† 1: As in troubleshooting and fixing the problem, not the final test in\n    the submitted patch.  The test is unlikely to be good enough for\n    that.  But the patch is signed off on the small chance that it can\n    be used because why not.\n"},{"id":"519309","messageId":"3f731776-9a9e-4c8f-8de9-99d470503345@app.fastmail.com","threadId":"63551","inReplyTo":"aDp55upE6AhYunz7@ArchLinux","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2025-05-31T12:17:34Z","receivedAt":"2025-05-31T12:20:56Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"On Sat, May 31, 2025, at 05:39, shejialuo wrote:\n> It is reported that \"git refs verify\" would fail when encountering\n> worktrees created on Git v2.43.0 or older versions. These versions\n\nNit: maybe\n\n    \"git refs verify\" doesn't work if there are worktrees created on Git\n    v2.43.0 ...\n\nThe part about it specifically not working if there are no worktree refs\nmight be obvious when you take in all of the context here (no refs/\ndirectory).  I don’t know.\n\n> don't automatically create the \"refs\" directory, causing the error:\n>\n>     error: cannot open directory .git/worktrees/<worktree name>/refs:\n>     No such file or directory\n>\n> Since 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n> 2024-01-08), we automatically create the \"refs\" directory for new\n> worktrees. However, the fsck code incorrectly assumes all linked\n> worktrees have this directory, thus introducing compatibility issue.\n\nThanks for finding that commit.\n\nAt this point in the message it seems like the fsck code never worked\nwith these old linked worktrees.  But `git refs verify` used to work\nwith them until 7c78d819e6a (ref: support multiple worktrees check for\nrefs, 2024-11-20) which was part of v2.48.0.  So I think it’s worth\nmentioning that commit as well.\n\nYou wrote on the first email which I’ll just respond to here since\nit’s relevant:\n\nhttps://lore.kernel.org/git/a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com/T/#mada29f8b0d02091d21412d8bd57cc666bc657c04\n\n> > And hope that this fix would land in this release.\n\nLike I said in the first email the only minor regression in this release\ncycle is that git-fsck(1) reports these errors on stderr because the\ndefault `--reference`.  This was how I spotted the issue on rc0.  But I\nneglected to mention that the commit that introduced `--references`\n(default) for git-fsck(1) is v2.48.0-rc1-49-gc1cf918d3ad (builtin/fsck:\nadd `git refs verify` child process, 2025-02-28).[1]\n\nSo based on the last what’s cooking email[2] it depends on if the stderr\noutput regresssion from git-fsck(1) in this release cycle is severe\nenough to need be fixed in this release.  Because the `git refs-verify`\nproblem has been there since v2.48.0.\n\n† 1: Part of the reason for neglecting that was that building that\n    commit fails for me.  So the bisection skipped it and couldn’t find the\n    commit.  Is that just me?  The merge commit does build de35b7b3ff (Merge\n    branch 'sj/ref-consistency-checks-more', 2025-03-26).  I changed\n    `start_progress(r, _(\"Checking ref database\"), 1);` to\n    `progress = start_progress(_(\"Checking ref database\"), 1);`.  I\n    don’t know if that is wrong but it made the bisection script run\n    without having to error out with `125`.\n\n[2]: https://lore.kernel.org/git/xmqqiklhd3tc.fsf@gitster.g/T/#u\n\n>\n> Check for ENOENT errno before reporting directory access errors for\n> linked worktrees to maintain backward compatibility.\n>\n> Reported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n> Signed-off-by: shejialuo <shejialuo@gmail.com>\n> ---\n>  refs/files-backend.c     |  3 +++\n>  t/t0602-reffiles-fsck.sh | 15 +++++++++++++++\n>  2 files changed, 18 insertions(+)\n>\n> diff --git a/refs/files-backend.c b/refs/files-backend.c\n> index 4d1f65a57a..bf6f89b1d1 100644\n> --- a/refs/files-backend.c\n> +++ b/refs/files-backend.c\n> @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store\n> *ref_store,\n>\n>  \titer = dir_iterator_begin(sb.buf, 0);\n>  \tif (!iter) {\n> +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n> +\t\t\tgoto out;\n> +\n>  \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>  \t\tgoto out;\n>  \t}\n> diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\n> index f671ac4d3a..615b7c0683 100755\n> --- a/t/t0602-reffiles-fsck.sh\n> +++ b/t/t0602-reffiles-fsck.sh\n> @@ -110,6 +110,21 @@ test_expect_success 'ref name check should be\n> adapted into fsck messages' '\n>  \t)\n>  '\n>\n> +test_expect_success 'no refs directory of worktree should not cause problems' '\n> +\ttest_when_finished \"rm -rf repo\" &&\n> +\tgit init repo &&\n> +\t(\n> +\t\tcd repo &&\n> +\t\ttest_commit initial &&\n> +\n\nNit: blank line?\n\n> +\t\tgit worktree add --detach ./worktree &&\n> +\t\t# Simulate old directory layout\n> +\t\trm -rf ./git/worktrees/worktree/refs &&\n\nEric[3] had a `git rev-parse --git-dir` suggestion instead of using `.git`.\n\n[3]: https://lore.kernel.org/git/a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com/T/#mb42bdb046c391f2583c2200668945408a2d0396f\n\n> +\t\tgit refs verify 2>err &&\n> +\t\ttest_must_be_empty err\n> +\t)\n> +'\n> +\n>  test_expect_success 'ref name check should work for multiple worktrees' '\n>  \ttest_when_finished \"rm -rf repo\" &&\n>  \tgit init repo &&\n> --\n> 2.49.0\n"},{"id":"519362","messageId":"xmqqv7pfudux.fsf@gitster.g","threadId":"63551","inReplyTo":"3f731776-9a9e-4c8f-8de9-99d470503345@app.fastmail.com","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-02T01:33:10Z","receivedAt":"2025-06-02T01:33:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Kristoffer Haugsbakk\" <code@khaugsbakk.name> writes:\n\n> On Sat, May 31, 2025, at 05:39, shejialuo wrote:\n>> It is reported that \"git refs verify\" would fail when encountering\n>> worktrees created on Git v2.43.0 or older versions. These versions\n>\n> Nit: maybe\n>\n>     \"git refs verify\" doesn't work if there are worktrees created on Git\n>     v2.43.0 ...\n\nYeah, \"It is reported that\" was somewhat odd introduction.\n\n>> don't automatically create the \"refs\" directory, causing the error:\n>>\n>>     error: cannot open directory .git/worktrees/<worktree name>/refs:\n>>     No such file or directory\n\nThe original of this part already reads quite well, I think.\n\n>> Since 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n>> 2024-01-08), we automatically create the \"refs\" directory for new\n>> worktrees. However, the fsck code incorrectly assumes all linked\n>> worktrees have this directory, thus introducing compatibility issue.\n>\n> Thanks for finding that commit.\n\nYup.  And that one is v2.44.0-rc0~58^2, and that is where \"v2.43\" in\nthe above description comes from.\n\n> At this point in the message it seems like the fsck code never worked\n> with these old linked worktrees.  But `git refs verify` used to work\n> with them until 7c78d819e6a (ref: support multiple worktrees check for\n> refs, 2024-11-20) which was part of v2.48.0.  So I think it’s worth\n> mentioning that commit as well.\n\nGood suggestion.\n\n> Like I said in the first email the only minor regression in this release\n> cycle is that git-fsck(1) reports these errors on stderr because the\n> default `--reference`.  This was how I spotted the issue on rc0.  But I\n> neglected to mention that the commit that introduced `--references`\n> (default) for git-fsck(1) is v2.48.0-rc1-49-gc1cf918d3ad (builtin/fsck:\n> add `git refs verify` child process, 2025-02-28).[1]\n\nThanks for a careful analysis.  The \"fix\" is rather obvious, so\nlet's see if we can come up with the final wording of the commit log\nmessage and merge it down in time ;-).\n\n"},{"id":"519401","messageId":"b92b5d93-7f7f-4370-ac79-7d9767bb0db5@gmail.com","threadId":"63551","inReplyTo":"aDp55upE6AhYunz7@ArchLinux","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-06-02T09:53:50Z","receivedAt":"2025-06-02T09:53:53Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Shejialuo\n\nOn 31/05/2025 04:39, shejialuo wrote:\n> diff --git a/refs/files-backend.c b/refs/files-backend.c\n> index 4d1f65a57a..bf6f89b1d1 100644\n> --- a/refs/files-backend.c\n> +++ b/refs/files-backend.c\n> @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n>   \n>   \titer = dir_iterator_begin(sb.buf, 0);\n>   \tif (!iter) {\n> +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n> +\t\t\tgoto out;\n> +\n>   \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>   \t\tgoto out;\n>   \t}\n\nI think it would be clearer to write this as\n\n\tif (is_main_worktree(wt) || errno != ENOENT)\n\t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n\tgoto out;\n\nso that the condition that triggers the error message is explicit rather \nthan having to mentally invert the condition to figure out when we \nreturn an error\n\nBest Wishes\n\nPhillip\n\n> diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\n> index f671ac4d3a..615b7c0683 100755\n> --- a/t/t0602-reffiles-fsck.sh\n> +++ b/t/t0602-reffiles-fsck.sh\n> @@ -110,6 +110,21 @@ test_expect_success 'ref name check should be adapted into fsck messages' '\n>   \t)\n>   '\n>   \n> +test_expect_success 'no refs directory of worktree should not cause problems' '\n> +\ttest_when_finished \"rm -rf repo\" &&\n> +\tgit init repo &&\n> +\t(\n> +\t\tcd repo &&\n> +\t\ttest_commit initial &&\n> +\n> +\t\tgit worktree add --detach ./worktree &&\n> +\t\t# Simulate old directory layout\n> +\t\trm -rf ./git/worktrees/worktree/refs &&\n> +\t\tgit refs verify 2>err &&\n> +\t\ttest_must_be_empty err\n> +\t)\n> +'\n> +\n>   test_expect_success 'ref name check should work for multiple worktrees' '\n>   \ttest_when_finished \"rm -rf repo\" &&\n>   \tgit init repo &&\n\n"},{"id":"519408","messageId":"aD176UYWKEbmhiaw@pks.im","threadId":"63551","inReplyTo":"b92b5d93-7f7f-4370-ac79-7d9767bb0db5@gmail.com","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-06-02T10:24:41Z","receivedAt":"2025-06-02T10:24:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Jun 02, 2025 at 10:53:50AM +0100, Phillip Wood wrote:\n> Hi Shejialuo\n> \n> On 31/05/2025 04:39, shejialuo wrote:\n> > diff --git a/refs/files-backend.c b/refs/files-backend.c\n> > index 4d1f65a57a..bf6f89b1d1 100644\n> > --- a/refs/files-backend.c\n> > +++ b/refs/files-backend.c\n> > @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n> >   \titer = dir_iterator_begin(sb.buf, 0);\n> >   \tif (!iter) {\n> > +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n> > +\t\t\tgoto out;\n> > +\n> >   \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n> >   \t\tgoto out;\n> >   \t}\n> \n> I think it would be clearer to write this as\n> \n> \tif (is_main_worktree(wt) || errno != ENOENT)\n> \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n> \tgoto out;\n> \n> so that the condition that triggers the error message is explicit rather\n> than having to mentally invert the condition to figure out when we return an\n> error\n\nThe downside though is that this mandates that `is_main_worktree()` must\nnever set `errno` itself. So while it may be clearer, the original\nversion feels safer to me.\n\nPatrick\n"},{"id":"519439","messageId":"aD2LaKR-nJVoGMWu@ArchLinux","threadId":"63551","inReplyTo":"3f731776-9a9e-4c8f-8de9-99d470503345@app.fastmail.com","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T11:30:48Z","receivedAt":"2025-06-02T11:30:51Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Sat, May 31, 2025 at 02:17:34PM +0200, Kristoffer Haugsbakk wrote:\n> On Sat, May 31, 2025, at 05:39, shejialuo wrote:\n> > It is reported that \"git refs verify\" would fail when encountering\n> > worktrees created on Git v2.43.0 or older versions. These versions\n> \n> Nit: maybe\n> \n>     \"git refs verify\" doesn't work if there are worktrees created on Git\n>     v2.43.0 ...\n> \n> The part about it specifically not working if there are no worktree refs\n> might be obvious when you take in all of the context here (no refs/\n> directory).  I don’t know.\n> \n\nRight, I will improve this.\n\n> > don't automatically create the \"refs\" directory, causing the error:\n> >\n> >     error: cannot open directory .git/worktrees/<worktree name>/refs:\n> >     No such file or directory\n> >\n> > Since 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n> > 2024-01-08), we automatically create the \"refs\" directory for new\n> > worktrees. However, the fsck code incorrectly assumes all linked\n> > worktrees have this directory, thus introducing compatibility issue.\n> \n> Thanks for finding that commit.\n> \n> At this point in the message it seems like the fsck code never worked\n> with these old linked worktrees.  But `git refs verify` used to work\n> with them until 7c78d819e6a (ref: support multiple worktrees check for\n> refs, 2024-11-20) which was part of v2.48.0.  So I think it’s worth\n> mentioning that commit as well.\n> \n\nGood suggestion.\n\n> You wrote on the first email which I’ll just respond to here since\n> it’s relevant:\n> \n> https://lore.kernel.org/git/a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com/T/#mada29f8b0d02091d21412d8bd57cc666bc657c04\n> \n> > > And hope that this fix would land in this release.\n> \n> Like I said in the first email the only minor regression in this release\n> cycle is that git-fsck(1) reports these errors on stderr because the\n> default `--reference`.  This was how I spotted the issue on rc0.  But I\n> neglected to mention that the commit that introduced `--references`\n> (default) for git-fsck(1) is v2.48.0-rc1-49-gc1cf918d3ad (builtin/fsck:\n> add `git refs verify` child process, 2025-02-28).[1]\n> \n\nBecause we would call \"git refs verify\" subprocess in \"git-fsck(1)\" in\nthis release cycle, I just want to fix this problem before the release.\nThus, it won't affect the users.\n\n> So based on the last what’s cooking email[2] it depends on if the stderr\n> output regresssion from git-fsck(1) in this release cycle is severe\n> enough to need be fixed in this release.  Because the `git refs-verify`\n> problem has been there since v2.48.0.\n> \n> † 1: Part of the reason for neglecting that was that building that\n>     commit fails for me.  So the bisection skipped it and couldn’t find the\n>     commit.  Is that just me?  The merge commit does build de35b7b3ff (Merge\n>     branch 'sj/ref-consistency-checks-more', 2025-03-26).  I changed\n>     `start_progress(r, _(\"Checking ref database\"), 1);` to\n>     `progress = start_progress(_(\"Checking ref database\"), 1);`.  I\n>     don’t know if that is wrong but it made the bisection script run\n>     without having to error out with `125`.\n> \n> [2]: https://lore.kernel.org/git/xmqqiklhd3tc.fsf@gitster.g/T/#u\n> \n> >\n> > Check for ENOENT errno before reporting directory access errors for\n> > linked worktrees to maintain backward compatibility.\n> >\n> > Reported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n> > Signed-off-by: shejialuo <shejialuo@gmail.com>\n> > ---\n> >  refs/files-backend.c     |  3 +++\n> >  t/t0602-reffiles-fsck.sh | 15 +++++++++++++++\n> >  2 files changed, 18 insertions(+)\n> >\n> > diff --git a/refs/files-backend.c b/refs/files-backend.c\n> > index 4d1f65a57a..bf6f89b1d1 100644\n> > --- a/refs/files-backend.c\n> > +++ b/refs/files-backend.c\n> > @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store\n> > *ref_store,\n> >\n> >  \titer = dir_iterator_begin(sb.buf, 0);\n> >  \tif (!iter) {\n> > +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n> > +\t\t\tgoto out;\n> > +\n> >  \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n> >  \t\tgoto out;\n> >  \t}\n> > diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\n> > index f671ac4d3a..615b7c0683 100755\n> > --- a/t/t0602-reffiles-fsck.sh\n> > +++ b/t/t0602-reffiles-fsck.sh\n> > @@ -110,6 +110,21 @@ test_expect_success 'ref name check should be\n> > adapted into fsck messages' '\n> >  \t)\n> >  '\n> >\n> > +test_expect_success 'no refs directory of worktree should not cause problems' '\n> > +\ttest_when_finished \"rm -rf repo\" &&\n> > +\tgit init repo &&\n> > +\t(\n> > +\t\tcd repo &&\n> > +\t\ttest_commit initial &&\n> > +\n> \n> Nit: blank line?\n> \n\nI would improve this. Normally in this test file, I would add a blank\nline to indicate the basic setup ends. So, I should do the following\n\n\tcd repo &&\n\ttest_commit initial &&\n\tgit worktree add --detach ./worktree &&\n\n\trm -rf ...\n\nI would improve this in the next version.\n\n> > +\t\tgit worktree add --detach ./worktree &&\n> > +\t\t# Simulate old directory layout\n> > +\t\trm -rf ./git/worktrees/worktree/refs &&\n> \n> Eric[3] had a `git rev-parse --git-dir` suggestion instead of using `.git`.\n> \n> [3]: https://lore.kernel.org/git/a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com/T/#mb42bdb046c391f2583c2200668945408a2d0396f\n> \n\nGood suggestion, let me improve this.\n\n> > +\t\tgit refs verify 2>err &&\n> > +\t\ttest_must_be_empty err\n> > +\t)\n> > +'\n> > +\n> >  test_expect_success 'ref name check should work for multiple worktrees' '\n> >  \ttest_when_finished \"rm -rf repo\" &&\n> >  \tgit init repo &&\n> > --\n> > 2.49.0\n\nThanks,\nJialuo\n"},{"id":"519442","messageId":"aD2WBkxVGilxH5vM@ArchLinux","threadId":"63551","inReplyTo":"b92b5d93-7f7f-4370-ac79-7d9767bb0db5@gmail.com","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T12:16:06Z","receivedAt":"2025-06-02T12:16:10Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Mon, Jun 02, 2025 at 10:53:50AM +0100, Phillip Wood wrote:\n> Hi Shejialuo\n> \n> On 31/05/2025 04:39, shejialuo wrote:\n> > diff --git a/refs/files-backend.c b/refs/files-backend.c\n> > index 4d1f65a57a..bf6f89b1d1 100644\n> > --- a/refs/files-backend.c\n> > +++ b/refs/files-backend.c\n> > @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n> >   \titer = dir_iterator_begin(sb.buf, 0);\n> >   \tif (!iter) {\n> > +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n> > +\t\t\tgoto out;\n> > +\n> >   \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n> >   \t\tgoto out;\n> >   \t}\n> \n> I think it would be clearer to write this as\n> \n> \tif (is_main_worktree(wt) || errno != ENOENT)\n> \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n> \tgoto out;\n> \n> so that the condition that triggers the error message is explicit rather\n> than having to mentally invert the condition to figure out when we return an\n> error\n> \n\nI agree with you that by using this way, when reading above code, we\ncould know explicitly in which situation, we would report the error.\n\nPatrick has given his safety concern with reordering the condition\ncheck. If `is_main_worktree(wt)` were to modify error (although there is\na minor possibility that it would), it could interfere with next errno\ncheck.\n\nBesides this, I somehow prefer the short-circuit way. Although in the\ncurrent code, we only have small code paths after the short-circuit way,\nthis pattern follows a common defensive programming practice where we\nhandle special cases early and exit quickly. This approach reduces nesting\nand makes the main logic flow cleaner by filtering out edge cases upfront.\n\nSo, let's keep this. Really thanks for your suggestion.\n\n> Best Wishes\n> \n> Phillip\n> \n\nJialuo\n"},{"id":"519454","messageId":"aD2cCzBlyW8y9b7e@ArchLinux","threadId":"63551","inReplyTo":"aDp55upE6AhYunz7@ArchLinux","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T12:41:47Z","receivedAt":"2025-06-02T12:41:51Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Sat, May 31, 2025 at 11:39:18AM +0800, shejialuo wrote:\n> +test_expect_success 'no refs directory of worktree should not cause problems' '\n> +\ttest_when_finished \"rm -rf repo\" &&\n> +\tgit init repo &&\n> +\t(\n> +\t\tcd repo &&\n> +\t\ttest_commit initial &&\n> +\n> +\t\tgit worktree add --detach ./worktree &&\n> +\t\t# Simulate old directory layout\n> +\t\trm -rf ./git/worktrees/worktree/refs &&\n\nFYI. I made a mistake here, it should be \".git/worktrees\" but not \"./git\".\n\n> +\t\tgit refs verify 2>err &&\n> +\t\ttest_must_be_empty err\n> +\t)\n> +'\n> +\n>  test_expect_success 'ref name check should work for multiple worktrees' '\n>  \ttest_when_finished \"rm -rf repo\" &&\n>  \tgit init repo &&\n> -- \n> 2.49.0\n> \n"},{"id":"519459","messageId":"aD2mhOlwl1LSYnpe@ArchLinux","threadId":"63551","inReplyTo":"aDp55upE6AhYunz7@ArchLinux","subject":"[PATCH v2 0/1] [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T13:26:28Z","receivedAt":"2025-06-02T13:26:32Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"Hi All:\n\nThis version updates the following things:\n\n1. Update the commit message to incorporate the commit message that\nintroduces the BUG to better explain.\n2. Update the shell script to avoid hardcode gitdir path.\n3. Change \"rm -rf\" to be \"rmdir\", which would be safer because we should\ndelete an empty directory, which has a better semantics.\n\nThanks,\nJialuo\n\nshejialuo (1):\n  fsck: ignore missing \"refs\" directory for linked worktrees\n\n refs/files-backend.c     |  3 +++\n t/t0602-reffiles-fsck.sh | 17 +++++++++++++++++\n 2 files changed, 20 insertions(+)\n\nRange-diff against v1:\n1:  bfde11adb6 ! 1:  d949a8a646 fsck: ignore missing \"refs\" directory for linked worktrees\n    @@ Metadata\n      ## Commit message ##\n         fsck: ignore missing \"refs\" directory for linked worktrees\n     \n    -    It is reported that \"git refs verify\" would fail when encountering\n    -    worktrees created on Git v2.43.0 or older versions. These versions\n    -    don't automatically create the \"refs\" directory, causing the error:\n    +    \"git refs verify\" doesn't work if there are worktrees created on Git\n    +    v2.43.0 or older versions. These versions don't automatically create the\n    +    \"refs\" directory, causing the error:\n     \n             error: cannot open directory .git/worktrees/<worktree name>/refs:\n             No such file or directory\n     \n         Since 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n         2024-01-08), we automatically create the \"refs\" directory for new\n    -    worktrees. However, the fsck code incorrectly assumes all linked\n    -    worktrees have this directory, thus introducing compatibility issue.\n    +    worktrees. And in 7c78d819e6 (ref: support multiple worktrees check for\n    +    refs, 2024-11-20), we assume that all linked worktrees have this\n    +    directory and would wrongly report an error to the user, thus\n    +    introducing compatibility issue.\n     \n         Check for ENOENT errno before reporting directory access errors for\n         linked worktrees to maintain backward compatibility.\n    @@ t/t0602-reffiles-fsck.sh: test_expect_success 'ref name check should be adapted\n     +\t(\n     +\t\tcd repo &&\n     +\t\ttest_commit initial &&\n    -+\n     +\t\tgit worktree add --detach ./worktree &&\n    ++\n    ++\t\tcd worktree &&\n    ++\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n     +\t\t# Simulate old directory layout\n    -+\t\trm -rf ./git/worktrees/worktree/refs &&\n    ++\t\trmdir \"$worktree_refdir\" &&\n     +\t\tgit refs verify 2>err &&\n     +\t\ttest_must_be_empty err\n     +\t)\n-- \n2.49.0\n\n"},{"id":"519460","messageId":"aD2nPXIXugVXfIpg@ArchLinux","threadId":"63551","inReplyTo":"aD2mhOlwl1LSYnpe@ArchLinux","subject":"[PATCH v2 1/1] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T13:29:33Z","receivedAt":"2025-06-02T13:29:37Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"\"git refs verify\" doesn't work if there are worktrees created on Git\nv2.43.0 or older versions. These versions don't automatically create the\n\"refs\" directory, causing the error:\n\n    error: cannot open directory .git/worktrees/<worktree name>/refs:\n    No such file or directory\n\nSince 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n2024-01-08), we automatically create the \"refs\" directory for new\nworktrees. And in 7c78d819e6 (ref: support multiple worktrees check for\nrefs, 2024-11-20), we assume that all linked worktrees have this\ndirectory and would wrongly report an error to the user, thus\nintroducing compatibility issue.\n\nCheck for ENOENT errno before reporting directory access errors for\nlinked worktrees to maintain backward compatibility.\n\nReported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\nSigned-off-by: shejialuo <shejialuo@gmail.com>\n---\n refs/files-backend.c     |  3 +++\n t/t0602-reffiles-fsck.sh | 17 +++++++++++++++++\n 2 files changed, 20 insertions(+)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4d1f65a57a..bf6f89b1d1 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n \n \titer = dir_iterator_begin(sb.buf, 0);\n \tif (!iter) {\n+\t\tif (errno == ENOENT && !is_main_worktree(wt))\n+\t\t\tgoto out;\n+\n \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n \t\tgoto out;\n \t}\ndiff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\nindex f671ac4d3a..9ff91d1a2b 100755\n--- a/t/t0602-reffiles-fsck.sh\n+++ b/t/t0602-reffiles-fsck.sh\n@@ -110,6 +110,23 @@ test_expect_success 'ref name check should be adapted into fsck messages' '\n \t)\n '\n \n+test_expect_success 'no refs directory of worktree should not cause problems' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\ttest_commit initial &&\n+\t\tgit worktree add --detach ./worktree &&\n+\n+\t\tcd worktree &&\n+\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n+\t\t# Simulate old directory layout\n+\t\trmdir \"$worktree_refdir\" &&\n+\t\tgit refs verify 2>err &&\n+\t\ttest_must_be_empty err\n+\t)\n+'\n+\n test_expect_success 'ref name check should work for multiple worktrees' '\n \ttest_when_finished \"rm -rf repo\" &&\n \tgit init repo &&\n-- \n2.49.0\n\n"},{"id":"519461","messageId":"f5c517b6-955c-49d8-9f05-d47c24925eb8@gmail.com","threadId":"63551","inReplyTo":"aD176UYWKEbmhiaw@pks.im","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"","fromEmail":"phillip.wood123@gmail.com","sentAt":"2025-06-02T13:50:01Z","receivedAt":"2025-06-02T13:50:05Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 02/06/2025 11:24, Patrick Steinhardt wrote:\n> On Mon, Jun 02, 2025 at 10:53:50AM +0100, Phillip Wood wrote:\n>> Hi Shejialuo\n>>\n>> On 31/05/2025 04:39, shejialuo wrote:\n>>> diff --git a/refs/files-backend.c b/refs/files-backend.c\n>>> index 4d1f65a57a..bf6f89b1d1 100644\n>>> --- a/refs/files-backend.c\n>>> +++ b/refs/files-backend.c\n>>> @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n>>>    \titer = dir_iterator_begin(sb.buf, 0);\n>>>    \tif (!iter) {\n>>> +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n>>> +\t\t\tgoto out;\n>>> +\n>>>    \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>>>    \t\tgoto out;\n>>>    \t}\n>>\n>> I think it would be clearer to write this as\n>>\n>> \tif (is_main_worktree(wt) || errno != ENOENT)\n>> \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>> \tgoto out;\n>>\n>> so that the condition that triggers the error message is explicit rather\n>> than having to mentally invert the condition to figure out when we return an\n>> error\n> \n> The downside though is that this mandates that `is_main_worktree()` must\n> never set `errno` itself. So while it may be clearer, the original\n> version feels safer to me.\n\nOh good point. We could save errno and then check the saved version but \nit maybe it is not worth changing it.\n\nBest Wishes\n\nPhillip>\n> Patrick\n\n"},{"id":"519464","messageId":"21461585-273f-46a9-a750-6ae7b414fcdc@app.fastmail.com","threadId":"63551","inReplyTo":"aD2nPXIXugVXfIpg@ArchLinux","subject":"Re: [PATCH v2 1/1] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2025-06-02T13:59:01Z","receivedAt":"2025-06-02T14:00:30Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"On Mon, Jun 2, 2025, at 15:29, shejialuo wrote:\n> \"git refs verify\" doesn't work if there are worktrees created on Git\n> v2.43.0 or older versions. These versions don't automatically create the\n> \"refs\" directory, causing the error:\n>\n>     error: cannot open directory .git/worktrees/<worktree name>/refs:\n>     No such file or directory\n\nGood.\n\n> Since 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n> 2024-01-08), we automatically create the \"refs\" directory for new\n> worktrees. And in 7c78d819e6 (ref: support multiple worktrees check for\n> refs, 2024-11-20), we assume that all linked worktrees have this\n> directory and would wrongly report an error to the user, thus\n> introducing compatibility issue.\n\nOkay, you don’t mention c1cf918d3ad (builtin/fsck: add `git refs verify`\nchild process, 2025-02-28) in the commit message because of your reply:\n\n> > Because we would call \"git refs verify\" subprocess in \"git-fsck(1)\"\n> > in this release cycle, I just want to fix this problem before the\n> > release.  Thus, it won't affect the users.\n\nhttps://lore.kernel.org/git/a2a50127-6ab9-4d8a-abcc-b1a741df293e@app.fastmail.com/T/#m01231abb77735b0f480743e0d2adecc172e1f170\n\nWhich I just mention here for completeness and my own memory.  ;)\n\nAll good.\n\n> Check for ENOENT errno before reporting directory access errors for\n> linked worktrees to maintain backward compatibility.\n>\n> Reported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\n> Signed-off-by: shejialuo <shejialuo@gmail.com>\n> [snip]\n> +test_expect_success 'no refs directory of worktree should not cause problems' '\n> +\ttest_when_finished \"rm -rf repo\" &&\n> +\tgit init repo &&\n> +\t(\n> +\t\tcd repo &&\n> +\t\ttest_commit initial &&\n> +\t\tgit worktree add --detach ./worktree &&\n> +\n> +\t\tcd worktree &&\n\nNow in this version you change-directory into `worktree`.  You would\nneed a new subshell for that (test style).  But I don’t see the need to\nchdir in the first place?\n\n> +\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n> +\t\t# Simulate old directory layout\n> +\t\trmdir \"$worktree_refdir\" &&\n> +\t\tgit refs verify 2>err &&\n> +\t\ttest_must_be_empty err\n> +\t)\n> +'\n> +\n>  test_expect_success 'ref name check should work for multiple worktrees' '\n>  \ttest_when_finished \"rm -rf repo\" &&\n>  \tgit init repo &&\n> --\n> 2.49.0\n\nThe test passes for me.  Also when applying only the test (and not the\nfix) the test fails as expected.  Good.\n"},{"id":"519465","messageId":"aD2xC0YBDm4TASHG@ArchLinux","threadId":"63551","inReplyTo":"21461585-273f-46a9-a750-6ae7b414fcdc@app.fastmail.com","subject":"Re: [PATCH v2 1/1] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T14:11:23Z","receivedAt":"2025-06-02T14:11:27Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"On Mon, Jun 02, 2025 at 03:59:01PM +0200, Kristoffer Haugsbakk wrote:\n> > +test_expect_success 'no refs directory of worktree should not cause problems' '\n> > +\ttest_when_finished \"rm -rf repo\" &&\n> > +\tgit init repo &&\n> > +\t(\n> > +\t\tcd repo &&\n> > +\t\ttest_commit initial &&\n> > +\t\tgit worktree add --detach ./worktree &&\n> > +\n> > +\t\tcd worktree &&\n> \n> Now in this version you change-directory into `worktree`.  You would\n> need a new subshell for that (test style).  But I don’t see the need to\n> chdir in the first place?\n> \n\nWe should change directory into the `worktree`. This is because now in\nthe test, we use \"git rev-parse --git-dir\" to get the git directory. We\nneed to find `gitdir` of the linked worktree but not the `gitdir` of the\nmain worktree. If we do not cd into the directory, we would get the\n`gitdir` of the main worktree.\n\nAnd I agree with you that we need to spawn a subshell. Let me update the\ncode. Thanks for reminding me, I forgot about that.\n\n> > +\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n> > +\t\t# Simulate old directory layout\n> > +\t\trmdir \"$worktree_refdir\" &&\n> > +\t\tgit refs verify 2>err &&\n> > +\t\ttest_must_be_empty err\n> > +\t)\n> > +'\n> > +\n> >  test_expect_success 'ref name check should work for multiple worktrees' '\n> >  \ttest_when_finished \"rm -rf repo\" &&\n> >  \tgit init repo &&\n> > --\n> > 2.49.0\n> \n> The test passes for me.  Also when applying only the test (and not the\n> fix) the test fails as expected.  Good.\n\nThanks for the feedback.\n\nJialuo\n"},{"id":"519466","messageId":"aD23w6-szFjKQGSj@ArchLinux","threadId":"63551","inReplyTo":"aD2mhOlwl1LSYnpe@ArchLinux","subject":"[PATCH v3 0/1] [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T14:40:03Z","receivedAt":"2025-06-02T14:40:06Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"\nHi All:\n\nChanges in v2:\n\n1. Update the commit message to incorporate the commit message that\nintroduces the BUG to better explain.\n2. Update the shell script to avoid hardcode gitdir path.\n3. Change \"rm -rf\" to be \"rmdir\", which would be safer because we should\ndelete an empty directory, which has a better semantics.\n\n---\n\nChanges in v3:\n\n1. Use subshell for test style.\n\nThanks,\nJialuo\n\nshejialuo (1):\n  fsck: ignore missing \"refs\" directory for linked worktrees\n\n refs/files-backend.c     |  3 +++\n t/t0602-reffiles-fsck.sh | 19 +++++++++++++++++++\n 2 files changed, 22 insertions(+)\n\nRange-diff against v2:\n1:  d949a8a646 ! 1:  e4c32971da fsck: ignore missing \"refs\" directory for linked worktrees\n    @@ t/t0602-reffiles-fsck.sh: test_expect_success 'ref name check should be adapted\n     +\t\ttest_commit initial &&\n     +\t\tgit worktree add --detach ./worktree &&\n     +\n    -+\t\tcd worktree &&\n    -+\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n    -+\t\t# Simulate old directory layout\n    -+\t\trmdir \"$worktree_refdir\" &&\n    -+\t\tgit refs verify 2>err &&\n    -+\t\ttest_must_be_empty err\n    ++\t\t(\n    ++\t\t\tcd worktree &&\n    ++\t\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n    ++\t\t\t# Simulate old directory layout\n    ++\t\t\trmdir \"$worktree_refdir\" &&\n    ++\t\t\tgit refs verify 2>err &&\n    ++\t\t\ttest_must_be_empty err\n    ++\t\t)\n     +\t)\n     +'\n     +\n-- \n2.49.0\n\n"},{"id":"519467","messageId":"aD24H3nVTwTq8JDq@ArchLinux","threadId":"63551","inReplyTo":"aD23w6-szFjKQGSj@ArchLinux","subject":"[PATCH v3 1/1] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"shejialuo","fromEmail":"shejialuo@gmail.com","sentAt":"2025-06-02T14:41:35Z","receivedAt":"2025-06-02T14:41:50Z","isPatch":true,"sender":{"key":"shejialuo@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56911263?v=4"},"body":"\"git refs verify\" doesn't work if there are worktrees created on Git\nv2.43.0 or older versions. These versions don't automatically create the\n\"refs\" directory, causing the error:\n\n    error: cannot open directory .git/worktrees/<worktree name>/refs:\n    No such file or directory\n\nSince 8f4c00de95 (builtin/worktree: create refdb via ref backend,\n2024-01-08), we automatically create the \"refs\" directory for new\nworktrees. And in 7c78d819e6 (ref: support multiple worktrees check for\nrefs, 2024-11-20), we assume that all linked worktrees have this\ndirectory and would wrongly report an error to the user, thus\nintroducing compatibility issue.\n\nCheck for ENOENT errno before reporting directory access errors for\nlinked worktrees to maintain backward compatibility.\n\nReported-by: Kristoffer Haugsbakk <code@khaugsbakk.name>\nSigned-off-by: shejialuo <shejialuo@gmail.com>\n---\n refs/files-backend.c     |  3 +++\n t/t0602-reffiles-fsck.sh | 19 +++++++++++++++++++\n 2 files changed, 22 insertions(+)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 4d1f65a57a..bf6f89b1d1 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n \n \titer = dir_iterator_begin(sb.buf, 0);\n \tif (!iter) {\n+\t\tif (errno == ENOENT && !is_main_worktree(wt))\n+\t\t\tgoto out;\n+\n \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n \t\tgoto out;\n \t}\ndiff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh\nindex f671ac4d3a..0ef483659d 100755\n--- a/t/t0602-reffiles-fsck.sh\n+++ b/t/t0602-reffiles-fsck.sh\n@@ -110,6 +110,25 @@ test_expect_success 'ref name check should be adapted into fsck messages' '\n \t)\n '\n \n+test_expect_success 'no refs directory of worktree should not cause problems' '\n+\ttest_when_finished \"rm -rf repo\" &&\n+\tgit init repo &&\n+\t(\n+\t\tcd repo &&\n+\t\ttest_commit initial &&\n+\t\tgit worktree add --detach ./worktree &&\n+\n+\t\t(\n+\t\t\tcd worktree &&\n+\t\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n+\t\t\t# Simulate old directory layout\n+\t\t\trmdir \"$worktree_refdir\" &&\n+\t\t\tgit refs verify 2>err &&\n+\t\t\ttest_must_be_empty err\n+\t\t)\n+\t)\n+'\n+\n test_expect_success 'ref name check should work for multiple worktrees' '\n \ttest_when_finished \"rm -rf repo\" &&\n \tgit init repo &&\n-- \n2.49.0\n\n"},{"id":"519470","messageId":"d7265bca-ac47-4610-834d-da91042ccdf0@app.fastmail.com","threadId":"63551","inReplyTo":"aD23w6-szFjKQGSj@ArchLinux","subject":"Re: [PATCH v3 0/1] [BUG] refs: verify does not work if there are v2.43.0 or older worktrees w/o wt. refs","fromName":"Kristoffer Haugsbakk","fromEmail":"code@khaugsbakk.name","sentAt":"2025-06-02T15:01:44Z","receivedAt":"2025-06-02T15:02:45Z","isPatch":true,"sender":{"key":"code@khaugsbakk.name","avatar":"https://avatars.githubusercontent.com/u/2229597?v=4"},"body":"On Mon, Jun 2, 2025, at 16:40, shejialuo wrote:\n> [snip]\n>\n> Range-diff against v2:\n> 1:  d949a8a646 ! 1:  e4c32971da fsck: ignore missing \"refs\" directory\n> for linked worktrees\n>     @@ t/t0602-reffiles-fsck.sh: test_expect_success 'ref name check\n> should be adapted\n>      +\t\ttest_commit initial &&\n>      +\t\tgit worktree add --detach ./worktree &&\n>      +\n>     -+\t\tcd worktree &&\n>     -+\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n>     -+\t\t# Simulate old directory layout\n>     -+\t\trmdir \"$worktree_refdir\" &&\n>     -+\t\tgit refs verify 2>err &&\n>     -+\t\ttest_must_be_empty err\n>     ++\t\t(\n>     ++\t\t\tcd worktree &&\n>     ++\t\t\tworktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n>     ++\t\t\t# Simulate old directory layout\n>     ++\t\t\trmdir \"$worktree_refdir\" &&\n>     ++\t\t\tgit refs verify 2>err &&\n>     ++\t\t\ttest_must_be_empty err\n>     ++\t\t)\n>      +\t)\n>      +'\n>      +\n> --\n> 2.49.0\n\nThis version works as well.  Thanks!\n\n    $ git range-diff --no-color --no-notes --inter-hunk-context=1 --ignore-all-space <range>\n    1:  ddbf0f8cf4c ! 1:  ce802ef6698 fsck: ignore missing \"refs\" directory for linked worktrees\n        @@ t/t0602-reffiles-fsck.sh: test_expect_success 'ref name check should be adapted\n         +          test_commit initial &&\n         +          git worktree add --detach ./worktree &&\n         +\n        ++          (\n         +                  cd worktree &&\n         +                  worktree_refdir=\"$(git rev-parse --git-dir)/refs\" &&\n         +                  # Simulate old directory layout\n         +                  rmdir \"$worktree_refdir\" &&\n         +                  git refs verify 2>err &&\n         +                  test_must_be_empty err\n         +          )\n        ++  )\n         +'\n         +\n          test_expect_success 'ref name check should work for multiple worktrees' '\n"},{"id":"519502","messageId":"xmqq34chudom.fsf@gitster.g","threadId":"63551","inReplyTo":"aD176UYWKEbmhiaw@pks.im","subject":"Re: [PATCH] fsck: ignore missing \"refs\" directory for linked worktrees","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-06-02T19:49:13Z","receivedAt":"2025-06-02T19:49:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> On Mon, Jun 02, 2025 at 10:53:50AM +0100, Phillip Wood wrote:\n>> Hi Shejialuo\n>> \n>> On 31/05/2025 04:39, shejialuo wrote:\n>> > diff --git a/refs/files-backend.c b/refs/files-backend.c\n>> > index 4d1f65a57a..bf6f89b1d1 100644\n>> > --- a/refs/files-backend.c\n>> > +++ b/refs/files-backend.c\n>> > @@ -3762,6 +3762,9 @@ static int files_fsck_refs_dir(struct ref_store *ref_store,\n>> >   \titer = dir_iterator_begin(sb.buf, 0);\n>> >   \tif (!iter) {\n>> > +\t\tif (errno == ENOENT && !is_main_worktree(wt))\n>> > +\t\t\tgoto out;\n>> > +\n>> >   \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>> >   \t\tgoto out;\n>> >   \t}\n>> \n>> I think it would be clearer to write this as\n>> \n>> \tif (is_main_worktree(wt) || errno != ENOENT)\n>> \t\tret = error_errno(_(\"cannot open directory %s\"), sb.buf);\n>> \tgoto out;\n>> \n>> so that the condition that triggers the error message is explicit rather\n>> than having to mentally invert the condition to figure out when we return an\n>> error\n>\n> The downside though is that this mandates that `is_main_worktree()` must\n> never set `errno` itself. So while it may be clearer, the original\n> version feels safer to me.\n\nFWIW, I found that the logic flow of the original more natural than\nthe proposed rewrite.  \"dir_iterator_begin() appears to have failed\nby not returning a usable iterator, so we may need to complain, but\nas a special case, we can tolerate missing refs/ hierarchy if we are\nnot in the primary working tree.\" was how I read these three\nadditional lines.\n\n\n"}]}