From: David Turner <dturner@twopensource.com>
To: git@vger.kernel.org, mhagger@alum.mit.edu,
chriscool@tuxfamily.org, pclouds@gmail.com
Cc: David Turner <dturner@twopensource.com>
Subject: [PATCH v3 3/4] refs: make refs/worktree/* per-worktree
Date: Wed, 12 Aug 2015 17:57:24 -0400 [thread overview]
Message-ID: <1439416645-19173-3-git-send-email-dturner@twopensource.com> (raw)
In-Reply-To: <1439416645-19173-1-git-send-email-dturner@twopensource.com>
We need a place to stick refs for bisects in progress that is not
shared between worktrees. So we use the refs/worktree/ hierarchy.
The is_per_worktree_ref function and associated docs learn that
refs/worktree/ is per-worktree, as does the git_path code in path.c
The ref-packing functions learn that per-worktree refs should not be
packed (since packed-refs is common rather than per-worktree).
Signed-off-by: David Turner <dturner@twopensource.com>
---
Documentation/glossary-content.txt | 5 +++--
path.c | 1 +
refs.c | 32 +++++++++++++++++++++++++++++++-
t/t0060-path-utils.sh | 1 +
t/t1400-update-ref.sh | 18 ++++++++++++++++++
t/t3210-pack-refs.sh | 7 +++++++
6 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 8c6478b..5c707e6 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -413,8 +413,9 @@ 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
- later include other unusual refs.
+ global. This is presently only <<def_HEAD,HEAD>> and any refs
+ that start with `refs/worktree/`, but might later include other
+ unusual refs.
[[def_pseudoref]]pseudoref::
Pseudorefs are a class of files under `$GIT_DIR` which behave
diff --git a/path.c b/path.c
index 21a4ce7..c53f732 100644
--- a/path.c
+++ b/path.c
@@ -110,6 +110,7 @@ struct common_dir common_list[] = {
{ "lost-found", 0, 1, 0 },
{ "objects", 0, 1, 0 },
{ "refs", 0, 1, 0 },
+ { "refs/worktree", 0, 1, 1 },
{ "remotes", 0, 1, 0 },
{ "worktrees", 0, 1, 0 },
{ "rr-cache", 0, 1, 0 },
diff --git a/refs.c b/refs.c
index e6fc3fe..30331bc 100644
--- a/refs.c
+++ b/refs.c
@@ -298,6 +298,11 @@ struct ref_entry {
};
static void read_loose_refs(const char *dirname, struct ref_dir *dir);
+static int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len);
+static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache,
+ const char *dirname, size_t len,
+ int incomplete);
+static void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry);
static struct ref_dir *get_ref_dir(struct ref_entry *entry)
{
@@ -306,6 +311,24 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry)
dir = &entry->u.subdir;
if (entry->flag & REF_INCOMPLETE) {
read_loose_refs(entry->name, dir);
+
+ /*
+ * Manually add refs/worktree, which, being
+ * per-worktree, might not appear in the directory
+ * listing for refs/ in the main repo.
+ */
+ if (!strcmp(entry->name, "refs/")) {
+ int pos = search_ref_dir(dir, "refs/worktree/", 14);
+ if (pos < 0) {
+ struct ref_entry *child_entry;
+ child_entry = create_dir_entry(dir->ref_cache,
+ "refs/worktree/",
+ 14, 1);
+ add_entry_to_dir(dir, child_entry);
+ read_loose_refs("refs/worktree",
+ &child_entry->u.subdir);
+ }
+ }
entry->flag &= ~REF_INCOMPLETE;
}
return dir;
@@ -2643,6 +2666,8 @@ struct pack_refs_cb_data {
struct ref_to_prune *ref_to_prune;
};
+static int is_per_worktree_ref(const char *refname);
+
/*
* An each_ref_entry_fn that is run over loose references only. If
* the loose reference can be packed, add an entry in the packed ref
@@ -2656,6 +2681,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 (is_per_worktree_ref(entry->name))
+ return 0;
+
/* ALWAYS pack tags */
if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref)
return 0;
@@ -2850,7 +2879,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, "refs/worktree/");
}
static int is_pseudoref_syntax(const char *refname)
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 93605f4..28e6dff 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -275,6 +275,7 @@ test_git_path GIT_COMMON_DIR=bar remotes/bar bar/remotes/bar
test_git_path GIT_COMMON_DIR=bar branches/bar bar/branches/bar
test_git_path GIT_COMMON_DIR=bar logs/refs/heads/master bar/logs/refs/heads/master
test_git_path GIT_COMMON_DIR=bar refs/heads/master bar/refs/heads/master
+test_git_path GIT_COMMON_DIR=bar refs/worktree/foo .git/refs/worktree/foo
test_git_path GIT_COMMON_DIR=bar hooks/me bar/hooks/me
test_git_path GIT_COMMON_DIR=bar config bar/config
test_git_path GIT_COMMON_DIR=bar packed-refs bar/packed-refs
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 9d21c19..7ecd33b 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -1131,4 +1131,22 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches
)
'
+test_expect_success 'handle per-worktree refs in refs/worktree' '
+ git commit --allow-empty -m "initial commit" &&
+ git worktree add -b branch worktree &&
+ (
+ cd worktree &&
+ git commit --allow-empty -m "test commit" &&
+ git for-each-ref | test_must_fail grep refs/worktree &&
+ git update-ref refs/worktree/something HEAD &&
+ git rev-parse refs/worktree/something >../worktree-head &&
+ git for-each-ref | grep refs/worktree/something
+ ) &&
+ test_path_is_missing .git/refs/worktree &&
+ test_must_fail git rev-parse refs/worktree/something &&
+ git update-ref refs/worktree/something HEAD &&
+ git rev-parse refs/worktree/something >main-head &&
+ ! test_cmp main-head worktree-head
+'
+
test_done
diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
index 8aae98d..c54cd29 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 refs/worktree' '
+ git update-ref refs/worktree/local HEAD &&
+ git pack-refs --all --prune &&
+ ! grep refs/worktree/local .git/packed-refs >/dev/null &&
+ test_path_is_file .git/refs/worktree/local
+'
+
test_expect_success 'disable reflogs' '
git config core.logallrefupdates false &&
rm -rf .git/logs
--
2.0.4.315.gad8727a-twtrsrc
next prev parent reply other threads:[~2015-08-12 21:57 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-12 21:57 [PATCH v3 1/4] refs: clean up common_list David Turner
2015-08-12 21:57 ` [PATCH v3 2/4] path: optimize common dir checking David Turner
2015-08-12 22:48 ` Junio C Hamano
2015-08-13 9:05 ` Michael Haggerty
2015-08-14 17:04 ` Junio C Hamano
2015-08-14 20:04 ` David Turner
2015-08-14 20:27 ` Junio C Hamano
2015-08-14 20:54 ` David Turner
2015-08-15 18:20 ` Michael Haggerty
2015-08-15 18:12 ` Michael Haggerty
2015-08-17 15:55 ` Junio C Hamano
2015-08-15 7:59 ` Duy Nguyen
2015-08-16 5:04 ` David Turner
2015-08-16 12:20 ` Duy Nguyen
2015-08-12 21:57 ` David Turner [this message]
2015-08-13 17:15 ` [PATCH v3 3/4] refs: make refs/worktree/* per-worktree Eric Sunshine
2015-08-13 17:41 ` David Turner
2015-08-13 20:16 ` Michael Haggerty
2015-08-13 20:32 ` David Turner
2015-08-14 8:18 ` Michael Haggerty
2015-08-14 17:10 ` Junio C Hamano
2015-08-15 8:04 ` Duy Nguyen
2015-08-12 21:57 ` [PATCH v3 4/4] bisect: make bisection refs per-worktree David Turner
2015-08-15 7:44 ` [PATCH v3 1/4] refs: clean up common_list Duy Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1439416645-19173-3-git-send-email-dturner@twopensource.com \
--to=dturner@twopensource.com \
--cc=chriscool@tuxfamily.org \
--cc=git@vger.kernel.org \
--cc=mhagger@alum.mit.edu \
--cc=pclouds@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).