Checkout callbacks #321
86
checkout.go
86
checkout.go
|
@ -2,6 +2,8 @@ package git
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
|
extern void _go_git_populate_checkout_cb(git_checkout_options *opts);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
@ -10,9 +12,18 @@ import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CheckoutNotifyType uint
|
||||||
type CheckoutStrategy uint
|
type CheckoutStrategy uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
CheckoutNotifyNone CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_NONE
|
||||||
|
CheckoutNotifyConflict CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_CONFLICT
|
||||||
|
CheckoutNotifyDirty CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_DIRTY
|
||||||
|
CheckoutNotifyUpdated CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_UPDATED
|
||||||
|
CheckoutNotifyUntracked CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_UNTRACKED
|
||||||
|
CheckoutNotifyIgnored CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_IGNORED
|
||||||
|
CheckoutNotifyAll CheckoutNotifyType = C.GIT_CHECKOUT_NOTIFY_ALL
|
||||||
|
|
||||||
CheckoutNone CheckoutStrategy = C.GIT_CHECKOUT_NONE // Dry run, no actual updates
|
CheckoutNone CheckoutStrategy = C.GIT_CHECKOUT_NONE // Dry run, no actual updates
|
||||||
CheckoutSafe CheckoutStrategy = C.GIT_CHECKOUT_SAFE // Allow safe updates that cannot overwrite uncommitted data
|
CheckoutSafe CheckoutStrategy = C.GIT_CHECKOUT_SAFE // Allow safe updates that cannot overwrite uncommitted data
|
||||||
CheckoutForce CheckoutStrategy = C.GIT_CHECKOUT_FORCE // Allow all updates to force working directory to look like index
|
CheckoutForce CheckoutStrategy = C.GIT_CHECKOUT_FORCE // Allow all updates to force working directory to look like index
|
||||||
|
@ -37,15 +48,21 @@ const (
|
||||||
CheckoutUpdateSubmodulesIfChanged CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED // Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED)
|
CheckoutUpdateSubmodulesIfChanged CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED // Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type CheckoutNotifyCallback func(why CheckoutNotifyType, path string, baseline, target, workdir DiffFile) ErrorCode
|
||||||
|
type CheckoutProgressCallback func(path string, completed, total uint) ErrorCode
|
||||||
|
|
||||||
type CheckoutOpts struct {
|
type CheckoutOpts struct {
|
||||||
Strategy CheckoutStrategy // Default will be a dry run
|
Strategy CheckoutStrategy // Default will be a dry run
|
||||||
DisableFilters bool // Don't apply filters like CRLF conversion
|
DisableFilters bool // Don't apply filters like CRLF conversion
|
||||||
DirMode os.FileMode // Default is 0755
|
DirMode os.FileMode // Default is 0755
|
||||||
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
||||||
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY
|
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY
|
||||||
TargetDirectory string // Alternative checkout path to workdir
|
NotifyFlags CheckoutNotifyType // Default will be none
|
||||||
Paths []string
|
NotifyCallback CheckoutNotifyCallback
|
||||||
Baseline *Tree
|
ProgressCallback CheckoutProgressCallback
|
||||||
|
TargetDirectory string // Alternative checkout path to workdir
|
||||||
|
Paths []string
|
||||||
|
Baseline *Tree
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
|
func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
|
||||||
|
@ -55,6 +72,13 @@ func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts {
|
||||||
opts.DirMode = os.FileMode(c.dir_mode)
|
opts.DirMode = os.FileMode(c.dir_mode)
|
||||||
opts.FileMode = os.FileMode(c.file_mode)
|
opts.FileMode = os.FileMode(c.file_mode)
|
||||||
opts.FileOpenFlags = int(c.file_open_flags)
|
opts.FileOpenFlags = int(c.file_open_flags)
|
||||||
|
opts.NotifyFlags = CheckoutNotifyType(c.notify_flags)
|
||||||
|
if c.notify_payload != nil {
|
||||||
|
opts.NotifyCallback = pointerHandles.Get(c.notify_payload).(*CheckoutOpts).NotifyCallback
|
||||||
|
}
|
||||||
|
if c.progress_payload != nil {
|
||||||
|
opts.ProgressCallback = pointerHandles.Get(c.progress_payload).(*CheckoutOpts).ProgressCallback
|
||||||
|
}
|
||||||
if c.target_directory != nil {
|
if c.target_directory != nil {
|
||||||
opts.TargetDirectory = C.GoString(c.target_directory)
|
opts.TargetDirectory = C.GoString(c.target_directory)
|
||||||
}
|
}
|
||||||
|
@ -70,6 +94,38 @@ func (opts *CheckoutOpts) toC() *C.git_checkout_options {
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export checkoutNotifyCallback
|
||||||
|
func checkoutNotifyCallback(why C.git_checkout_notify_t, cpath *C.char, cbaseline, ctarget, cworkdir, data unsafe.Pointer) int {
|
||||||
|
if data == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
path := C.GoString(cpath)
|
||||||
|
var baseline, target, workdir DiffFile
|
||||||
|
if cbaseline != nil {
|
||||||
|
baseline = diffFileFromC((*C.git_diff_file)(cbaseline))
|
||||||
|
}
|
||||||
|
if ctarget != nil {
|
||||||
|
target = diffFileFromC((*C.git_diff_file)(ctarget))
|
||||||
|
}
|
||||||
|
if cworkdir != nil {
|
||||||
|
workdir = diffFileFromC((*C.git_diff_file)(cworkdir))
|
||||||
|
}
|
||||||
|
opts := pointerHandles.Get(data).(*CheckoutOpts)
|
||||||
|
if opts.NotifyCallback == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(opts.NotifyCallback(CheckoutNotifyType(why), path, baseline, target, workdir))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export checkoutProgressCallback
|
||||||
|
func checkoutProgressCallback(path *C.char, completed_steps, total_steps C.size_t, data unsafe.Pointer) int {
|
||||||
|
opts := pointerHandles.Get(data).(*CheckoutOpts)
|
||||||
|
if opts.ProgressCallback == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return int(opts.ProgressCallback(C.GoString(path), uint(completed_steps), uint(total_steps)))
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the CheckoutOpts struct to the corresponding
|
// Convert the CheckoutOpts struct to the corresponding
|
||||||
// C-struct. Returns a pointer to ptr, or nil if opts is nil, in order
|
// C-struct. Returns a pointer to ptr, or nil if opts is nil, in order
|
||||||
// to help with what to pass.
|
// to help with what to pass.
|
||||||
|
@ -83,6 +139,17 @@ func populateCheckoutOpts(ptr *C.git_checkout_options, opts *CheckoutOpts) *C.gi
|
||||||
ptr.disable_filters = cbool(opts.DisableFilters)
|
ptr.disable_filters = cbool(opts.DisableFilters)
|
||||||
ptr.dir_mode = C.uint(opts.DirMode.Perm())
|
ptr.dir_mode = C.uint(opts.DirMode.Perm())
|
||||||
ptr.file_mode = C.uint(opts.FileMode.Perm())
|
ptr.file_mode = C.uint(opts.FileMode.Perm())
|
||||||
|
ptr.notify_flags = C.uint(opts.NotifyFlags)
|
||||||
|
if opts.NotifyCallback != nil || opts.ProgressCallback != nil {
|
||||||
|
C._go_git_populate_checkout_cb(ptr)
|
||||||
|
}
|
||||||
|
payload := pointerHandles.Track(opts)
|
||||||
|
if opts.NotifyCallback != nil {
|
||||||
|
ptr.notify_payload = payload
|
||||||
|
}
|
||||||
|
if opts.ProgressCallback != nil {
|
||||||
|
ptr.progress_payload = payload
|
||||||
|
}
|
||||||
if opts.TargetDirectory != "" {
|
if opts.TargetDirectory != "" {
|
||||||
ptr.target_directory = C.CString(opts.TargetDirectory)
|
ptr.target_directory = C.CString(opts.TargetDirectory)
|
||||||
}
|
}
|
||||||
|
@ -106,6 +173,9 @@ func freeCheckoutOpts(ptr *C.git_checkout_options) {
|
||||||
if ptr.paths.count > 0 {
|
if ptr.paths.count > 0 {
|
||||||
freeStrarray(&ptr.paths)
|
freeStrarray(&ptr.paths)
|
||||||
}
|
}
|
||||||
|
if ptr.notify_payload != nil {
|
||||||
|
pointerHandles.Untrack(ptr.notify_payload)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates files in the index and the working tree to match the content of
|
// Updates files in the index and the working tree to match the content of
|
||||||
|
|
1
clone.go
1
clone.go
|
@ -41,7 +41,6 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error)
|
||||||
|
|
||||||
var ptr *C.git_repository
|
var ptr *C.git_repository
|
||||||
ret := C.git_clone(&ptr, curl, cpath, copts)
|
ret := C.git_clone(&ptr, curl, cpath, copts)
|
||||||
freeCheckoutOpts(&copts.checkout_opts)
|
|
||||||
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, MakeGitError(ret)
|
return nil, MakeGitError(ret)
|
||||||
|
|
|
@ -10,6 +10,12 @@ void _go_git_populate_remote_cb(git_clone_options *opts)
|
||||||
opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
|
opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _go_git_populate_checkout_cb(git_checkout_options *opts)
|
||||||
|
{
|
||||||
|
opts->notify_cb = (git_checkout_notify_cb)checkoutNotifyCallback;
|
||||||
|
opts->progress_cb = (git_checkout_progress_cb)checkoutProgressCallback;
|
||||||
|
}
|
||||||
|
|
||||||
int _go_git_visit_submodule(git_repository *repo, void *fct)
|
int _go_git_visit_submodule(git_repository *repo, void *fct)
|
||||||
{
|
{
|
||||||
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
||||||
|
|
Loading…
Reference in New Issue