From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Michael Haggerty" <mhagger@alum.mit.edu>,
"Stefan Beller" <sbeller@google.com>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v4 12/16] files-backend: make reflog iterator go through per-worktree reflog
Date: Wed, 23 Aug 2017 19:37:00 +0700 [thread overview]
Message-ID: <20170823123704.16518-13-pclouds@gmail.com> (raw)
In-Reply-To: <20170823123704.16518-1-pclouds@gmail.com>
refs/bisect is unfortunately per-worktree, so we need to look in
per-worktree logs/refs/bisect in addition to per-repo logs/refs. The
current iterator only goes through per-repo logs/refs.
Use merge iterator to walk two ref stores at the same time and pick
per-worktree refs from the right iterator.
PS. Note the unsorted order of for_each_reflog in the test. This is
supposed to be OK, for now. If we enforce order on for_each_reflog()
then some more work will be required.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
refs/files-backend.c | 59 +++++++++++++++++++++++++++++++++----------
t/t1407-worktree-ref-store.sh | 30 ++++++++++++++++++++++
2 files changed, 75 insertions(+), 14 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 5cca55510b..d4d22882ef 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -106,15 +106,6 @@ static void files_reflog_path(struct files_ref_store *refs,
struct strbuf *sb,
const char *refname)
{
- if (!refname) {
- /*
- * FIXME: of course this is wrong in multi worktree
- * setting. To be fixed real soon.
- */
- strbuf_addf(sb, "%s/logs", refs->gitcommondir);
- return;
- }
-
switch (ref_type(refname)) {
case REF_TYPE_PER_WORKTREE:
case REF_TYPE_PSEUDOREF:
@@ -2055,23 +2046,63 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
files_reflog_iterator_abort
};
-static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
+static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
+ const char *gitdir)
{
- struct files_ref_store *refs =
- files_downcast(ref_store, REF_STORE_READ,
- "reflog_iterator_begin");
struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
struct ref_iterator *ref_iterator = &iter->base;
struct strbuf sb = STRBUF_INIT;
base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable);
- files_reflog_path(refs, &sb, NULL);
+ strbuf_addf(&sb, "%s/logs", gitdir);
iter->dir_iterator = dir_iterator_begin(sb.buf);
iter->ref_store = ref_store;
strbuf_release(&sb);
+
return ref_iterator;
}
+static enum iterator_selection reflog_iterator_select(
+ struct ref_iterator *iter_worktree,
+ struct ref_iterator *iter_common,
+ void *cb_data)
+{
+ if (iter_worktree) {
+ /*
+ * We're a bit loose here. We probably should ignore
+ * common refs if they are accidentally added as
+ * per-worktree refs.
+ */
+ return ITER_SELECT_0;
+ } else if (iter_common) {
+ if (ref_type(iter_common->refname) == REF_TYPE_NORMAL)
+ return ITER_SELECT_1;
+
+ /*
+ * The main ref store may contain main worktree's
+ * per-worktree refs, which should be ignored
+ */
+ return ITER_SKIP_1;
+ } else
+ return ITER_DONE;
+}
+
+static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_store)
+{
+ struct files_ref_store *refs =
+ files_downcast(ref_store, REF_STORE_READ,
+ "reflog_iterator_begin");
+
+ if (!strcmp(refs->gitdir, refs->gitcommondir)) {
+ return reflog_iterator_begin(ref_store, refs->gitcommondir);
+ } else {
+ return merge_ref_iterator_begin(
+ reflog_iterator_begin(ref_store, refs->gitdir),
+ reflog_iterator_begin(ref_store, refs->gitcommondir),
+ reflog_iterator_select, refs);
+ }
+}
+
/*
* If update is a direct update of head_ref (the reference pointed to
* by HEAD), then add an extra REF_LOG_ONLY update for HEAD.
diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh
index 5df06f3556..8842d0329f 100755
--- a/t/t1407-worktree-ref-store.sh
+++ b/t/t1407-worktree-ref-store.sh
@@ -49,4 +49,34 @@ test_expect_success 'create_symref(FOO, refs/heads/master)' '
test_cmp expected actual
'
+test_expect_success 'for_each_reflog()' '
+ echo $_z40 > .git/logs/PSEUDO-MAIN &&
+ mkdir -p .git/logs/refs/bisect &&
+ echo $_z40 > .git/logs/refs/bisect/random &&
+
+ echo $_z40 > .git/worktrees/wt/logs/PSEUDO-WT &&
+ mkdir -p .git/worktrees/wt/logs/refs/bisect &&
+ echo $_z40 > .git/worktrees/wt/logs/refs/bisect/wt-random &&
+
+ $RWT for-each-reflog | cut -c 42- | sort >actual &&
+ cat >expected <<-\EOF &&
+ HEAD 0x1
+ PSEUDO-WT 0x0
+ refs/bisect/wt-random 0x0
+ refs/heads/master 0x0
+ refs/heads/wt-master 0x0
+ EOF
+ test_cmp expected actual &&
+
+ $RMAIN for-each-reflog | cut -c 42- | sort >actual &&
+ cat >expected <<-\EOF &&
+ HEAD 0x1
+ PSEUDO-MAIN 0x0
+ refs/bisect/random 0x0
+ refs/heads/master 0x0
+ refs/heads/wt-master 0x0
+ EOF
+ test_cmp expected actual
+'
+
test_done
--
2.11.0.157.gd943d85
next prev parent reply other threads:[~2017-08-23 12:38 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-23 12:36 [PATCH v4 00/16] Fix git-gc losing objects in multi worktree Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 01/16] revision.h: new flag in struct rev_info wrt. worktree-related refs Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 02/16] refs.c: use is_dir_sep() in resolve_gitlink_ref() Nguyễn Thái Ngọc Duy
2017-08-23 19:14 ` Stefan Beller
2017-09-06 11:08 ` Duy Nguyen
2017-09-06 17:41 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 03/16] revision.c: refactor add_index_objects_to_pending() Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 04/16] revision.c: --indexed-objects add objects from all worktrees Nguyễn Thái Ngọc Duy
2017-08-23 19:25 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 05/16] refs.c: refactor get_submodule_ref_store(), share common free block Nguyễn Thái Ngọc Duy
2017-08-23 19:34 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 06/16] refs: move submodule slash stripping code to get_submodule_ref_store Nguyễn Thái Ngọc Duy
2017-09-09 5:45 ` Michael Haggerty
2017-08-23 12:36 ` [PATCH v4 07/16] refs: add refs_head_ref() Nguyễn Thái Ngọc Duy
2017-08-24 21:52 ` Junio C Hamano
2017-09-06 11:23 ` Duy Nguyen
2017-08-23 12:36 ` [PATCH v4 08/16] revision.c: use refs_for_each*() instead of for_each_*_submodule() Nguyễn Thái Ngọc Duy
2017-08-24 21:56 ` Junio C Hamano
2017-08-23 12:36 ` [PATCH v4 09/16] refs.c: move for_each_remote_ref_submodule() to submodule.c Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 10/16] refs: remove dead for_each_*_submodule() Nguyễn Thái Ngọc Duy
2017-08-23 19:45 ` Stefan Beller
2017-09-09 5:59 ` Michael Haggerty
2017-08-23 12:36 ` [PATCH v4 11/16] revision.c: --all adds HEAD from all worktrees Nguyễn Thái Ngọc Duy
2017-08-23 19:54 ` Stefan Beller
2017-09-06 11:19 ` Duy Nguyen
2017-09-06 17:43 ` Stefan Beller
2017-09-09 6:04 ` Michael Haggerty
2017-08-23 12:37 ` Nguyễn Thái Ngọc Duy [this message]
2017-08-24 14:13 ` [PATCH v4 12/16] files-backend: make reflog iterator go through per-worktree reflog Richard Maw
2017-09-09 6:30 ` Michael Haggerty
2017-08-23 12:37 ` [PATCH v4 13/16] revision.c: --reflog add HEAD reflog from all worktrees Nguyễn Thái Ngọc Duy
2017-08-23 12:37 ` [PATCH v4 14/16] rev-list: expose and document --single-worktree Nguyễn Thái Ngọc Duy
2017-08-23 20:45 ` Stefan Beller
2017-08-23 12:37 ` [PATCH v4 15/16] refs.c: remove fallback-to-main-store code get_submodule_ref_store() Nguyễn Thái Ngọc Duy
2017-09-09 6:36 ` Michael Haggerty
2017-08-23 12:37 ` [PATCH v4 16/16] refs.c: reindent get_submodule_ref_store() Nguyễn Thái Ngọc Duy
2017-09-09 6:41 ` Michael Haggerty
2017-08-25 11:21 ` [PATCH v4 00/16] Fix git-gc losing objects in multi worktree Michael J Gruber
2017-09-06 10:53 ` Duy Nguyen
2017-09-09 6:45 ` Michael Haggerty
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=20170823123704.16518-13-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mhagger@alum.mit.edu \
--cc=sbeller@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.