-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
git_buf
: now a public-only API (git_str
is our internal API)
#6078
Conversation
f70883f
to
fe07fa6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is quite a diff. I'll admit I didn't check every single file for the conversion but did go over the other ones.
It's kinda big for everything to be changing, but it is better to have different types for internal and external uses, and the only users who might notice are those implementing things close to the library and which should expect changes either way.
git_str str = GIT_STR_INIT; \ | ||
int error; \ | ||
if ((error = git_buf_tostr(&str, buf)) == 0 && \ | ||
(error = fn(&str, __VA_ARGS__)) == 0) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the opposite logic from what we would normally use in our series of ifs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is - that's intentional. Since fn
is arbitrary, it might return > 0
for some reason. (I don't recall if any of them do offhand) and that should be returned to the user. I find the above more readable than what would be closer to our normal logic:
if ((error = git_buf_tostr(&str, buf)) < 0 || \
(error = fn(&str, __VA_ARGS__)) != 0) \
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough
fe07fa6
to
ab4892f
Compare
We have been inconsistent about the way that we handle `git_buf`s provided by users. _Usually_ we require that it has been properly initialized with `GIT_BUF_INIT`, but _sometimes_ we simply overwrite the data in it regardless. And even more rarely, we will grow a user-provided buffer and concatenate data onto it (see `git_diff_format_email`). Document the path forward for `git_buf`, which is that we always require that the buffer is intitialized with `GIT_BUF_INIT`. `git_diff_format_email` will be kept backward compatible but users are encouraged to switch to the new `git_email` APIs.
libgit2 has two distinct requirements that were previously solved by `git_buf`. We require: 1. A general purpose string class that provides a number of utility APIs for manipulating data (eg, concatenating, truncating, etc). 2. A structure that we can use to return strings to callers that they can take ownership of. By using a single class (`git_buf`) for both of these purposes, we have confused the API to the point that refactorings are difficult and reasoning about correctness is also difficult. Move the utility class `git_buf` to be called `git_str`: this represents its general purpose, as an internal string buffer class. The name also is an homage to Junio Hamano ("gitstr"). The public API remains `git_buf`, and has a much smaller footprint. It is generally only used as an "out" param with strict requirements that follow the documentation. (Exceptions exist for some legacy APIs to avoid breaking callers unnecessarily.) Utility functions exist to convert a user-specified `git_buf` to a `git_str` so that we can call internal functions, then converting it back again.
ab4892f
to
f0e693b
Compare
This change is slightly backward incompatible. libgit2 1.4.0 made a chagne to the `git_buf` structure and deprecated a bunch of associated functions, to the effect that `git_buf` is no longer modifiable by users. It is expected that `git_buf` should only be set by libgit2 itself as a return from various functions. So this change to the `data_buffer` class removes all modifier methods. A data_buffer is returned where libgit2 returns a `git_buf`, but we no longer allow the caller to modify the buffer data or grow the buffer. related: libgit2/libgit2#6078 Perhaps we should change methods returning a `data_buffer` to return a `std::string` instead?
To achieve the same result as #5534 (but in a completely opposite way), this makes
git_buf
a public only structure.git_buf
s use in public APIs. This provides documentation as to how the APIs that return data in agit_buf
will behave.git_buf
API from our internal string manipulation functions. The publicgit_buf
is now only for providing a hunk of memory back to a user with a mechanism for them to reliably free it. Our internal string (and buffer) manipulation functions are nowgit_str
.After the work that we did throughout the post-v1.0 releases, point (2) is largely a mechanical exercise.
This introduces some helper functions to (safely) adapt a
git_buf
into agit_str
for use internally.Since many APIs are not strictly public-only (we want to be able to call them internally), this introduces a helpful wrapper function that will allow us to simply produce a wrapper API over our private APIs that expose it with a
git_buf
. This allows us to have a simple private API using agit_str
that is wrapped with agit_buf
without much boilerplate.