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 <dturner@xxxxxxxxxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html