diff options
Diffstat (limited to 'diff.go')
| -rw-r--r-- | diff.go | 219 |
1 files changed, 169 insertions, 50 deletions
@@ -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 - } |
