From: "John Cai via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Phillip Wood" <phillip.wood123@gmail.com>,
"Kristoffer Haugsbakk" <code@khaugsbakk.name>,
"Jeff King" <peff@peff.net>, "Patrick Steinhardt" <ps@pks.im>,
"Jean-Noël Avila" <avila.jn@gmail.com>,
"Linus Arver" <linusarver@gmail.com>,
"John Cai" <johncai86@gmail.com>
Subject: [PATCH v3 0/3] keep track of unresolved value of symbolic-ref in ref iterators
Date: Wed, 07 Aug 2024 19:42:45 +0000 [thread overview]
Message-ID: <pull.1712.v3.git.git.1723059768.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1712.v2.git.git.1722524334.gitgitgadget@gmail.com>
For reftable development, it's useful to be able to print out the direct
value of a symbolic reference before resolution. This is currently possible
with git-for-each-ref, but since the iterators do not keep track of the
value of the symbolic ref, a separate call needs to be made each time making
it inefficient.
Address this inefficiency by keeping track of the value of the symbolic
reference in the ref iterator. This patch series also ends with a commit to
use this value in the iterator through callbacks in ref-filter.c.
This series started with [1] but I decided to send a separate patch series
since it is substantially different.
Benchmarking shows that with these changes, we experience a speedup in
git-for-each-ref(1) on a repository with many symbolic refs:
$ hyperfine --warmup 5 "git for-each-ref --format='%(refname) %(objectname)
%(symref)'" "~/Projects/git/git for-each-ref --format='%(refname)
%(objectname) %(symref)'" Benchmark 1: git for-each-ref --format='%(refname)
%(objectname) %(symref)' Time (mean ± σ): 905.1 ms ± 13.2 ms [User: 56.3 ms,
System: 628.6 ms] Range (min … max): 893.4 ms … 936.9 ms 10 runs
Benchmark 2: ~/Projects/git/git for-each-ref --format='%(refname)
%(objectname) %(symref)' Time (mean ± σ): 482.2 ms ± 26.4 ms [User: 34.7 ms,
System: 410.6 ms] Range (min … max): 459.4 ms … 541.8 ms 10 runs
Summary ~/Projects/git/git for-each-ref --format='%(refname) %(objectname)
%(symref)' ran 1.88 ± 0.11 times faster than git for-each-ref
--format='%(refname) %(objectname) %(symref)'
Changes since V2:
* Style tweaks
* Added a NEEDSWORK comment around fallback code
* Stay consistent in the meaning of a non-NULL referent member in the
iterator
Changes since V1
* Use the return value from refs_resolve_ref_unsafe instead of using an out
parameter
1. https://lore.kernel.org/git/pull.1684.git.git.1709592718743.gitgitgadget@gmail.com/
John Cai (3):
refs: keep track of unresolved reference value in iterators
refs: add referent to each_ref_fn
ref-filter: populate symref from iterator
bisect.c | 3 ++-
builtin/bisect.c | 4 +++-
builtin/checkout.c | 2 +-
builtin/describe.c | 2 +-
builtin/fetch.c | 3 ++-
builtin/fsck.c | 4 ++--
builtin/gc.c | 1 +
builtin/name-rev.c | 2 +-
builtin/pack-objects.c | 5 +++--
builtin/receive-pack.c | 2 +-
builtin/remote.c | 4 +++-
builtin/repack.c | 1 +
builtin/replace.c | 1 +
builtin/rev-parse.c | 4 ++--
builtin/show-branch.c | 8 ++++----
builtin/show-ref.c | 3 ++-
builtin/submodule--helper.c | 1 +
builtin/worktree.c | 1 +
commit-graph.c | 1 +
delta-islands.c | 2 +-
fetch-pack.c | 2 ++
help.c | 2 +-
http-backend.c | 4 ++--
log-tree.c | 2 +-
ls-refs.c | 4 ++--
midx-write.c | 2 +-
negotiator/default.c | 2 +-
negotiator/skipping.c | 2 +-
notes.c | 2 +-
object-name.c | 2 +-
pseudo-merge.c | 1 +
reachable.c | 2 +-
ref-filter.c | 17 ++++++++++++-----
reflog.c | 1 +
refs.c | 14 +++++++-------
refs.h | 2 +-
refs/files-backend.c | 21 ++++++++++++++++-----
refs/iterator.c | 4 +++-
refs/ref-cache.c | 6 ++++++
refs/ref-cache.h | 2 ++
refs/refs-internal.h | 1 +
refs/reftable-backend.c | 10 ++++++++--
remote.c | 4 ++--
replace-object.c | 1 +
revision.c | 2 +-
server-info.c | 2 +-
shallow.c | 2 ++
submodule.c | 2 ++
t/helper/test-ref-store.c | 2 +-
upload-pack.c | 8 ++++----
walker.c | 1 +
worktree.c | 2 +-
52 files changed, 122 insertions(+), 63 deletions(-)
base-commit: 557ae147e6cdc9db121269b058c757ac5092f9c9
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1712%2Fjohn-cai%2Fjc%2Fsymbolic-ref-in-iterator-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1712/john-cai/jc/symbolic-ref-in-iterator-v3
Pull-Request: https://github.com/git/git/pull/1712
Range-diff vs v2:
1: ac0957c9e6a ! 1: fc3defd9c47 refs: keep track of unresolved reference value in iterators
@@ refs/files-backend.c: static void loose_fill_ref_dir_regular_file(struct files_r
-
- if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,
- &oid, &flag)) {
-+ const char* referent = refs_resolve_ref_unsafe(&refs->base,
++ const char *referent = refs_resolve_ref_unsafe(&refs->base,
+ refname,
+ RESOLVE_REF_READING,
+ &oid, &flag);
@@ refs/files-backend.c: static void loose_fill_ref_dir_regular_file(struct files_r
}
- add_entry_to_dir(dir, create_ref_entry(refname, &oid, flag));
+
++ if (!(flag & REF_ISSYMREF))
++ referent = NULL;
++
+ add_entry_to_dir(dir, create_ref_entry(refname, referent, &oid, flag));
}
@@ refs/files-backend.c: static int files_ref_iterator_advance(struct ref_iterator
iter->base.flags = iter->iter0->flags;
+ if (iter->iter0->flags & REF_ISSYMREF)
+ iter->base.referent = iter->iter0->referent;
++ else
++ iter->base.referent = NULL;
+
return ITER_OK;
}
## refs/iterator.c ##
-@@
- #include "refs.h"
- #include "refs/refs-internal.h"
- #include "iterator.h"
-+#include "strbuf.h"
-
- int ref_iterator_advance(struct ref_iterator *ref_iterator)
- {
@@ refs/iterator.c: void base_ref_iterator_init(struct ref_iterator *iter,
{
iter->vtable = vtable;
@@ refs/ref-cache.c: struct ref_entry *create_ref_entry(const char *refname,
FLEX_ALLOC_STR(ref, name, refname);
oidcpy(&ref->u.value.oid, oid);
ref->flag = flag;
-+
-+ if (flag & REF_ISSYMREF)
-+ ref->u.value.referent = xstrdup_or_null(referent);
++ ref->u.value.referent = xstrdup_or_null(referent);
+
return ref;
}
@@ refs/refs-internal.h: enum do_for_each_ref_flags {
};
## refs/reftable-backend.c ##
+@@ refs/reftable-backend.c: static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
+ struct reftable_ref_iterator *iter =
+ (struct reftable_ref_iterator *)ref_iterator;
+ struct reftable_ref_store *refs = iter->refs;
++ const char *referent = NULL;
+
+ while (!iter->err) {
+ int flags = 0;
@@ refs/reftable-backend.c: static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
the_repository->hash_algo);
break;
case REFTABLE_REF_SYMREF:
- if (!refs_resolve_ref_unsafe(&iter->refs->base, iter->ref.refname,
- RESOLVE_REF_READING, &iter->oid, &flags))
-+ iter->base.referent = refs_resolve_ref_unsafe(&iter->refs->base,
++ referent = refs_resolve_ref_unsafe(&iter->refs->base,
+ iter->ref.refname,
+ RESOLVE_REF_READING,
+ &iter->oid,
+ &flags);
-+ if (!iter->base.referent)
++ if (!referent)
oidclr(&iter->oid, the_repository->hash_algo);
break;
default:
+@@ refs/reftable-backend.c: static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
+ continue;
+
+ iter->base.refname = iter->ref.refname;
++ iter->base.referent = referent;
+ iter->base.oid = &iter->oid;
+ iter->base.flags = flags;
+
2: 1f3a604fae7 = 2: 0b6e732ad7e refs: add referent to each_ref_fn
3: 3e147e7d850 ! 3: 83b70ab8287 ref-filter: populate symref from iterator
@@ Commit message
Signed-off-by: John Cai <johncai86@gmail.com>
## ref-filter.c ##
+@@ ref-filter.c: static int populate_value(struct ref_array_item *ref, struct strbuf *err)
+
+ CALLOC_ARRAY(ref->value, used_atom_cnt);
+
++ /**
++ * NEEDSWORK: The following code might be unncessary if all codepaths
++ * that call populate_value() populates the symref member of ref_array_item
++ * like in apply_ref_filter(). Currently pretty_print_ref() is the only codepath
++ * that calls populate_value() without first populating symref.
++ */
+ if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
+ ref->symref = refs_resolve_refdup(get_main_ref_store(the_repository),
+ ref->refname,
@@ ref-filter.c: static int filter_ref_kind(struct ref_filter *filter, const char *refname)
return ref_kind_from_refname(refname);
}
@@ ref-filter.c: static struct ref_array_item *apply_ref_filter(const char *refname
ref->commit = commit;
ref->flag = flag;
ref->kind = kind;
-+ if (flag & REF_ISSYMREF)
-+ ref->symref = xstrdup_or_null(referent);
++ ref->symref = xstrdup_or_null(referent);
return ref;
}
--
gitgitgadget
next prev parent reply other threads:[~2024-08-07 19:42 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-06 17:26 [PATCH 0/4] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-06-06 17:26 ` [PATCH 1/4] refs: add referent parameter to refs_resolve_ref_unsafe John Cai via GitGitGadget
2024-06-06 18:21 ` Junio C Hamano
2024-06-06 18:23 ` Junio C Hamano
2024-06-07 13:43 ` John Cai
2024-06-07 15:21 ` Junio C Hamano
2024-06-10 7:29 ` Patrick Steinhardt
2024-06-10 18:09 ` Junio C Hamano
2024-06-06 21:02 ` John Cai
2024-06-06 22:44 ` Junio C Hamano
2024-06-28 15:30 ` Kristoffer Haugsbakk
2024-06-28 19:47 ` Junio C Hamano
2024-06-30 10:12 ` Linus Arver
2024-06-30 18:19 ` Junio C Hamano
2024-06-11 8:50 ` Jeff King
2024-07-30 14:38 ` John Cai
2024-06-06 17:26 ` [PATCH 2/4] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-06-11 9:01 ` Jeff King
2024-06-06 17:26 ` [PATCH 3/4] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-06-06 17:26 ` [PATCH 4/4] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 0/3] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-08-01 16:41 ` Junio C Hamano
2024-08-05 10:59 ` Patrick Steinhardt
2024-08-05 15:40 ` Junio C Hamano
2024-08-01 14:58 ` [PATCH v2 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-01 14:58 ` [PATCH v2 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-01 16:43 ` Junio C Hamano
2024-08-01 16:51 ` Junio C Hamano
2024-08-01 16:54 ` Junio C Hamano
2024-08-06 19:49 ` John Cai
2024-08-06 20:17 ` Junio C Hamano
2024-08-07 19:42 ` John Cai via GitGitGadget [this message]
2024-08-07 19:42 ` [PATCH v3 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-08-07 21:40 ` Junio C Hamano
2024-08-08 18:09 ` John Cai
2024-08-07 19:42 ` [PATCH v3 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-07 19:42 ` [PATCH v3 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 0/3] keep track of unresolved value of symbolic-ref in ref iterators John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 1/3] refs: keep track of unresolved reference value in iterators John Cai via GitGitGadget
2024-11-23 8:24 ` shejialuo
2024-08-09 15:37 ` [PATCH v4 2/3] refs: add referent to each_ref_fn John Cai via GitGitGadget
2024-08-09 15:37 ` [PATCH v4 3/3] ref-filter: populate symref from iterator John Cai via GitGitGadget
2024-08-09 16:51 ` [PATCH v4 0/3] keep track of unresolved value of symbolic-ref in ref iterators Junio C Hamano
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=pull.1712.v3.git.git.1723059768.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=avila.jn@gmail.com \
--cc=code@khaugsbakk.name \
--cc=git@vger.kernel.org \
--cc=johncai86@gmail.com \
--cc=linusarver@gmail.com \
--cc=peff@peff.net \
--cc=phillip.wood123@gmail.com \
--cc=ps@pks.im \
/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).