----
 In multiple working trees, some refs may be shared between all working
 trees, some refs are local. One example is HEAD is different for all
-working trees. This section is about the sharing rules.
+working trees. This section is about the sharing rules and how to access
+refs of one working tree from another.
 
 In general, all pseudo refs are per working tree and all refs starting
 with "refs/" are shared. Pseudo refs are ones like HEAD which are
 exception to this: refs inside refs/bisect and refs/worktree is not
 shared.
 
+Refs that are per working tree can still be accessed from another
+working tree via two special paths, main-worktree and worktrees. The
+former gives access to per-worktree refs of the main working tree,
+while the latter to all linked working trees.
+
+For example, main-worktree/HEAD or main-worktree/refs/bisect/good
+resolve to the same value as the main working tree's HEAD and
+refs/bisect/good respectively. Similarly, worktrees/foo/HEAD or
+worktrees/bar/refs/bisect/bad are the same as
+GIT_COMMON_DIR/worktrees/foo/HEAD and
+GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad.
+
 To access refs, it's best not to look inside GIT_DIR directly. Instead
 use commands such as linkgit:git-revparse[1] or linkgit:git-update-ref[1]
 which will handle refs correctly.
 
        return 1;
 }
 
+static int is_main_pseudoref_syntax(const char *refname)
+{
+       return skip_prefix(refname, "main-worktree/", &refname) &&
+               *refname &&
+               is_pseudoref_syntax(refname);
+}
+
+static int is_other_pseudoref_syntax(const char *refname)
+{
+       if (!skip_prefix(refname, "worktrees/", &refname))
+               return 0;
+       refname = strchr(refname, '/');
+       if (!refname || !refname[1])
+               return 0;
+       return is_pseudoref_syntax(refname + 1);
+}
+
 enum ref_type ref_type(const char *refname)
 {
        if (is_per_worktree_ref(refname))
                return REF_TYPE_PER_WORKTREE;
        if (is_pseudoref_syntax(refname))
                return REF_TYPE_PSEUDOREF;
+       if (is_main_pseudoref_syntax(refname))
+               return REF_TYPE_MAIN_PSEUDOREF;
+       if (is_other_pseudoref_syntax(refname))
+               return REF_TYPE_OTHER_PSEUDOREF;
        return REF_TYPE_NORMAL;
 }
 
 
 int ref_is_hidden(const char *, const char *);
 
 enum ref_type {
-       REF_TYPE_PER_WORKTREE,
-       REF_TYPE_PSEUDOREF,
-       REF_TYPE_NORMAL,
+       REF_TYPE_PER_WORKTREE,    /* refs inside refs/ but not shared       */
+       REF_TYPE_PSEUDOREF,       /* refs outside refs/ in current worktree */
+       REF_TYPE_MAIN_PSEUDOREF,  /* pseudo refs from the main worktree     */
+       REF_TYPE_OTHER_PSEUDOREF, /* pseudo refs from other worktrees       */
+       REF_TYPE_NORMAL,          /* normal/shared refs inside refs/        */
 };
 
 enum ref_type ref_type(const char *refname);
 
 #include "../object.h"
 #include "../dir.h"
 #include "../chdir-notify.h"
+#include "worktree.h"
 
 /*
  * This backend uses the following flags in `ref_update::flags` for
        return refs;
 }
 
+static void files_reflog_path_other_worktrees(struct files_ref_store *refs,
+                                             struct strbuf *sb,
+                                             const char *refname)
+{
+       const char *real_ref;
+       const char *worktree_name;
+       int length;
+
+       if (parse_worktree_ref(refname, &worktree_name, &length, &real_ref))
+               BUG("refname %s is not a other-worktree ref", refname);
+
+       if (worktree_name)
+               strbuf_addf(sb, "%s/worktrees/%.*s/logs/%s", refs->gitcommondir,
+                           length, worktree_name, real_ref);
+       else
+               strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir,
+                           real_ref);
+}
+
 static void files_reflog_path(struct files_ref_store *refs,
                              struct strbuf *sb,
                              const char *refname)
        case REF_TYPE_PSEUDOREF:
                strbuf_addf(sb, "%s/logs/%s", refs->gitdir, refname);
                break;
+       case REF_TYPE_OTHER_PSEUDOREF:
+       case REF_TYPE_MAIN_PSEUDOREF:
+               return files_reflog_path_other_worktrees(refs, sb, refname);
        case REF_TYPE_NORMAL:
                strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
                break;
        case REF_TYPE_PSEUDOREF:
                strbuf_addf(sb, "%s/%s", refs->gitdir, refname);
                break;
+       case REF_TYPE_MAIN_PSEUDOREF:
+               if (!skip_prefix(refname, "main-worktree/", &refname))
+                       BUG("ref %s is not a main pseudoref", refname);
+               /* fallthrough */
+       case REF_TYPE_OTHER_PSEUDOREF:
        case REF_TYPE_NORMAL:
                strbuf_addf(sb, "%s/%s", refs->gitcommondir, refname);
                break;
 
        ( cd wt2 && test_cmp_rev worktree/foo wt2 )
 '
 
