Add DiffBlobs
This lets you diff two arbitrary blobs with arbitrary names.
This commit is contained in:
parent
86e9917919
commit
e066d24efb
48
diff.go
48
diff.go
|
@ -5,6 +5,7 @@ package git
|
|||
|
||||
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);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
|
@ -670,3 +671,50 @@ func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff,
|
|||
}
|
||||
return newDiffFromC(diffPtr), nil
|
||||
}
|
||||
|
||||
// DiffBlobs performs a diff between two arbitrary blobs. You can pass
|
||||
// whatever file names you'd like for them to appear as in the diff.
|
||||
func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, opts *DiffOptions, fileCallback DiffForEachFileCallback, detail DiffDetail) error {
|
||||
data := &diffForEachData{
|
||||
FileCallback: fileCallback,
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
var oldBlobPtr, newBlobPtr *C.git_blob
|
||||
if oldBlob != nil {
|
||||
oldBlobPtr = oldBlob.cast_ptr
|
||||
}
|
||||
if newBlob != nil {
|
||||
newBlobPtr = newBlob.cast_ptr
|
||||
}
|
||||
|
||||
oldBlobPath := C.CString(oldAsPath)
|
||||
defer C.free(unsafe.Pointer(oldBlobPath))
|
||||
newBlobPath := C.CString(newAsPath)
|
||||
defer C.free(unsafe.Pointer(newBlobPath))
|
||||
|
||||
copts, _ := diffOptionsToC(opts)
|
||||
defer freeDiffOptions(copts)
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
ecode := C._go_git_diff_blobs(oldBlobPtr, oldBlobPath, newBlobPtr, newBlobPath, copts, 1, intHunks, intLines, handle)
|
||||
if ecode < 0 {
|
||||
return MakeGitError(ecode)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
47
diff_test.go
47
diff_test.go
|
@ -187,3 +187,50 @@ func createTestTrees(t *testing.T, repo *Repository) (originalTree *Tree, newTre
|
|||
|
||||
return originalTree, newTree
|
||||
}
|
||||
|
||||
func TestDiffBlobs(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer cleanupTestRepo(t, repo)
|
||||
|
||||
odb, err := repo.Odb()
|
||||
checkFatal(t, err)
|
||||
|
||||
id1, err := odb.Write([]byte("hello\nhello\n"), ObjectBlob)
|
||||
checkFatal(t, err)
|
||||
|
||||
id2, err := odb.Write([]byte("hallo\nhallo\n"), ObjectBlob)
|
||||
checkFatal(t, err)
|
||||
|
||||
blob1, err := repo.LookupBlob(id1)
|
||||
checkFatal(t, err)
|
||||
|
||||
blob2, err := repo.LookupBlob(id2)
|
||||
checkFatal(t, err)
|
||||
|
||||
var files, hunks, lines int
|
||||
err = DiffBlobs(blob1, "hi", blob2, "hi", nil,
|
||||
func(delta DiffDelta, progress float64) (DiffForEachHunkCallback, error) {
|
||||
files++
|
||||
return func(hunk DiffHunk) (DiffForEachLineCallback, error) {
|
||||
hunks++
|
||||
return func(line DiffLine) error {
|
||||
lines++
|
||||
return nil
|
||||
}, nil
|
||||
}, nil
|
||||
},
|
||||
DiffDetailLines)
|
||||
|
||||
if files != 1 {
|
||||
t.Fatal("Bad number of files iterated")
|
||||
}
|
||||
|
||||
if hunks != 1 {
|
||||
t.Fatal("Bad number of hunks iterated")
|
||||
}
|
||||
|
||||
// two removals, two additions
|
||||
if lines != 4 {
|
||||
t.Fatalf("Bad number of lines iterated")
|
||||
}
|
||||
}
|
||||
|
|
21
wrapper.c
21
wrapper.c
|
@ -62,6 +62,27 @@ int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLin
|
|||
return git_diff_foreach(diff, fcb, hcb, lcb, payload);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)&diffForEachFileCb;
|
||||
}
|
||||
|
||||
if (eachHunk) {
|
||||
hcb = (git_diff_hunk_cb)&diffForEachHunkCb;
|
||||
}
|
||||
|
||||
if (eachLine) {
|
||||
lcb = (git_diff_line_cb)&diffForEachLineCb;
|
||||
}
|
||||
|
||||
return git_diff_blobs(old, old_path, new, new_path, opts, fcb, hcb, lcb, payload);
|
||||
}
|
||||
|
||||
void _go_git_setup_diff_notify_callbacks(git_diff_options *opts) {
|
||||
opts->notify_cb = (git_diff_notify_cb)diffNotifyCb;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue