git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 0/3] keep track of unresolved value of symbolic-ref in ref iterators

From
John Cai via GitGitGadget <gitgitgadget@gmail.com>
Date
Aug 9, 2024, 15:37 UTC
Message-ID
<pull.1712.v4.git.git.1723217871.gitgitgadget@gmail.com>
In-Reply-To
<pull.1712.v3.git.git.1723059768.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 V3:
 * Added blank line to separate declarations from statements
 * unconditionally set referent member in base iterator in files backend
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        | 17 +++++++++++++----
 refs/iterator.c             |  4 +++-
 refs/ref-cache.c            |  5 +++++
 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, 118 insertions(+), 62 deletions(-)
base-commit: 557ae147e6cdc9db121269b058c757ac5092f9c9
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1712%2Fjohn-cai%2Fjc%2Fsymbolic-ref-in-iterator-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1712/john-cai/jc/symbolic-ref-in-iterator-v4
Pull-Request: https://github.com/git/git/pull/1712
Range-diff vs v3:
 1:  fc3defd9c47 ! 1:  c4f5f5b7dd8 refs: keep track of unresolved reference value in iterators
     @@ refs/files-backend.c: static void loose_fill_ref_dir_regular_file(struct files_r
       {
       	struct object_id oid;
       	int flag;
     --
     --	if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,
     --				     &oid, &flag)) {
      +	const char *referent = refs_resolve_ref_unsafe(&refs->base,
      +						       refname,
      +						       RESOLVE_REF_READING,
      +						       &oid, &flag);
     + 
     +-	if (!refs_resolve_ref_unsafe(&refs->base, refname, RESOLVE_REF_READING,
     +-				     &oid, &flag)) {
      +	if (!referent) {
       		oidclr(&oid, the_repository->hash_algo);
       		flag |= REF_ISBROKEN;
     @@ refs/files-backend.c: static int files_ref_iterator_advance(struct ref_iterator
       		iter->base.refname = iter->iter0->refname;
       		iter->base.oid = iter->iter0->oid;
       		iter->base.flags = iter->iter0->flags;
     -+		if (iter->iter0->flags & REF_ISSYMREF)
     -+			iter->base.referent = iter->iter0->referent;
     -+		else
     -+			iter->base.referent = NULL;
     ++		iter->base.referent = iter->iter0->referent;
      +
       		return ITER_OK;
       	}
     @@ refs/iterator.c: static int merge_ref_iterator_advance(struct ref_iterator *ref_
       			iter->base.flags = (*iter->current)->flags;
      
       ## refs/ref-cache.c ##
     -@@
     - #include "refs-internal.h"
     - #include "ref-cache.h"
     - #include "../iterator.h"
     -+#include "../strbuf.h"
     - 
     - void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry)
     - {
      @@ refs/ref-cache.c: struct ref_dir *get_ref_dir(struct ref_entry *entry)
       }
       
 2:  0b6e732ad7e = 2:  6cfac5e51f5 refs: add referent to each_ref_fn
 3:  83b70ab8287 = 3:  9f609f4d0f5 ref-filter: populate symref from iterator
-- 
gitgitgadget
Previous: John Cai via GitGitGadgetNext: John Cai via GitGitGadget
Message 39 of 44 in “keep track of unresolved value of symbolic-ref in ref iterators”
  1. 0/4 keep track of unresolved value of symbolic-ref in ref iteratorsJohn Cai via GitGitGadget, Jun 6, 2024
  2. 2/4 refs: keep track of unresolved reference value in iteratorsJohn Cai via GitGitGadget, Jun 6, 2024
  3. Jeff KingJun 11, 2024
  4. 1/4 refs: add referent parameter to refs_resolve_ref_unsafeJohn Cai via GitGitGadget, Jun 6, 2024
  5. Junio C HamanoJun 6, 2024
  6. Junio C HamanoJun 6, 2024
  7. John CaiJun 7, 2024
  8. Junio C HamanoJun 7, 2024
  9. Patrick SteinhardtJun 10, 2024
  10. Junio C HamanoJun 10, 2024
  11. John CaiJun 6, 2024
  12. Junio C HamanoJun 6, 2024
  13. Kristoffer HaugsbakkJun 28, 2024
  14. Junio C HamanoJun 28, 2024
  15. Linus ArverJun 30, 2024
  16. Junio C HamanoJun 30, 2024
  17. Jeff KingJun 11, 2024
  18. John CaiJul 30, 2024
  19. 4/4 ref-filter: populate symref from iteratorJohn Cai via GitGitGadget, Jun 6, 2024
  20. 3/4 refs: add referent to each_ref_fnJohn Cai via GitGitGadget, Jun 6, 2024
  21. 0/3 keep track of unresolved value of symbolic-ref in ref iteratorsJohn Cai via GitGitGadget, Aug 1, 2024
  22. 1/3 refs: keep track of unresolved reference value in iteratorsJohn Cai via GitGitGadget, Aug 1, 2024
  23. Junio C HamanoAug 1, 2024
  24. Patrick SteinhardtAug 5, 2024
  25. Junio C HamanoAug 5, 2024
  26. 3/3 ref-filter: populate symref from iteratorJohn Cai via GitGitGadget, Aug 1, 2024
  27. Junio C HamanoAug 1, 2024
  28. Junio C HamanoAug 1, 2024
  29. Junio C HamanoAug 1, 2024
  30. John CaiAug 6, 2024
  31. Junio C HamanoAug 6, 2024
  32. 2/3 refs: add referent to each_ref_fnJohn Cai via GitGitGadget, Aug 1, 2024
  33. 0/3 keep track of unresolved value of symbolic-ref in ref iteratorsJohn Cai via GitGitGadget, Aug 7, 2024
  34. 1/3 refs: keep track of unresolved reference value in iteratorsJohn Cai via GitGitGadget, Aug 7, 2024
  35. Junio C HamanoAug 7, 2024
  36. John CaiAug 8, 2024
  37. 2/3 refs: add referent to each_ref_fnJohn Cai via GitGitGadget, Aug 7, 2024
  38. 3/3 ref-filter: populate symref from iteratorJohn Cai via GitGitGadget, Aug 7, 2024
  39. 0/3 keep track of unresolved value of symbolic-ref in ref iteratorsJohn Cai via GitGitGadget, Aug 9, 2024
  40. 1/3 refs: keep track of unresolved reference value in iteratorsJohn Cai via GitGitGadget, Aug 9, 2024
  41. shejialuoNov 23, 2024
  42. 2/3 refs: add referent to each_ref_fnJohn Cai via GitGitGadget, Aug 9, 2024
  43. 3/3 ref-filter: populate symref from iteratorJohn Cai via GitGitGadget, Aug 9, 2024
  44. Junio C HamanoAug 9, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.