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

Re: [PATCH v3 3/4] refs: selectively set prefix in the seek functions

From
Karthik Nayak <karthik.188@gmail.com>
Date
Jul 17, 2025, 09:01 UTC
Message-ID
<CAOLa=ZSKsdGDERNS_1hJrBMn0muSOJ46SZz2bn8OHZndJ2Hu3g@mail.gmail.com>
In-Reply-To
<xmqqfrevc3b6.fsf@gitster.g>
Junio C Hamano <gitster@pobox.com> writes:
Show 23 quoted lines
> Karthik Nayak <karthik.188@gmail.com> writes:
>
>> Let's say a user is iterating with a prefix set to 'refs/heads/', this
>> would iterate over all the refs with that prefix. But mid-way the user
>> realizes that they only care about 'refs/heads/feature/' prefix and they
>> ask the iterator to set that as the prefix.
>>
>> In such a situation, the iterator seeks to 'refs/heads/feature/' and
>> will only yield references with that prefix. In short, the previous
>> prefix state was reset.
>
> Yes, even though I wouldn't call such an operation "seek", "Ah, I do
> not need the entire refs/heads/ walked, only refs/heads/feature/ is
> enough" is an operation mode that makes sense.
>
> But not for paging, though.
>
> If your web application is showing all branches, one pageful at a
> time, and the first page ended at refs/heads/feature/something and
> you ended up "seeking" to refs/heads/feature/ to start the second
> page, you do not want your second page to end when the iteration
> goes out of refs/heads/feature/ hierarchy, no?
>

Yup and this (we show all references beyond the seek) is the current implementation. I was talking about the internal implementation of 'refs_iteration_seek()' which is the function used for seek and setting the prefix.

To clarify, this is the current implementation:

$ git for-each-ref 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/bar 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/feature/x 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/feature/y 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/foo 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/goo/x 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/goo/y 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/heads/master 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/tags/tagged/2 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/tags/tagged/3 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/tags/v1 6f4b58c4968eb82277cf5b1cf8775117e5b83de0 commit refs/tags/v2

$ git for-each-ref --format="%(refname)" --start-after=refs/heads/goo refs/heads/goo/x refs/heads/goo/y refs/heads/master refs/tags/tagged/2 refs/tags/tagged/3 refs/tags/v1 refs/tags/v2

$ git for-each-ref --format="%(refname)" --start-after=refs/heads/master refs/tags/tagged/2 refs/tags/tagged/3 refs/tags/v1 refs/tags/v2

$ git for-each-ref --format="%(refname)" --start-after=refs/heads/goo/x refs/heads/goo/y refs/heads/master refs/tags/tagged/2 refs/tags/tagged/3 refs/tags/v1 refs/tags/v2

$ git for-each-ref --format="%(refname)" refs/heads/feature refs/heads/feature/x refs/heads/feature/y

You can see we list all references beyond the seek.
Show 10 quoted lines
> It seems to me that the root cause of the confusion is because
> prefix, which is to let iteration finish way before the data runs
> out (instead finish when the iteration steps out of a given
> subhierarchy denoted by the prefix), is somehow abused as the
> current position of the cursor.  Shouldn't they be two separate
> concepts?  The cursor needs to fall within the prefix while the
> iterator is active, so they are not two totally independent things,
> but prefix is pretty much static while the cursor position is very
> dynamic.
>
The prefix setup in 'ref_iteration_seek' does two things, let's consider
prefix: 'refs/heads/feature'
1. It sets the cursor to seek to 'refs/heads/feature'
2. It also sets the internal prefix matching to 'refs/heads/feature'

In Contrast seeking via 'ref_iteration_seek' only sets the cursor to 'refs/heads/feature'.

To make this simpler, we've changed 'ref_iteration_seek' to do:
1. seek the cursor to the requested reference
2. Set prefix if the REF_ITERATOR_SEEK_SET_PREFIX is set, and unset the
prefix otherwise.

The state reset I was talking about in my previous emails refers to step #2 here, where when no 'REF_ITERATOR_SEEK_SET_PREFIX' is set, we remove any previous prefix set.

