Compare commits
33 Commits
Author | SHA1 | Date |
---|---|---|
|
334260d743 | |
|
bbe9884c35 | |
|
f0554d8c8b | |
|
f37109968c | |
|
68bcb1859a | |
|
5492b49e19 | |
|
1c8297ab83 | |
|
28bc42ce82 | |
|
0b98f7beae | |
|
3cc2126300 | |
|
42a90d4e68 | |
|
c18c8693fe | |
|
4567e4f7fa | |
|
717a47f754 | |
|
e9668545c9 | |
|
2209188637 | |
|
a3c2ac18dc | |
|
c94904ea37 | |
|
ddc1515c8e | |
|
b829eb1edb | |
|
a16e24a99e | |
|
74bc3c6242 | |
|
208cdaef76 | |
|
6ffad323ba | |
|
380684bb10 | |
|
aa7dfab1cf | |
|
c6b94a160e | |
|
6fa4c8ea15 | |
|
a2f93e91d2 | |
|
18802c24e3 | |
|
db6f44c71c | |
|
393098522c | |
|
278dc9ac4f |
|
@ -13,3 +13,9 @@ go:
|
|||
matrix:
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /v\d+/
|
||||
- next
|
||||
|
|
14
Makefile
14
Makefile
|
@ -3,9 +3,19 @@ default: test
|
|||
build-libgit2:
|
||||
./script/build-libgit2-static.sh
|
||||
|
||||
test: build-libgit2
|
||||
test-static: build-libgit2
|
||||
go run script/check-MakeGitError-thread-lock.go
|
||||
go test -tags static ./...
|
||||
|
||||
build-static: build-libgit2
|
||||
go build -tags static ./...
|
||||
|
||||
install-static: build-libgit2
|
||||
go install -tags static ./...
|
||||
|
||||
test:
|
||||
go run script/check-MakeGitError-thread-lock.go
|
||||
go test ./...
|
||||
|
||||
install: build-libgit2
|
||||
install:
|
||||
go install ./...
|
||||
|
|
|
@ -73,6 +73,10 @@ func (i *BranchIterator) ForEach(f BranchIteratorFunc) error {
|
|||
}
|
||||
}
|
||||
|
||||
if err != nil && IsErrorCode(err, ErrIterOver) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
86
checkout.go
86
checkout.go
|
@ -2,6 +2,8 @@ package git
|
|||
|
||||
/*
|
||||
#include <git2.h>
|
||||
|
||||
extern void _go_git_populate_checkout_cb(git_checkout_options *opts);
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
|
@ -10,9 +12,18 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
type CheckoutNotifyType uint
|
||||
type CheckoutStrategy uint
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -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)
|
||||
)
|
||||
|
||||
type CheckoutNotifyCallback func(why CheckoutNotifyType, path string, baseline, target, workdir DiffFile) ErrorCode
|
||||
type CheckoutProgressCallback func(path string, completed, total uint) ErrorCode
|
||||
|
||||
type CheckoutOpts struct {
|
||||
Strategy CheckoutStrategy // Default will be a dry run
|
||||
DisableFilters bool // Don't apply filters like CRLF conversion
|
||||
DirMode os.FileMode // Default is 0755
|
||||
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
||||
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY
|
||||
TargetDirectory string // Alternative checkout path to workdir
|
||||
Paths []string
|
||||
Baseline *Tree
|
||||
Strategy CheckoutStrategy // Default will be a dry run
|
||||
DisableFilters bool // Don't apply filters like CRLF conversion
|
||||
DirMode os.FileMode // Default is 0755
|
||||
FileMode os.FileMode // Default is 0644 or 0755 as dictated by blob
|
||||
FileOpenFlags int // Default is O_CREAT | O_TRUNC | O_WRONLY
|
||||
NotifyFlags CheckoutNotifyType // Default will be none
|
||||
NotifyCallback CheckoutNotifyCallback
|
||||
ProgressCallback CheckoutProgressCallback
|
||||
TargetDirectory string // Alternative checkout path to workdir
|
||||
Paths []string
|
||||
Baseline *Tree
|
||||
}
|
||||
|
||||
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.FileMode = os.FileMode(c.file_mode)
|
||||
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 {
|
||||
opts.TargetDirectory = C.GoString(c.target_directory)
|
||||
}
|
||||
|
@ -70,6 +94,38 @@ func (opts *CheckoutOpts) toC() *C.git_checkout_options {
|
|||
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
|
||||
// C-struct. Returns a pointer to ptr, or nil if opts is nil, in order
|
||||
// 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.dir_mode = C.uint(opts.DirMode.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 != "" {
|
||||
ptr.target_directory = C.CString(opts.TargetDirectory)
|
||||
}
|
||||
|
@ -106,6 +173,9 @@ func freeCheckoutOpts(ptr *C.git_checkout_options) {
|
|||
if ptr.paths.count > 0 {
|
||||
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
|
||||
|
|
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
|
||||
ret := C.git_clone(&ptr, curl, cpath, copts)
|
||||
freeCheckoutOpts(&copts.checkout_opts)
|
||||
|
||||
if ret < 0 {
|
||||
return nil, MakeGitError(ret)
|
||||
|
|
|
@ -44,13 +44,15 @@ func NewCredUserpassPlaintext(username string, password string) (int, Cred) {
|
|||
return int(ret), cred
|
||||
}
|
||||
|
||||
func NewCredSshKey(username string, publickey string, privatekey string, passphrase string) (int, Cred) {
|
||||
// NewCredSshKey creates new ssh credentials reading the public and private keys
|
||||
// from the file system.
|
||||
func NewCredSshKey(username string, publicKeyPath string, privateKeyPath string, passphrase string) (int, Cred) {
|
||||
cred := Cred{}
|
||||
cusername := C.CString(username)
|
||||
defer C.free(unsafe.Pointer(cusername))
|
||||
cpublickey := C.CString(publickey)
|
||||
cpublickey := C.CString(publicKeyPath)
|
||||
defer C.free(unsafe.Pointer(cpublickey))
|
||||
cprivatekey := C.CString(privatekey)
|
||||
cprivatekey := C.CString(privateKeyPath)
|
||||
defer C.free(unsafe.Pointer(cprivatekey))
|
||||
cpassphrase := C.CString(passphrase)
|
||||
defer C.free(unsafe.Pointer(cpassphrase))
|
||||
|
@ -58,6 +60,22 @@ func NewCredSshKey(username string, publickey string, privatekey string, passphr
|
|||
return int(ret), cred
|
||||
}
|
||||
|
||||
// NewCredSshKeyFromMemory creates new ssh credentials using the publicKey and privateKey
|
||||
// arguments as the values for the public and private keys.
|
||||
func NewCredSshKeyFromMemory(username string, publicKey string, privateKey string, passphrase string) (int, Cred) {
|
||||
cred := Cred{}
|
||||
cusername := C.CString(username)
|
||||
defer C.free(unsafe.Pointer(cusername))
|
||||
cpublickey := C.CString(publicKey)
|
||||
defer C.free(unsafe.Pointer(cpublickey))
|
||||
cprivatekey := C.CString(privateKey)
|
||||
defer C.free(unsafe.Pointer(cprivatekey))
|
||||
cpassphrase := C.CString(passphrase)
|
||||
defer C.free(unsafe.Pointer(cpassphrase))
|
||||
ret := C.git_cred_ssh_key_memory_new(&cred.ptr, cusername, cpublickey, cprivatekey, cpassphrase)
|
||||
return int(ret), cred
|
||||
}
|
||||
|
||||
func NewCredSshKeyFromAgent(username string) (int, Cred) {
|
||||
cred := Cred{}
|
||||
cusername := C.CString(username)
|
||||
|
|
4
git.go
4
git.go
|
@ -1,10 +1,6 @@
|
|||
package git
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I${SRCDIR}/vendor/libgit2/include
|
||||
#cgo LDFLAGS: -L${SRCDIR}/vendor/libgit2/build/ -lgit2
|
||||
#cgo windows LDFLAGS: -lwinhttp
|
||||
#cgo !windows pkg-config: --static ${SRCDIR}/vendor/libgit2/build/libgit2.pc
|
||||
#include <git2.h>
|
||||
#include <git2/sys/openssl.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// +build !static
|
||||
|
||||
package git
|
||||
|
||||
/*
|
||||
#cgo pkg-config: libgit2
|
||||
#include <git2.h>
|
||||
*/
|
||||
import "C"
|
|
@ -0,0 +1,11 @@
|
|||
// +build static
|
||||
|
||||
package git
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I${SRCDIR}/vendor/libgit2/include
|
||||
#cgo LDFLAGS: -L${SRCDIR}/vendor/libgit2/build/ -lgit2
|
||||
#cgo windows LDFLAGS: -lwinhttp
|
||||
#cgo !windows pkg-config: --static ${SRCDIR}/vendor/libgit2/build/libgit2.pc
|
||||
*/
|
||||
import "C"
|
16
index.go
16
index.go
|
@ -278,6 +278,22 @@ func (v *Index) RemoveByPath(path string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RemoveDirectory removes all entries from the index under a given directory.
|
||||
func (v *Index) RemoveDirectory(dir string, stage int) error {
|
||||
cstr := C.CString(dir)
|
||||
defer C.free(unsafe.Pointer(cstr))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
ret := C.git_index_remove_directory(v.ptr, cstr, C.int(stage))
|
||||
if ret < 0 {
|
||||
return MakeGitError(ret)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Index) WriteTreeTo(repo *Repository) (*Oid, error) {
|
||||
oid := new(Oid)
|
||||
|
||||
|
|
|
@ -109,6 +109,46 @@ func TestIndexAddAndWriteTreeTo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestIndexRemoveDirectory(t *testing.T) {
|
||||
repo := createTestRepo(t)
|
||||
defer cleanupTestRepo(t, repo)
|
||||
|
||||
odb, err := repo.Odb()
|
||||
checkFatal(t, err)
|
||||
|
||||
blobID, err := odb.Write([]byte("fou\n"), ObjectBlob)
|
||||
checkFatal(t, err)
|
||||
|
||||
idx, err := NewIndex()
|
||||
checkFatal(t, err)
|
||||
|
||||
entryCount := idx.EntryCount()
|
||||
if entryCount != 0 {
|
||||
t.Fatal("Index should count 0 entry")
|
||||
}
|
||||
|
||||
entry := IndexEntry{
|
||||
Path: "path/to/LISEZ_MOI",
|
||||
Id: blobID,
|
||||
Mode: FilemodeBlob,
|
||||
}
|
||||
|
||||
err = idx.Add(&entry)
|
||||
checkFatal(t, err)
|
||||
|
||||
entryCount = idx.EntryCount()
|
||||
if entryCount != 1 {
|
||||
t.Fatal("Index should count 1 entry")
|
||||
}
|
||||
|
||||
err = idx.RemoveDirectory("path", 0)
|
||||
|
||||
entryCount = idx.EntryCount()
|
||||
if entryCount != 0 {
|
||||
t.Fatal("Index should count 0 entry")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexAddAllNoCallback(t *testing.T) {
|
||||
t.Parallel()
|
||||
repo := createTestRepo(t)
|
||||
|
|
4
odb.go
4
odb.go
|
@ -36,8 +36,8 @@ func NewOdb() (odb *Odb, err error) {
|
|||
return odb, nil
|
||||
}
|
||||
|
||||
func NewOdbBackendFromC(ptr *C.git_odb_backend) (backend *OdbBackend) {
|
||||
backend = &OdbBackend{ptr}
|
||||
func NewOdbBackendFromC(ptr unsafe.Pointer) (backend *OdbBackend) {
|
||||
backend = &OdbBackend{(*C.git_odb_backend)(ptr)}
|
||||
return backend
|
||||
}
|
||||
|
||||
|
|
5
refdb.go
5
refdb.go
|
@ -9,6 +9,7 @@ extern void _go_git_refdb_backend_free(git_refdb_backend *backend);
|
|||
import "C"
|
||||
import (
|
||||
"runtime"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Refdb struct {
|
||||
|
@ -34,8 +35,8 @@ func (v *Repository) NewRefdb() (refdb *Refdb, err error) {
|
|||
return refdb, nil
|
||||
}
|
||||
|
||||
func NewRefdbBackendFromC(ptr *C.git_refdb_backend) (backend *RefdbBackend) {
|
||||
backend = &RefdbBackend{ptr}
|
||||
func NewRefdbBackendFromC(ptr unsafe.Pointer) (backend *RefdbBackend) {
|
||||
backend = &RefdbBackend{(*C.git_refdb_backend)(ptr)}
|
||||
return backend
|
||||
}
|
||||
|
||||
|
|
29
remote.go
29
remote.go
|
@ -239,7 +239,7 @@ func completionCallback(completion_type C.git_remote_completion_type, data unsaf
|
|||
func credentialsCallback(_cred **C.git_cred, _url *C.char, _username_from_url *C.char, allowed_types uint, data unsafe.Pointer) int {
|
||||
callbacks, _ := pointerHandles.Get(data).(*RemoteCallbacks)
|
||||
if callbacks.CredentialsCallback == nil {
|
||||
return 0
|
||||
return C.GIT_PASSTHROUGH
|
||||
}
|
||||
url := C.GoString(_url)
|
||||
username_from_url := C.GoString(_username_from_url)
|
||||
|
@ -492,6 +492,26 @@ func (o *Remote) PushUrl() string {
|
|||
return C.GoString(C.git_remote_pushurl(o.ptr))
|
||||
}
|
||||
|
||||
func (c *RemoteCollection) Rename(remote, newname string) ([]string, error) {
|
||||
cproblems := C.git_strarray{}
|
||||
defer freeStrarray(&cproblems)
|
||||
cnewname := C.CString(newname)
|
||||
defer C.free(unsafe.Pointer(cnewname))
|
||||
cremote := C.CString(remote)
|
||||
defer C.free(unsafe.Pointer(cremote))
|
||||
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
ret := C.git_remote_rename(&cproblems, c.repo.ptr, cremote, cnewname)
|
||||
if ret < 0 {
|
||||
return []string{}, MakeGitError(ret)
|
||||
}
|
||||
|
||||
problems := makeStringsFromCStrings(cproblems.strings, int(cproblems.count))
|
||||
return problems, nil
|
||||
}
|
||||
|
||||
func (c *RemoteCollection) SetUrl(remote, url string) error {
|
||||
curl := C.CString(url)
|
||||
defer C.free(unsafe.Pointer(curl))
|
||||
|
@ -730,6 +750,13 @@ func (o *Remote) Connect(direction ConnectDirection, callbacks *RemoteCallbacks,
|
|||
return nil
|
||||
}
|
||||
|
||||
func (o *Remote) Disconnect() {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
C.git_remote_disconnect(o.ptr)
|
||||
}
|
||||
|
||||
func (o *Remote) Ls(filterRefs ...string) ([]RemoteHead, error) {
|
||||
|
||||
var refs **C.git_remote_head
|
||||
|
|
|
@ -13,7 +13,7 @@ if [ "x$TRAVIS_BRANCH" = "xnext" ]; then
|
|||
fi
|
||||
|
||||
cd "${HOME}"
|
||||
LG2VER="0.24.0"
|
||||
LG2VER="0.25.0"
|
||||
wget -O libgit2-${LG2VER}.tar.gz https://github.com/libgit2/libgit2/archive/v${LG2VER}.tar.gz
|
||||
tar -xzvf libgit2-${LG2VER}.tar.gz
|
||||
cd libgit2-${LG2VER} && mkdir build && cd build
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ae5838f118a4819e608990a815bf8fc482be5772
|
||||
Subproject commit 2fcb8705e584ca61f6c4657525c9d2713f6a39d2
|
4
walk.go
4
walk.go
|
@ -173,10 +173,6 @@ func (v *RevWalk) Iterate(fun RevWalkIterator) (err error) {
|
|||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
if err.(GitError).Code == ErrIterOver {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@ void _go_git_populate_remote_cb(git_clone_options *opts)
|
|||
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)
|
||||
{
|
||||
return git_submodule_foreach(repo, (gogit_submodule_cbk)&SubmoduleVisitor, fct);
|
||||
|
|
Loading…
Reference in New Issue