{"thread":{"id":"41536","subject":"[PATCH 5/6] WIP: fix unborn branch case","startedAt":"2016-02-26T16:39:40Z","lastAt":"2016-02-27T02:15:55Z","messageCount":11,"participants":["Michael J Gruber","Junio C Hamano","Duy Nguyen"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"279533","messageId":"cover.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":null,"subject":"[PATCH/WIP 0/6] Detached HEADs in new worktrees considered harmful","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:40Z","receivedAt":"2016-02-26T16:39:40Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Before someone loses their HEAD I should put this series out (again).\n\n1/6 is a tiny documentation fix.\n\n2/6 demonstrates that \"git prune\" in the main worktree loses HEADs in other\nworktrees, and vice versa.\n\nIn fact, one should rethink the meaning of \"git rev-list --all\" in the context\nof per-worktree refs such as HEAD.\n\n3/6 is a possible fix (making \"--all\" mean \"all refs in all worktrees\") but may\nbe too intrusive.\n\n4/6, 5/6, 6/6 are some WIP patches about making 3/6 less intrusive and fixing\nsome cases where do_head_ref_worktrees() has problems that do_head_ref() doesn't\nhave.\n\nMichael J Gruber (6):\n  Documentation/git-worktree: spell --detach correctly\n  t6014: test prune with detached HEADs in separate worktrees\n  rev-list: list all heads with --all\n  WIP: mess only with mark_reachable\n  fix unborn branch case\n  revisions: list all worktree HEADs with --all\n\n Documentation/git-worktree.txt     |  2 +-\n Documentation/rev-list-options.txt |  2 +-\n reachable.c                        |  2 +-\n refs.h                             |  1 +\n refs/files-backend.c               | 34 +++++++++++++++++++++++++++++++++-\n t/t6014-rev-list-all.sh            | 25 +++++++++++++++++++++++++\n 6 files changed, 62 insertions(+), 4 deletions(-)\n\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279532","messageId":"f0c859d9736058736a58d8c9898c9b5417a63b8c.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH 1/6] Documentation/git-worktree: spell --detach correctly","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:41Z","receivedAt":"2016-02-26T16:39:41Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n Documentation/git-worktree.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\nindex 62c76c1..51a2ea0 100644\n--- a/Documentation/git-worktree.txt\n+++ b/Documentation/git-worktree.txt\n@@ -50,7 +50,7 @@ Create `<path>` and checkout `<branch>` into it. The new working directory\n is linked to the current repository, sharing everything except working\n directory specific files such as HEAD, index, etc.\n +\n-If `<branch>` is omitted and neither `-b` nor `-B` nor `--detached` used,\n+If `<branch>` is omitted and neither `-b` nor `-B` nor `--detach` used,\n then, as a convenience, a new branch based at HEAD is created automatically,\n as if `-b $(basename <path>)` was specified.\n \n-- \n2.7.2.618.g7a61b68\n"},{"id":"279530","messageId":"47fd12af598614ca10fa28cb36fb98ca9ab6d7bb.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH 2/6] t6014: test prune with detached HEADs in separate worktrees","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:42Z","receivedAt":"2016-02-26T16:39:42Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"\"git prune\" relies on \"git rev-list --all\" to list all reachable,\nnon-prunable commits. In the presence of per-worktree refs such as HEAD\nthis becomes more complicated.\n\nAdd a test that makes sure that per-worktree refs from other worktrees\nare not omitted.\n\nThis is currently broken, possibly resulting in data loss.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n t/t6014-rev-list-all.sh | 25 +++++++++++++++++++++++++\n 1 file changed, 25 insertions(+)\n\ndiff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh\nindex c9bedd2..99bf8ae 100755\n--- a/t/t6014-rev-list-all.sh\n+++ b/t/t6014-rev-list-all.sh\n@@ -39,4 +39,29 @@ test_expect_success 'rev-list --graph --no-walk is forbidden' '\n \ttest_must_fail git rev-list --graph --no-walk HEAD\n '\n \n+test_expect_success 'setup worktree tests' '\n+\tmkdir newtree &&\n+\tgit worktree add --detach newtree master^ &&\n+\t(\n+\t\tcd newtree &&\n+\t\tcommit detached2\n+\t)\n+'\n+\n+test_expect_failure 'prune in main worktree does not lose detached HEAD in new worktree' '\n+\tgit prune --expire=now &&\n+\t(\n+\t\tcd newtree &&\n+\t\tgit show HEAD\n+\t)\n+'\n+\n+test_expect_failure 'prune in new worktree does not lose detached HEAD in main worktree' '\n+\t(\n+\t\tcd newtree &&\n+\t\tgit prune --expire=now\n+\t) &&\n+\tgit show HEAD\n+'\n+\n test_done\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279529","messageId":"61d93b0aba1d4cb7348066db0b48f1ce2d5b35c5.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH/RFD 3/6] rev-list: list all heads with --all","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:43Z","receivedAt":"2016-02-26T16:39:43Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"HEAD is a worktree specific sysmref, so that a repository with multiple\nworktrees can have multiple HEADs, or HEADs in a worktree different from\nthe current worktree.\n\nSo far, \"rev-parse --all\" adds only the HEAD from the current worktree\nto the list of refs (besides branches etc.). So, a detached HEAD from a\ndifferent checkout would be missed unless a shared ref (or current HEAD)\npoints to it (or descents from it). As a consequence, \"git prune\" can\nprune detached HEADs from worktrees and leave the repo in an\ninconsistent state.\n\nMake \"rev-parse --all\" add the HEADs from all worktrees. This results in\na non-worktree-specific ref list and solves the pruning problem.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n\nNotes:\n    This patch solves the pruning problem with worktrees, but I feel quite\n    uneasy about substituting the ref solving at the very heart of refs.c. So\n    please consider this a mere poc and a request for discussion/input\n    about how to do this the right way.\n    \n    In essence, I feel the worktree interface still has to evolve a bit: I'd\n    rather for_each_worktree than loop myself, and if many call sites need to\n    be aware of multiple heads or worktrees than get_worktrees() should be\n    part of our init stuff, not here. [I may be out of sync of newer progress.]\n\n refs/files-backend.c | 15 +++++++++++----\n 1 file changed, 11 insertions(+), 4 deletions(-)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 81f68f8..5bdb568 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -4,6 +4,7 @@\n #include \"../lockfile.h\"\n #include \"../object.h\"\n #include \"../dir.h\"\n+#include \"../worktree.h\"\n \n struct ref_lock {\n \tchar *ref_name;\n@@ -1748,7 +1749,8 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base,\n static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \tstruct object_id oid;\n-\tint flag;\n+\tstruct worktree **worktrees;\n+\tint i, retval;\n \n \tif (submodule) {\n \t\tif (resolve_gitlink_ref(submodule, \"HEAD\", oid.hash) == 0)\n@@ -1757,10 +1759,15 @@ static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n \t\treturn 0;\n \t}\n \n-\tif (!read_ref_full(\"HEAD\", RESOLVE_REF_READING, oid.hash, &flag))\n-\t\treturn fn(\"HEAD\", &oid, flag, cb_data);\n+\tworktrees = get_worktrees();\n+\tretval = 0;\n+\tfor (i=0; worktrees[i]; i++) {\n+\t\thashcpy(oid.hash, worktrees[i]->head_sha1);\n+\t\tretval = retval || fn(\"HEAD\", &oid, worktrees[i]->is_detached ? 0 : REF_ISSYMREF, cb_data);\n+\t}\n \n-\treturn 0;\n+\tfree_worktrees(worktrees);\n+\treturn retval;\n }\n \n int head_ref(each_ref_fn fn, void *cb_data)\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279528","messageId":"b318af9a93f1d49f4480d63b74fa07d4b605f16b.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH 4/6] WIP: mess only with mark_reachable","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:44Z","receivedAt":"2016-02-26T16:39:44Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"This still messes up gc/prune on an empty repo where the worktree code\ncan't parse HEAD properly. Bummer. That code sucks for the non-worktree\ncase.\n\nSigned-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n reachable.c          |  2 +-\n refs.h               |  1 +\n refs/files-backend.c | 23 +++++++++++++++++++++++\n 3 files changed, 25 insertions(+), 1 deletion(-)\n\ndiff --git a/reachable.c b/reachable.c\nindex ed35201..15a06a7 100644\n--- a/reachable.c\n+++ b/reachable.c\n@@ -177,7 +177,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,\n \tfor_each_ref(add_one_ref, revs);\n \n \t/* detached HEAD is not included in the list above */\n-\thead_ref(add_one_ref, revs);\n+\thead_ref_worktrees(add_one_ref, revs);\n \n \t/* Add all reflog info */\n \tif (mark_reflog)\ndiff --git a/refs.h b/refs.h\nindex 2f3decb..c9621b4 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -183,6 +183,7 @@ typedef int each_ref_fn(const char *refname,\n  * stop the iteration.\n  */\n extern int head_ref(each_ref_fn fn, void *cb_data);\n+extern int head_ref_worktrees(each_ref_fn fn, void *cb_data);\n extern int for_each_ref(each_ref_fn fn, void *cb_data);\n extern int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data);\n extern int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken);\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 5bdb568..f020c52 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1749,6 +1749,24 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base,\n static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \tstruct object_id oid;\n+\tint flag;\n+\n+\tif (submodule) {\n+\t\tif (resolve_gitlink_ref(submodule, \"HEAD\", oid.hash) == 0)\n+\t\t\treturn fn(\"HEAD\", &oid, 0, cb_data);\n+\n+\t\treturn 0;\n+\t}\n+\n+\tif (!read_ref_full(\"HEAD\", RESOLVE_REF_READING, oid.hash, &flag))\n+\t\treturn fn(\"HEAD\", &oid, flag, cb_data);\n+\n+\treturn 0;\n+}\n+\n+static int do_head_ref_worktrees(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\tstruct object_id oid;\n \tstruct worktree **worktrees;\n \tint i, retval;\n \n@@ -1775,6 +1793,11 @@ int head_ref(each_ref_fn fn, void *cb_data)\n \treturn do_head_ref(NULL, fn, cb_data);\n }\n \n+int head_ref_worktrees(each_ref_fn fn, void *cb_data)\n+{\n+\treturn do_head_ref_worktrees(NULL, fn, cb_data);\n+}\n+\n int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \treturn do_head_ref(submodule, fn, cb_data);\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279527","messageId":"9d4ba4d9aa4deaf88c4e7e1d9d92fb18717e7b2c.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH 5/6] WIP: fix unborn branch case","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:45Z","receivedAt":"2016-02-26T16:39:45Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n refs/files-backend.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex f020c52..1614854 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1780,6 +1780,8 @@ static int do_head_ref_worktrees(const char *submodule, each_ref_fn fn, void *cb\n \tworktrees = get_worktrees();\n \tretval = 0;\n \tfor (i=0; worktrees[i]; i++) {\n+\t\tif (is_null_sha1(worktrees[i]->head_sha1))\n+\t\t\tcontinue;\n \t\thashcpy(oid.hash, worktrees[i]->head_sha1);\n \t\tretval = retval || fn(\"HEAD\", &oid, worktrees[i]->is_detached ? 0 : REF_ISSYMREF, cb_data);\n \t}\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279531","messageId":"99338f7eca7172a2e168c1ac2cfdb0ffc84f8a28.1456504190.git.git@drmicha.warpmail.net","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"[PATCH 6/6] revisions: list all worktree HEADs with --all","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2016-02-26T16:39:46Z","receivedAt":"2016-02-26T16:39:46Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n---\n\nNotes:\n    Note that ever since\n    f0298cf (revision walker: include a detached HEAD in --all, 2009-01-16)\n    the documentation failed to mention the inclusion of HEAD with \"--all\".\n\n Documentation/rev-list-options.txt | 2 +-\n refs/files-backend.c               | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex 4f009d4..fe37956 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -134,7 +134,7 @@ parents) and `--max-parents=-1` (negative numbers denote no upper limit).\n \n --all::\n \tPretend as if all the refs in `refs/` are listed on the\n-\tcommand line as '<commit>'.\n+\tcommand line as '<commit>', as well as the HEADs of all worktrees.\n \n --branches[=<pattern>]::\n \tPretend as if all the refs in `refs/heads` are listed\ndiff --git a/refs/files-backend.c b/refs/files-backend.c\nindex 1614854..e717db0 100644\n--- a/refs/files-backend.c\n+++ b/refs/files-backend.c\n@@ -1802,7 +1802,7 @@ int head_ref_worktrees(each_ref_fn fn, void *cb_data)\n \n int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn do_head_ref(submodule, fn, cb_data);\n+\treturn do_head_ref_worktrees(submodule, fn, cb_data);\n }\n \n int for_each_ref(each_ref_fn fn, void *cb_data)\n-- \n2.7.2.618.g7a61b68\n"},{"id":"279543","messageId":"xmqq60xbl6ej.fsf@gitster.mtv.corp.google.com","threadId":"41536","inReplyTo":"cover.1456504190.git.git@drmicha.warpmail.net","subject":"Re: [PATCH/WIP 0/6] Detached HEADs in new worktrees considered harmful","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-26T17:37:24Z","receivedAt":"2016-02-26T17:37:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Before someone loses their HEAD I should put this series out (again).\n>\n> 1/6 is a tiny documentation fix.\n>\n> 2/6 demonstrates that \"git prune\" in the main worktree loses HEADs in other\n> worktrees, and vice versa.\n\nYou do need to teach the reachability code to consider points that\nare outside refs/ (HEAD and index, at least; I also recall there\nwere talks about per-worktree hierarchies in refs/?) as anchoring\nobjects to the non-prunable part of the history.\n\nThe prune/fsck reachability code already knows to consider objects\nthat are reachable only from the index as reachable, and I do not\nthink \"rev-list --all\" is used to enumerate them for safekeeping\n(even when the worktree feature is not used).  The reachability code\nthat enumerates objects in the index and cache-tree needs to learn\nto peek into sibling worktrees' private objects, I would think, and\nI do not think the addition is a good match for rev-list.\n"},{"id":"279544","messageId":"xmqq1t7zl5on.fsf@gitster.mtv.corp.google.com","threadId":"41536","inReplyTo":"f0c859d9736058736a58d8c9898c9b5417a63b8c.1456504190.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 1/6] Documentation/git-worktree: spell --detach correctly","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-26T17:52:56Z","receivedAt":"2016-02-26T17:52:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n> ---\n>  Documentation/git-worktree.txt | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt\n> index 62c76c1..51a2ea0 100644\n> --- a/Documentation/git-worktree.txt\n> +++ b/Documentation/git-worktree.txt\n> @@ -50,7 +50,7 @@ Create `<path>` and checkout `<branch>` into it. The new working directory\n>  is linked to the current repository, sharing everything except working\n>  directory specific files such as HEAD, index, etc.\n>  +\n> -If `<branch>` is omitted and neither `-b` nor `-B` nor `--detached` used,\n> +If `<branch>` is omitted and neither `-b` nor `-B` nor `--detach` used,\n\nThat is correct, but I wonder if there is an \" is\" missing there...?\n\n>  then, as a convenience, a new branch based at HEAD is created automatically,\n>  as if `-b $(basename <path>)` was specified.\n"},{"id":"279545","messageId":"xmqqwpprjqmc.fsf@gitster.mtv.corp.google.com","threadId":"41536","inReplyTo":"47fd12af598614ca10fa28cb36fb98ca9ab6d7bb.1456504190.git.git@drmicha.warpmail.net","subject":"Re: [PATCH 2/6] t6014: test prune with detached HEADs in separate worktrees","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-02-26T18:03:39Z","receivedAt":"2016-02-26T18:03:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael J Gruber <git@drmicha.warpmail.net> writes:\n\n> \"git prune\" relies on \"git rev-list --all\" to list all reachable,\n> non-prunable commits. In the presence of per-worktree refs such as HEAD\n> this becomes more complicated.\n\nNot \"all\", perhaps \"majority of\".  The index is another anchor point\nand rev-list is not involved in it at all.\n\nFor those that are anchored by refs and ref-like things, I think the\nright thing to do is not to change the semantics of \"--all\" like\n[3/6] does, but to invent a new option to \"for-each-ref\" that shows\nonly the refs and ref-like things that are private to the worktree.\nThat set may include HEAD and refs/bisect/*, perhaps.\n\nWith that, the scripted equivalent of \"git repack\", \"git prune\" and\n\"git fsck\" can ask \"git worktree list\" the list of worktrees to\nconsult, and in each of them run \"git for-each-ref --private\" and\n\"git ls-files -s\" to grab the objects to be used as the starting\npoint of reachability traversal.\n"},{"id":"279597","messageId":"CACsJy8CrYYjiyeKZuHW=erJ-JZyaWdJKCAzO=zLs2HwSb5ifKA@mail.gmail.com","threadId":"41536","inReplyTo":"61d93b0aba1d4cb7348066db0b48f1ce2d5b35c5.1456504190.git.git@drmicha.warpmail.net","subject":"Re: [PATCH/RFD 3/6] rev-list: list all heads with --all","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2016-02-27T02:15:55Z","receivedAt":"2016-02-27T02:15:55Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Feb 26, 2016 at 11:39 PM, Michael J Gruber\n<git@drmicha.warpmail.net> wrote:\n> HEAD is a worktree specific sysmref, so that a repository with multiple\n> worktrees can have multiple HEADs, or HEADs in a worktree different from\n> the current worktree.\n>\n> So far, \"rev-parse --all\" adds only the HEAD from the current worktree\n> to the list of refs (besides branches etc.). So, a detached HEAD from a\n> different checkout would be missed unless a shared ref (or current HEAD)\n> points to it (or descents from it). As a consequence, \"git prune\" can\n> prune detached HEADs from worktrees and leave the repo in an\n> inconsistent state.\n>\n> Make \"rev-parse --all\" add the HEADs from all worktrees. This results in\n> a non-worktree-specific ref list and solves the pruning problem.\n>\n> Signed-off-by: Michael J Gruber <git@drmicha.warpmail.net>\n> ---\n>\n> Notes:\n>     This patch solves the pruning problem with worktrees, but I feel quite\n>     uneasy about substituting the ref solving at the very heart of refs.c. So\n>     please consider this a mere poc and a request for discussion/input\n>     about how to do this the right way.\n>\n>     In essence, I feel the worktree interface still has to evolve a bit: I'd\n>     rather for_each_worktree than loop myself, and if many call sites need to\n>     be aware of multiple heads or worktrees than get_worktrees() should be\n>     part of our init stuff, not here. [I may be out of sync of newer progress.]\n\nHow about adding for_each_head_ref_submodule()  and make\nhandle_revision_pseudo_opt() use it with a new option, .e.g\n--all-work-trees?\n\nI looked over head_ref and head_ref_submodule call sites. I think\nwe're ok. Most of them only concern about \"our head\". for-each-ref may\nneed some improvement though.\n-- \nDuy\n"}]}