diff options
| -rw-r--r-- | .gitmodules | 3 | ||||
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | branch.go | 36 | ||||
| -rw-r--r-- | checkout.go | 15 | ||||
| -rw-r--r-- | cherrypick_test.go | 2 | ||||
| -rw-r--r-- | git.go | 1 | ||||
| -rw-r--r-- | merge.go | 10 | ||||
| -rw-r--r-- | push_test.go | 2 | ||||
| -rw-r--r-- | reference.go | 30 | ||||
| -rw-r--r-- | reference_test.go | 21 | ||||
| -rw-r--r-- | remote.go | 38 | ||||
| -rw-r--r-- | remote_test.go | 15 | ||||
| -rw-r--r-- | repository.go | 61 | ||||
| -rw-r--r-- | reset.go | 26 | ||||
| -rw-r--r-- | reset_test.go | 45 | ||||
| -rw-r--r-- | revparse_test.go | 2 | ||||
| -rwxr-xr-x | script/build-libgit2-static.sh | 19 | ||||
| -rw-r--r-- | script/check-MakeGitError-thread-lock.go | 2 | ||||
| -rwxr-xr-x | script/with-static.sh | 12 | ||||
| -rw-r--r-- | submodule.go | 7 | ||||
| m--------- | vendor/libgit2 | 0 |
22 files changed, 174 insertions, 186 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8eb5872 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vendor/libgit2"] + path = vendor/libgit2 + url = https://github.com/libgit2/libgit2 @@ -1,8 +1,11 @@ default: test -test: +build-libgit2: + ./script/build-libgit2-static.sh + +test: build-libgit2 go run script/check-MakeGitError-thread-lock.go - go test ./... + ./script/with-static.sh go test ./... -install: - go install ./... +install: build-libgit2 + ./script/with-static.sh go install ./... @@ -40,7 +40,7 @@ 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 ----------------- @@ -90,30 +90,16 @@ func (repo *Repository) NewBranchIterator(flags BranchType) (*BranchIterator, er return newBranchIteratorFromC(repo, ptr), nil } -func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool, signature *Signature, msg string) (*Branch, error) { +func (repo *Repository) CreateBranch(branchName string, target *Commit, force bool) (*Branch, error) { ref := new(Reference) cBranchName := C.CString(branchName) cForce := cbool(force) - cSignature, err := signature.toC() - if err != nil { - return nil, err - } - defer C.git_signature_free(cSignature) - - var cmsg *C.char - if msg == "" { - cmsg = nil - } else { - cmsg = C.CString(msg) - defer C.free(unsafe.Pointer(cmsg)) - } - runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_branch_create(&ref.ptr, repo.ptr, cBranchName, target.cast_ptr, cForce, cSignature, cmsg) + ret := C.git_branch_create(&ref.ptr, repo.ptr, cBranchName, target.cast_ptr, cForce) if ret < 0 { return nil, MakeGitError(ret) } @@ -131,29 +117,15 @@ func (b *Branch) Delete() error { return nil } -func (b *Branch) Move(newBranchName string, force bool, signature *Signature, msg string) (*Branch, error) { +func (b *Branch) Move(newBranchName string, force bool) (*Branch, error) { var ptr *C.git_reference cNewBranchName := C.CString(newBranchName) cForce := cbool(force) - cSignature, err := signature.toC() - if err != nil { - return nil, err - } - defer C.git_signature_free(cSignature) - - var cmsg *C.char - if msg == "" { - cmsg = nil - } else { - cmsg = C.CString(msg) - defer C.free(unsafe.Pointer(cmsg)) - } - runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_branch_move(&ptr, b.Reference.ptr, cNewBranchName, cForce, cSignature, cmsg) + ret := C.git_branch_move(&ptr, b.Reference.ptr, cNewBranchName, cForce) if ret < 0 { return nil, MakeGitError(ret) } diff --git a/checkout.go b/checkout.go index 9874d2b..d747344 100644 --- a/checkout.go +++ b/checkout.go @@ -15,18 +15,23 @@ type CheckoutStrategy uint const ( 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 - CheckoutSafeCreate CheckoutStrategy = C.GIT_CHECKOUT_SAFE_CREATE // Allow safe updates plus creation of missing files - CheckoutForce CheckoutStrategy = C.GIT_CHECKOUT_FORCE // Allow all updates to force working directory to look like index + CheckoutRecreateMissing CheckoutStrategy = C.GIT_CHECKOUT_RECREATE_MISSING // Allow checkout to recreate missing files CheckoutAllowConflicts CheckoutStrategy = C.GIT_CHECKOUT_ALLOW_CONFLICTS // Allow checkout to make safe updates even if conflicts are found CheckoutRemoveUntracked CheckoutStrategy = C.GIT_CHECKOUT_REMOVE_UNTRACKED // Remove untracked files not in index (that are not ignored) CheckoutRemoveIgnored CheckoutStrategy = C.GIT_CHECKOUT_REMOVE_IGNORED // Remove ignored files not in index CheckoutUpdateOnly CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_ONLY // Only update existing files, don't create new ones CheckoutDontUpdateIndex CheckoutStrategy = C.GIT_CHECKOUT_DONT_UPDATE_INDEX // Normally checkout updates index entries as it goes; this stops that CheckoutNoRefresh CheckoutStrategy = C.GIT_CHECKOUT_NO_REFRESH // Don't refresh index/config/etc before doing checkout + CheckoutSkipUnmerged CheckoutStrategy = C.GIT_CHECKOUT_SKIP_UNMERGED // Allow checkout to skip unmerged files + CheckoutUserOurs CheckoutStrategy = C.GIT_CHECKOUT_USE_OURS // For unmerged files, checkout stage 2 from index + CheckoutUseTheirs CheckoutStrategy = C.GIT_CHECKOUT_USE_THEIRS // For unmerged files, checkout stage 3 from index CheckoutDisablePathspecMatch CheckoutStrategy = C.GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH // Treat pathspec as simple list of exact match file paths - CheckoutSkipUnmerged CheckoutStrategy = C.GIT_CHECKOUT_SKIP_UNMERGED // Allow checkout to skip unmerged files (NOT IMPLEMENTED) - CheckoutUserOurs CheckoutStrategy = C.GIT_CHECKOUT_USE_OURS // For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED) - CheckoutUseTheirs CheckoutStrategy = C.GIT_CHECKOUT_USE_THEIRS // For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED) + CheckoutSkipLockedDirectories CheckoutStrategy = C.GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES // Ignore directories in use, they will be left empty + CheckoutDontOverwriteIgnored CheckoutStrategy = C.GIT_CHECKOUT_DONT_OVERWRITE_IGNORED // Don't overwrite ignored files that exist in the checkout target + CheckoutConflictStyleMerge CheckoutStrategy = C.GIT_CHECKOUT_CONFLICT_STYLE_MERGE // Write normal merge files for conflicts + CheckoutConflictStyleDiff3 CheckoutStrategy = C.GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 // Include common ancestor data in diff3 format files for conflicts + CheckoutDontRemoveExisting CheckoutStrategy = C.GIT_CHECKOUT_DONT_REMOVE_EXISTING // Don't overwrite existing files or folders + CheckoutDontWriteIndex CheckoutStrategy = C.GIT_CHECKOUT_DONT_WRITE_INDEX // Normally checkout writes the index upon completion; this prevents that CheckoutUpdateSubmodules CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_SUBMODULES // Recursively checkout submodules with same options (NOT IMPLEMENTED) CheckoutUpdateSubmodulesIfChanged CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED // Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) ) diff --git a/cherrypick_test.go b/cherrypick_test.go index 09bc524..a3246bd 100644 --- a/cherrypick_test.go +++ b/cherrypick_test.go @@ -16,7 +16,7 @@ func checkout(t *testing.T, repo *Repository, commit *Commit) { t.Fatal(err) } - err = repo.SetHeadDetached(commit.Id(), commit.Author(), "checkout") + err = repo.SetHeadDetached(commit.Id()) if err != nil { t.Fatal(err) } @@ -3,7 +3,6 @@ package git /* #include <git2.h> #include <git2/sys/openssl.h> -#cgo pkg-config: libgit2 */ import "C" import ( @@ -84,8 +84,8 @@ const ( ) type MergeOptions struct { - Version uint - Flags MergeTreeFlag + Version uint + TreeFlags MergeTreeFlag RenameThreshold uint TargetLimit uint @@ -97,7 +97,7 @@ type MergeOptions struct { func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions { return MergeOptions{ Version: uint(opts.version), - Flags: MergeTreeFlag(opts.flags), + TreeFlags: MergeTreeFlag(opts.tree_flags), RenameThreshold: uint(opts.rename_threshold), TargetLimit: uint(opts.target_limit), FileFavor: MergeFileFavor(opts.file_favor), @@ -123,7 +123,7 @@ func (mo *MergeOptions) toC() *C.git_merge_options { } return &C.git_merge_options{ version: C.uint(mo.Version), - flags: C.git_merge_tree_flag_t(mo.Flags), + tree_flags: C.git_merge_tree_flag_t(mo.TreeFlags), rename_threshold: C.uint(mo.RenameThreshold), target_limit: C.uint(mo.TargetLimit), file_favor: C.git_merge_file_favor_t(mo.FileFavor), @@ -333,7 +333,7 @@ func populateCMergeFileOptions(c *C.git_merge_file_options, options MergeFileOpt c.our_label = C.CString(options.OurLabel) c.their_label = C.CString(options.TheirLabel) c.favor = C.git_merge_file_favor_t(options.Favor) - c.flags = C.git_merge_file_flags_t(options.Flags) + c.flags = C.uint(options.Flags) } func freeCMergeFileOptions(c *C.git_merge_file_options) { diff --git a/push_test.go b/push_test.go index e36e407..4686c65 100644 --- a/push_test.go +++ b/push_test.go @@ -16,7 +16,7 @@ func TestRemotePush(t *testing.T) { seedTestRepo(t, localRepo) - err = remote.Push([]string{"refs/heads/master"}, nil, nil, "") + err = remote.Push([]string{"refs/heads/master"}, nil) checkFatal(t, err) _, err = localRepo.LookupReference("refs/remotes/test_push/master") diff --git a/reference.go b/reference.go index ef12d0b..61e2b26 100644 --- a/reference.go +++ b/reference.go @@ -27,7 +27,7 @@ func newReferenceFromC(ptr *C.git_reference, repo *Repository) *Reference { return ref } -func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) (*Reference, error) { +func (v *Reference) SetSymbolicTarget(target string, msg string) (*Reference, error) { var ptr *C.git_reference ctarget := C.CString(target) @@ -36,12 +36,6 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) runtime.LockOSThread() defer runtime.UnlockOSThread() - csig, err := sig.toC() - if err != nil { - return nil, err - } - defer C.free(unsafe.Pointer(csig)) - var cmsg *C.char if msg == "" { cmsg = nil @@ -50,7 +44,7 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) defer C.free(unsafe.Pointer(cmsg)) } - ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, csig, cmsg) + ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, cmsg) if ret < 0 { return nil, MakeGitError(ret) } @@ -58,18 +52,12 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) return newReferenceFromC(ptr, v.repo), nil } -func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Reference, error) { +func (v *Reference) SetTarget(target *Oid, msg string) (*Reference, error) { var ptr *C.git_reference runtime.LockOSThread() defer runtime.UnlockOSThread() - csig, err := sig.toC() - if err != nil { - return nil, err - } - defer C.free(unsafe.Pointer(csig)) - var cmsg *C.char if msg == "" { cmsg = nil @@ -78,7 +66,7 @@ func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Referen defer C.free(unsafe.Pointer(cmsg)) } - ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), csig, cmsg) + ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), cmsg) if ret < 0 { return nil, MakeGitError(ret) } @@ -100,17 +88,11 @@ func (v *Reference) Resolve() (*Reference, error) { return newReferenceFromC(ptr, v.repo), nil } -func (v *Reference) Rename(name string, force bool, sig *Signature, msg string) (*Reference, error) { +func (v *Reference) Rename(name string, force bool, msg string) (*Reference, error) { var ptr *C.git_reference cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - csig, err := sig.toC() - if err != nil { - return nil, err - } - defer C.free(unsafe.Pointer(csig)) - var cmsg *C.char if msg == "" { cmsg = nil @@ -122,7 +104,7 @@ func (v *Reference) Rename(name string, force bool, sig *Signature, msg string) runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), csig, cmsg) + ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), cmsg) if ret < 0 { return nil, MakeGitError(ret) diff --git a/reference_test.go b/reference_test.go index 5720a66..e891e7a 100644 --- a/reference_test.go +++ b/reference_test.go @@ -13,14 +13,7 @@ func TestRefModification(t *testing.T) { commitId, treeId := seedTestRepo(t, repo) - loc, err := time.LoadLocation("Europe/Berlin") - checkFatal(t, err) - sig := &Signature{ - Name: "Rand Om Hacker", - Email: "[email protected]", - When: time.Date(2013, 03, 06, 14, 30, 0, 0, loc), - } - _, err = repo.CreateReference("refs/tags/tree", treeId, true, sig, "testTreeTag") + _, err := repo.CreateReference("refs/tags/tree", treeId, true, "testTreeTag") checkFatal(t, err) tag, err := repo.LookupReference("refs/tags/tree") @@ -51,7 +44,7 @@ func TestRefModification(t *testing.T) { t.Fatalf("Wrong ref target") } - _, err = tag.Rename("refs/tags/renamed", false, nil, "") + _, err = tag.Rename("refs/tags/renamed", false, "") checkFatal(t, err) tag, err = repo.LookupReference("refs/tags/renamed") checkFatal(t, err) @@ -84,13 +77,13 @@ func TestReferenceIterator(t *testing.T) { commitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree) checkFatal(t, err) - _, err = repo.CreateReference("refs/heads/one", commitId, true, sig, "headOne") + _, err = repo.CreateReference("refs/heads/one", commitId, true, "headOne") checkFatal(t, err) - _, err = repo.CreateReference("refs/heads/two", commitId, true, sig, "headTwo") + _, err = repo.CreateReference("refs/heads/two", commitId, true, "headTwo") checkFatal(t, err) - _, err = repo.CreateReference("refs/heads/three", commitId, true, sig, "headThree") + _, err = repo.CreateReference("refs/heads/three", commitId, true, "headThree") checkFatal(t, err) iter, err := repo.NewReferenceIterator() @@ -143,7 +136,7 @@ func TestReferenceOwner(t *testing.T) { commitId, _ := seedTestRepo(t, repo) - ref, err := repo.CreateReference("refs/heads/foo", commitId, true, nil, "") + ref, err := repo.CreateReference("refs/heads/foo", commitId, true, "") checkFatal(t, err) owner := ref.Owner() @@ -162,7 +155,7 @@ func TestUtil(t *testing.T) { commitId, _ := seedTestRepo(t, repo) - ref, err := repo.CreateReference("refs/heads/foo", commitId, true, nil, "") + ref, err := repo.CreateReference("refs/heads/foo", commitId, true, "") checkFatal(t, err) ref2, err := repo.DwimReference("foo") @@ -598,18 +598,9 @@ func (o *Remote) UpdateFetchHead() bool { // Fetch performs a fetch operation. refspecs specifies which refspecs // to use for this fetch, use an empty list to use the refspecs from -// the configuration; sig and msg specify what to use for the reflog -// entries. Leave nil and "" to use defaults. -func (o *Remote) Fetch(refspecs []string, sig *Signature, msg string) error { - - var csig *C.git_signature = nil - if sig != nil { - csig, err := sig.toC() - if err != nil { - return err - } - defer C.free(unsafe.Pointer(csig)) - } +// the configuration; msg specifies what to use for the reflog +// entries. Leave "" to use defaults. +func (o *Remote) Fetch(refspecs []string, msg string) error { var cmsg *C.char = nil if msg != "" { @@ -625,7 +616,7 @@ func (o *Remote) Fetch(refspecs []string, sig *Signature, msg string) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_remote_fetch(o.ptr, &crefspecs, csig, cmsg) + ret := C.git_remote_fetch(o.ptr, &crefspecs, cmsg) if ret < 0 { return MakeGitError(ret) } @@ -696,24 +687,7 @@ func (o *Remote) Ls(filterRefs ...string) ([]RemoteHead, error) { return heads, nil } -func (o *Remote) Push(refspecs []string, opts *PushOptions, sig *Signature, msg string) error { - var csig *C.git_signature = nil - if sig != nil { - csig, err := sig.toC() - if err != nil { - return err - } - defer C.free(unsafe.Pointer(csig)) - } - - var cmsg *C.char - if msg == "" { - cmsg = nil - } else { - cmsg = C.CString(msg) - defer C.free(unsafe.Pointer(cmsg)) - } - +func (o *Remote) Push(refspecs []string, opts *PushOptions) error { var copts C.git_push_options C.git_push_init_options(&copts, C.GIT_PUSH_OPTIONS_VERSION) if opts != nil { @@ -728,7 +702,7 @@ func (o *Remote) Push(refspecs []string, opts *PushOptions, sig *Signature, msg runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_remote_push(o.ptr, &crefspecs, &copts, csig, cmsg) + ret := C.git_remote_push(o.ptr, &crefspecs, &copts) if ret < 0 { return MakeGitError(ret) } diff --git a/remote_test.go b/remote_test.go index 25ee13d..23c80f5 100644 --- a/remote_test.go +++ b/remote_test.go @@ -3,7 +3,6 @@ package git import ( "fmt" "testing" - "time" ) func TestRefspecs(t *testing.T) { @@ -69,7 +68,7 @@ func TestCertificateCheck(t *testing.T) { err = remote.SetCallbacks(&callbacks) checkFatal(t, err) - err = remote.Fetch([]string{}, nil, "") + err = remote.Fetch([]string{}, "") checkFatal(t, err) } @@ -159,13 +158,7 @@ func TestRemotePrune(t *testing.T) { checkFatal(t, err) defer commit.Free() - sig := &Signature{ - Name: "Rand Om Hacker", - Email: "[email protected]", - When: time.Now(), - } - - remoteRef, err := remoteRepo.CreateBranch("test-prune", commit, true, sig, "branch test-prune") + remoteRef, err := remoteRepo.CreateBranch("test-prune", commit, true) checkFatal(t, err) repo := createTestRepo(t) @@ -179,10 +172,10 @@ func TestRemotePrune(t *testing.T) { remote, err := repo.CreateRemote("origin", remoteUrl) checkFatal(t, err) - err = remote.Fetch([]string{"test-prune"}, sig, "") + err = remote.Fetch([]string{"test-prune"}, "") checkFatal(t, err) - _, err = repo.CreateReference("refs/remotes/origin/test-prune", head, true, sig, "remote reference") + _, err = repo.CreateReference("refs/remotes/origin/test-prune", head, true, "remote reference") checkFatal(t, err) err = remoteRef.Delete() diff --git a/repository.go b/repository.go index 7fac277..9917c60 100644 --- a/repository.go +++ b/repository.go @@ -206,65 +206,35 @@ func (v *Repository) Head() (*Reference, error) { return newReferenceFromC(ptr, v), nil } -func (v *Repository) SetHead(refname string, sig *Signature, msg string) error { +func (v *Repository) SetHead(refname string) error { cname := C.CString(refname) defer C.free(unsafe.Pointer(cname)) - csig, err := sig.toC() - if err != nil { - return err - } - defer C.free(unsafe.Pointer(csig)) - - var cmsg *C.char - if msg != "" { - cmsg = C.CString(msg) - defer C.free(unsafe.Pointer(cmsg)) - } - runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_repository_set_head(v.ptr, cname, csig, cmsg) + ecode := C.git_repository_set_head(v.ptr, cname) if ecode != 0 { return MakeGitError(ecode) } return nil } -func (v *Repository) SetHeadDetached(id *Oid, sig *Signature, msg string) error { - csig, err := sig.toC() - if err != nil { - return err - } - defer C.free(unsafe.Pointer(csig)) - - var cmsg *C.char - if msg != "" { - cmsg = C.CString(msg) - defer C.free(unsafe.Pointer(cmsg)) - } - +func (v *Repository) SetHeadDetached(id *Oid) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_repository_set_head_detached(v.ptr, id.toC(), csig, cmsg) + ecode := C.git_repository_set_head_detached(v.ptr, id.toC()) if ecode != 0 { return MakeGitError(ecode) } return nil } -func (v *Repository) CreateReference(name string, id *Oid, force bool, sig *Signature, msg string) (*Reference, error) { +func (v *Repository) CreateReference(name string, id *Oid, force bool, msg string) (*Reference, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - csig, err := sig.toC() - if err != nil { - return nil, err - } - defer C.free(unsafe.Pointer(csig)) - var cmsg *C.char if msg == "" { cmsg = nil @@ -278,7 +248,7 @@ func (v *Repository) CreateReference(name string, id *Oid, force bool, sig *Sign runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_reference_create(&ptr, v.ptr, cname, id.toC(), cbool(force), csig, cmsg) + ecode := C.git_reference_create(&ptr, v.ptr, cname, id.toC(), cbool(force), cmsg) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -286,19 +256,13 @@ func (v *Repository) CreateReference(name string, id *Oid, force bool, sig *Sign return newReferenceFromC(ptr, v), nil } -func (v *Repository) CreateSymbolicReference(name, target string, force bool, sig *Signature, msg string) (*Reference, error) { +func (v *Repository) CreateSymbolicReference(name, target string, force bool, msg string) (*Reference, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) ctarget := C.CString(target) defer C.free(unsafe.Pointer(ctarget)) - csig, err := sig.toC() - if err != nil { - return nil, err - } - defer C.free(unsafe.Pointer(csig)) - var cmsg *C.char if msg == "" { cmsg = nil @@ -312,7 +276,7 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), csig, cmsg) + ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), cmsg) if ecode < 0 { return nil, MakeGitError(ecode) } @@ -652,16 +616,19 @@ func (v *Repository) RemoveNote(ref string, author, committer *Signature, id *Oi // DefaultNoteRef returns the default notes reference for a repository func (v *Repository) DefaultNoteRef() (string, error) { - var ptr *C.char + buf := C.git_buf{} runtime.LockOSThread() defer runtime.UnlockOSThread() - if ret := C.git_note_default_ref(&ptr, v.ptr); ret < 0 { + if ret := C.git_note_default_ref(&buf, v.ptr); ret < 0 { return "", MakeGitError(ret) } - return C.GoString(ptr), nil + ret := C.GoString(buf.ptr) + C.git_buf_free(&buf) + + return ret, nil } type RepositoryState int diff --git a/reset.go b/reset.go new file mode 100644 index 0000000..b5b7435 --- /dev/null +++ b/reset.go @@ -0,0 +1,26 @@ +package git + +/* +#include <git2.h> +*/ +import "C" +import "runtime" + +type ResetType int + +const ( + ResetSoft ResetType = C.GIT_RESET_SOFT + ResetMixed ResetType = C.GIT_RESET_MIXED + ResetHard ResetType = C.GIT_RESET_HARD +) + +func (r *Repository) ResetToCommit(commit *Commit, resetType ResetType, opts *CheckoutOpts) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + ret := C.git_reset(r.ptr, commit.gitObject.ptr, C.git_reset_t(resetType), opts.toC()) + + if ret < 0 { + return MakeGitError(ret) + } + return nil +} diff --git a/reset_test.go b/reset_test.go new file mode 100644 index 0000000..ec578bd --- /dev/null +++ b/reset_test.go @@ -0,0 +1,45 @@ +package git + +import ( + "io/ioutil" + "testing" +) + +func TestResetToCommit(t *testing.T) { + repo := createTestRepo(t) + seedTestRepo(t, repo) + // create commit to reset to + commitId, _ := updateReadme(t, repo, "testing reset") + // create commit to reset from + nextCommitId, _ := updateReadme(t, repo, "will be reset") + + // confirm that we wrote "will be reset" to the readme + newBytes, err := ioutil.ReadFile(pathInRepo(repo, "README")) + checkFatal(t, err) + if string(newBytes) != "will be reset" { + t.Fatalf("expected %s to equal 'will be reset'", string(newBytes)) + } + + // confirm that the head of the repo is the next commit id + head, err := repo.Head() + checkFatal(t, err) + if head.Target().String() != nextCommitId.String() { + t.Fatalf( + "expected to be at latest commit %s, but was %s", + nextCommitId.String(), + head.Target().String(), + ) + } + + commitToResetTo, err := repo.LookupCommit(commitId) + checkFatal(t, err) + + repo.ResetToCommit(commitToResetTo, ResetHard, &CheckoutOpts{}) + + // check that the file now reads "testing reset" like it did before + bytes, err := ioutil.ReadFile(pathInRepo(repo, "README")) + checkFatal(t, err) + if string(bytes) != "testing reset" { + t.Fatalf("expected %s to equal 'testing reset'", string(bytes)) + } +} diff --git a/revparse_test.go b/revparse_test.go index 2ccdca2..4bc327c 100644 --- a/revparse_test.go +++ b/revparse_test.go @@ -34,7 +34,7 @@ func TestRevparseExt(t *testing.T) { _, treeId := seedTestRepo(t, repo) - ref, err := repo.CreateReference("refs/heads/master", treeId, true, nil, "") + ref, err := repo.CreateReference("refs/heads/master", treeId, true, "") checkFatal(t, err) obj, ref, err := repo.RevparseExt("master") diff --git a/script/build-libgit2-static.sh b/script/build-libgit2-static.sh new file mode 100755 index 0000000..5723721 --- /dev/null +++ b/script/build-libgit2-static.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -ex + +VENDORED_PATH=vendor/libgit2 + +cd $VENDORED_PATH && +mkdir -p install/lib && +mkdir -p build && +cd build && +cmake -DTHREADSAFE=ON \ + -DBUILD_CLAR=OFF \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_C_FLAGS=-fPIC \ + -DCMAKE_BUILD_TYPE="RelWithDebInfo" \ + -DCMAKE_INSTALL_PREFIX=../install \ + .. && + +cmake --build . diff --git a/script/check-MakeGitError-thread-lock.go b/script/check-MakeGitError-thread-lock.go index f6b01b3..77411f7 100644 --- a/script/check-MakeGitError-thread-lock.go +++ b/script/check-MakeGitError-thread-lock.go @@ -1,3 +1,5 @@ +// +build ignore + package main import ( diff --git a/script/with-static.sh b/script/with-static.sh new file mode 100755 index 0000000..3f60e31 --- /dev/null +++ b/script/with-static.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +set -ex + +export BUILD="$PWD/vendor/libgit2/build" +export PCFILE="$BUILD/libgit2.pc" + +FLAGS=$(pkg-config --static --libs $PCFILE) || exit 1 +export CGO_LDFLAGS="$BUILD/libgit2.a -L$BUILD ${FLAGS}" +export CGO_CFLAGS="-I$PWD/vendor/libgit2/include" + +$@ diff --git a/submodule.go b/submodule.go index 3882462..6edc1d7 100644 --- a/submodule.go +++ b/submodule.go @@ -16,7 +16,6 @@ type SubmoduleUpdateOptions struct { *CheckoutOpts *RemoteCallbacks CloneCheckoutStrategy CheckoutStrategy - Signature *Signature } // Submodule @@ -352,11 +351,5 @@ func populateSubmoduleUpdateOptions(ptr *C.git_submodule_update_options, opts *S populateRemoteCallbacks(&ptr.remote_callbacks, opts.RemoteCallbacks) ptr.clone_checkout_strategy = C.uint(opts.CloneCheckoutStrategy) - sig, err := opts.Signature.toC() - if err != nil { - return err - } - ptr.signature = sig - return nil } diff --git a/vendor/libgit2 b/vendor/libgit2 new file mode 160000 +Subproject 4c02d393748d0db382450871ad9ef6898a2ce36 |
