libgit2/libgit2 — pull request #2101 by arrbee (2014-02-04 21:28:32+00:00)
Title: Add a warning API and use it for bad signatures

The idea here is to add an API for reporting warnings where data appears to be bad but recoverable. For example, having an invalid timestamp in a commit signature or finding a `.gitattributes` file that can't actually be read. In these cases, we are currently faced with either reporting an error and failing in a situation that we could continue from (and Git often would), or ignoring the problem without giving the caller any notice that some questionable data was encountered (and in some cases, returning partially incorrect data as a result - e.g. we have no way of representing a bad signature timestamp, so we would just use a fallback value).

The driver for this is that we've been encountering some cases where libgit2 is more strict that Git for handling some data and I wanted a better option that just ignoring data problems when they are seen.

**This is just as initial take.** I expect that the API will need to change quite a bit before we accept it into libgit2. Currently, I wanted the warning callback to get a lot of data about what was happening, so I tried to shoehorn things into a generic API with a lot of parameters.

Thinking it over, I think there are a number of options to proceed:

1. Use something like I have here with a generic warning signature (probably with fewer parameters than I've specified) and make the warning handler look at the message to decide what to do.
2. Create warning specific structures that get filled in depending on the warning, along with adding the specific warning codes to `include/git2/sys/warning.h` so the callback can know what structure it is looking at.
3. Add some sort of warning/error context stack where we could push data frames (e.g. top frame is a repository object, next frame down is a commit object being loaded, next frame down is the signature object being filled in, final frame is the string being parsed), and then the callback gets the stack of data frames with the option to report the error as desired. This could be useful for errors, too. Obviously this would have to be done with thread-local data.

We'll also have to decide where the warning callback should reside and how it should be set. I've opted to make it a single global value right now. I think that's probably the only good option. I've also opted to set it via `git_libgit2_opts` but I could easily add a setter API directly to `include/git2/sys/warning.h` which would restore type-safety (i.e. I should probably just do that).