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

Re: libgit2 - a true git library

From
Shawn O. Pearce <spearce@spearce.org>
Date
Nov 1, 2008, 00:13 UTC
Message-ID
<20081101001300.GE14786@spearce.org>
In-Reply-To
<7v63n872bs.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> wrote:
> I understand that the apidocs/ is a very early work-in-progress, but
> still, it bothers me that it is unclear to me what lifetime rules are in
> effect on the in-core objects.
Yes, this needs a lot more documentation.
Show 5 quoted lines
> For example, in C-git, commit objects are
> not just parsed but are modified in place as history is traversed
> (e.g. their flags smudged and their parents simplified).  You have "flags"
> field in commit, which implies to me that the design shares this same
> "modified by processing in-place" assumption.
Yup.  I was assuming the same model, we modify in-place.
Show 6 quoted lines
> It is great for processing
> efficiency as long as you are a "run once and let exit(3) clean-up" type
> of program, but is quite problematic otherwise.  commit.flags that C-git
> uses for traversal marker purposes, together with "who are parents and
> children of this commit", should probably be kept inside traversal module,
> if you want to make this truly reusable.

Its not efficient to keep this data inside of the "traversal module" instance (aka what I called git_revp_t). You really want it inside of the commit itself (aka git_commit_t).

My thought here is that git_commit_t's are scoped within a given git_revp_t that was used when they were parsed. That is:

  git_revp_t *pool_a = git_revp_alloc(db, NULL);
  git_revp_t *pool_b = git_revp_alloc(db, NULL);
  git_oid_t id;
  git_commit_t *commit_a, *commit_b, *commit_c;
  git_oid_mkstr(&id, "3c223b36af9cace4f802a855fbb588b1dccf0648");
  commit_a = git_commit_parse(pool_a, &id);
  commit_b = git_commit_parse(pool_b, &id);
  commit_c = git_commit_parse(pool_a, &id);
  if (commit_a == commit_b)
    die("the world just exploded");
  else
    printf("this was correct behavior\n");
  if (commit_a == commit_c)
    printf("this was correct behavior\n");
  else
    die("the hash table is broken");

To completely different git_revp_t's on the same database yeild different commit pointers, but successive calls to parse the same commit in the same pool yield the same pointer.

Certain operations on the pool can cause it to alter its state in a way that cannot be reversed (e.g. rewrite parents). In such cases the caller should free the pool and alloc a new one in order to issue new traversals against the same object database, but with the original (or differently rewritten) parent information.

> By the way, I hate git_result_t.  That should be "int", the most natural
> integral type on the platform.

Yea, I'm torn on git_result_t myself. Some library APIs use their own result type, but as a typedef off int.

I'm tempted to stick with int for the result type, but I don't want readers to confuse our result type of 0 == success, <0 == failure with some case where we return a signed integral value as a result of a computation.

I'm also debating the error handling. Do we return the error code as the return value from the function, or do we stick it into some sort of thread-global like classic "errno", or do we ask the application to pass in a structure to us?

E.g.:
Return code:
  git_result_t r = git_foo_bar(...);
  if (r < 0)
  	die("foo_bar failed: %s", git_strerr(r));
Use an errno:
  if (git_foo_bar(...))
  	die("foo_bar failed: %s", git_strerr(git_errno));
Use a caller allocated struct:
  git_error_t err;
  if (git_foo_bar(..., &err))
  	die("foo_bar failed: %s", git_strerr(&err));

I'm slightly leaning towards the result code approach, as it means we don't have to mess around with thread local variables.

We don't get to pass back anything more complex than an int (possibly losing context about parameter values and/or on-disk state we want to report on), but we also don't have to deal with thread-locals or some messy "always pass a thread context parameter".

