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

Re: [PATCH v6 1/4] last-modified: new subcommand to show when files were last modified

From
Christian Couder <christian.couder@gmail.com>
Date
Aug 2, 2025, 11:31 UTC
Message-ID
<CAP8UFD1hdykpEaFrs1VoHbU1f-vT7xL2R6uvFWzjPQKRp0eoEw@mail.gmail.com>
In-Reply-To
<CAP8UFD3rV5CmHbbmg9vQodJ3U=WxfmWHnaio+7RcBAKz=2Ar-A@mail.gmail.com>

On Sat, Aug 2, 2025 at 10:18 AM Christian Couder <christian.couder@gmail.com> wrote:

Show 41 quoted lines
>
> On Fri, Aug 1, 2025 at 7:06 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> > Given that even a long-time contributor gets confused (including me,
> > who needed to see where we documented this for our developers),
> > perhaps a clarification patch is in order?
> >
> > --- >8 ---
> > Subject: CodingGuidelines: clarify that S_release() does not reinitialize
> >
> > In the section for naming various API functions, the fact that
> > S_release() only releases the resources without preparing the
> > structure for immediate reuse becomes only apparent when you
> > readentries for S_release() and S_clear().
> >
> > Clarify the description of S_release() a bit to make the entry self
> > sufficient.
> >
> > Signed-off-by: Junio C Hamano <gitster@pobox.com>
> > ---
> >  Documentation/CodingGuidelines | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git c/Documentation/CodingGuidelines w/Documentation/CodingGuidelines
> > index c1046abfb7..76ec6268f2 100644
> > --- c/Documentation/CodingGuidelines
> > +++ w/Documentation/CodingGuidelines
> > @@ -610,8 +610,9 @@ For C programs:
> >      - `S_init()` initializes a structure without allocating the
> >        structure itself.
> >
> > -    - `S_release()` releases a structure's contents without freeing the
> > -      structure.
> > +    - `S_release()` releases a structure's contents without reinitializing
> > +      the structure for immediate reuse, and without freeing the structure
> > +      itself.
> >
> >      - `S_clear()` is equivalent to `S_release()` followed by `S_init()`
> >        such that the structure is directly usable after clearing it. When
>
> Yeah, I think that could help. Thanks!

For information, I have asked ChatGPT o3-pro (which can analyse a whole repo) about this and here is what it says:

---------------------------
Q: In the source code of the Git SCM software are there standard ways
of naming functions that release memory from a struct or clear a
struct? Are they consistently named using "clear" or "release" or
"free" or "clear_and_free" or other things like that depending on what
they actually do?
A:
What the names mean in Git’s C code – quick rules of thumb
- *_clear():
  effect: Free only the heap‑memory owned by the struct (arrays,
strings, hash‑table buckets, etc.) and reset its fields to an
initial/empty state.
  reuse possible: Yes – the variable itself remains valid and can be
filled again.
- *_release():
  effect: Historical synonym for the same thing as *_clear(), kept for
backward compatibility in a few low‑level APIs.
  reuse possible: Yes – same as above.
- free_*() or *_free():
  effect: Free the struct itself (it was malloc‑ed) and everything it
points at. After the call the pointer becomes dangling and must not be
reused.
  reuse possible: No – the storage is gone.
- *_clear_and_free():
  effect: Convenience wrapper that first calls the type’s *_clear() on
each contained element and then frees those elements themselves.
Mainly used for containers implemented as macros.
  reuse possible: Not applicable – it is meant to be the last
operation on the container.
How consistent is the convention?
- Within each mini‑API the convention is very strict
  The strbuf API always pairs strbuf_init() / strbuf_release(), the
strvec API always pairs strvec_init() / strvec_clear(), etc.
- Across the whole Git code‑base the spelling is mostly consistent but
not 100 % uniform
  Very early core helpers (pre‑1.6): usually *_release()
  Code written in the last decade: *_clear() for “empty in‑place”,
free_*() for “destroy”
- No “mixed‑semantics” functions
  You will not find a helper that sometimes frees the struct and
sometimes only clears it depending on flags. The name alone tells you
which category it belongs to.
[...]
Bottom line
Git uses two distinct verbs to convey intent:
- clear / release – light‑weight reset, keep the container alive
- free – heavy‑weight destruction of the container itself

