Skip to content
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

Add git_diff_buffers #943

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 51 additions & 0 deletions diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ extern void _go_git_populate_apply_callbacks(git_apply_options *options);
extern int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLine, void *payload);
extern void _go_git_setup_diff_notify_callbacks(git_diff_options* opts);
extern int _go_git_diff_blobs(git_blob *old, const char *old_path, git_blob *new, const char *new_path, git_diff_options *opts, int eachFile, int eachHunk, int eachLine, void *payload);
extern int _go_git_diff_buffers(const void *old_buffer, size_t old_len, const char *old_as_path, const void *new_buffer, size_t new_len, const char *new_as_path, const git_diff_options *opts, int eachFile, int eachHunk, int eachLine, void *payload);

*/
import "C"
import (
Expand Down Expand Up @@ -888,6 +890,55 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string,
return nil
}

// DiffBuffers performs a diff between two arbitrary buffers. You can pass
// whatever file names you'd like for them to appear as in the diff.
func DiffBuffers(oldBuffer []byte, oldAsPath string, newBufer []byte, newAsPath string, opts *DiffOptions, fileCallback DiffForEachFileCallback, detail DiffDetail) error {
var err error
data := &diffForEachCallbackData{
fileCallback: fileCallback,
errorTarget: &err,
}

intHunks := C.int(0)
if detail >= DiffDetailHunks {
intHunks = C.int(1)
}

intLines := C.int(0)
if detail >= DiffDetailLines {
intLines = C.int(1)
}

handle := pointerHandles.Track(data)
defer pointerHandles.Untrack(handle)

cOldBuffer := C.CBytes(oldBuffer)
defer C.free(unsafe.Pointer(cOldBuffer))
cNewBuffer := C.CBytes(newBufer)
defer C.free(unsafe.Pointer(cNewBuffer))

cOldAsPath := C.CString(oldAsPath)
defer C.free(unsafe.Pointer(cOldAsPath))
cNewAsPath := C.CString(newAsPath)
defer C.free(unsafe.Pointer(cNewAsPath))

copts := populateDiffOptions(&C.git_diff_options{}, opts, nil, &err)
defer freeDiffOptions(copts)

runtime.LockOSThread()
defer runtime.UnlockOSThread()

ret := C._go_git_diff_buffers(cOldBuffer, C.size_t(len(oldBuffer)), cOldAsPath, cNewBuffer, C.size_t(len(newBufer)), cNewAsPath, copts, 1, intHunks, intLines, handle)
if ret == C.int(ErrorCodeUser) && err != nil {
return err
}
if ret < 0 {
return MakeGitError(ret)
}

return nil
}

// ApplyHunkCallback is a callback that will be made per delta (file) when applying a patch.
type ApplyHunkCallback func(*DiffHunk) (apply bool, err error)

Expand Down
28 changes: 28 additions & 0 deletions wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,34 @@ int _go_git_diff_blobs(
return git_diff_blobs(old, old_path, new, new_path, opts, fcb, NULL, hcb, lcb, payload);
}

int _go_git_diff_buffers(
const void *old_buffer,
size_t old_len,
const char *old_as_path,
const void *new_buffer,
size_t new_len,
const char *new_as_path,
const git_diff_options *opts,
int eachFile,
int eachHunk,
int eachLine,
void *payload)
{
git_diff_file_cb fcb = NULL;
git_diff_hunk_cb hcb = NULL;
git_diff_line_cb lcb = NULL;

if (eachFile)
fcb = (git_diff_file_cb)&diffForEachFileCallback;
if (eachHunk)
hcb = (git_diff_hunk_cb)&diffForEachHunkCallback;
if (eachLine)
lcb = (git_diff_line_cb)&diffForEachLineCallback;

return git_diff_buffers(old_buffer, old_len, old_as_path, new_buffer, new_len, new_as_path, opts, fcb, NULL, hcb, lcb, payload);
}


void _go_git_setup_diff_notify_callbacks(git_diff_options *opts)
{
opts->notify_cb = (git_diff_notify_cb)&diffNotifyCallback;
Expand Down