-- 
Shawn.
Previous: Pierre HabouzitNext: Nicolas Pitre
Message 35 of 83 in “libgit2 - a true git library”
  1. Shawn O. PearceOct 31, 2008
  2. Pieter de BieOct 31, 2008
  3. Pieter de BieOct 31, 2008
  4. Pierre HabouzitOct 31, 2008
  5. Shawn O. PearceOct 31, 2008
  6. Pierre HabouzitOct 31, 2008
  7. Shawn O. PearceOct 31, 2008
  8. Pierre HabouzitOct 31, 2008
  9. Junio C HamanoOct 31, 2008
  10. Shawn O. PearceOct 31, 2008
  11. Pierre HabouzitNov 1, 2008
  12. Andreas EricssonNov 1, 2008
  13. Pierre HabouzitNov 1, 2008
  14. Shawn O. PearceNov 1, 2008
  15. Andreas EricssonNov 1, 2008
  16. Shawn O. PearceNov 2, 2008
  17. Andreas EricssonNov 3, 2008
  18. Shawn O. PearceNov 2, 2008
  19. Pierre HabouzitNov 2, 2008
  20. Nicolas PitreOct 31, 2008
  21. david@lang.hmOct 31, 2008
  22. Nicolas PitreOct 31, 2008
  23. Shawn O. PearceOct 31, 2008
  24. Shawn O. PearceOct 31, 2008
  25. Pierre HabouzitOct 31, 2008
  26. Pierre HabouzitOct 31, 2008
  27. Nicolas PitreOct 31, 2008
  28. Andreas EricssonNov 1, 2008
  29. Pieter de BieOct 31, 2008
  30. Shawn O. PearceOct 31, 2008
  31. Junio C HamanoOct 31, 2008
  32. Pierre HabouzitNov 1, 2008
  33. Shawn O. PearceNov 1, 2008
  34. Pierre HabouzitNov 1, 2008
  35. Shawn O. PearceNov 1, 2008
  36. Nicolas PitreNov 1, 2008
  37. Shawn O. PearceNov 1, 2008
  38. Nicolas PitreNov 1, 2008
  39. Shawn O. PearceNov 1, 2008
  40. Johannes SchindelinNov 1, 2008
  41. Pierre HabouzitNov 1, 2008
  42. Nicolas PitreNov 1, 2008
  43. Pierre HabouzitNov 1, 2008
  44. Johannes SchindelinNov 1, 2008
  45. Junio C HamanoOct 31, 2008
  46. Pierre HabouzitOct 31, 2008
  47. Shawn O. PearceOct 31, 2008
  48. Jakub NarebskiOct 31, 2008
  49. david@lang.hmNov 1, 2008
  50. Shawn O. PearceNov 1, 2008
  51. david@lang.hmNov 1, 2008
  52. Pierre HabouzitNov 1, 2008
  53. Nicolas PitreNov 1, 2008
  54. Pierre HabouzitNov 1, 2008
  55. Nicolas PitreNov 1, 2008
  56. Shawn O. PearceNov 1, 2008
  57. Nicolas PitreNov 1, 2008
  58. Shawn O. PearceNov 1, 2008
  59. Scott ChaconNov 2, 2008
  60. Scott ChaconNov 2, 2008
  61. Shawn O. PearceNov 2, 2008
  62. David BrownNov 2, 2008
  63. Shawn O. PearceNov 3, 2008
  64. Pierre HabouzitNov 1, 2008
  65. david@lang.hmNov 1, 2008
  66. Brian GernhardtOct 31, 2008
  67. Andreas EricssonOct 31, 2008
  68. Shawn O. PearceOct 31, 2008
  69. Junio C HamanoOct 31, 2008
  70. Andreas EricssonNov 1, 2008
  71. Johannes SchindelinOct 31, 2008
  72. Bruno SantosOct 31, 2008
  73. Shawn O. PearceOct 31, 2008
  74. Andreas EricssonNov 1, 2008
  75. Shawn O. PearceNov 1, 2008
  76. Johannes SchindelinNov 2, 2008
  77. Pierre HabouzitNov 2, 2008
  78. Andreas EricssonNov 3, 2008
  79. Steve FrécinauxNov 8, 2008
  80. Andreas EricssonNov 8, 2008
  81. Pierre HabouzitNov 8, 2008
  82. Andreas EricssonNov 9, 2008
  83. Shawn O. PearceNov 9, 2008

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.