summaryrefslogtreecommitdiff
path: root/diff.go
diff options
context:
space:
mode:
Diffstat (limited to 'diff.go')
-rw-r--r--diff.go219
1 files changed, 169 insertions, 50 deletions
diff --git a/diff.go b/diff.go
index f762a56..63fa867 100644
--- a/diff.go
+++ b/diff.go
@@ -164,6 +164,72 @@ func (diff *Diff) Free() error {
return nil
}
+func (diff *Diff) FindSimilar(opts *DiffFindOptions) error {
+
+ var copts *C.git_diff_find_options
+ if opts != nil {
+ copts = &C.git_diff_find_options{
+ version: C.GIT_DIFF_FIND_OPTIONS_VERSION,
+ flags: C.uint32_t(opts.Flags),
+ rename_threshold: C.uint16_t(opts.RenameThreshold),
+ copy_threshold: C.uint16_t(opts.CopyThreshold),
+ rename_from_rewrite_threshold: C.uint16_t(opts.RenameFromRewriteThreshold),
+ break_rewrite_threshold: C.uint16_t(opts.BreakRewriteThreshold),
+ rename_limit: C.size_t(opts.RenameLimit),
+ }
+ }
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_diff_find_similar(diff.ptr, copts)
+ if ecode < 0 {
+ return MakeGitError(ecode)
+ }
+
+ return nil
+}
+
+type DiffStats struct {
+ ptr *C.git_diff_stats
+}
+
+func (stats *DiffStats) Free() error {
+ if stats.ptr == nil {
+ return ErrInvalid
+ }
+ runtime.SetFinalizer(stats, nil)
+ C.git_diff_stats_free(stats.ptr)
+ stats.ptr = nil
+ return nil
+}
+
+func (stats *DiffStats) Insertions() int {
+ return int(C.git_diff_stats_insertions(stats.ptr))
+}
+
+func (stats *DiffStats) Deletions() int {
+ return int(C.git_diff_stats_deletions(stats.ptr))
+}
+
+func (stats *DiffStats) FilesChanged() int {
+ return int(C.git_diff_stats_files_changed(stats.ptr))
+}
+
+func (diff *Diff) Stats() (*DiffStats, error) {
+ stats := new(DiffStats)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ if ecode := C.git_diff_get_stats(&stats.ptr, diff.ptr); ecode < 0 {
+ return nil, MakeGitError(ecode)
+ }
+ runtime.SetFinalizer(stats, (*DiffStats).Free)
+
+ return stats, nil
+}
+
type diffForEachData struct {
FileCallback DiffForEachFileCallback
HunkCallback DiffForEachHunkCallback
@@ -264,6 +330,9 @@ func (diff *Diff) Patch(deltaIndex int) (*Patch, error) {
}
var patchPtr *C.git_patch
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
ecode := C.git_patch_from_diff(&patchPtr, diff.ptr, C.size_t(deltaIndex))
if ecode < 0 {
return nil, MakeGitError(ecode)
@@ -313,8 +382,8 @@ type DiffOptions struct {
Pathspec []string
NotifyCallback DiffNotifyCallback
- ContextLines uint16
- InterhunkLines uint16
+ ContextLines uint32
+ InterhunkLines uint32
IdAbbrev uint16
MaxSize int
@@ -325,6 +394,10 @@ type DiffOptions struct {
func DefaultDiffOptions() (DiffOptions, error) {
opts := C.git_diff_options{}
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
ecode := C.git_diff_init_options(&opts, C.GIT_DIFF_OPTIONS_VERSION)
if ecode < 0 {
return DiffOptions{}, MakeGitError(ecode)
@@ -334,10 +407,64 @@ func DefaultDiffOptions() (DiffOptions, error) {
Flags: DiffOptionsFlag(opts.flags),
IgnoreSubmodules: SubmoduleIgnore(opts.ignore_submodules),
Pathspec: makeStringsFromCStrings(opts.pathspec.strings, int(opts.pathspec.count)),
- ContextLines: uint16(opts.context_lines),
- InterhunkLines: uint16(opts.interhunk_lines),
+ ContextLines: uint32(opts.context_lines),
+ InterhunkLines: uint32(opts.interhunk_lines),
IdAbbrev: uint16(opts.id_abbrev),
MaxSize: int(opts.max_size),
+ OldPrefix: "a",
+ NewPrefix: "b",
+ }, nil
+}
+
+type DiffFindOptionsFlag int
+
+const (
+ DiffFindByConfig DiffFindOptionsFlag = C.GIT_DIFF_FIND_BY_CONFIG
+ DiffFindRenames DiffFindOptionsFlag = C.GIT_DIFF_FIND_RENAMES
+ DiffFindRenamesFromRewrites DiffFindOptionsFlag = C.GIT_DIFF_FIND_RENAMES_FROM_REWRITES
+ DiffFindCopies DiffFindOptionsFlag = C.GIT_DIFF_FIND_COPIES
+ DiffFindCopiesFromUnmodified DiffFindOptionsFlag = C.GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED
+ DiffFindRewrites DiffFindOptionsFlag = C.GIT_DIFF_FIND_REWRITES
+ DiffFindBreakRewrites DiffFindOptionsFlag = C.GIT_DIFF_BREAK_REWRITES
+ DiffFindAndBreakRewrites DiffFindOptionsFlag = C.GIT_DIFF_FIND_AND_BREAK_REWRITES
+ DiffFindForUntracked DiffFindOptionsFlag = C.GIT_DIFF_FIND_FOR_UNTRACKED
+ DiffFindAll DiffFindOptionsFlag = C.GIT_DIFF_FIND_ALL
+ DiffFindIgnoreLeadingWhitespace DiffFindOptionsFlag = C.GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE
+ DiffFindIgnoreWhitespace DiffFindOptionsFlag = C.GIT_DIFF_FIND_IGNORE_WHITESPACE
+ DiffFindDontIgnoreWhitespace DiffFindOptionsFlag = C.GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE
+ DiffFindExactMatchOnly DiffFindOptionsFlag = C.GIT_DIFF_FIND_EXACT_MATCH_ONLY
+ DiffFindBreakRewritesForRenamesOnly DiffFindOptionsFlag = C.GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY
+ DiffFindRemoveUnmodified DiffFindOptionsFlag = C.GIT_DIFF_FIND_REMOVE_UNMODIFIED
+)
+
+//TODO implement git_diff_similarity_metric
+type DiffFindOptions struct {
+ Flags DiffFindOptionsFlag
+ RenameThreshold uint16
+ CopyThreshold uint16
+ RenameFromRewriteThreshold uint16
+ BreakRewriteThreshold uint16
+ RenameLimit uint
+}
+
+func DefaultDiffFindOptions() (DiffFindOptions, error) {
+ opts := C.git_diff_find_options{}
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+
+ ecode := C.git_diff_find_init_options(&opts, C.GIT_DIFF_FIND_OPTIONS_VERSION)
+ if ecode < 0 {
+ return DiffFindOptions{}, MakeGitError(ecode)
+ }
+
+ return DiffFindOptions{
+ Flags: DiffFindOptionsFlag(opts.flags),
+ RenameThreshold: uint16(opts.rename_threshold),
+ CopyThreshold: uint16(opts.copy_threshold),
+ RenameFromRewriteThreshold: uint16(opts.rename_from_rewrite_threshold),
+ BreakRewriteThreshold: uint16(opts.break_rewrite_threshold),
+ RenameLimit: uint(opts.rename_limit),
}, nil
}
@@ -374,21 +501,8 @@ func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, m
return 0
}
-func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (*Diff, error) {
- var diffPtr *C.git_diff
- var oldPtr, newPtr *C.git_tree
-
- if oldTree != nil {
- oldPtr = oldTree.cast_ptr
- }
-
- if newTree != nil {
- newPtr = newTree.cast_ptr
- }
-
+func diffOptionsToC(opts *DiffOptions) (copts *C.git_diff_options, notifyData *diffNotifyData) {
cpathspec := C.git_strarray{}
- var copts *C.git_diff_options
- var notifyData *diffNotifyData
if opts != nil {
notifyData = &diffNotifyData{
Callback: opts.NotifyCallback,
@@ -396,7 +510,6 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (
if opts.Pathspec != nil {
cpathspec.count = C.size_t(len(opts.Pathspec))
cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
- defer freeStrarray(&cpathspec)
}
copts = &C.git_diff_options{
@@ -404,10 +517,12 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (
flags: C.uint32_t(opts.Flags),
ignore_submodules: C.git_submodule_ignore_t(opts.IgnoreSubmodules),
pathspec: cpathspec,
- context_lines: C.uint16_t(opts.ContextLines),
- interhunk_lines: C.uint16_t(opts.InterhunkLines),
+ context_lines: C.uint32_t(opts.ContextLines),
+ interhunk_lines: C.uint32_t(opts.InterhunkLines),
id_abbrev: C.uint16_t(opts.IdAbbrev),
max_size: C.git_off_t(opts.MaxSize),
+ old_prefix: C.CString(opts.OldPrefix),
+ new_prefix: C.CString(opts.NewPrefix),
}
if opts.NotifyCallback != nil {
@@ -415,6 +530,35 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (
copts.notify_payload = unsafe.Pointer(notifyData)
}
}
+ return
+}
+
+func freeDiffOptions(copts *C.git_diff_options) {
+ if copts != nil {
+ cpathspec := copts.pathspec
+ freeStrarray(&cpathspec)
+ C.free(unsafe.Pointer(copts.old_prefix))
+ C.free(unsafe.Pointer(copts.new_prefix))
+ }
+}
+
+func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (*Diff, error) {
+ var diffPtr *C.git_diff
+ var oldPtr, newPtr *C.git_tree
+
+ if oldTree != nil {
+ oldPtr = oldTree.cast_ptr
+ }
+
+ if newTree != nil {
+ newPtr = newTree.cast_ptr
+ }
+
+ copts, notifyData := diffOptionsToC(opts)
+ defer freeDiffOptions(copts)
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
ecode := C.git_diff_tree_to_tree(&diffPtr, v.ptr, oldPtr, newPtr, copts)
if ecode < 0 {
@@ -435,35 +579,11 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff,
oldPtr = oldTree.cast_ptr
}
- cpathspec := C.git_strarray{}
- var copts *C.git_diff_options
- var notifyData *diffNotifyData
- if opts != nil {
- notifyData = &diffNotifyData{
- Callback: opts.NotifyCallback,
- }
- if opts.Pathspec != nil {
- cpathspec.count = C.size_t(len(opts.Pathspec))
- cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
- defer freeStrarray(&cpathspec)
- }
+ copts, notifyData := diffOptionsToC(opts)
+ defer freeDiffOptions(copts)
- copts = &C.git_diff_options{
- version: C.GIT_DIFF_OPTIONS_VERSION,
- flags: C.uint32_t(opts.Flags),
- ignore_submodules: C.git_submodule_ignore_t(opts.IgnoreSubmodules),
- pathspec: cpathspec,
- context_lines: C.uint16_t(opts.ContextLines),
- interhunk_lines: C.uint16_t(opts.InterhunkLines),
- id_abbrev: C.uint16_t(opts.IdAbbrev),
- max_size: C.git_off_t(opts.MaxSize),
- }
-
- if opts.NotifyCallback != nil {
- C._go_git_setup_diff_notify_callbacks(copts)
- copts.notify_payload = unsafe.Pointer(notifyData)
- }
- }
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
ecode := C.git_diff_tree_to_workdir(&diffPtr, v.ptr, oldPtr, copts)
if ecode < 0 {
@@ -474,5 +594,4 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff,
return notifyData.Diff, nil
}
return newDiffFromC(diffPtr), nil
-
}