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

Re: [RFC PATCH 0/8] Introduce Git Standard Library

From
LALinus Arver <linusa@google.com>
Date
Jun 30, 2023, 07:01 UTC
Message-ID
<owly4jmp8mdf.fsf@fine.c.googlers.com>
In-Reply-To
<20230627195251.1973421-1-calvinwan@google.com>
Hello Calvin,
Calvin Wan <calvinwan@google.com> writes:
Show 36 quoted lines
> With our current method of building Git, we can imagine the dependency
> graph as such:
>
>         Git
>          /\
>         /  \
>        /    \
>   libgit.a   ext deps
>
> In libifying parts of Git, we want to shrink the dependency graph to
> only the minimal set of dependencies, so libraries should not use
> libgit.a. Instead, it would look like:
>
>                 Git
>                 /\
>                /  \
>               /    \
>           libgit.a  ext deps
>              /\
>             /  \
>            /    \
> object-store.a  (other lib)
>       |        /
>       |       /
>       |      /
>  config.a   / 
>       |    /
>       |   /
>       |  /
> git-std-lib.a
>
> Instead of containing all of the objects in Git, libgit.a would contain
> objects that are not built by libraries it links against. Consequently,
> if someone wanted their own custom build of Git with their own custom
> implementation of the object store, they would only have to swap out
> object-store.a rather than do a hard fork of Git.

