{"thread":{"id":"39990","subject":"[PATCH/RFC 0/2] bisect per-worktree","startedAt":"2015-07-31T23:56:50Z","lastAt":"2015-08-03T23:20:26Z","messageCount":15,"participants":["David Turner","Michael Haggerty","Junio C Hamano","Duy Nguyen"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"267246","messageId":"1438387012-29229-1-git-send-email-dturner@twopensource.com","threadId":"39990","inReplyTo":null,"subject":"[PATCH/RFC 0/2] bisect per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-07-31T23:56:50Z","receivedAt":"2015-07-31T23:56:50Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"This is RFC because I'm not sure why show-ref only works on refs/ (and\nwhether it should learn to look in worktree-refs/).  I'm also not sure\nwhether there are other changes I should make to refs.c to handle\nper-worktree refs; I basically did the simplest thing I could think of\nto start with.\n"},{"id":"267247","messageId":"1438387012-29229-2-git-send-email-dturner@twopensource.com","threadId":"39990","inReplyTo":"1438387012-29229-1-git-send-email-dturner@twopensource.com","subject":"[PATCH 1/2] refs: workree-refs/* become per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-07-31T23:56:51Z","receivedAt":"2015-07-31T23:56:51Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"We need a place to stick refs for bisects in progress that is not\nshared between worktrees.  So we use the worktree-refs/ hierarchy\ninstead of the refs/.\n\nTo do this, load loose refs from \"worktree-refs/\" as well as from \"refs/\".\nThe is_per_worktree_ref function and associated docs learn that\nworktree-refs/ is per-worktree.\n\nThe ref-packing functions learn that refs beginning with\nworktree-refs/ should not be packed (since packed-refs is common\nrather than per-worktree).\n\nSigned-off-by: David Turner <dturner@twopensource.com>\n---\n Documentation/glossary-content.txt |  3 ++-\n refs.c                             | 13 ++++++++++---\n t/t3210-pack-refs.sh               |  7 +++++++\n 3 files changed, 19 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt\nindex 8c6478b..e2847a9 100644\n--- a/Documentation/glossary-content.txt\n+++ b/Documentation/glossary-content.txt\n@@ -413,7 +413,8 @@ exclude;;\n \n [[def_per_worktree_ref]]per-worktree ref::\n \tRefs that are per-<<def_working_tree,worktree>>, rather than\n-\tglobal.  This is presently only <<def_HEAD,HEAD>>, but might\n+\tglobal.  This is presently only <<def_HEAD,HEAD>> and any refs\n+\tthat start with `worktree-refs/` (rather than `refs/`), but might\n \tlater include other unusual refs.\n \n [[def_pseudoref]]pseudoref::\ndiff --git a/refs.c b/refs.c\nindex e6fc3fe..c556b6f 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1433,15 +1433,17 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs)\n \tif (!refs->loose) {\n \t\t/*\n \t\t * Mark the top-level directory complete because we\n-\t\t * are about to read the only subdirectory that can\n+\t\t * are about to read the only subdirectories that can\n \t\t * hold references:\n \t\t */\n \t\trefs->loose = create_dir_entry(refs, \"\", 0, 0);\n \t\t/*\n-\t\t * Create an incomplete entry for \"refs/\":\n+\t\t * Create incomplete entries for \"refs/\" and \"worktree-refs\":\n \t\t */\n \t\tadd_entry_to_dir(get_ref_dir(refs->loose),\n \t\t\t\t create_dir_entry(refs, \"refs/\", 5, 1));\n+\t\tadd_entry_to_dir(get_ref_dir(refs->loose),\n+\t\t\t\t create_dir_entry(refs, \"worktree-refs/\", 14, 1));\n \t}\n \treturn get_ref_dir(refs->loose);\n }\n@@ -2656,6 +2658,10 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)\n \tstruct ref_entry *packed_entry;\n \tint is_tag_ref = starts_with(entry->name, \"refs/tags/\");\n \n+\t/* Do not pack per-worktree refs: */\n+\tif (starts_with(entry->name, \"worktree-refs/\"))\n+\t\treturn 0;\n+\n \t/* ALWAYS pack tags */\n \tif (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref)\n \t\treturn 0;\n@@ -2850,7 +2856,8 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)\n \n static int is_per_worktree_ref(const char *refname)\n {\n-\treturn !strcmp(refname, \"HEAD\");\n+\treturn !strcmp(refname, \"HEAD\") ||\n+\t\tstarts_with(refname, \"worktree-refs/\");\n }\n \n static int is_pseudoref_syntax(const char *refname)\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 8aae98d..0800a1c 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -160,6 +160,13 @@ test_expect_success 'pack ref directly below refs/' '\n \ttest_path_is_missing .git/refs/top\n '\n \n+test_expect_success 'do not pack ref in worktree-refs' '\n+\tgit update-ref worktree-refs/local HEAD &&\n+\tgit pack-refs --all --prune &&\n+\t! grep worktree-refs/local .git/packed-refs >/dev/null &&\n+\ttest_path_is_file .git/worktree-refs/local\n+'\n+\n test_expect_success 'disable reflogs' '\n \tgit config core.logallrefupdates false &&\n \trm -rf .git/logs\n-- \n2.0.4.315.gad8727a-twtrsrc\n"},{"id":"267248","messageId":"1438387012-29229-3-git-send-email-dturner@twopensource.com","threadId":"39990","inReplyTo":"1438387012-29229-1-git-send-email-dturner@twopensource.com","subject":"[PATCH 2/2] bisect: make bisection refs per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-07-31T23:56:52Z","receivedAt":"2015-07-31T23:56:52Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"Using the new worktree-refs/ refs, make bisection per-worktree.\n\ngit show-ref presently only handles refs under refs/, so we change\ngit bisect to use git rev-parse instead.\n\nSigned-off-by: David Turner <dturner@twopensource.com>\n---\n Documentation/git-bisect.txt       |  4 ++--\n Documentation/rev-list-options.txt | 14 +++++++-------\n bisect.c                           |  2 +-\n builtin/rev-parse.c                |  4 ++--\n git-bisect.sh                      | 14 +++++++-------\n revision.c                         |  2 +-\n t/t6030-bisect-porcelain.sh        | 20 ++++++++++----------\n 7 files changed, 30 insertions(+), 30 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex e97f2de..d8753d0 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -82,7 +82,7 @@ to ask for the next commit that needs testing.\n \n Eventually there will be no more revisions left to inspect, and the\n command will print out a description of the first bad commit. The\n-reference `refs/bisect/bad` will be left pointing at that commit.\n+reference `worktree-refs/bisect/bad` will be left pointing at that commit.\n \n \n Bisect reset\n@@ -373,7 +373,7 @@ on a single line.\n ------------\n $ git bisect start HEAD <known-good-commit> [ <boundary-commit> ... ] --no-checkout\n $ git bisect run sh -c '\n-\tGOOD=$(git for-each-ref \"--format=%(objectname)\" refs/bisect/good-*) &&\n+\tGOOD=$(git for-each-ref \"--format=%(objectname)\" worktree-refs/bisect/good-*) &&\n \tgit rev-list --objects BISECT_HEAD --not $GOOD >tmp.$$ &&\n \tgit pack-objects --stdout >/dev/null <tmp.$$\n \trc=$?\ndiff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt\nindex a9b808f..b00b2fa 100644\n--- a/Documentation/rev-list-options.txt\n+++ b/Documentation/rev-list-options.txt\n@@ -183,9 +183,9 @@ explicitly.\n \n ifndef::git-rev-list[]\n --bisect::\n-\tPretend as if the bad bisection ref `refs/bisect/bad`\n+\tPretend as if the bad bisection ref `worktree-refs/bisect/bad`\n \twas listed and as if it was followed by `--not` and the good\n-\tbisection refs `refs/bisect/good-*` on the command\n+\tbisection refs `worktree-refs/bisect/good-*` on the command\n \tline. Cannot be combined with --first-parent.\n endif::git-rev-list[]\n \n@@ -548,10 +548,10 @@ Bisection Helpers\n --bisect::\n \tLimit output to the one commit object which is roughly halfway between\n \tincluded and excluded commits. Note that the bad bisection ref\n-\t`refs/bisect/bad` is added to the included commits (if it\n-\texists) and the good bisection refs `refs/bisect/good-*` are\n+\t`worktree-refs/bisect/bad` is added to the included commits (if it\n+\texists) and the good bisection refs `worktree-refs/bisect/good-*` are\n \tadded to the excluded commits (if they exist). Thus, supposing there\n-\tare no refs in `refs/bisect/`, if\n+\tare no refs in `worktree-refs/bisect/`, if\n +\n -----------------------------------------------------------------------\n \t$ git rev-list --bisect foo ^bar ^baz\n@@ -571,7 +571,7 @@ one. Cannot be combined with --first-parent.\n \n --bisect-vars::\n \tThis calculates the same as `--bisect`, except that refs in\n-\t`refs/bisect/` are not used, and except that this outputs\n+\t`worktree-refs/bisect/` are not used, and except that this outputs\n \ttext ready to be eval'ed by the shell. These lines will assign the\n \tname of the midpoint revision to the variable `bisect_rev`, and the\n \texpected number of commits to be tested after `bisect_rev` is tested\n@@ -584,7 +584,7 @@ one. Cannot be combined with --first-parent.\n --bisect-all::\n \tThis outputs all the commit objects between the included and excluded\n \tcommits, ordered by their distance to the included and excluded\n-\tcommits. Refs in `refs/bisect/` are not used. The farthest\n+\tcommits. Refs in `worktree-refs/bisect/` are not used. The farthest\n \tfrom them is displayed first. (This is the only one displayed by\n \t`--bisect`.)\n +\ndiff --git a/bisect.c b/bisect.c\nindex 33ac88d..63bd5cf 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -425,7 +425,7 @@ static int register_ref(const char *refname, const struct object_id *oid,\n \n static int read_bisect_refs(void)\n {\n-\treturn for_each_ref_in(\"refs/bisect/\", register_ref, NULL);\n+\treturn for_each_ref_in(\"worktree-refs/bisect/\", register_ref, NULL);\n }\n \n static void read_bisect_paths(struct argv_array *array)\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 02d747d..ad56154 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -663,8 +663,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--bisect\")) {\n-\t\t\t\tfor_each_ref_in(\"refs/bisect/bad\", show_reference, NULL);\n-\t\t\t\tfor_each_ref_in(\"refs/bisect/good\", anti_reference, NULL);\n+\t\t\t\tfor_each_ref_in(\"worktree-refs/bisect/bad\", show_reference, NULL);\n+\t\t\t\tfor_each_ref_in(\"worktree-refs/bisect/good\", anti_reference, NULL);\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (starts_with(arg, \"--branches=\")) {\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ea63223..cef4a94 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -210,7 +210,7 @@ bisect_write() {\n \t\t*)\n \t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n \tesac\n-\tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n+\tgit update-ref \"worktree-refs/bisect/$tag\" \"$rev\" || exit\n \techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n \ttest -n \"$nolog\" || echo \"git bisect $state $rev\" >>\"$GIT_DIR/BISECT_LOG\"\n }\n@@ -282,8 +282,8 @@ bisect_state() {\n \n bisect_next_check() {\n \tmissing_good= missing_bad=\n-\tgit show-ref -q --verify refs/bisect/$TERM_BAD || missing_bad=t\n-\ttest -n \"$(git for-each-ref \"refs/bisect/$TERM_GOOD-*\")\" || missing_good=t\n+\tgit rev-parse -q --verify worktree-refs/bisect/$TERM_BAD >/dev/null || missing_bad=t\n+\ttest -n \"$(git for-each-ref \"worktree-refs/bisect/$TERM_GOOD-*\")\" || missing_good=t\n \n \tcase \"$missing_good,$missing_bad,$1\" in\n \t,,*)\n@@ -341,15 +341,15 @@ bisect_next() {\n \t# Check if we should exit because bisection is finished\n \tif test $res -eq 10\n \tthen\n-\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/$TERM_BAD)\n+\t\tbad_rev=$(git rev-parse -q --verify worktree-refs/bisect/$TERM_BAD)\n \t\tbad_commit=$(git show-branch $bad_rev)\n \t\techo \"# first $TERM_BAD commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\texit 0\n \telif test $res -eq 2\n \tthen\n \t\techo \"# only skipped commits left to test\" >>\"$GIT_DIR/BISECT_LOG\"\n-\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/$TERM_GOOD-*\")\n-\t\tfor skipped in $(git rev-list refs/bisect/$TERM_BAD --not $good_revs)\n+\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"worktree-refs/bisect/$TERM_GOOD-*\")\n+\t\tfor skipped in $(git rev-list worktree-refs/bisect/$TERM_BAD --not $good_revs)\n \t\tdo\n \t\t\tskipped_commit=$(git show-branch $skipped)\n \t\t\techo \"# possible first $TERM_BAD commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n@@ -412,7 +412,7 @@ Try 'git bisect reset <commit>'.\")\"\n \n bisect_clean_state() {\n \t# There may be some refs packed during bisection.\n-\tgit for-each-ref --format='%(refname) %(objectname)' refs/bisect/\\* |\n+\tgit for-each-ref --format='%(refname) %(objectname)' worktree-refs/bisect/\\* |\n \twhile read ref hash\n \tdo\n \t\tgit update-ref -d $ref $hash || exit\ndiff --git a/revision.c b/revision.c\nindex b6b2cf7..90c9c36 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2084,7 +2084,7 @@ extern void read_bisect_terms(const char **bad, const char **good);\n static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data, const char *term) {\n \tstruct strbuf bisect_refs = STRBUF_INIT;\n \tint status;\n-\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", term);\n+\tstrbuf_addf(&bisect_refs, \"worktree-refs/bisect/%s\", term);\n \tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n \tstrbuf_release(&bisect_refs);\n \treturn status;\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9e2c203..b5dffd6 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -68,7 +68,7 @@ test_expect_success 'bisect fails if given any junk instead of revs' '\n \tgit bisect reset &&\n \ttest_must_fail git bisect start foo $HASH1 -- &&\n \ttest_must_fail git bisect start $HASH4 $HASH1 bar -- &&\n-\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest -z \"$(git for-each-ref \"worktree-refs/bisect/*\")\" &&\n \ttest -z \"$(ls .git/BISECT_* 2>/dev/null)\" &&\n \tgit bisect start &&\n \ttest_must_fail git bisect good foo $HASH1 &&\n@@ -77,7 +77,7 @@ test_expect_success 'bisect fails if given any junk instead of revs' '\n \ttest_must_fail git bisect bad $HASH3 $HASH4 &&\n \ttest_must_fail git bisect skip bar $HASH3 &&\n \ttest_must_fail git bisect skip $HASH1 foo &&\n-\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest -z \"$(git for-each-ref \"worktree-refs/bisect/*\")\" &&\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4\n '\n@@ -115,7 +115,7 @@ test_expect_success 'bisect reset removes packed refs' '\n \tgit pack-refs --all --prune &&\n \tgit bisect next &&\n \tgit bisect reset &&\n-\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest -z \"$(git for-each-ref \"worktree-refs/bisect/*\")\" &&\n \ttest -z \"$(git for-each-ref \"refs/heads/bisect\")\"\n '\n \n@@ -126,7 +126,7 @@ test_expect_success 'bisect reset removes bisect state after --no-checkout' '\n \tgit bisect bad $HASH3 &&\n \tgit bisect next &&\n \tgit bisect reset &&\n-\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest -z \"$(git for-each-ref \"worktree-refs/bisect/*\")\" &&\n \ttest -z \"$(git for-each-ref \"refs/heads/bisect\")\" &&\n \ttest -z \"$(git for-each-ref \"BISECT_HEAD\")\"\n '\n@@ -176,7 +176,7 @@ test_expect_success 'bisect start: no \".git/BISECT_START\" if checkout error' '\n \tgit branch > branch.output &&\n \tgrep \"* other\" branch.output > /dev/null &&\n \ttest_must_fail test -e .git/BISECT_START &&\n-\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest -z \"$(git for-each-ref \"worktree-refs/bisect/*\")\" &&\n \tgit checkout HEAD hello\n '\n \n@@ -671,7 +671,7 @@ test_expect_success 'bisect: --no-checkout - target before breakage' '\n \tgit bisect bad BISECT_HEAD &&\n \tcheck_same BROKEN_HASH5 BISECT_HEAD &&\n \tgit bisect bad BISECT_HEAD &&\n-\tcheck_same BROKEN_HASH5 bisect/bad &&\n+\tcheck_same BROKEN_HASH5 worktree-refs/bisect/bad &&\n \tgit bisect reset\n '\n \n@@ -682,7 +682,7 @@ test_expect_success 'bisect: --no-checkout - target in breakage' '\n \tgit bisect bad BISECT_HEAD &&\n \tcheck_same BROKEN_HASH5 BISECT_HEAD &&\n \tgit bisect good BISECT_HEAD &&\n-\tcheck_same BROKEN_HASH6 bisect/bad &&\n+\tcheck_same BROKEN_HASH6 worktree-refs/bisect/bad &&\n \tgit bisect reset\n '\n \n@@ -693,7 +693,7 @@ test_expect_success 'bisect: --no-checkout - target after breakage' '\n \tgit bisect good BISECT_HEAD &&\n \tcheck_same BROKEN_HASH8 BISECT_HEAD &&\n \tgit bisect good BISECT_HEAD &&\n-\tcheck_same BROKEN_HASH9 bisect/bad &&\n+\tcheck_same BROKEN_HASH9 worktree-refs/bisect/bad &&\n \tgit bisect reset\n '\n \n@@ -702,13 +702,13 @@ test_expect_success 'bisect: demonstrate identification of damage boundary' \"\n \tgit checkout broken &&\n \tgit bisect start broken master --no-checkout &&\n \tgit bisect run \\\"\\$SHELL_PATH\\\" -c '\n-\t\tGOOD=\\$(git for-each-ref \\\"--format=%(objectname)\\\" refs/bisect/good-*) &&\n+\t\tGOOD=\\$(git for-each-ref \\\"--format=%(objectname)\\\" worktree-refs/bisect/good-*) &&\n \t\tgit rev-list --objects BISECT_HEAD --not \\$GOOD >tmp.\\$\\$ &&\n \t\tgit pack-objects --stdout >/dev/null < tmp.\\$\\$\n \t\trc=\\$?\n \t\trm -f tmp.\\$\\$\n \t\ttest \\$rc = 0' &&\n-\tcheck_same BROKEN_HASH6 bisect/bad &&\n+\tcheck_same BROKEN_HASH6 worktree-refs/bisect/bad &&\n \tgit bisect reset\n \"\n \n-- \n2.0.4.315.gad8727a-twtrsrc\n"},{"id":"267253","messageId":"55BC4438.8060709@alum.mit.edu","threadId":"39990","inReplyTo":"1438387012-29229-1-git-send-email-dturner@twopensource.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2015-08-01T03:59:52Z","receivedAt":"2015-08-01T03:59:52Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 08/01/2015 01:56 AM, David Turner wrote:\n> This is RFC because I'm not sure why show-ref only works on refs/ (and\n> whether it should learn to look in worktree-refs/).  I'm also not sure\n> whether there are other changes I should make to refs.c to handle\n> per-worktree refs; I basically did the simplest thing I could think of\n> to start with.\n\nIt seems to me that adding a new top-level \"worktree-refs\" directory is\npretty traumatic. Lots of people and tools will have made the assumption\nthat all \"normal\" references live under \"refs/\".\n\nEach worktree has a name, right? What if worktree-specific refs were\nstored under \"refs/worktree/<name>/\" or something? This would require\nthe name to be a valid reference name component, but I think that is a\nprudent idea anyway.\n\nOf course that doesn't answer the question: where should the refs for\nthe main repository go? I suppose either in the current place, or maybe\nthe main repository should have a name too (e.g. \"main\") and its\nreferences should be stored under \"refs/worktree/main/\".\n\nThese worktree-specific refs should presumably be deleted automatically\nwhen the worktree is deleted.\n\nEither way, there's also the question of who should know how to find the\nworktree-specific references--the program that wants to access them, or\nshould there be a secret invisible mapping that is done on lookup, and\nthat knows the full list of references that want to be worktree-specific\n(for example, that in a linked worktree, \"refs/bisect/*\" should be\nsilently redirected to \"refs/worktree/<name>/bisect/*\")?\n\nIt's all a bit frightening, frankly.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\n"},{"id":"267254","messageId":"CAPc5daVnfit8pkjc2HCSn0erW-q++We8gx8tPsb_ptd5H+CpJg@mail.gmail.com","threadId":"39990","inReplyTo":"55BC4438.8060709@alum.mit.edu","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-01T05:12:51Z","receivedAt":"2015-08-01T05:12:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"On Fri, Jul 31, 2015 at 8:59 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>\n> It seems to me that adding a new top-level \"worktree-refs\" directory is\n> pretty traumatic. Lots of people and tools will have made the assumption\n> that all \"normal\" references live under \"refs/\".\n> ...\n> It's all a bit frightening, frankly.\n\nI actually feel the prospect of pluggable ref backend more frightening,\nfrankly ;-). These bisect refs are just like FETCH_HEAD and MERGE_HEAD,\nnot about the primary purpose of the \"repository\" to grow the history of refs\n(branches), but about ephemeral pointers into the history used to help keep\ntrack of what is being done in the worktree upstairs. There is no need for\nthese to be visible across worktrees. If we use the real refs that are grobal\nin the repository (as opposed to per-worktree ones), we would hit the backend\ndatabas with transactions to update these ephemeral things, which somehow\nmakes me feel stupid.\n\nI wish we could just make refs/bisect/* (or whatever the current bisect\ncode uses) automatically per worktree. I know David dismissed it saying\nthat the current code is not set up to allow it easily, but is it\nreally a fundamental\nlimitation, or is it just a matter of coding a few more dozens of lines?\n\nIf we can keep using the same location under refs/ and transparently make\nthem appear per-worktree, \"what is the name of the main one?\", and \"do we\neven need to call the one and the only one 'main'?\" will automatically\ndisappear.\nOf course, \"git bisect\" and \"gitk --bisect\" does not have to change if\nwe go that\nroute.\n\nAnd there will not be any backward compatibility worries. If you are not\nusing multiple worktrees, you will see them as refs/bisect/*, just at the\nsame location as you are familiar with.\n"},{"id":"267256","messageId":"1438408545.4735.40.camel@twopensource.com","threadId":"39990","inReplyTo":"CAPc5daVnfit8pkjc2HCSn0erW-q++We8gx8tPsb_ptd5H+CpJg@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-08-01T05:55:45Z","receivedAt":"2015-08-01T05:55:45Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Fri, 2015-07-31 at 22:12 -0700, Junio C Hamano wrote:\n> On Fri, Jul 31, 2015 at 8:59 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> >\n> > It seems to me that adding a new top-level \"worktree-refs\" directory is\n> > pretty traumatic. Lots of people and tools will have made the assumption\n> > that all \"normal\" references live under \"refs/\".\n> > ...\n> > It's all a bit frightening, frankly.\n> \n> I actually feel the prospect of pluggable ref backend more frightening,\n> frankly ;-). These bisect refs are just like FETCH_HEAD and MERGE_HEAD,\n> not about the primary purpose of the \"repository\" to grow the history of refs\n> (branches), but about ephemeral pointers into the history used to help keep\n> track of what is being done in the worktree upstairs. There is no need for\n> these to be visible across worktrees. If we use the real refs that are grobal\n> in the repository (as opposed to per-worktree ones), we would hit the backend\n> databas with transactions to update these ephemeral things, which somehow\n> makes me feel stupid.\n\nAgreed, I think it's a mistake to complicate the global ref namespace\nlike that.\n\n> I wish we could just make refs/bisect/* (or whatever the current bisect\n> code uses) automatically per worktree. I know David dismissed it saying\n> that the current code is not set up to allow it easily, but is it\n> really a fundamental\n> limitation, or is it just a matter of coding a few more dozens of lines?\n\nWe still need the packed-refs and is_per_worktree_ref change; we need a\ndifferent and more complicated loose-refs loading change, and we need\nchanges to path.c to treat refs/bisect different from refs/.  Probably a\nfew dozen lines, yeah.  And it's sort of ugly to make the refs/bisect\nspecial case into a fundamental part of the repository structure.  \n\nI'm worried that we'll discover a need for more of these.  But I can do\nthe rewrite and see how it looks (probably on Monday).\n\nDo we need to worry about reflogs for these?  If so, a few more lines,\nprobably.\n\n> If we can keep using the same location under refs/ and transparently make\n> them appear per-worktree, \"what is the name of the main one?\", and \"do we\n> even need to call the one and the only one 'main'?\" will automatically\n> disappear.\n> Of course, \"git bisect\" and \"gitk --bisect\" does not have to change if\n> we go that\n> route.\n> \n> And there will not be any backward compatibility worries. If you are not\n> using multiple worktrees, you will see them as refs/bisect/*, just at the\n> same location as you are familiar with.\n\nYes, this is a good point.\n"},{"id":"267261","messageId":"55BC6C5C.1070707@alum.mit.edu","threadId":"39990","inReplyTo":"CAPc5daVnfit8pkjc2HCSn0erW-q++We8gx8tPsb_ptd5H+CpJg@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Michael Haggerty","fromEmail":"mhagger@alum.mit.edu","sentAt":"2015-08-01T06:51:08Z","receivedAt":"2015-08-01T06:51:08Z","isPatch":true,"sender":{"key":"mhagger@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/119718?v=4"},"body":"On 08/01/2015 07:12 AM, Junio C Hamano wrote:\n> On Fri, Jul 31, 2015 at 8:59 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>>\n>> It seems to me that adding a new top-level \"worktree-refs\" directory is\n>> pretty traumatic. Lots of people and tools will have made the assumption\n>> that all \"normal\" references live under \"refs/\".\n>> ...\n>> It's all a bit frightening, frankly.\n> \n> I actually feel the prospect of pluggable ref backend more frightening,\n> frankly ;-). These bisect refs are just like FETCH_HEAD and MERGE_HEAD,\n> not about the primary purpose of the \"repository\" to grow the history of refs\n> (branches), but about ephemeral pointers into the history used to help keep\n> track of what is being done in the worktree upstairs. There is no need for\n> these to be visible across worktrees. If we use the real refs that are grobal\n> in the repository (as opposed to per-worktree ones), we would hit the backend\n> databas with transactions to update these ephemeral things, which somehow\n> makes me feel stupid.\n\nHmm, ok, so you are thinking of a remote database with high latency. I\nwas thinking more of something like LMDB, with latency comparable to\nfilesystem storage.\n\nThese worktree-specific references might be ephemeral, but they also\nimply reachability, which means that they need to be visible at least\nduring object pruning. Moreover, if the references don't live in the\nsame database with the rest of the references, then we have to deal with\nraces due to updating references in different places without atomicity.\n\nThe refs+object store is the most important thing for maintaining the\nintegrity of a repo and avoiding races. To me it seems easier to do so\nif there is a single refs+objects store than if we have some references\nover here on the file system, some over there in a LMDB, etc. So my gut\nfeeling is for the primary reference storage to be in a single reference\nnamespace that (at least in principle) can be stored in a single ACID\ndatabase.\n\nFor each worktree, we could then create a different view of the\nreferences by splicing parts of the full reference namespace together.\nThis could even be based on config settings so that we don't have to\nhardcode information like \"refs/bisect/* is worktree-specific\" deep in\nthe references module. Suppose we could write\n\n[worktree.refs]\n\tmap = refs/worktrees/*:\n\tmap = refs/bisect/*:refs/worktrees/[worktree]/refs/bisect/*\n\nwhich would mean (a) hide the references under refs/worktrees\", and (b)\nmake it look as if the references under\nrefs/worktrees/[worktree]/refs/bisect actually appear under refs/bisect\n(where \"[worktree]\" is replaced with the current worktree's name). By\nmaking these settings configurable, we allow other projects to define\ntheir own worktree-specific reference namespaces too.\n\nThe corresponding main repo might hide \"refs/worktrees/*\" but leave its\nrefs/bisect namespace exposed in the usual place.\n\n\"git prune\" would see the whole namespace as it really is so that it can\ncompute reachability correctly.\n\nMichael\n\n-- \nMichael Haggerty\nmhagger@alum.mit.edu\n"},{"id":"267294","messageId":"xmqq1tfla6rh.fsf@gitster.dls.corp.google.com","threadId":"39990","inReplyTo":"55BC6C5C.1070707@alum.mit.edu","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-02T18:24:02Z","receivedAt":"2015-08-02T18:24:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Haggerty <mhagger@alum.mit.edu> writes:\n\n> Hmm, ok, so you are thinking of a remote database with high latency. I\n> was thinking more of something like LMDB, with latency comparable to\n> filesystem storage.\n\nNot necessarily.  The comment was more from conceptual point: \"Why\nshare what needs not to be shared?\"\n\n> These worktree-specific references might be ephemeral, but they also\n> imply reachability, which means that they need to be visible at least\n> during object pruning.\n\nTrue, but for bisect in particular, that is moot.  You are in\nsightseer mode, marking various (older) points in time of an\nexisting history that is already anchored by branches and tags.\n\n> Moreover, if the references don't live in the\n> same database with the rest of the references, then we have to deal with\n> races due to updating references in different places without atomicity.\n\nDoes that still hold true in the context of bisection?  You do not\neven want atomicity to get in the way when you found this old commit\nis bad and are about to mark the next one for testing by checking it\nout.  You still want to mark the \"bad\" one (as it being bad is already\nan established fact after testing), even if the subsequent checkout\nof another commit (i.e. update to \"HEAD\") fails.\n\nBut these two comments above do take advantage of the fact that we\nare discussing \"bisect\" and nothing else.  As a set of points to\nconsider in a more general context, I do agree that there are refs\nand ref-like things that are per-worktree but still has to be part\nof reachability, which \"HEAD\" is the prime example ;-), and some of\nthem may want to be part of a transaction.\n\nI however think what David has been calling pseudo-refs falls more\nin the \"ephemeral and unnecessary to participate in reachabliity or\ntransaction\" category (e.g. CHERRY_PICK_HEAD).  And I think the refs\nused during bisection falls into the same category.\n\n> For each worktree, we could then create a different view of the\n> references by splicing parts of the full reference namespace together.\n> ...\n> \"git prune\" would see the whole namespace as it really is so that it can\n> compute reachability correctly.\n\nI really like this as a mechanism to include refs/ hierarchy, some\npart of which is shared and some part of which is private.\n\nI do not think bisect or pseudorefs needs that, though.\n"},{"id":"267307","messageId":"CACsJy8B4HY2Vv=Zyf_T6qXkWY79JaGjPafv-SK0UcYukf=fH1w@mail.gmail.com","threadId":"39990","inReplyTo":"55BC6C5C.1070707@alum.mit.edu","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-03T12:35:54Z","receivedAt":"2015-08-03T12:35:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Aug 1, 2015 at 1:51 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> For each worktree, we could then create a different view of the\n> references by splicing parts of the full reference namespace together.\n> This could even be based on config settings so that we don't have to\n> hardcode information like \"refs/bisect/* is worktree-specific\" deep in\n> the references module. Suppose we could write\n>\n> [worktree.refs]\n>         map = refs/worktrees/*:\n>         map = refs/bisect/*:refs/worktrees/[worktree]/refs/bisect/*\n\nPerhaps the destination should be worktrees/[worktree]/refs/bisect/*.\nDoes it have to start with \"refs/\"?\n\n> which would mean (a) hide the references under refs/worktrees\", and (b)\n> make it look as if the references under\n> refs/worktrees/[worktree]/refs/bisect actually appear under refs/bisect\n> (where \"[worktree]\" is replaced with the current worktree's name). By\n> making these settings configurable, we allow other projects to define\n> their own worktree-specific reference namespaces too.\n>\n> The corresponding main repo might hide \"refs/worktrees/*\" but leave its\n> refs/bisect namespace exposed in the usual place.\n>\n> \"git prune\" would see the whole namespace as it really is so that it can\n> compute reachability correctly.\n\nFor multiple wortrees, first we basically remap paths in .git,\nrelocate some to worktrees/[worktree]/ (already done), then we're\ngoing to remap config keys (submodule support, just proof of concept\nso far), remapping ref paths sounds like the logical next step if some\nunder refs/ needs to be worktree-specific. I wonder if current ref\nnamespace code could be extended to do this?\n-- \nDuy\n"},{"id":"267308","messageId":"CACsJy8Cx_PTehaeQgXxGaTNRF2DUSNqbBYPQ5gQ0BYGpz6kQvQ@mail.gmail.com","threadId":"39990","inReplyTo":"55BC4438.8060709@alum.mit.edu","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-03T13:02:40Z","receivedAt":"2015-08-03T13:02:40Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sat, Aug 1, 2015 at 10:59 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> Either way, there's also the question of who should know how to find the\n> worktree-specific references--the program that wants to access them, or\n> should there be a secret invisible mapping that is done on lookup, and\n> that knows the full list of references that want to be worktree-specific\n> (for example, that in a linked worktree, \"refs/bisect/*\" should be\n> silently redirected to \"refs/worktree/<name>/bisect/*\")?\n>\n> It's all a bit frightening, frankly.\n\nI would think all work to make pluggable backends happen should allow\nus to do this kind of transparent mapping. We can add a new file-based\nbackend with just this redirection, can't we? I haven't read the\nupdated refs.c though, need to do it now..\n-- \nDuy\n"},{"id":"267314","messageId":"CACsJy8B6Fg-1haJZ_xMGk8Xy0zUpeOJYgRWKbZxy_RB11JfF7g@mail.gmail.com","threadId":"39990","inReplyTo":"CACsJy8Cx_PTehaeQgXxGaTNRF2DUSNqbBYPQ5gQ0BYGpz6kQvQ@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-03T14:03:16Z","receivedAt":"2015-08-03T14:03:16Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Aug 3, 2015 at 8:02 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Sat, Aug 1, 2015 at 10:59 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n>> Either way, there's also the question of who should know how to find the\n>> worktree-specific references--the program that wants to access them, or\n>> should there be a secret invisible mapping that is done on lookup, and\n\nAfter re-reading some code, I think this invisible mapping on lookup\nis already done for our file-based ref backend. Take\nresolve_ref_unsafe_1 for example, the call strbuf_git_path() may\nreturn \".git/worktrees/foo/HEAD\", not \".git/HEAD\", given the input ref\n\"HEAD\". So ref names are already separated from where they are stored.\n\n>> that knows the full list of references that want to be worktree-specific\n>> (for example, that in a linked worktree, \"refs/bisect/*\" should be\n>> silently redirected to \"refs/worktree/<name>/bisect/*\")?\n\nMy decision to hard code these paths may turn out a bad thing (it's\ncommon_list[] in path.c). Perhaps I should let the user extend them,\nbut we will not allow to override a small subset of paths because that\nmay break stuff horribly.\n\n>> It's all a bit frightening, frankly.\n>\n> I would think all work to make pluggable backends happen should allow\n> us to do this kind of transparent mapping. We can add a new file-based\n> backend with just this redirection, can't we? I haven't read the\n> updated refs.c though, need to do it now..\n-- \nDuy\n"},{"id":"267336","messageId":"1438631396.7348.33.camel@twopensource.com","threadId":"39990","inReplyTo":"55BC6C5C.1070707@alum.mit.edu","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-08-03T19:49:56Z","receivedAt":"2015-08-03T19:49:56Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Sat, 2015-08-01 at 08:51 +0200, Michael Haggerty wrote:\n> On 08/01/2015 07:12 AM, Junio C Hamano wrote:\n> > On Fri, Jul 31, 2015 at 8:59 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:\n> >>\n> >> It seems to me that adding a new top-level \"worktree-refs\" directory is\n> >> pretty traumatic. Lots of people and tools will have made the assumption\n> >> that all \"normal\" references live under \"refs/\".\n> >> ...\n> >> It's all a bit frightening, frankly.\n> > \n> > I actually feel the prospect of pluggable ref backend more frightening,\n> > frankly ;-). These bisect refs are just like FETCH_HEAD and MERGE_HEAD,\n> > not about the primary purpose of the \"repository\" to grow the history of refs\n> > (branches), but about ephemeral pointers into the history used to help keep\n> > track of what is being done in the worktree upstairs. There is no need for\n> > these to be visible across worktrees. If we use the real refs that are grobal\n> > in the repository (as opposed to per-worktree ones), we would hit the backend\n> > databas with transactions to update these ephemeral things, which somehow\n> > makes me feel stupid.\n> \n> Hmm, ok, so you are thinking of a remote database with high latency. I\n> was thinking more of something like LMDB, with latency comparable to\n> filesystem storage.\n> \n> These worktree-specific references might be ephemeral, but they also\n> imply reachability, which means that they need to be visible at least\n> during object pruning. Moreover, if the references don't live in the\n> same database with the rest of the references, then we have to deal with\n> races due to updating references in different places without atomicity.\n> \n> The refs+object store is the most important thing for maintaining the\n> integrity of a repo and avoiding races. To me it seems easier to do so\n> if there is a single refs+objects store than if we have some references\n> over here on the file system, some over there in a LMDB, etc. So my gut\n> feeling is for the primary reference storage to be in a single reference\n> namespace that (at least in principle) can be stored in a single ACID\n> database.\n>\n> For each worktree, we could then create a different view of the\n> references by splicing parts of the full reference namespace together.\n> This could even be based on config settings so that we don't have to\n> hardcode information like \"refs/bisect/* is worktree-specific\" deep in\n> the references module. Suppose we could write\n> \n> [worktree.refs]\n> \tmap = refs/worktrees/*:\n> \tmap = refs/bisect/*:refs/worktrees/[worktree]/refs/bisect/*\n> \n> which would mean (a) hide the references under refs/worktrees\", and (b)\n> make it look as if the references under\n> refs/worktrees/[worktree]/refs/bisect actually appear under refs/bisect\n> (where \"[worktree]\" is replaced with the current worktree's name). By\n> making these settings configurable, we allow other projects to define\n> their own worktree-specific reference namespaces too.\n> \n> The corresponding main repo might hide \"refs/worktrees/*\" but leave its\n> refs/bisect namespace exposed in the usual place.\n> \n> \"git prune\" would see the whole namespace as it really is so that it can\n> compute reachability correctly.\n\nI think making this configurable is (a) overkill and (b) dangerous.\nIt's dangerous because the semantics of which refs are per-worktree is\nimportant to the correct operation of git, and allowing users to mess\nwith it seems like a big mistake.  Instead, we should figure out a\nsimple scheme and define it globally.\n\nI think refs/worktree -> refs/worktrees/[worktree]/ would do fine as a\nfixed scheme, if we go that route.\n\nWe would need two separate views of the refs hierarchy, though: one used\nby prune (and pack-refs) that is non-mapped (that is, includes\nper-worktree refs for each worktree), and one for general use that is\nmapped.   Maybe this is just a flag to the ref traversal functions.\n\nBut I'm not sure that this is really the right way to go.\n\nAs I understand it, we don't presently do many transactions that include\nboth pseudorefs or per-worktree refs and other refs.  And we definitely\ndon't want to move pseudorefs into the database since there's so much\ncode that assumes they're files.  Also, the vast majority of refs are\ncommon, rather than per-worktree.  In fact, the only per-worktree refs\nI've seen mentioned so far are the bisect refs and NOTES_MERGE_REF and\nHEAD.  Of these, only HEAD is needed for pruning. Are there more that I\nhaven't thought of?\n\nSo I'm not sure the gain from moving per-worktree refs into the database\nis that great.\n\nThere are some downsides of moving per-worktree refs into the database:\n\n1. More operations in one worktree can now contend with operations in\nanother worktree for the database.  LMDB only allows a single write\ntransaction at a time.  \n\n2. The refs API would be more complicated: it would need to deal with\nremapped vs raw ref paths.  Refs backends would need to have functions\nto prune per-worktree data when a worktree is destroyed. \n\n4. We would still need to deal with pseudorefs, so there's still some\nmissing transactional safety, and still the complication of dealing with\nfiles on the filesystem.\n\nSimply treating refs/worktree as per-worktree, while the rest of refs/\nis not, would be a few dozen lines of code.  The full remapping approach\nis likely to be a lot more. I've already got the lmdb backend working\nwith something like this approach.  If we decide on a complicated\napproach, I am likely to run out of time to work on pluggable backends.\n"},{"id":"267349","messageId":"xmqqvbcw6pml.fsf@gitster.dls.corp.google.com","threadId":"39990","inReplyTo":"1438631396.7348.33.camel@twopensource.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-03T21:14:42Z","receivedAt":"2015-08-03T21:14:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Turner <dturner@twopensource.com> writes:\n\n> I think making this configurable is (a) overkill and (b) dangerous.\n> It's dangerous because the semantics of which refs are per-worktree is\n> important to the correct operation of git, and allowing users to mess\n> with it seems like a big mistake.  Instead, we should figure out a\n> simple scheme and define it globally.\n>\n> I think refs/worktree -> refs/worktrees/[worktree]/ would do fine as a\n> fixed scheme, if we go that route.\n\nOK.\n\n> We would need two separate views of the refs hierarchy, though: one used\n> by prune (and pack-refs) that is non-mapped (that is, includes\n> per-worktree refs for each worktree), and one for general use that is\n> mapped.   Maybe this is just a flag to the ref traversal functions.\n\nTrue.  Alternatively we could just view refs/worktree/* as if they\nare symbolic refs that point into refs/worktrees/$my_worktree/*, but\nthat would imply making the latter always visible to all worktrees,\nwhich would hurt when people use it to interact with outside world\n(namely, refs in other people's private area should probably not be\nadvertised).\n\n> As I understand it, we don't presently do many transactions that include\n> both pseudorefs or per-worktree refs and other refs.  And we definitely\n> don't want to move pseudorefs into the database since there's so much\n> code that assumes they're files.  Also, the vast majority of refs are\n> common, rather than per-worktree.  In fact, the only per-worktree refs\n> I've seen mentioned so far are the bisect refs and NOTES_MERGE_REF and\n> HEAD.  Of these, only HEAD is needed for pruning. Are there more that I\n> haven't thought of?\n\nI myself have come up with nothing other than the above.  Let's hear\nfrom others.\n\n> So I'm not sure the gain from moving per-worktree refs into the database\n> is that great.\n\nI am on the same wavelength as you are on this.\n\n> There are some downsides of moving per-worktree refs into the database:\n> ...\n\nAll good points except #3, which I cannot judge if it is good or bad.\n\n> ...\n> Simply treating refs/worktree as per-worktree, while the rest of refs/\n> is not, would be a few dozen lines of code.  The full remapping approach\n> is likely to be a lot more.\n\nWe may be over-engineering with Michael's and even with the more\nsimpler refs/worktree/* -> refs/worktrees/$mine/* fixed mapping;\nI tend to agree with you.\n"},{"id":"267372","messageId":"CACsJy8Aab0-JQitEnxYwiepPBvkgHzZudALpQSi2VS54_x4d7Q@mail.gmail.com","threadId":"39990","inReplyTo":"1438631396.7348.33.camel@twopensource.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-03T23:09:17Z","receivedAt":"2015-08-03T23:09:17Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Tue, Aug 4, 2015 at 2:49 AM, David Turner <dturner@twopensource.com> wrote:\n> Simply treating refs/worktree as per-worktree, while the rest of refs/\n> is not, would be a few dozen lines of code.  The full remapping approach\n> is likely to be a lot more. I've already got the lmdb backend working\n> with something like this approach.  If we decide on a complicated\n> approach, I am likely to run out of time to work on pluggable backends.\n\nI think you still have another option: decide that lmdb backend does\nnot (yet) support multiple worktrees (which means make \"git worktree\nadd\" reject when lmdb backend is used). That would simplify some for\nyou and we can continue on at a later time.\n-- \nDuy\n"},{"id":"267373","messageId":"1438644026.7348.37.camel@twopensource.com","threadId":"39990","inReplyTo":"CACsJy8Aab0-JQitEnxYwiepPBvkgHzZudALpQSi2VS54_x4d7Q@mail.gmail.com","subject":"Re: [PATCH/RFC 0/2] bisect per-worktree","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-08-03T23:20:26Z","receivedAt":"2015-08-03T23:20:26Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Tue, 2015-08-04 at 06:09 +0700, Duy Nguyen wrote:\n> On Tue, Aug 4, 2015 at 2:49 AM, David Turner <dturner@twopensource.com> wrote:\n> > Simply treating refs/worktree as per-worktree, while the rest of refs/\n> > is not, would be a few dozen lines of code.  The full remapping approach\n> > is likely to be a lot more. I've already got the lmdb backend working\n> > with something like this approach.  If we decide on a complicated\n> > approach, I am likely to run out of time to work on pluggable backends.\n> \n> I think you still have another option: decide that lmdb backend does\n> not (yet) support multiple worktrees (which means make \"git worktree\n> add\" reject when lmdb backend is used). That would simplify some for\n> you and we can continue on at a later time.\n\nSome of our developers are pretty excited about multiple worktrees, so I\ndon't really want to do that.  Also, it's easier to develop when more of\nthe tests pass under the LMDB backend (no need to investigate whether\nworktrees are the reason for failures when there are no failures).\n"}]}