The rule is consistent enough that you can rely on it when reading or writing Git’s C code; the rare exceptions are historical, not ambiguous.

Q: Some say that if the structure can be immediately reused afterwards
without requiring another reinit the function should be named using
"clear", otherwise if it only releases memory then it should be called
"release". Is it true?
A:
Short answer – no.

In the Git source tree the verbs clear and release are not used to distinguish “can I reuse the struct afterwards?” vs. “is this the final teardown?”. Both variants free all heap memory owned by the structure and then reset the in‑memory object to its pristine, empty state, so the variable can be used again without an extra call to the corresponding …_init() helper.

[...]
Why two different verbs exist
- Historical baggage – the very early helper that everybody still
uses, strbuf, was written long before today’s “*_clear()” convention
emerged, so its lifecycle pair is strbuf_init() / strbuf_release().
- Later subsystems standardised on *_clear() when they were introduced
(string‑list, strvec, oidset, hashmap, etc.).
- Because Git’s internal APIs are used by thousands of call‑sites,
there has been no large‑scale renaming; both spellings therefore
coexist.
[...]
Conclusion

The folk rule you quoted (“* use clear if the struct can be reused, release if not *”) does not match what the Git code actually does:

strbuf_release() allows immediate reuse – just like every *_clear() helper does.
The difference in naming is historical, not semantic.

