We need a place to stick refs for bisects in progress that is not
shared between worktrees.  So we use the worktree-refs/ hierarchy
instead of the refs/.

To do this, load loose refs from "worktree-refs/" as well as from "refs/".
The is_per_worktree_ref function and associated docs learn that
worktree-refs/ is per-worktree.

The ref-packing functions learn that refs beginning with
worktree-refs/ should not be packed (since packed-refs is common
rather than per-worktree).

Signed-off-by: David Turner <[email protected]>
---
 Documentation/glossary-content.txt |  3 ++-
 refs.c                             | 13 ++++++++++---
 t/t3210-pack-refs.sh               |  7 +++++++
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index 8c6478b..e2847a9 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -413,7 +413,8 @@ exclude;;
 
 [[def_per_worktree_ref]]per-worktree ref::
        Refs that are per-<<def_working_tree,worktree>>, rather than
-       global.  This is presently only <<def_HEAD,HEAD>>, but might
+       global.  This is presently only <<def_HEAD,HEAD>> and any refs
+       that start with `worktree-refs/` (rather than `refs/`), but might
        later include other unusual refs.
 
 [[def_pseudoref]]pseudoref::
diff --git a/refs.c b/refs.c
index e6fc3fe..c556b6f 100644
--- a/refs.c
+++ b/refs.c
@@ -1433,15 +1433,17 @@ static struct ref_dir *get_loose_refs(struct ref_cache 
*refs)
        if (!refs->loose) {
                /*
                 * Mark the top-level directory complete because we
-                * are about to read the only subdirectory that can
+                * are about to read the only subdirectories that can
                 * hold references:
                 */
                refs->loose = create_dir_entry(refs, "", 0, 0);
                /*
-                * Create an incomplete entry for "refs/":
+                * Create incomplete entries for "refs/" and "worktree-refs":
                 */
                add_entry_to_dir(get_ref_dir(refs->loose),
                                 create_dir_entry(refs, "refs/", 5, 1));
+               add_entry_to_dir(get_ref_dir(refs->loose),
+                                create_dir_entry(refs, "worktree-refs/", 14, 
1));
        }
        return get_ref_dir(refs->loose);
 }
@@ -2656,6 +2658,10 @@ static int pack_if_possible_fn(struct ref_entry *entry, 
void *cb_data)
        struct ref_entry *packed_entry;
        int is_tag_ref = starts_with(entry->name, "refs/tags/");
 
+       /* Do not pack per-worktree refs: */
+       if (starts_with(entry->name, "worktree-refs/"))
+               return 0;
+
        /* ALWAYS pack tags */
        if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref)
                return 0;
@@ -2850,7 +2856,8 @@ static int delete_ref_loose(struct ref_lock *lock, int 
flag, struct strbuf *err)
 
 static int is_per_worktree_ref(const char *refname)
 {
-       return !strcmp(refname, "HEAD");
+       return !strcmp(refname, "HEAD") ||
+               starts_with(refname, "worktree-refs/");
 }
 
 static int is_pseudoref_syntax(const char *refname)
diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
index 8aae98d..0800a1c 100755
--- a/t/t3210-pack-refs.sh
+++ b/t/t3210-pack-refs.sh
@@ -160,6 +160,13 @@ test_expect_success 'pack ref directly below refs/' '
        test_path_is_missing .git/refs/top
 '
 
+test_expect_success 'do not pack ref in worktree-refs' '
+       git update-ref worktree-refs/local HEAD &&
+       git pack-refs --all --prune &&
+       ! grep worktree-refs/local .git/packed-refs >/dev/null &&
+       test_path_is_file .git/worktree-refs/local
+'
+
 test_expect_success 'disable reflogs' '
        git config core.logallrefupdates false &&
        rm -rf .git/logs
-- 
2.0.4.315.gad8727a-twtrsrc

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to