Show 15 quoted lines
>> This series did start out that way around, so ease of implementation
>> isn't it. It was more of a side-effect of not clearing state.
>
> I am even more worried about usability and correctness aspect of
> what was described here now.  After seeking to refs/heads/feature/,
> do we continue to iterate and step out of refs/heads/feature/
> hierarchy or can we cut off a particular page that started with a
> ref within refs/heads/feature/ subhierarchy when we exhaust refs in
> refs/heads/feature/ and have to wait for getting asked for the next
> page before we show refs/heads/gsomething that is outside
> refs/heads/feature/ and sorts after?  The "I reset to iterate over
> refs/heads/feature/ because the entire refs/heads/ is not what I
> care about" example makes me worried about this.
>
> Thanks.

I think we're crossing paths and talking different things. I hope the examples above clarify things. The current implementation doesn't support '--start-after' and prefix setting at the same time:

$ git for-each-ref --format="%(refname)" --start-after=refs/heads/master refs/heads fatal: cannot use --start-after with patterns

Happy to clarify if this doesn't make sense.
Thanks
Previous: Junio C HamanoNext: Junio C Hamano
Message 52 of 102 in “for-each-ref: introduce seeking functionality via '--skip-until'”
  1. 0/4 for-each-ref: introduce seeking functionality via '--skip-until'Karthik Nayak, Jul 1, 2025
  2. 2/4 ref-cache: remove unused function 'find_ref_entry()'Karthik Nayak, Jul 1, 2025
  3. Junio C HamanoJul 14, 2025
  4. 1/4 refs: expose `ref_iterator` via 'refs.h'Karthik Nayak, Jul 1, 2025
  5. 3/4 refs: selectively set prefix in the seek functionsKarthik Nayak, Jul 1, 2025
  6. Patrick SteinhardtJul 3, 2025
  7. Karthik NayakJul 3, 2025
  8. 4/4 for-each-ref: introduce a '--skip-until' optionKarthik Nayak, Jul 1, 2025
  9. Patrick SteinhardtJul 3, 2025
  10. Karthik NayakJul 3, 2025
  11. Patrick SteinhardtJul 3, 2025
  12. Junio C HamanoJul 1, 2025
  13. Karthik NayakJul 2, 2025
  14. Junio C HamanoJul 1, 2025
  15. Karthik NayakJul 2, 2025
  16. Karthik NayakJul 3, 2025
  17. Phillip WoodJul 2, 2025
  18. Karthik NayakJul 2, 2025
  19. Patrick SteinhardtJul 3, 2025
  20. Junio C HamanoJul 3, 2025
  21. Patrick SteinhardtJul 3, 2025
  22. Karthik NayakJul 3, 2025
  23. 0/4 for-each-ref: introduce seeking functionality via '--skip-until'Karthik Nayak, Jul 4, 2025
  24. 1/4 refs: expose `ref_iterator` via 'refs.h'Karthik Nayak, Jul 4, 2025
  25. 2/4 ref-cache: remove unused function 'find_ref_entry()'Karthik Nayak, Jul 4, 2025
  26. 3/4 refs: selectively set prefix in the seek functionsKarthik Nayak, Jul 4, 2025
  27. 4/4 for-each-ref: introduce a '--skip-until' optionKarthik Nayak, Jul 4, 2025
  28. Junio C HamanoJul 7, 2025
  29. Karthik NayakJul 7, 2025
  30. Andreas SchwabJul 4, 2025
  31. Karthik NayakJul 4, 2025
  32. Andreas SchwabJul 4, 2025
  33. Karthik NayakJul 4, 2025
  34. Andreas SchwabJul 4, 2025
  35. Karthik NayakJul 7, 2025
  36. Junio C HamanoJul 4, 2025
  37. Karthik NayakJul 7, 2025
  38. Phillip WoodJul 7, 2025
  39. Karthik NayakJul 8, 2025
  40. 0/4 for-each-ref: introduce seeking functionality via '--start-after'Karthik Nayak, Jul 8, 2025
  41. 1/4 refs: expose `ref_iterator` via 'refs.h'Karthik Nayak, Jul 8, 2025
  42. 2/4 ref-cache: remove unused function 'find_ref_entry()'Karthik Nayak, Jul 8, 2025
  43. 3/4 refs: selectively set prefix in the seek functionsKarthik Nayak, Jul 8, 2025
  44. Patrick SteinhardtJul 10, 2025
  45. Karthik NayakJul 11, 2025
  46. Junio C HamanoJul 14, 2025
  47. Karthik NayakJul 15, 2025
  48. Junio C HamanoJul 15, 2025
  49. Karthik NayakJul 16, 2025
  50. Junio C HamanoJul 16, 2025
  51. Junio C HamanoJul 16, 2025
  52. Karthik NayakJul 17, 2025
  53. Junio C HamanoJul 17, 2025
  54. 4/4 for-each-ref: introduce a '--start-after' optionKarthik Nayak, Jul 8, 2025
  55. Junio C HamanoJul 8, 2025
  56. Karthik NayakJul 9, 2025
  57. 0/4 for-each-ref: introduce seeking functionality via '--start-after'Karthik Nayak, Jul 11, 2025
  58. 2/4 ref-cache: remove unused function 'find_ref_entry()'Karthik Nayak, Jul 11, 2025
  59. 1/4 refs: expose `ref_iterator` via 'refs.h'Karthik Nayak, Jul 11, 2025
  60. 3/4 refs: selectively set prefix in the seek functionsKarthik Nayak, Jul 11, 2025
  61. Christian CouderJul 14, 2025
  62. Karthik NayakJul 15, 2025
  63. 4/4 for-each-ref: introduce a '--start-after' optionKarthik Nayak, Jul 11, 2025
  64. Christian CouderJul 14, 2025
  65. Junio C HamanoJul 14, 2025
  66. Karthik NayakJul 15, 2025
  67. Christian CouderJul 14, 2025
  68. Junio C HamanoJul 14, 2025
  69. Karthik NayakJul 15, 2025
  70. 0/5 for-each-ref: introduce seeking functionality via '--start-after'Karthik Nayak, Jul 15, 2025
  71. 1/5 refs: expose `ref_iterator` via 'refs.h'Karthik Nayak, Jul 15, 2025
  72. 2/5 ref-cache: remove unused function 'find_ref_entry()'Karthik Nayak, Jul 15, 2025
  73. Junio C HamanoJul 17, 2025
  74. Karthik NayakJul 17, 2025
  75. Junio C HamanoJul 17, 2025
  76. 3/5 refs: selectively set prefix in the seek functionsKarthik Nayak, Jul 15, 2025
  77. Jeff KingJul 17, 2025
  78. Karthik NayakJul 17, 2025
  79. Jeff KingJul 17, 2025
  80. 4/5 ref-filter: remove unnecessary else clauseKarthik Nayak, Jul 15, 2025
  81. 5/5 for-each-ref: introduce a '--start-after' optionKarthik Nayak, Jul 15, 2025
  82. Junio C HamanoJul 17, 2025
  83. Karthik NayakJul 22, 2025
  84. Junio C HamanoJul 15, 2025
  85. Kyle LippincottJul 17, 2025
  86. Jeff KingJul 17, 2025
  87. Kyle LippincottJul 17, 2025
  88. Karthik NayakJul 17, 2025
  89. Kyle LippincottJul 17, 2025
  90. Jeff KingJul 17, 2025
  91. Jeff KingJul 17, 2025
  92. Karthik NayakJul 21, 2025
  93. Jeff KingJul 21, 2025
  94. Karthik NayakJul 22, 2025
  95. Junio C HamanoJul 17, 2025
  96. ref-iterator-seek: correctly initialize the prefix_state for a new levelJunio C Hamano, Jul 23, 2025
  97. Kyle LippincottJul 23, 2025
  98. Jeff KingJul 23, 2025
  99. Karthik NayakJul 24, 2025
  100. Junio C HamanoJul 24, 2025
  101. ref-cache: set prefix_state when seekingKarthik Nayak, Jul 24, 2025
  102. Junio C HamanoJul 24, 2025

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.