What about the case where someone wants to build program Foo which just pulls in some bits of Git? For example, I am thinking of trailer.[ch] which could be refactored to expose a public API. Then the Foo program could pull this public trailer manipulation API in as a library dependency (so that Foo can parse trailers in commit messages without re-implementing that logic in Foo's own codebase). With the proposed Git Standard Library (GSL) model above, would my Foo program also have to pull in GSL? If so, isn't this onerous because of the additional bloat? The Foo developers just want the banana, not the gorilla holding the banana in the jungle, so to speak.

Show 19 quoted lines
> Rationale behind Git Standard Library
> ================
>
> The rationale behind Git Standard Library essentially is the result of
> two observations within the Git codebase: every file includes
> git-compat-util.h which defines functions in a couple of different
> files, and wrapper.c + usage.c have difficult-to-separate circular
> dependencies with each other and other files.
>
> Ubiquity of git-compat-util.h and circular dependencies
> ========
>
> Every file in the Git codebase includes git-compat-util.h. It serves as
> "a compatibility aid that isolates the knowledge of platform specific
> inclusion order and what feature macros to define before including which
> system header" (Junio[5]). Since every file includes git-compat-util.h, and
> git-compat-util.h includes wrapper.h and usage.h, it would make sense
> for wrapper.c and usage.c to be a part of the root library. They have
> difficult to separate circular dependencies with each other so they
s/difficult to separate/difficult-to-separate
Show 21 quoted lines
> can't be independent libraries. Wrapper.c has dependencies on parse.c,
> abspath.c, strbuf.c, which in turn also have dependencies on usage.c and
> wrapper.c -- more circular dependencies. 
>
> Tradeoff between swappability and refactoring
> ========
>
> From the above dependency graph, we can see that git-std-lib.a could be
> many smaller libraries rather than a singular library. So why choose a
> singular library when multiple libraries can be individually easier to
> swap and are more modular? A singular library requires less work to
> separate out circular dependencies within itself so it becomes a
> tradeoff question between work and reward. While there may be a point in
> the future where a file like usage.c would want its own library so that
> someone can have custom die() or error(), the work required to refactor
> out the circular dependencies in some files would be enormous due to
> their ubiquity so therefore I believe it is not worth the tradeoff
> currently. Additionally, we can in the future choose to do this refactor
> and change the API for the library if there becomes enough of a reason
> to do so (remember we are avoiding promising stability of the interfaces
> of those libraries).

Would getting us down the currently proposed path make it even more difficult to do this refactor? If so, I think it's worth mentioning.

Show 24 quoted lines
> Reuse of compatibility functions in git-compat-util.h
> ========
>
> Most functions defined in git-compat-util.h are implemented in compat/
> and have dependencies limited to strbuf.h and wrapper.h so they can be
> easily included in git-std-lib.a, which as a root dependency means that
> higher level libraries do not have to worry about compatibility files in
> compat/. The rest of the functions defined in git-compat-util.h are
> implemented in top level files and, in this patch set, are hidden behind
> an #ifdef if their implementation is not in git-std-lib.a.
>
> Rationale summary
> ========
>
> The Git Standard Library allows us to get the libification ball rolling
> with other libraries in Git (such as Glen's removal of global state from
> config iteration[6] prepares a config library). By not spending many
> more months attempting to refactor difficult circular dependencies and
> instead spending that time getting to a state where we can test out
> swapping a library out such as config or object store, we can prove the
> viability of Git libification on a much faster time scale. Additionally
> the code cleanups that have happened so far have been minor and
> beneficial for the codebase. It is probable that making large movements
> would negatively affect code clarity.

It sounds like the circular dependencies are so difficult to untangle that they are the primary motivation behind grouping these tightly-coupled libraries together into the Git Standard Library (GSL) banner. Still, I think it would help reviewers if you explain what tradeoffs we are making by accepting the circular dependencies as they are instead of untangling them. Conversely, if we assume that there are no circular dependencies, what kind of benefits do we get when designing the GSL from this (improved) position? Would there be little to no additional benefits? If so, then I think it would be easier to support the current approach (as removing the circularities would not give us significant advantages for libification).

Show 14 quoted lines
> Git Standard Library boundary
> ================
>
> While I have described above some useful heuristics for identifying
> potential candidates for git-std-lib.a, a standard library should not
> have a shaky definition for what belongs in it.
>
>  - Low-level files (aka operates only on other primitive types) that are
>    used everywhere within the codebase (wrapper.c, usage.c, strbuf.c)
>    - Dependencies that are low-level and widely used
>      (abspath.c, date.c, hex-ll.c, parse.c, utf8.c)
>  - low-level git/* files with functions defined in git-compat-util.h
>    (ctype.c)
>  - compat/*

I'm confused. Is the list above an example of a shaky definition, or the opposite? IOW, do you mean that the list above should be the initial set of content to include in the GSL? Or _not_ to include?

Show 12 quoted lines
> Series structure
> ================
>
> While my strbuf and git-compat-util series can stand alone, they also
> function as preparatory patches for this series. There are more cleanup
> patches in this series, but since most of them have marginal benefits
> probably not worth the churn on its own, I decided not to split them
> into a separate series like with strbuf and git-compat-util. As an RFC,
> I am looking for comments on whether the rationale behind git-std-lib
> makes sense as well as whether there are better ways to build and enable
> git-std-lib in patch 7, specifically regarding Makefile rules and the
> usage of ifdef's to stub out certain functions and headers. 

If the cleanups are independent I think it would be simpler to put them in a separate series.

In general, I think the doc would make a stronger case if it expanded the discussions around alternative approaches to the one proposed, with the reasons why they were rejected.

Minor nits:
- Documentation/technical/git-std-lib.txt: (style) prefer "we" over "I" ("we
  believe" instead of "I believe").
- There are some "\ No newline at end of file" warnings in this series.

Thanks, Linus

Previous: Calvin WanNext: Calvin Wan
Message 29 of 111 in “Introduce Git Standard Library”
  1. 0/8 Introduce Git Standard LibraryCalvin Wan, Jun 27, 2023
  2. 1/8 trace2: log fsync stats in trace2 rather than wrapperCalvin Wan, Jun 27, 2023
  3. Victoria DyeJun 28, 2023
  4. Calvin WanJul 5, 2023
  5. Victoria DyeJul 5, 2023
  6. Jeff HostetlerJul 11, 2023
  7. 2/8 hex-ll: split out functionality from hexCalvin Wan, Jun 27, 2023
  8. Phillip WoodJun 28, 2023
  9. Calvin WanJun 28, 2023
  10. 3/8 object: move function to object.cCalvin Wan, Jun 27, 2023
  11. 4/8 config: correct bad boolean env value error messageCalvin Wan, Jun 27, 2023
  12. 5/8 parse: create new library for parsing strings and env valuesCalvin Wan, Jun 27, 2023
  13. Junio C HamanoJun 27, 2023
  14. 6/8 pager: remove pager_in_use()Calvin Wan, Jun 27, 2023
  15. Junio C HamanoJun 27, 2023
  16. Calvin WanJun 27, 2023
  17. Glen ChooJun 28, 2023
  18. Glen ChooJun 28, 2023
  19. Calvin WanJun 28, 2023
  20. Junio C HamanoJun 28, 2023
  21. Junio C HamanoJun 28, 2023
  22. 8/8 git-std-lib: add test file to call git-std-lib.a functionsCalvin Wan, Jun 27, 2023
  23. 7/8 git-std-lib: introduce git standard libraryCalvin Wan, Jun 27, 2023
  24. Phillip WoodJun 28, 2023
  25. Calvin WanJun 28, 2023
  26. Phillip WoodJun 30, 2023
  27. Glen ChooJun 28, 2023
  28. Calvin WanJun 28, 2023
  29. Linus ArverJun 30, 2023
  30. 0/7 Introduce Git Standard LibraryCalvin Wan, Aug 10, 2023
  31. 2/7 object: move function to object.cCalvin Wan, Aug 10, 2023
  32. Junio C HamanoAug 10, 2023
  33. Glen ChooAug 10, 2023
  34. Junio C HamanoAug 10, 2023
  35. 1/7 hex-ll: split out functionality from hexCalvin Wan, Aug 10, 2023
  36. 3/7 config: correct bad boolean env value error messageCalvin Wan, Aug 10, 2023
  37. Junio C HamanoAug 10, 2023
  38. 5/7 date: push pager.h dependency upCalvin Wan, Aug 10, 2023
  39. Glen ChooAug 10, 2023
  40. Jonathan TanAug 14, 2023
  41. 4/7 parse: create new library for parsing strings and env valuesCalvin Wan, Aug 10, 2023
  42. Glen ChooAug 10, 2023
  43. Junio C HamanoAug 10, 2023
  44. Jonathan TanAug 14, 2023
  45. Jonathan TanAug 14, 2023
  46. Junio C HamanoAug 14, 2023
  47. 7/7 git-std-lib: add test file to call git-std-lib.a functionsCalvin Wan, Aug 10, 2023
  48. Jonathan TanAug 14, 2023
  49. 6/7 git-std-lib: introduce git standard libraryCalvin Wan, Aug 10, 2023
  50. Jonathan TanAug 14, 2023
  51. Glen ChooAug 10, 2023
  52. Phillip WoodAug 15, 2023
  53. Calvin WanAug 16, 2023
  54. Junio C HamanoAug 16, 2023
  55. Phillip WoodAug 15, 2023
  56. 0/6 Introduce Git Standard LibraryCalvin Wan, Sep 8, 2023
  57. 2/6 wrapper: remove dependency to Git-specific internal fileCalvin Wan, Sep 8, 2023
  58. Jonathan TanSep 15, 2023
  59. 1/6 hex-ll: split out functionality from hexCalvin Wan, Sep 8, 2023
  60. 3/6 config: correct bad boolean env value error messageCalvin Wan, Sep 8, 2023
  61. 4/6 parse: create new library for parsing strings and env valuesCalvin Wan, Sep 8, 2023
  62. 5/6 git-std-lib: introduce git standard libraryCalvin Wan, Sep 8, 2023
  63. Phillip WoodSep 11, 2023
  64. Phillip WoodSep 27, 2023
  65. Jonathan TanSep 15, 2023
  66. phillip.wood123@gmail.comSep 26, 2023
  67. 6/6 git-std-lib: add test file to call git-std-lib.a functionsCalvin Wan, Sep 8, 2023
  68. Junio C HamanoSep 9, 2023
  69. Jonathan TanSep 15, 2023
  70. Junio C HamanoSep 15, 2023
  71. Junio C HamanoSep 8, 2023
  72. Junio C HamanoSep 8, 2023
  73. 0/4 Preliminary patches before git-std-libJonathan Tan, Sep 29, 2023
  74. 1/4 hex-ll: separate out non-hash-algo functionsJonathan Tan, Sep 29, 2023
  75. Linus ArverOct 21, 2023
  76. 2/4 wrapper: reduce scope of remove_or_warn()Jonathan Tan, Sep 29, 2023
  77. phillip.wood123@gmail.comOct 10, 2023
  78. Junio C HamanoOct 10, 2023
  79. Jonathan TanOct 10, 2023
  80. 3/4 config: correct bad boolean env value error messageJonathan Tan, Sep 29, 2023
  81. Junio C HamanoSep 29, 2023
  82. 4/4 parse: separate out parsing functions from config.hJonathan Tan, Sep 29, 2023
  83. phillip.wood123@gmail.comOct 10, 2023
  84. Jonathan TanOct 10, 2023
  85. Phillip WoodOct 10, 2023
  86. Junio C HamanoOct 10, 2023
  87. phillip.wood123@gmail.comOct 10, 2023
  88. Jonathan TanOct 10, 2023
  89. 0/3 Introduce Git Standard LibraryCalvin Wan, Feb 22, 2024
  90. 1/3 pager: include stdint.h because uintmax_t is usedCalvin Wan, Feb 22, 2024
  91. Junio C HamanoFeb 22, 2024
  92. Kyle LippincottFeb 26, 2024
  93. Junio C HamanoFeb 27, 2024
  94. Kyle LippincottFeb 27, 2024
  95. Junio C HamanoFeb 27, 2024
  96. Kyle LippincottFeb 27, 2024
  97. Junio C HamanoFeb 27, 2024
  98. Jeff KingFeb 27, 2024
  99. Jeff KingFeb 27, 2024
  100. Kyle LippincottFeb 27, 2024
  101. Kyle LippincottFeb 24, 2024
  102. Junio C HamanoFeb 24, 2024
  103. 2/3 git-std-lib: introduce Git Standard LibraryCalvin Wan, Feb 22, 2024
  104. Phillip WoodFeb 29, 2024
  105. Junio C HamanoFeb 29, 2024
  106. Linus ArverFeb 29, 2024
  107. Junio C HamanoFeb 29, 2024
  108. Linus ArverFeb 29, 2024
  109. 3/3 test-stdlib: show that git-std-lib is independentCalvin Wan, Feb 22, 2024
  110. Junio C HamanoFeb 22, 2024
  111. Junio C HamanoMar 7, 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.