+test_expect_success 'resolve main-worktree/HEAD' '
+       test_cmp_rev main-worktree/HEAD initial &&
+       ( cd wt1 && test_cmp_rev main-worktree/HEAD initial ) &&
+       ( cd wt2 && test_cmp_rev main-worktree/HEAD initial )
+'
+
+test_expect_success 'ambiguous main-worktree/HEAD' '
+       mkdir -p .git/refs/heads/main-worktree &&
+       test_when_finished rm -f .git/refs/heads/main-worktree/HEAD &&
+       cp .git/HEAD .git/refs/heads/main-worktree/HEAD &&
+       git rev-parse main-worktree/HEAD 2>warn &&
+       grep "main-worktree/HEAD.*ambiguous" warn
+'
+
+test_expect_success 'resolve worktrees/xx/HEAD' '
+       test_cmp_rev worktrees/wt1/HEAD wt1 &&
+       ( cd wt1 && test_cmp_rev worktrees/wt1/HEAD wt1 ) &&
+       ( cd wt2 && test_cmp_rev worktrees/wt1/HEAD wt1 )
+'
+
+test_expect_success 'ambiguous worktrees/xx/HEAD' '
+       mkdir -p .git/refs/heads/worktrees/wt1 &&
+       test_when_finished rm -f .git/refs/heads/worktrees/wt1/HEAD &&
+       cp .git/HEAD .git/refs/heads/worktrees/wt1/HEAD &&
+       git rev-parse worktrees/wt1/HEAD 2>warn &&
+       grep "worktrees/wt1/HEAD.*ambiguous" warn
+'
+
+test_expect_success 'reflog of main-worktree/HEAD' '
+       git reflog HEAD | sed "s/HEAD/main-worktree\/HEAD/" >expected &&
+       git reflog main-worktree/HEAD >actual &&
+       test_cmp expected actual &&
+       git -C wt1 reflog main-worktree/HEAD >actual.wt1 &&
+       test_cmp expected actual.wt1
+'
+
+test_expect_success 'reflog of worktrees/xx/HEAD' '
+       git -C wt2 reflog HEAD | sed "s/HEAD/worktrees\/wt2\/HEAD/" >expected &&
+       git reflog worktrees/wt2/HEAD >actual &&
+       test_cmp expected actual &&
+       git -C wt1 reflog worktrees/wt2/HEAD >actual.wt1 &&
+       test_cmp expected actual.wt1 &&
+       git -C wt2 reflog worktrees/wt2/HEAD >actual.wt2 &&
+       test_cmp expected actual.wt2
+'
+
 test_done
 
        return ret;
 }
 
+int parse_worktree_ref(const char *worktree_ref, const char **name,
+                      int *name_length, const char **ref)
+{
+       if (skip_prefix(worktree_ref, "main-worktree/", &worktree_ref)) {
+               if (!*worktree_ref)
+                       return -1;
+               if (name)
+                       *name = NULL;
+               if (name_length)
+                       *name_length = 0;
+               if (ref)
+                       *ref = worktree_ref;
+               return 0;
+       }
+       if (skip_prefix(worktree_ref, "worktrees/", &worktree_ref)) {
+               const char *slash = strchr(worktree_ref, '/');
+
+               if (!slash || slash == worktree_ref || !slash[1])
+                       return -1;
+               if (name)
+                       *name = worktree_ref;
+               if (name_length)
+                       *name_length = slash - worktree_ref;
+               if (ref)
+                       *ref = slash + 1;
+               return 0;
+       }
+       return -1;
+}
+
 int other_head_refs(each_ref_fn fn, void *cb_data)
 {
        struct worktree **worktrees, **p;
 
                                     const char *fmt, ...)
        __attribute__((format (printf, 2, 3)));
 
+/*
+ * Parse a worktree ref (i.e. with prefix main-worktree/ or
+ * worktrees/) and return the position of the worktree's name and
+ * length (or NULL and zero if it's main worktree), and ref.
+ *
+ * All name, name_length and ref arguments could be NULL.
+ */
+int parse_worktree_ref(const char *worktree_ref, const char **name,
+                      int *name_length, const char **ref);
 #endif