When marshalling diff callback data to Go structs, any `char*` need to
be pre-emptively copied onto Go's heap as they're invalidated as soon as
our callback function returns. This patch adds this extra copy before
sending the value to the channel, which fixes a bug wherein
`DiffLine.Content`, `DiffFile.Path` and `DiffHunk.Header` would
previously return garbage data.
It is possible that the typed enums from libgit2 should be exported as
distinct types rather than numeric constants (e.g, `git_delta_t` and
`git_line_t` should be typed), but this has not been done in this patch.
This commit adds barebones capacity to generate diffs from two trees and
to emit those as git-style diffs (via `Patch.String`), or to enumerate
the files/hunks/lines in the diff to emit the data yourself.
The walk functions have been implemented in the same manner as the Odb
walking methods.
Note that not all of the functionality is implemented for either the
`git_diff_*` nor the `git_patch_*` functions, and there are unexposed
constants which would likely be useful to add.
The library stores error information in thread-local storage, which
means we need to make sure that the Go runtime doesn't switch OS
threads between the time we call a function and th time we attempt to
retrieve the error information.
The interface to these streams should be what you expect from Go, and
both have Write and Close functions so they implement
Reader/ReadCloser and Write/WriteCloser respectively.
The Library's iterators now can return either the reference or the
reference's name. As the name is what we're set up for, rename the
functions appropriately so we compile against altest development.
Don't name the return values, as they conflict with the names we want
inside and the types don't match what we want to have inside. We need
them to be two-way channels in the function, and then pass
unidirectional references to the different functions.
In case of an error in the writer, the packbuilder will stay around
waiting for someone to read from its channel. The state associated
with a packbuilder is non-trivial and it will keep a reference to the
object, so the GC won't be able to free it.
Change the ForEach interface to also return a "stop" channel. Closing
the channel or writing into it will cause the first receive clause to
act, making the callback to return -1, aborting the operation and
ending the goroutine, freeing its hold on the packbuilder.
Unfortunately libgit2 sometimes returns an error without setting an
error message. Provide an alternative message instead of trying to
dereference nil.