diff --git a/README.md b/README.md index d10c46e..b0af2f9 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@ Run `go get -d github.com/libgit2/git2go` to download the code and go to your `$ will compile libgit2 and run `go install` such that it's statically linked to the git2go package. +Paralellism and network operations +---------------------------------- + +libgit2 uses OpenSSL and LibSSH2 for performing encrypted network connections. For now, git2go asks libgit2 to set locking for OpenSSL. This makes HTTPS connections thread-safe, but it is fragile and will likely stop doing it soon. This may also make SSH connections thread-safe if your copy of libssh2 is linked against OpenSSL. Check libgit2's `THREADSAFE.md` for more information. + Running the tests ----------------- diff --git a/diff.go b/diff.go index f762a56..d89a2f9 100644 --- a/diff.go +++ b/diff.go @@ -313,8 +313,8 @@ type DiffOptions struct { Pathspec []string NotifyCallback DiffNotifyCallback - ContextLines uint16 - InterhunkLines uint16 + ContextLines uint32 + InterhunkLines uint32 IdAbbrev uint16 MaxSize int @@ -334,8 +334,8 @@ 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), }, nil @@ -404,8 +404,8 @@ 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), } @@ -453,8 +453,8 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff, 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), } diff --git a/git.go b/git.go index adfa3b0..72d8d03 100644 --- a/git.go +++ b/git.go @@ -93,7 +93,14 @@ var ( ) func init() { - C.git_threads_init() + C.git_libgit2_init() + + // This is not something we should be doing, as we may be + // stomping all over someone else's setup. The user should do + // this themselves or use some binding/wrapper which does it + // in such a way that they can be sure they're the only ones + // setting it up. + C.git_openssl_set_locking() } // Oid represents the id for a Git object. diff --git a/merge.go b/merge.go index 93ac71b..83a682c 100644 --- a/merge.go +++ b/merge.go @@ -4,9 +4,9 @@ package git #include #include -extern git_merge_head** _go_git_make_merge_head_array(size_t len); -extern void _go_git_merge_head_array_set(git_merge_head** array, git_merge_head* ptr, size_t n); -extern git_merge_head* _go_git_merge_head_array_get(git_merge_head** array, size_t n); +extern git_annotated_commit** _go_git_make_merge_head_array(size_t len); +extern void _go_git_annotated_commit_array_set(git_annotated_commit** array, git_annotated_commit* ptr, size_t n); +extern git_annotated_commit* _go_git_annotated_commit_array_get(git_annotated_commit** array, size_t n); */ import "C" @@ -15,23 +15,23 @@ import ( "unsafe" ) -type MergeHead struct { - ptr *C.git_merge_head +type AnnotatedCommit struct { + ptr *C.git_annotated_commit } -func newMergeHeadFromC(c *C.git_merge_head) *MergeHead { - mh := &MergeHead{ptr: c} - runtime.SetFinalizer(mh, (*MergeHead).Free) +func newAnnotatedCommitFromC(c *C.git_annotated_commit) *AnnotatedCommit { + mh := &AnnotatedCommit{ptr: c} + runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return mh } -func (mh *MergeHead) Free() { +func (mh *AnnotatedCommit) Free() { runtime.SetFinalizer(mh, nil) - C.git_merge_head_free(mh.ptr) + C.git_annotated_commit_free(mh.ptr) } -func (r *Repository) MergeHeadFromFetchHead(branchName string, remoteURL string, oid *Oid) (*MergeHead, error) { - mh := &MergeHead{} +func (r *Repository) AnnotatedCommitFromFetchHead(branchName string, remoteURL string, oid *Oid) (*AnnotatedCommit, error) { + mh := &AnnotatedCommit{} cbranchName := C.CString(branchName) defer C.free(unsafe.Pointer(cbranchName)) @@ -39,33 +39,33 @@ func (r *Repository) MergeHeadFromFetchHead(branchName string, remoteURL string, cremoteURL := C.CString(remoteURL) defer C.free(unsafe.Pointer(cremoteURL)) - ret := C.git_merge_head_from_fetchhead(&mh.ptr, r.ptr, cbranchName, cremoteURL, oid.toC()) + ret := C.git_annotated_commit_from_fetchhead(&mh.ptr, r.ptr, cbranchName, cremoteURL, oid.toC()) if ret < 0 { return nil, MakeGitError(ret) } - runtime.SetFinalizer(mh, (*MergeHead).Free) + runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return mh, nil } -func (r *Repository) MergeHeadFromId(oid *Oid) (*MergeHead, error) { - mh := &MergeHead{} +func (r *Repository) LookupAnnotatedCommit(oid *Oid) (*AnnotatedCommit, error) { + mh := &AnnotatedCommit{} - ret := C.git_merge_head_from_id(&mh.ptr, r.ptr, oid.toC()) + ret := C.git_annotated_commit_lookup(&mh.ptr, r.ptr, oid.toC()) if ret < 0 { return nil, MakeGitError(ret) } - runtime.SetFinalizer(mh, (*MergeHead).Free) + runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return mh, nil } -func (r *Repository) MergeHeadFromRef(ref *Reference) (*MergeHead, error) { - mh := &MergeHead{} +func (r *Repository) AnnotatedCommitFromRef(ref *Reference) (*AnnotatedCommit, error) { + mh := &AnnotatedCommit{} - ret := C.git_merge_head_from_ref(&mh.ptr, r.ptr, ref.ptr) + ret := C.git_annotated_commit_from_ref(&mh.ptr, r.ptr, ref.ptr) if ret < 0 { return nil, MakeGitError(ret) } - runtime.SetFinalizer(mh, (*MergeHead).Free) + runtime.SetFinalizer(mh, (*AnnotatedCommit).Free) return mh, nil } @@ -127,19 +127,19 @@ const ( MergeFileFavorUnion MergeFileFavor = C.GIT_MERGE_FILE_FAVOR_UNION ) -func (r *Repository) Merge(theirHeads []*MergeHead, mergeOptions *MergeOptions, checkoutOptions *CheckoutOpts) error { +func (r *Repository) Merge(theirHeads []*AnnotatedCommit, mergeOptions *MergeOptions, checkoutOptions *CheckoutOpts) error { runtime.LockOSThread() defer runtime.UnlockOSThread() cMergeOpts := mergeOptions.toC() cCheckoutOpts := checkoutOptions.toC() - gmerge_head_array := make([]*C.git_merge_head, len(theirHeads)) + gmerge_head_array := make([]*C.git_annotated_commit, len(theirHeads)) for i := 0; i < len(theirHeads); i++ { gmerge_head_array[i] = theirHeads[i].ptr } ptr := unsafe.Pointer(&gmerge_head_array[0]) - err := C.git_merge(r.ptr, (**C.git_merge_head)(ptr), C.size_t(len(theirHeads)), cMergeOpts, cCheckoutOpts) + err := C.git_merge(r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads)), cMergeOpts, cCheckoutOpts) if err < 0 { return MakeGitError(err) } @@ -164,18 +164,18 @@ const ( MergePreferenceFastForwardOnly MergePreference = C.GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY ) -func (r *Repository) MergeAnalysis(theirHeads []*MergeHead) (MergeAnalysis, MergePreference, error) { +func (r *Repository) MergeAnalysis(theirHeads []*AnnotatedCommit) (MergeAnalysis, MergePreference, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - gmerge_head_array := make([]*C.git_merge_head, len(theirHeads)) + gmerge_head_array := make([]*C.git_annotated_commit, len(theirHeads)) for i := 0; i < len(theirHeads); i++ { gmerge_head_array[i] = theirHeads[i].ptr } ptr := unsafe.Pointer(&gmerge_head_array[0]) var analysis C.git_merge_analysis_t var preference C.git_merge_preference_t - err := C.git_merge_analysis(&analysis, &preference, r.ptr, (**C.git_merge_head)(ptr), C.size_t(len(theirHeads))) + err := C.git_merge_analysis(&analysis, &preference, r.ptr, (**C.git_annotated_commit)(ptr), C.size_t(len(theirHeads))) if err < 0 { return MergeAnalysisNone, MergePreferenceNone, MakeGitError(err) } diff --git a/merge_test.go b/merge_test.go index 7e884c0..1eba806 100644 --- a/merge_test.go +++ b/merge_test.go @@ -13,10 +13,10 @@ func TestMergeWithSelf(t *testing.T) { master, err := repo.LookupReference("refs/heads/master") checkFatal(t, err) - mergeHead, err := repo.MergeHeadFromRef(master) + mergeHead, err := repo.AnnotatedCommitFromRef(master) checkFatal(t, err) - mergeHeads := make([]*MergeHead, 1) + mergeHeads := make([]*AnnotatedCommit, 1) mergeHeads[0] = mergeHead err = repo.Merge(mergeHeads, nil, nil) checkFatal(t, err) @@ -30,10 +30,10 @@ func TestMergeAnalysisWithSelf(t *testing.T) { master, err := repo.LookupReference("refs/heads/master") checkFatal(t, err) - mergeHead, err := repo.MergeHeadFromRef(master) + mergeHead, err := repo.AnnotatedCommitFromRef(master) checkFatal(t, err) - mergeHeads := make([]*MergeHead, 1) + mergeHeads := make([]*AnnotatedCommit, 1) mergeHeads[0] = mergeHead a, _, err := repo.MergeAnalysis(mergeHeads) checkFatal(t, err) diff --git a/remote.go b/remote.go index a2288fa..afa3808 100644 --- a/remote.go +++ b/remote.go @@ -318,7 +318,7 @@ func (repo *Repository) CreateAnonymousRemote(url, fetch string) (*Remote, error return remote, nil } -func (repo *Repository) LoadRemote(name string) (*Remote, error) { +func (repo *Repository) LookupRemote(name string) (*Remote, error) { remote := &Remote{} cname := C.CString(name) @@ -327,7 +327,7 @@ func (repo *Repository) LoadRemote(name string) (*Remote, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_remote_load(&remote.ptr, repo.ptr, cname) + ret := C.git_remote_lookup(&remote.ptr, repo.ptr, cname) if ret < 0 { return nil, MakeGitError(ret) } diff --git a/vendor/libgit2 b/vendor/libgit2 index d09458f..169497d 160000 --- a/vendor/libgit2 +++ b/vendor/libgit2 @@ -1 +1 @@ -Subproject commit d09458f3e9f24afa0689ce90b7d4191872372634 +Subproject commit 169497d1e7c238d2925577d1af3dc03e9a507cd3