If you want to know whether the variable itself has been freed, look for free_*()/*_free(), not for the presence or absence of the word release.

Q: Do you have other examples than strbuf_release using "release"
where the function behaves like a "clear" function?
A:

Yes – a handful of other helpers are spelled “*_release()”, yet they merely clear the inside of an on‑stack/object‑lifetime struct and leave the container itself reusable

- Line reader: void line_buffer_release(struct line_buffer *buf);
  Closes the underlying file descriptor and frees its internal scratch
space; the struct line_buffer itself remains valid and can be
re‑initialised with line_buffer_open() if desired.
- Packet‑line writer: void packet_writer_release(struct packet_writer *writer);
  Calls strbuf_release(&writer‑>scratch_buf) and clears a few flags;
the struct packet_writer lives on so the caller may point it at
another FILE * later.
- FS‑monitor IPC channel: void fsmonitor_ipc__release(struct
fsmonitor_ipc *ipc);
  Shuts down the socket, frees small temp buffers, and zeroes the
struct for re‑use inside the long‑running daemon.

All of these match the behaviour of strbuf_release() rather than that of the many *_free() helpers which actually free() the struct itself.

How many are there?

A quick git grep '_release(struct' over the Git 2.50 tree finds fewer than a dozen hits, and every one of them follows this “clear‑but‑don’t‑free” pattern. In other words:

- *_release() in Git never deallocates the container itself.
- The form survives today only in subsystems that pre‑date the later
project‑wide switch to *_clear() (or that wrap strbuf_release()
internally).
- Newer code consistently uses *_clear() for the same semantics.
Bottom line

strbuf_release() is not unique, but it is the template that the other rare *_release() helpers copy: they wipe the contents and reset the struct so you can keep using the variable. If you are looking at Git C code and see “_release” in a function name, you can safely assume “clear in place” – not “free the object.”

---------------------------

In short it looks like it doesn't think there should be a distinction between *_release() and *_clear(), because in many cases the existing *_release() functions (starting with strbuf_release()) leave the struct ready for immediate reuse.

For the documentation update, it suggests:
  - `S_release()` releases a structure's contents without freeing the
    structure. In older subsystems (e.g. *strbuf*), the helper also
    resets the object to its initial, empty state; newer code should
    prefer `S_clear()` for that purpose.

But if our intention is to tend towards a clear distinction between "clear" and "release" even if in practice there is not a clear distinction right now (because of historical reasons), I think we could compromise with something like:

- `S_release()` releases a structure's contents without reinitializing
  the structure for immediate reuse, and without freeing the structure
  itself. In older subsystems (e.g. *strbuf*), the helper also
  resets the object to its initial, empty state; newer code should
  prefer `S_clear()` for that purpose.
Previous: Christian CouderNext: Christian Couder
Message 121 of 135 in “Introduce git-blame-tree(1) command”
  1. 0/5 Introduce git-blame-tree(1) commandToon Claes, Apr 22, 2025
  2. 1/5 blame-tree: introduce new subcommand to blame filesToon Claes, Apr 22, 2025
  3. Junio C HamanoApr 24, 2025
  4. Toon ClaesMay 7, 2025
  5. 2/5 t/perf: add blame-tree perf scriptToon Claes, Apr 22, 2025
  6. 3/5 blame-tree: use Bloom filters when availableToon Claes, Apr 22, 2025
  7. 4/5 blame-tree: implement faster algorithmToon Claes, Apr 22, 2025
  8. 5/5 blame-tree.c: initialize revision machinery without walkToon Claes, Apr 22, 2025
  9. Marc BranchaudApr 23, 2025
  10. Toon ClaesMay 7, 2025
  11. Marc BranchaudMay 7, 2025
  12. Junio C HamanoMay 7, 2025
  13. Marc BranchaudMay 8, 2025
  14. Junio C HamanoMay 8, 2025
  15. Marc BranchaudMay 8, 2025
  16. Toon ClaesMay 14, 2025
  17. Junio C HamanoMay 14, 2025
  18. Marc BranchaudMay 14, 2025
  19. Patrick SteinhardtMay 15, 2025
  20. Junio C HamanoMay 15, 2025
  21. Marc BranchaudMay 15, 2025
  22. Jeff KingMay 15, 2025
  23. Patrick SteinhardtMay 16, 2025
  24. Toon ClaesMay 20, 2025
  25. Marc BranchaudMay 15, 2025
  26. Patrick SteinhardtMay 16, 2025
  27. Marc BranchaudMay 14, 2025
  28. Kristoffer HaugsbakkMay 7, 2025
  29. D. Ben KnobleMay 8, 2025
  30. Marc BranchaudMay 8, 2025
  31. D. Ben KnobleMay 8, 2025
  32. 0/5 Introduce git-last-modified(1) commandToon Claes, May 23, 2025
  33. 1/5 last-modified: new subcommand to show when files were last modifiedToon Claes, May 23, 2025
  34. Justin ToblerMay 25, 2025
  35. Toon ClaesJun 5, 2025
  36. Patrick SteinhardtMay 27, 2025
  37. Toon ClaesJun 13, 2025
  38. Kristoffer HaugsbakkJun 13, 2025
  39. 2/5 t/perf: add last-modified perf scriptToon Claes, May 23, 2025
  40. 3/5 last-modified: use Bloom filters when availableToon Claes, May 23, 2025
  41. Patrick SteinhardtMay 27, 2025
  42. Toon ClaesJun 13, 2025
  43. 4/5 last-modified: implement faster algorithmToon Claes, May 23, 2025
  44. Patrick SteinhardtMay 27, 2025
  45. 5/5 last-modified: initialize revision machinery without walkToon Claes, May 23, 2025
  46. Patrick SteinhardtMay 27, 2025
  47. Kristoffer HaugsbakkJul 1, 2025
  48. Junio C HamanoJul 1, 2025
  49. Kristoffer HaugsbakkJul 1, 2025
  50. Toon ClaesJul 2, 2025
  51. Toon ClaesJul 9, 2025
  52. Junio C HamanoJul 9, 2025
  53. 0/3 Introduce git-last-modified(1) commandToon Claes, Jun 30, 2025
  54. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Jun 30, 2025
  55. Kristoffer HaugsbakkJul 1, 2025
  56. Junio C HamanoJul 2, 2025
  57. 2/3 t/perf: add last-modified perf scriptToon Claes, Jun 30, 2025
  58. 3/3 last-modified: use Bloom filters when availableToon Claes, Jun 30, 2025
  59. Junio C HamanoJul 1, 2025
  60. 0/3 Introduce git-last-modified(1) commandToon Claes, Jul 9, 2025
  61. Junio C HamanoJul 9, 2025
  62. Junio C HamanoJul 10, 2025
  63. 0/6 Introduce git-last-modified(1) commandToon Claes, Jul 16, 2025
  64. 1/6 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 16, 2025
  65. Taylor BlauJul 18, 2025
  66. Jeff KingJul 19, 2025
  67. Toon ClaesJul 22, 2025
  68. Christian CouderAug 1, 2025
  69. Junio C HamanoAug 1, 2025
  70. 2/6 t/perf: add last-modified perf scriptToon Claes, Jul 16, 2025
  71. Taylor BlauJul 18, 2025
  72. Toon ClaesJul 22, 2025
  73. 3/6 last-modified: use Bloom filters when availableToon Claes, Jul 16, 2025
  74. Taylor BlauJul 18, 2025
  75. Toon ClaesJul 22, 2025
  76. 4/6 pretty: allow caller to disable indentationToon Claes, Jul 16, 2025
  77. Junio C HamanoJul 16, 2025
  78. Toon ClaesJul 17, 2025
  79. 5/6 last-modified: support --extended formatToon Claes, Jul 16, 2025
  80. Junio C HamanoJul 16, 2025
  81. Toon ClaesJul 17, 2025
  82. Junio C HamanoJul 17, 2025
  83. Junio C HamanoJul 18, 2025
  84. Toon ClaesJul 22, 2025
  85. 6/6 fixup! last-modified: use Bloom filters when availableToon Claes, Jul 16, 2025
  86. Taylor BlauJul 17, 2025
  87. Toon ClaesJul 22, 2025
  88. Toon ClaesJul 30, 2025
  89. Patrick SteinhardtJul 31, 2025
  90. 0/4 Introduce git-last-modified(1) commandToon Claes, Jul 30, 2025
  91. Junio C HamanoJul 31, 2025
  92. Junio C HamanoJul 31, 2025
  93. 0/3 Introduce git-last-modified(1) commandToon Claes, Aug 5, 2025
  94. Patrick SteinhardtAug 5, 2025
  95. Junio C HamanoAug 5, 2025
  96. Junio C HamanoAug 5, 2025
  97. Toon ClaesAug 5, 2025
  98. Jean-Noël AVILAAug 5, 2025
  99. Junio C HamanoAug 5, 2025
  100. Toon ClaesAug 6, 2025
  101. Junio C HamanoAug 6, 2025
  102. Junio C HamanoAug 28, 2025
  103. Junio C HamanoAug 5, 2025
  104. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Aug 5, 2025
  105. 2/3 t/perf: add last-modified perf scriptToon Claes, Aug 5, 2025
  106. 3/3 last-modified: use Bloom filters when availableToon Claes, Aug 5, 2025
  107. 1/4 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 30, 2025
  108. Patrick SteinhardtJul 31, 2025
  109. Toon ClaesAug 1, 2025
  110. Junio C HamanoAug 1, 2025
  111. Patrick SteinhardtAug 4, 2025
  112. Junio C HamanoAug 4, 2025
  113. Toon ClaesAug 5, 2025
  114. Jean-Noël AVILAAug 1, 2025
  115. Toon ClaesAug 5, 2025
  116. Patrick SteinhardtAug 4, 2025
  117. Christian CouderAug 1, 2025
  118. Patrick SteinhardtAug 1, 2025
  119. Junio C HamanoAug 1, 2025
  120. Christian CouderAug 2, 2025
  121. Christian CouderAug 2, 2025
  122. Christian CouderAug 2, 2025
  123. Junio C HamanoAug 2, 2025
  124. Patrick SteinhardtAug 4, 2025
  125. 2/4 t/perf: add last-modified perf scriptToon Claes, Jul 30, 2025
  126. 3/4 commit-graph: export prepare_commit_graph()Toon Claes, Jul 30, 2025
  127. Patrick SteinhardtJul 31, 2025
  128. 4/4 last-modified: use Bloom filters when availableToon Claes, Jul 30, 2025
  129. Patrick SteinhardtJul 31, 2025
  130. Toon ClaesAug 1, 2025
  131. Patrick SteinhardtAug 4, 2025
  132. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 9, 2025
  133. 2/3 t/perf: add last-modified perf scriptToon Claes, Jul 9, 2025
  134. 3/3 last-modified: use Bloom filters when availableToon Claes, Jul 9, 2025
  135. 6/6 fixup! last-modified: use Bloom filters when availableToon Claes, Jul 16, 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.