2014-02-20 00:25:30 -06:00
|
|
|
package git
|
|
|
|
|
|
|
|
/*
|
|
|
|
#include <git2.h>
|
|
|
|
|
|
|
|
extern int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLine, void *payload);
|
|
|
|
*/
|
|
|
|
import "C"
|
|
|
|
import (
|
|
|
|
"runtime"
|
|
|
|
"unsafe"
|
|
|
|
)
|
|
|
|
|
2014-02-26 04:34:38 -06:00
|
|
|
type DiffFlag int
|
2014-02-26 05:58:45 -06:00
|
|
|
const (
|
2014-02-26 16:01:32 -06:00
|
|
|
DiffFlagBinary = DiffFlag(C.GIT_DIFF_FLAG_BINARY)
|
2014-02-26 05:58:45 -06:00
|
|
|
DiffFlagNotBinary = C.GIT_DIFF_FLAG_NOT_BINARY
|
|
|
|
DiffFlagValidOid = C.GIT_DIFF_FLAG_VALID_OID
|
|
|
|
)
|
2014-02-26 04:34:38 -06:00
|
|
|
|
2014-02-26 05:58:45 -06:00
|
|
|
type Delta int
|
2014-02-23 18:04:55 -06:00
|
|
|
const (
|
2014-02-26 16:01:32 -06:00
|
|
|
DeltaUnmodified = Delta(C.GIT_DELTA_UNMODIFIED)
|
2014-02-26 05:58:45 -06:00
|
|
|
DeltaAdded = C.GIT_DELTA_ADDED
|
|
|
|
DeltaDeleted = C.GIT_DELTA_DELETED
|
|
|
|
DeltaModified = C.GIT_DELTA_MODIFIED
|
|
|
|
DeltaRenamed = C.GIT_DELTA_RENAMED
|
|
|
|
DeltaCopied = C.GIT_DELTA_COPIED
|
|
|
|
DeltaIgnored = C.GIT_DELTA_IGNORED
|
|
|
|
DeltaUntracked = C.GIT_DELTA_UNTRACKED
|
|
|
|
DeltaTypeChange = C.GIT_DELTA_TYPECHANGE
|
|
|
|
)
|
2014-02-23 18:04:55 -06:00
|
|
|
|
2014-02-26 05:58:45 -06:00
|
|
|
type DiffLineType int
|
|
|
|
const (
|
2014-02-26 16:01:32 -06:00
|
|
|
DiffLineContext = DiffLineType(C.GIT_DIFF_LINE_CONTEXT)
|
2014-02-23 18:04:55 -06:00
|
|
|
DiffLineAddition = C.GIT_DIFF_LINE_ADDITION
|
|
|
|
DiffLineDeletion = C.GIT_DIFF_LINE_DELETION
|
|
|
|
DiffLineContextEOFNL = C.GIT_DIFF_LINE_CONTEXT_EOFNL
|
|
|
|
DiffLineAddEOFNL = C.GIT_DIFF_LINE_ADD_EOFNL
|
|
|
|
DiffLineDelEOFNL = C.GIT_DIFF_LINE_DEL_EOFNL
|
|
|
|
|
|
|
|
DiffLineFileHdr = C.GIT_DIFF_LINE_FILE_HDR
|
|
|
|
DiffLineHunkHdr = C.GIT_DIFF_LINE_HUNK_HDR
|
|
|
|
DiffLineBinary = C.GIT_DIFF_LINE_BINARY
|
|
|
|
)
|
|
|
|
|
2014-02-20 00:25:30 -06:00
|
|
|
type DiffFile struct {
|
2014-02-23 18:49:04 -06:00
|
|
|
Path string
|
2014-02-26 16:01:32 -06:00
|
|
|
Oid *Oid
|
|
|
|
Size int
|
|
|
|
Flags DiffFlag
|
|
|
|
Mode uint16
|
2014-02-20 00:25:30 -06:00
|
|
|
}
|
|
|
|
|
2014-02-23 18:49:04 -06:00
|
|
|
func newDiffFile(file *C.git_diff_file) *DiffFile {
|
|
|
|
return &DiffFile{
|
|
|
|
Path: C.GoString(file.path),
|
2014-02-26 16:01:32 -06:00
|
|
|
Oid: newOidFromC(&file.oid),
|
|
|
|
Size: int(file.size),
|
|
|
|
Flags: DiffFlag(file.flags),
|
|
|
|
Mode: uint16(file.mode),
|
2014-02-23 18:49:04 -06:00
|
|
|
}
|
2014-02-20 00:25:30 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type DiffDelta struct {
|
2014-02-26 16:01:32 -06:00
|
|
|
Status Delta
|
|
|
|
Flags DiffFlag
|
|
|
|
Similarity uint16
|
2014-02-23 18:49:04 -06:00
|
|
|
OldFile *DiffFile
|
|
|
|
NewFile *DiffFile
|
|
|
|
}
|
|
|
|
|
|
|
|
func newDiffDelta(delta *C.git_diff_delta) *DiffDelta {
|
|
|
|
return &DiffDelta{
|
2014-02-26 16:01:32 -06:00
|
|
|
Status: Delta(delta.status),
|
|
|
|
Flags: DiffFlag(delta.flags),
|
|
|
|
Similarity: uint16(delta.similarity),
|
2014-02-23 18:49:04 -06:00
|
|
|
OldFile: newDiffFile(&delta.old_file),
|
|
|
|
NewFile: newDiffFile(&delta.new_file),
|
|
|
|
}
|
2014-02-20 00:25:30 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
type DiffHunk struct {
|
2014-02-26 16:01:32 -06:00
|
|
|
OldStart int
|
|
|
|
OldLines int
|
|
|
|
NewStart int
|
|
|
|
NewLines int
|
2014-02-23 18:49:04 -06:00
|
|
|
Header string
|
2014-02-20 00:25:30 -06:00
|
|
|
DiffDelta
|
|
|
|
}
|
|
|
|
|
2014-02-23 18:49:04 -06:00
|
|
|
func newDiffHunk(delta *C.git_diff_delta, hunk *C.git_diff_hunk) *DiffHunk {
|
|
|
|
return &DiffHunk{
|
2014-02-26 16:01:32 -06:00
|
|
|
OldStart: int(hunk.old_start),
|
|
|
|
OldLines: int(hunk.old_lines),
|
|
|
|
NewStart: int(hunk.new_start),
|
|
|
|
NewLines: int(hunk.new_lines),
|
2014-02-23 18:49:04 -06:00
|
|
|
Header: C.GoStringN(&hunk.header[0], C.int(hunk.header_len)),
|
|
|
|
DiffDelta: *newDiffDelta(delta),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-20 00:25:30 -06:00
|
|
|
type DiffLine struct {
|
2014-02-26 05:58:45 -06:00
|
|
|
Origin DiffLineType
|
2014-02-26 04:34:38 -06:00
|
|
|
OldLineno int
|
|
|
|
NewLineno int
|
|
|
|
NumLines int
|
2014-02-23 18:49:04 -06:00
|
|
|
Content string
|
2014-02-20 00:25:30 -06:00
|
|
|
DiffHunk
|
|
|
|
}
|
|
|
|
|
2014-02-23 18:49:04 -06:00
|
|
|
func newDiffLine(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line) *DiffLine {
|
|
|
|
return &DiffLine{
|
2014-02-26 05:58:45 -06:00
|
|
|
Origin: DiffLineType(line.origin),
|
2014-02-26 04:34:38 -06:00
|
|
|
OldLineno: int(line.old_lineno),
|
|
|
|
NewLineno: int(line.new_lineno),
|
|
|
|
NumLines: int(line.num_lines),
|
2014-02-23 18:49:04 -06:00
|
|
|
Content: C.GoStringN(line.content, C.int(line.content_len)),
|
|
|
|
DiffHunk: *newDiffHunk(delta, hunk),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-20 00:25:30 -06:00
|
|
|
type Diff struct {
|
|
|
|
ptr *C.git_diff
|
|
|
|
}
|
|
|
|
|
|
|
|
func newDiff(ptr *C.git_diff) *Diff {
|
|
|
|
if ptr == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
diff := &Diff{
|
|
|
|
ptr: ptr,
|
|
|
|
}
|
|
|
|
|
|
|
|
runtime.SetFinalizer(diff, (*Diff).Free)
|
|
|
|
return diff
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) Free() {
|
|
|
|
runtime.SetFinalizer(diff, nil)
|
|
|
|
C.git_diff_free(diff.ptr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) forEachFileWrap(ch chan *DiffDelta) {
|
|
|
|
C._go_git_diff_foreach(diff.ptr, 1, 0, 0, unsafe.Pointer(&ch))
|
|
|
|
close(ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) ForEachFile() chan *DiffDelta {
|
|
|
|
ch := make(chan *DiffDelta, 0)
|
|
|
|
go diff.forEachFileWrap(ch)
|
|
|
|
return ch
|
|
|
|
}
|
|
|
|
|
|
|
|
//export diffForEachFileCb
|
|
|
|
func diffForEachFileCb(delta *C.git_diff_delta, progress C.float, payload unsafe.Pointer) int {
|
|
|
|
ch := *(*chan *DiffDelta)(payload)
|
|
|
|
|
|
|
|
select {
|
2014-02-23 18:49:04 -06:00
|
|
|
case ch <-newDiffDelta(delta):
|
2014-02-20 00:25:30 -06:00
|
|
|
case <-ch:
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) forEachHunkWrap(ch chan *DiffHunk) {
|
|
|
|
C._go_git_diff_foreach(diff.ptr, 0, 1, 0, unsafe.Pointer(&ch))
|
|
|
|
close(ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) ForEachHunk() chan *DiffHunk {
|
|
|
|
ch := make(chan *DiffHunk, 0)
|
|
|
|
go diff.forEachHunkWrap(ch)
|
|
|
|
return ch
|
|
|
|
}
|
|
|
|
|
|
|
|
//export diffForEachHunkCb
|
|
|
|
func diffForEachHunkCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, payload unsafe.Pointer) int {
|
|
|
|
ch := *(*chan *DiffHunk)(payload)
|
|
|
|
|
|
|
|
select {
|
2014-02-23 18:49:04 -06:00
|
|
|
case ch <-newDiffHunk(delta, hunk):
|
2014-02-20 00:25:30 -06:00
|
|
|
case <-ch:
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) forEachLineWrap(ch chan *DiffLine) {
|
|
|
|
C._go_git_diff_foreach(diff.ptr, 0, 0, 1, unsafe.Pointer(&ch))
|
|
|
|
close(ch)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) ForEachLine() chan *DiffLine {
|
|
|
|
ch := make(chan *DiffLine, 0)
|
|
|
|
go diff.forEachLineWrap(ch)
|
|
|
|
return ch
|
|
|
|
}
|
|
|
|
|
|
|
|
//export diffForEachLineCb
|
|
|
|
func diffForEachLineCb(delta *C.git_diff_delta, hunk *C.git_diff_hunk, line *C.git_diff_line, payload unsafe.Pointer) int {
|
|
|
|
ch := *(*chan *DiffLine)(payload)
|
|
|
|
|
|
|
|
select {
|
2014-02-23 18:49:04 -06:00
|
|
|
case ch <-newDiffLine(delta, hunk, line):
|
2014-02-20 00:25:30 -06:00
|
|
|
case <-ch:
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) NumDeltas() int {
|
|
|
|
return int(C.git_diff_num_deltas(diff.ptr))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) GetDelta(index int) *DiffDelta {
|
|
|
|
ptr := C.git_diff_get_delta(diff.ptr, C.size_t(index))
|
|
|
|
if ptr == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-02-23 18:49:04 -06:00
|
|
|
return newDiffDelta(ptr)
|
2014-02-20 00:25:30 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (diff *Diff) Patch(deltaIndex int) *Patch {
|
|
|
|
var patchPtr *C.git_patch
|
|
|
|
|
|
|
|
C.git_patch_from_diff(&patchPtr, diff.ptr, C.size_t(deltaIndex))
|
|
|
|
|
|
|
|
return newPatch(patchPtr)
|
|
|
|
}
|