From 57412d0293fa4d84bab60590aa9e4589f706ff0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Wed, 14 Jan 2015 14:11:19 +0100 Subject: [PATCH 01/17] Explain the difference between dynamic and static versions With the release of libgit2 v0.22 we can link against a version of library we've wrapped in more than a PoC sense. Explain the difference and say how to use each version. --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9995707..faeb5f5 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,24 @@ git2go [![GoDoc](https://godoc.org/github.com/libgit2/git2go?status.svg)](http://godoc.org/github.com/libgit2/git2go) [![Build Status](https://travis-ci.org/libgit2/git2go.svg?branch=master)](https://travis-ci.org/libgit2/git2go) -Go bindings for [libgit2](http://libgit2.github.com/). The master branch follows the latest libgit2 release. +Go bindings for [libgit2](http://libgit2.github.com/). The master branch follows the latest libgit2 release. The versioned branches indicate which libgit2 version they work against. Installing ---------- -This project needs libgit2, which is written in C so we need to build that as well. In order to build libgit2, you need `cmake`, `pkg-config` and a C compiler. You will also need the development packages for OpenSSL and LibSSH2 if you want to use HTTPS and SSH respectively. +This project needs libgit2, which is written in C so we need to build that as well. In order to build libgit2, you need `cmake`, `pkg-config` and a C compiler. You will also need the development packages for OpenSSL and LibSSH2 installed if you want libgit2 to support HTTPS and SSH respectively. + +### Stable version + +git2go has versioned branches which indicate which version of libgit2 they work against. Install the development package it on your system via your favourite package manager or from source and you can use a service like gopkg.in to use the appropriate version. For the libgit2 v0.22 case, you can use + + import "gopkg.in/libgit2/git2go.v22" + +to use a version of git2go which will work against libgit2 v0.22 and dynamically link to the library. + +### From master + +The master branch follows libgit2's master branch, which means there is no stable API or ABI to link against. git2go can statically link against a vendored version of libgit2. Run `go get -d github.com/libgit2/git2go` to download the code and go to your `$GOPATH/src/github.com/libgit2/git2go` dir. From there, we need to build the C code and put it into the resulting go binary. @@ -25,7 +37,7 @@ libgit2 uses OpenSSL and LibSSH2 for performing encrypted network connections. F Running the tests ----------------- -Similarly to installing, running the tests requires linking against the local libgit2 library, so the Makefile provides a wrapper +For the stable version, `go test` will work as usual. For the master branch, similarly to installing, running the tests requires linking against the local libgit2 library, so the Makefile provides a wrapper make test From 548bb9b5e9161fe876eeb3c23ceae061840cb532 Mon Sep 17 00:00:00 2001 From: Tarrant Rollins Date: Tue, 13 Jan 2015 19:48:45 -0800 Subject: [PATCH 02/17] Add Go functions for git_config_find_* functions ConfigFindGlobal -> git_config_find_global ConfigFindSystem -> git_config_find_system ConfigFindXDG -> git_config_find_xdg --- config.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/config.go b/config.go index 2965a69..9d25e35 100644 --- a/config.go +++ b/config.go @@ -35,14 +35,14 @@ const ( ) type ConfigEntry struct { - Name string + Name string Value string Level ConfigLevel } func newConfigEntryFromC(centry *C.git_config_entry) *ConfigEntry { return &ConfigEntry{ - Name: C.GoString(centry.name), + Name: C.GoString(centry.name), Value: C.GoString(centry.value), Level: ConfigLevel(centry.level), } @@ -74,7 +74,6 @@ func (c *Config) AddFile(path string, level ConfigLevel, force bool) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_config_add_file_ondisk(c.ptr, cpath, C.git_config_level_t(level), cbool(force)) if ret < 0 { return MakeGitError(ret) @@ -130,7 +129,6 @@ func (c *Config) LookupString(name string) (string, error) { return C.GoString(ptr), nil } - func (c *Config) LookupBool(name string) (bool, error) { var out C.int cname := C.CString(name) @@ -234,7 +232,6 @@ func (c *Config) SetInt32(name string, value int32) (err error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -368,3 +365,48 @@ func (iter *ConfigIterator) Free() { runtime.SetFinalizer(iter, nil) C.free(unsafe.Pointer(iter.ptr)) } + +func ConfigFindGlobal() (string, error) { + var buf C.git_buf + defer C.git_buf_free(&buf) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_config_find_global(&buf) + if ret < 0 { + return "", MakeGitError(ret) + } + + return C.GoString(buf.ptr), nil +} + +func ConfigFindSystem() (string, error) { + var buf C.git_buf + defer C.git_buf_free(&buf) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_config_find_system(&buf) + if ret < 0 { + return "", MakeGitError(ret) + } + + return C.GoString(buf.ptr), nil +} + +func ConfigFindXDG() (string, error) { + var buf C.git_buf + defer C.git_buf_free(&buf) + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_config_find_xdg(&buf) + if ret < 0 { + return "", MakeGitError(ret) + } + + return C.GoString(buf.ptr), nil +} From 1107c6824f887423be59b1ae633553480304b70c Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 28 Jan 2015 15:03:58 +0100 Subject: [PATCH 03/17] Add test triggering ForeachSubmodule panic. --- submodule_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 submodule_test.go diff --git a/submodule_test.go b/submodule_test.go new file mode 100644 index 0000000..1c8f471 --- /dev/null +++ b/submodule_test.go @@ -0,0 +1,24 @@ +package git + +import ( + "testing" +) + +func TestSubmoduleForeach(t *testing.T) { + repo := createTestRepo(t) + seedTestRepo(t, repo) + + _, err := repo.AddSubmodule("http://example.org/submodule", "submodule", true) + checkFatal(t, err) + + i := 0 + err = repo.ForeachSubmodule(func(sub *Submodule, name string) int { + i++ + return 0 + }) + checkFatal(t, err) + + if i != 1 { + t.Fatalf("expected one submodule found but got %i", i) + } +} From 2e481dbc7909beefd1afe199ba95b995819866cd Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 28 Jan 2015 14:38:42 +0100 Subject: [PATCH 04/17] Fix ForeachSubmodule panicing. As the SubmoduleVisitor function is called from inside libgit2 we cannot use Go types in its signature. Fix by using C types instead. --- submodule.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/submodule.go b/submodule.go index f3e9e83..6923c61 100644 --- a/submodule.go +++ b/submodule.go @@ -97,10 +97,10 @@ func (repo *Repository) LookupSubmodule(name string) (*Submodule, error) { type SubmoduleCbk func(sub *Submodule, name string) int //export SubmoduleVisitor -func SubmoduleVisitor(csub unsafe.Pointer, name string, cfct unsafe.Pointer) int { +func SubmoduleVisitor(csub unsafe.Pointer, name *C.char, cfct unsafe.Pointer) C.int { sub := &Submodule{(*C.git_submodule)(csub)} fct := *(*SubmoduleCbk)(cfct) - return fct(sub, name) + return (C.int)(fct(sub, C.GoString(name))) } func (repo *Repository) ForeachSubmodule(cbk SubmoduleCbk) error { From 92a1f92d912cdb5f68da8c1e5e3a4d1ebfd282db Mon Sep 17 00:00:00 2001 From: joseferminj Date: Thu, 22 Jan 2015 00:44:51 -0500 Subject: [PATCH 05/17] Add TargetDirectory field to Checkout options. TargetDirectory field indicates a alternative checkout path to workdir. --- checkout.go | 38 +++++++++++++++++++++++++++++--------- clone.go | 1 + merge.go | 1 + 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/checkout.go b/checkout.go index 9c7188e..06d010c 100644 --- a/checkout.go +++ b/checkout.go @@ -7,6 +7,7 @@ import "C" import ( "os" "runtime" + "unsafe" ) type CheckoutStrategy uint @@ -31,11 +32,12 @@ const ( ) 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 + 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 } func (opts *CheckoutOpts) toC() *C.git_checkout_options { @@ -60,17 +62,29 @@ 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()) - + if opts.TargetDirectory != "" { + ptr.target_directory = C.CString(opts.TargetDirectory) + } return ptr } +func freeCheckoutOpts(ptr *C.git_checkout_options) { + if ptr == nil { + return + } + C.free(unsafe.Pointer(ptr.target_directory)) +} + // Updates files in the index and the working tree to match the content of // the commit pointed at by HEAD. opts may be nil. func (v *Repository) CheckoutHead(opts *CheckoutOpts) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_checkout_head(v.ptr, opts.toC()) + cOpts := opts.toC() + defer freeCheckoutOpts(cOpts) + + ret := C.git_checkout_head(v.ptr, cOpts) if ret < 0 { return MakeGitError(ret) } @@ -90,7 +104,10 @@ func (v *Repository) CheckoutIndex(index *Index, opts *CheckoutOpts) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_checkout_index(v.ptr, iptr, opts.toC()) + cOpts := opts.toC() + defer freeCheckoutOpts(cOpts) + + ret := C.git_checkout_index(v.ptr, iptr, cOpts) if ret < 0 { return MakeGitError(ret) } @@ -102,7 +119,10 @@ func (v *Repository) CheckoutTree(tree *Tree, opts *CheckoutOpts) error { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_checkout_tree(v.ptr, tree.ptr, opts.toC()) + cOpts := opts.toC() + defer freeCheckoutOpts(cOpts) + + ret := C.git_checkout_tree(v.ptr, tree.ptr, cOpts) if ret < 0 { return MakeGitError(ret) } diff --git a/clone.go b/clone.go index 2e0fcce..b796b6e 100644 --- a/clone.go +++ b/clone.go @@ -30,6 +30,7 @@ func Clone(url string, path string, options *CloneOptions) (*Repository, error) var copts C.git_clone_options populateCloneOptions(&copts, options) + defer freeCheckoutOpts(&copts.checkout_opts) if len(options.CheckoutBranch) != 0 { copts.checkout_branch = C.CString(options.CheckoutBranch) diff --git a/merge.go b/merge.go index 3742f97..5b68a8b 100644 --- a/merge.go +++ b/merge.go @@ -145,6 +145,7 @@ func (r *Repository) Merge(theirHeads []*AnnotatedCommit, mergeOptions *MergeOpt cMergeOpts := mergeOptions.toC() cCheckoutOpts := checkoutOptions.toC() + defer freeCheckoutOpts(cCheckoutOpts) gmerge_head_array := make([]*C.git_annotated_commit, len(theirHeads)) for i := 0; i < len(theirHeads); i++ { From 3e05c1038589258b40efd4bfef4d5c387bcc73c9 Mon Sep 17 00:00:00 2001 From: motemen Date: Wed, 28 Jan 2015 20:49:05 +0900 Subject: [PATCH 06/17] Fix test to force diff prefixes. --- patch_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/patch_test.go b/patch_test.go index 569eac2..a061142 100644 --- a/patch_test.go +++ b/patch_test.go @@ -20,7 +20,11 @@ func TestPatch(t *testing.T) { newTree, err := repo.LookupTree(newTreeId) checkFatal(t, err) - diff, err := repo.DiffTreeToTree(originalTree, newTree, nil) + opts := &DiffOptions{ + OldPrefix: "a", + NewPrefix: "b", + } + diff, err := repo.DiffTreeToTree(originalTree, newTree, opts) checkFatal(t, err) patch, err := diff.Patch(0) From c10445cd67d400b1a58ccd6ad07f63b4612f8b11 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Wed, 11 Feb 2015 12:55:16 +0100 Subject: [PATCH 07/17] Add bindings for git_graph_* methods Add graph.go --- graph.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 graph.go diff --git a/graph.go b/graph.go new file mode 100644 index 0000000..f7cf8e9 --- /dev/null +++ b/graph.go @@ -0,0 +1,36 @@ +package git + +/* +#include +*/ +import "C" +import ( + "runtime" +) + +func (repo *Repository) GraphDescendantOf(commit, ancestor *Oid) (bool, error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ret := C.git_graph_descendant_of(repo.ptr, commit.toC(), ancestor.toC()) + if ret < 0 { + return false, MakeGitError(ret) + } + + return (ret > 0), nil +} + +func (repo *Repository) GraphAheadBehind(local, upstream *Oid) (ahead, behind int, err error) { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + var aheadT C.size_t + var behindT C.size_t + + ret := C.git_graph_ahead_behind(&aheadT, &behindT, repo.ptr, local.toC(), upstream.toC()) + if ret < 0 { + return 0, 0, MakeGitError(ret) + } + + return int(aheadT), int(behindT), nil +} From dddcbb71c45932feef3c2d0fe6fbdf375b0de644 Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Thu, 12 Feb 2015 18:49:54 +0100 Subject: [PATCH 08/17] Remove "Graph" prefix on method names --- graph.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graph.go b/graph.go index f7cf8e9..e5d7732 100644 --- a/graph.go +++ b/graph.go @@ -8,7 +8,7 @@ import ( "runtime" ) -func (repo *Repository) GraphDescendantOf(commit, ancestor *Oid) (bool, error) { +func (repo *Repository) DescendantOf(commit, ancestor *Oid) (bool, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -20,7 +20,7 @@ func (repo *Repository) GraphDescendantOf(commit, ancestor *Oid) (bool, error) { return (ret > 0), nil } -func (repo *Repository) GraphAheadBehind(local, upstream *Oid) (ahead, behind int, err error) { +func (repo *Repository) AheadBehind(local, upstream *Oid) (ahead, behind int, err error) { runtime.LockOSThread() defer runtime.UnlockOSThread() From 755721e68453c5d6de0681789dbe3307744fc9c4 Mon Sep 17 00:00:00 2001 From: David Calavera Date: Wed, 18 Feb 2015 15:32:50 +0530 Subject: [PATCH 09/17] Add BranchIterator#ForEach. This abstracts the branch iteration from the user. --- branch.go | 19 ++++++++++++++----- branch_test.go | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/branch.go b/branch.go index bb231c3..54b01fb 100644 --- a/branch.go +++ b/branch.go @@ -30,10 +30,7 @@ type BranchIterator struct { repo *Repository } -type BranchInfo struct { - Branch *Branch - Type BranchType -} +type BranchIteratorFunc func(*Branch, BranchType) error func newBranchIteratorFromC(repo *Repository, ptr *C.git_branch_iterator) *BranchIterator { i := &BranchIterator{repo: repo, ptr: ptr} @@ -65,8 +62,20 @@ func (i *BranchIterator) Free() { C.git_branch_iterator_free(i.ptr) } -func (repo *Repository) NewBranchIterator(flags BranchType) (*BranchIterator, error) { +func (i *BranchIterator) ForEach(f BranchIteratorFunc) error { + b, t, err := i.Next() + for err == nil { + err = f(b, t) + if err == nil { + b, t, err = i.Next() + } + } + + return err +} + +func (repo *Repository) NewBranchIterator(flags BranchType) (*BranchIterator, error) { refType := C.git_branch_t(flags) var ptr *C.git_branch_iterator diff --git a/branch_test.go b/branch_test.go index 44f6338..09ebeba 100644 --- a/branch_test.go +++ b/branch_test.go @@ -1,11 +1,8 @@ package git -import ( - "testing" -) +import "testing" func TestBranchIterator(t *testing.T) { - repo := createTestRepo(t) seedTestRepo(t, repo) @@ -24,3 +21,35 @@ func TestBranchIterator(t *testing.T) { t.Fatal("expected iterover") } } + +func TestBranchIteratorEach(t *testing.T) { + repo := createTestRepo(t) + seedTestRepo(t, repo) + + i, err := repo.NewBranchIterator(BranchLocal) + checkFatal(t, err) + + var names []string + f := func(b *Branch, t BranchType) error { + name, err := b.Name() + if err != nil { + return err + } + + names = append(names, name) + return nil + } + + err = i.ForEach(f) + if err != nil && !IsErrorCode(err, ErrIterOver) { + t.Fatal(err) + } + + if len(names) != 1 { + t.Fatalf("expect 1 branch, but it was %d\n", len(names)) + } + + if names[0] != "master" { + t.Fatalf("expect branch master, but it was %s\n", names[0]) + } +} From eec61815fbc963d0f81a95a9be4b061145541095 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:31:41 -0800 Subject: [PATCH 10/17] Fix typos in constants --- checkout.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/checkout.go b/checkout.go index 06d010c..72a1fe3 100644 --- a/checkout.go +++ b/checkout.go @@ -20,10 +20,10 @@ const ( 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 - CheckotUpdateOnly CheckoutStrategy = C.GIT_CHECKOUT_UPDATE_ONLY // Only update existing files, don't create new ones + 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 - CheckooutDisablePathspecMatch CheckoutStrategy = C.GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH // Treat pathspec as simple list of exact match file paths + 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) From 56ed0b22d7f7ab6185f14e0054346da3ca33c4fa Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:32:56 -0800 Subject: [PATCH 11/17] Repository state --- repository.go | 22 ++++++++++++++++++++++ status_test.go | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/repository.go b/repository.go index 7760c3a..11b0514 100644 --- a/repository.go +++ b/repository.go @@ -630,3 +630,25 @@ func (v *Repository) DefaultNoteRef() (string, error) { return C.GoString(ptr), nil } + +type RepositoryState int + +const ( + RepositoryStateNone RepositoryState = C.GIT_REPOSITORY_STATE_NONE + RepositoryStateMerge RepositoryState = C.GIT_REPOSITORY_STATE_MERGE + RepositoryStateRevert RepositoryState = C.GIT_REPOSITORY_STATE_REVERT + RepositoryStateCherrypick RepositoryState = C.GIT_REPOSITORY_STATE_CHERRYPICK + RepositoryStateBisect RepositoryState = C.GIT_REPOSITORY_STATE_BISECT + RepositoryStateRebase RepositoryState = C.GIT_REPOSITORY_STATE_REBASE + RepositoryStateRebaseInteractive RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_INTERACTIVE + RepositoryStateRebaseMerge RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_MERGE + RepositoryStateApplyMailbox RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX + RepositoryStateApplyMailboxOrRebase RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE +) + +func (r *Repository) State() RepositoryState { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + return RepositoryState(C.git_repository_state(r.ptr)) +} diff --git a/status_test.go b/status_test.go index 4be4824..d18fca1 100644 --- a/status_test.go +++ b/status_test.go @@ -12,6 +12,11 @@ func TestStatusFile(t *testing.T) { defer repo.Free() defer os.RemoveAll(repo.Workdir()) + state := repo.State() + if state != RepositoryStateNone { + t.Fatal("Incorrect repository state: ", state) + } + err := ioutil.WriteFile(path.Join(path.Dir(repo.Workdir()), "hello.txt"), []byte("Hello, World"), 0644) checkFatal(t, err) From c78b4d665e406af7e8cba608f65ac2171d3917b6 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:38:19 -0800 Subject: [PATCH 12/17] Cherrypick --- checkout.go | 13 +++++++++ cherrypick.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++ cherrypick_test.go | 73 ++++++++++++++++++++++++++++++++++++++++++++++ git_test.go | 6 +++- 4 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 cherrypick.go create mode 100644 cherrypick_test.go diff --git a/checkout.go b/checkout.go index 72a1fe3..6eb6098 100644 --- a/checkout.go +++ b/checkout.go @@ -40,6 +40,19 @@ type CheckoutOpts struct { TargetDirectory string // Alternative checkout path to workdir } +func checkoutOptionsFromC(c *C.git_checkout_options) CheckoutOpts { + opts := CheckoutOpts{} + opts.Strategy = CheckoutStrategy(c.checkout_strategy) + opts.DisableFilters = c.disable_filters != 0 + opts.DirMode = os.FileMode(c.dir_mode) + opts.FileMode = os.FileMode(c.file_mode) + opts.FileOpenFlags = int(c.file_open_flags) + if c.target_directory != nil { + opts.TargetDirectory = C.GoString(c.target_directory) + } + return opts +} + func (opts *CheckoutOpts) toC() *C.git_checkout_options { if opts == nil { return nil diff --git a/cherrypick.go b/cherrypick.go new file mode 100644 index 0000000..afc1b7e --- /dev/null +++ b/cherrypick.go @@ -0,0 +1,73 @@ +package git + +/* +#include +*/ +import "C" +import ( + "runtime" +) + +type CherrypickOptions struct { + Version uint + Mainline uint + MergeOpts MergeOptions + CheckoutOpts CheckoutOpts +} + +func cherrypickOptionsFromC(c *C.git_cherrypick_options) CherrypickOptions { + opts := CherrypickOptions{ + Version: uint(c.version), + Mainline: uint(c.mainline), + MergeOpts: mergeOptionsFromC(&c.merge_opts), + CheckoutOpts: checkoutOptionsFromC(&c.checkout_opts), + } + return opts +} + +func (opts *CherrypickOptions) toC() *C.git_cherrypick_options { + if opts == nil { + return nil + } + c := C.git_cherrypick_options{} + c.version = C.uint(opts.Version) + c.mainline = C.uint(opts.Mainline) + c.merge_opts = *opts.MergeOpts.toC() + c.checkout_opts = *opts.CheckoutOpts.toC() + return &c +} + +func freeCherrypickOpts(ptr *C.git_cherrypick_options) { + if ptr == nil { + return + } + freeCheckoutOpts(&ptr.checkout_opts) +} + +func DefaultCherrypickOptions() (CherrypickOptions, error) { + c := C.git_cherrypick_options{} + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_cherrypick_init_options(&c, C.GIT_CHERRYPICK_OPTIONS_VERSION) + if ecode < 0 { + return CherrypickOptions{}, MakeGitError(ecode) + } + defer freeCherrypickOpts(&c) + return cherrypickOptionsFromC(&c), nil +} + +func (v *Repository) Cherrypick(commit *Commit, opts CherrypickOptions) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + cOpts := opts.toC() + defer freeCherrypickOpts(cOpts) + + ecode := C.git_cherrypick(v.ptr, commit.cast_ptr, cOpts) + if ecode < 0 { + return MakeGitError(ecode) + } + return nil +} diff --git a/cherrypick_test.go b/cherrypick_test.go new file mode 100644 index 0000000..c867cf9 --- /dev/null +++ b/cherrypick_test.go @@ -0,0 +1,73 @@ +package git + +import ( + "io/ioutil" + "testing" +) + +func checkout(t *testing.T, repo *Repository, commit *Commit) { + tree, err := commit.Tree() + if err != nil { + t.Fatal(err) + } + + err = repo.CheckoutTree(tree, &CheckoutOpts{Strategy: CheckoutSafe}) + if err != nil { + t.Fatal(err) + } + + err = repo.SetHeadDetached(commit.Id(), commit.Author(), "checkout") + if err != nil { + t.Fatal(err) + } +} + +const content = "Herro, Worrd!" + +func readReadme(t *testing.T, repo *Repository) string { + bytes, err := ioutil.ReadFile(pathInRepo(repo, "README")) + if err != nil { + t.Fatal(err) + } + return string(bytes) +} + +func TestCherrypick(t *testing.T) { + repo := createTestRepo(t) + c1, _ := seedTestRepo(t, repo) + c2, _ := updateReadme(t, repo, content) + + commit1, err := repo.LookupCommit(c1) + if err != nil { + t.Fatal(err) + } + commit2, err := repo.LookupCommit(c2) + if err != nil { + t.Fatal(err) + } + + checkout(t, repo, commit1) + + if readReadme(t, repo) == content { + t.Fatalf("README has wrong content after checking out initial commit") + } + + opts, err := DefaultCherrypickOptions() + if err != nil { + t.Fatal(err) + } + + err = repo.Cherrypick(commit2, opts) + if err != nil { + t.Fatal(err) + } + + if readReadme(t, repo) != content { + t.Fatalf("README has wrong contents after cherry-picking") + } + + state := repo.State() + if state != RepositoryStateCherrypick { + t.Fatal("Incorrect repository state: ", state) + } +} diff --git a/git_test.go b/git_test.go index 56adeed..b9cf0a9 100644 --- a/git_test.go +++ b/git_test.go @@ -57,6 +57,10 @@ func seedTestRepo(t *testing.T, repo *Repository) (*Oid, *Oid) { return commitId, treeId } +func pathInRepo(repo *Repository, name string) string { + return path.Join(path.Dir(path.Dir(repo.Path())), name) +} + func updateReadme(t *testing.T, repo *Repository, content string) (*Oid, *Oid) { loc, err := time.LoadLocation("Europe/Berlin") checkFatal(t, err) @@ -67,7 +71,7 @@ func updateReadme(t *testing.T, repo *Repository, content string) (*Oid, *Oid) { } tmpfile := "README" - err = ioutil.WriteFile(path.Join(path.Dir(path.Dir(repo.Path())), tmpfile), []byte(content), 0644) + err = ioutil.WriteFile(pathInRepo(repo, tmpfile), []byte(content), 0644) checkFatal(t, err) idx, err := repo.Index() From db5fa66b483816614950b36bf204a0de681b705a Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:38:39 -0800 Subject: [PATCH 13/17] State cleanup --- cherrypick_test.go | 10 ++++++++++ repository.go | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/cherrypick_test.go b/cherrypick_test.go index c867cf9..f06dbdd 100644 --- a/cherrypick_test.go +++ b/cherrypick_test.go @@ -70,4 +70,14 @@ func TestCherrypick(t *testing.T) { if state != RepositoryStateCherrypick { t.Fatal("Incorrect repository state: ", state) } + + err = repo.StateCleanup() + if err != nil { + t.Fatal(err) + } + + state = repo.State() + if state != RepositoryStateNone { + t.Fatal("Incorrect repository state: ", state) + } } diff --git a/repository.go b/repository.go index 11b0514..cbb5d17 100644 --- a/repository.go +++ b/repository.go @@ -652,3 +652,14 @@ func (r *Repository) State() RepositoryState { return RepositoryState(C.git_repository_state(r.ptr)) } + +func (r *Repository) StateCleanup() error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + cErr := C.git_repository_state_cleanup(r.ptr) + if cErr < 0 { + return MakeGitError(cErr) + } + return nil +} From e439b931a6b23a84fd0d32114b25a9dd5e08ac29 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:39:35 -0800 Subject: [PATCH 14/17] Default signature --- branch.go | 10 +++++-- commit.go | 48 --------------------------------- reference.go | 15 ++++++++--- remote.go | 10 +++++-- repository.go | 55 ++++++++++++++++++++++++++++++-------- signature.go | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ submodule.go | 18 ++++++++++--- 7 files changed, 159 insertions(+), 70 deletions(-) create mode 100644 signature.go diff --git a/branch.go b/branch.go index 54b01fb..22b767e 100644 --- a/branch.go +++ b/branch.go @@ -96,7 +96,10 @@ func (repo *Repository) CreateBranch(branchName string, target *Commit, force bo cBranchName := C.CString(branchName) cForce := cbool(force) - cSignature := signature.toC() + cSignature, err := signature.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(cSignature) var cmsg *C.char @@ -133,7 +136,10 @@ func (b *Branch) Move(newBranchName string, force bool, signature *Signature, ms cNewBranchName := C.CString(newBranchName) cForce := cbool(force) - cSignature := signature.toC() + cSignature, err := signature.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(cSignature) var cmsg *C.char diff --git a/commit.go b/commit.go index 559a1bd..caaff74 100644 --- a/commit.go +++ b/commit.go @@ -9,8 +9,6 @@ import "C" import ( "runtime" - "time" - "unsafe" ) // Commit @@ -68,49 +66,3 @@ func (c *Commit) ParentId(n uint) *Oid { func (c *Commit) ParentCount() uint { return uint(C.git_commit_parentcount(c.cast_ptr)) } - -// Signature - -type Signature struct { - Name string - Email string - When time.Time -} - -func newSignatureFromC(sig *C.git_signature) *Signature { - // git stores minutes, go wants seconds - loc := time.FixedZone("", int(sig.when.offset)*60) - return &Signature{ - C.GoString(sig.name), - C.GoString(sig.email), - time.Unix(int64(sig.when.time), 0).In(loc), - } -} - -// the offset in mintes, which is what git wants -func (v *Signature) Offset() int { - _, offset := v.When.Zone() - return offset / 60 -} - -func (sig *Signature) toC() *C.git_signature { - - if sig == nil { - return nil - } - - var out *C.git_signature - - name := C.CString(sig.Name) - defer C.free(unsafe.Pointer(name)) - - email := C.CString(sig.Email) - defer C.free(unsafe.Pointer(email)) - - ret := C.git_signature_new(&out, name, email, C.git_time_t(sig.When.Unix()), C.int(sig.Offset())) - if ret < 0 { - return nil - } - - return out -} diff --git a/reference.go b/reference.go index 46436a6..ef12d0b 100644 --- a/reference.go +++ b/reference.go @@ -36,7 +36,10 @@ func (v *Reference) SetSymbolicTarget(target string, sig *Signature, msg string) runtime.LockOSThread() defer runtime.UnlockOSThread() - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return nil, err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -61,7 +64,10 @@ func (v *Reference) SetTarget(target *Oid, sig *Signature, msg string) (*Referen runtime.LockOSThread() defer runtime.UnlockOSThread() - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return nil, err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -99,7 +105,10 @@ func (v *Reference) Rename(name string, force bool, sig *Signature, msg string) cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return nil, err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char diff --git a/remote.go b/remote.go index 2684c20..84750d3 100644 --- a/remote.go +++ b/remote.go @@ -604,7 +604,10 @@ func (o *Remote) Fetch(refspecs []string, sig *Signature, msg string) error { var csig *C.git_signature = nil if sig != nil { - csig = sig.toC() + csig, err := sig.toC() + if err != nil { + return err + } defer C.free(unsafe.Pointer(csig)) } @@ -696,7 +699,10 @@ func (o *Remote) Ls(filterRefs ...string) ([]RemoteHead, error) { func (o *Remote) Push(refspecs []string, opts *PushOptions, sig *Signature, msg string) error { var csig *C.git_signature = nil if sig != nil { - csig = sig.toC() + csig, err := sig.toC() + if err != nil { + return err + } defer C.free(unsafe.Pointer(csig)) } diff --git a/repository.go b/repository.go index cbb5d17..7fac277 100644 --- a/repository.go +++ b/repository.go @@ -210,7 +210,10 @@ func (v *Repository) SetHead(refname string, sig *Signature, msg string) error { cname := C.CString(refname) defer C.free(unsafe.Pointer(cname)) - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -230,7 +233,10 @@ func (v *Repository) SetHead(refname string, sig *Signature, msg string) error { } func (v *Repository) SetHeadDetached(id *Oid, sig *Signature, msg string) error { - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -253,7 +259,10 @@ func (v *Repository) CreateReference(name string, id *Oid, force bool, sig *Sign cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return nil, err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -284,7 +293,10 @@ func (v *Repository) CreateSymbolicReference(name, target string, force bool, si ctarget := C.CString(target) defer C.free(unsafe.Pointer(ctarget)) - csig := sig.toC() + csig, err := sig.toC() + if err != nil { + return nil, err + } defer C.free(unsafe.Pointer(csig)) var cmsg *C.char @@ -352,10 +364,16 @@ func (v *Repository) CreateCommit( parentsarg = &cparents[0] } - authorSig := author.toC() + authorSig, err := author.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(authorSig) - committerSig := committer.toC() + committerSig, err := committer.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(committerSig) runtime.LockOSThread() @@ -384,7 +402,10 @@ func (v *Repository) CreateTag( cmessage := C.CString(message) defer C.free(unsafe.Pointer(cmessage)) - taggerSig := tagger.toC() + taggerSig, err := tagger.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(taggerSig) ctarget := commit.gitObject.ptr @@ -546,10 +567,16 @@ func (v *Repository) CreateNote( defer C.free(unsafe.Pointer(cref)) } - authorSig := author.toC() + authorSig, err := author.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(authorSig) - committerSig := committer.toC() + committerSig, err := committer.toC() + if err != nil { + return nil, err + } defer C.git_signature_free(committerSig) cnote := C.CString(note) @@ -601,10 +628,16 @@ func (v *Repository) RemoveNote(ref string, author, committer *Signature, id *Oi defer C.free(unsafe.Pointer(cref)) } - authorSig := author.toC() + authorSig, err := author.toC() + if err != nil { + return err + } defer C.git_signature_free(authorSig) - committerSig := committer.toC() + committerSig, err := committer.toC() + if err != nil { + return err + } defer C.git_signature_free(committerSig) runtime.LockOSThread() diff --git a/signature.go b/signature.go new file mode 100644 index 0000000..0518387 --- /dev/null +++ b/signature.go @@ -0,0 +1,73 @@ +package git + +/* +#include +*/ +import "C" +import ( + "runtime" + "time" + "unsafe" +) + +type Signature struct { + Name string + Email string + When time.Time +} + +func newSignatureFromC(sig *C.git_signature) *Signature { + // git stores minutes, go wants seconds + loc := time.FixedZone("", int(sig.when.offset)*60) + return &Signature{ + C.GoString(sig.name), + C.GoString(sig.email), + time.Unix(int64(sig.when.time), 0).In(loc), + } +} + +// the offset in mintes, which is what git wants +func (v *Signature) Offset() int { + _, offset := v.When.Zone() + return offset / 60 +} + +func (sig *Signature) toC() (*C.git_signature, error) { + if sig == nil { + return nil, nil + } + + var out *C.git_signature + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + name := C.CString(sig.Name) + defer C.free(unsafe.Pointer(name)) + + email := C.CString(sig.Email) + defer C.free(unsafe.Pointer(email)) + + ret := C.git_signature_new(&out, name, email, C.git_time_t(sig.When.Unix()), C.int(sig.Offset())) + if ret < 0 { + return nil, MakeGitError(ret) + } + + return out, nil +} + +func (repo *Repository) DefaultSignature() (*Signature, error) { + var out *C.git_signature + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + cErr := C.git_signature_default(&out, repo.ptr) + if cErr < 0 { + return nil, MakeGitError(cErr) + } + + defer C.git_signature_free(out) + + return newSignatureFromC(out), nil +} diff --git a/submodule.go b/submodule.go index 6923c61..7c6c922 100644 --- a/submodule.go +++ b/submodule.go @@ -318,7 +318,10 @@ func (repo *Repository) ReloadAllSubmodules(force bool) error { func (sub *Submodule) Update(init bool, opts *SubmoduleUpdateOptions) error { var copts C.git_submodule_update_options - populateSubmoduleUpdateOptions(&copts, opts) + err := populateSubmoduleUpdateOptions(&copts, opts) + if err != nil { + return err + } runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -331,15 +334,22 @@ func (sub *Submodule) Update(init bool, opts *SubmoduleUpdateOptions) error { return nil } -func populateSubmoduleUpdateOptions(ptr *C.git_submodule_update_options, opts *SubmoduleUpdateOptions) { +func populateSubmoduleUpdateOptions(ptr *C.git_submodule_update_options, opts *SubmoduleUpdateOptions) error { C.git_submodule_update_init_options(ptr, C.GIT_SUBMODULE_UPDATE_OPTIONS_VERSION) if opts == nil { - return + return nil } populateCheckoutOpts(&ptr.checkout_opts, opts.CheckoutOpts) populateRemoteCallbacks(&ptr.remote_callbacks, opts.RemoteCallbacks) ptr.clone_checkout_strategy = C.uint(opts.CloneCheckoutStrategy) - ptr.signature = opts.Signature.toC() + + sig, err := opts.Signature.toC() + if err != nil { + return err + } + ptr.signature = sig + + return nil } From 45d88ca5f4e69c9a07b867ec73da27f29bd77388 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 11:40:26 -0800 Subject: [PATCH 15/17] go fmt --- object.go | 8 ++++---- odb.go | 8 ++++---- odb_test.go | 4 ++-- packbuilder.go | 2 +- status.go | 31 +++++++++++++++---------------- tag_test.go | 2 +- 6 files changed, 27 insertions(+), 28 deletions(-) diff --git a/object.go b/object.go index 7428e0f..20cee85 100644 --- a/object.go +++ b/object.go @@ -25,12 +25,12 @@ type Object interface { } type gitObject struct { - ptr *C.git_object + ptr *C.git_object repo *Repository } -func (t ObjectType) String() (string) { - switch (t) { +func (t ObjectType) String() string { + switch t { case ObjectAny: return "Any" case ObjectBad: @@ -71,7 +71,7 @@ func (o *gitObject) Free() { func allocObject(cobj *C.git_object, repo *Repository) Object { obj := gitObject{ - ptr: cobj, + ptr: cobj, repo: repo, } diff --git a/odb.go b/odb.go index 19bb71c..ba03860 100644 --- a/odb.go +++ b/odb.go @@ -94,7 +94,7 @@ type OdbForEachCallback func(id *Oid) error type foreachData struct { callback OdbForEachCallback - err error + err error } //export odbForEachCb @@ -111,9 +111,9 @@ func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int { } func (v *Odb) ForEach(callback OdbForEachCallback) error { - data := foreachData { + data := foreachData{ callback: callback, - err: nil, + err: nil, } runtime.LockOSThread() @@ -138,7 +138,7 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) { runtime.LockOSThread() defer runtime.UnlockOSThread() - ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype)); + ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype)) if ret < 0 { return nil, MakeGitError(ret) } diff --git a/odb_test.go b/odb_test.go index 14a3658..5e6b7ff 100644 --- a/odb_test.go +++ b/odb_test.go @@ -1,9 +1,9 @@ package git import ( + "errors" "io" "os" - "errors" "testing" ) @@ -37,7 +37,7 @@ func TestOdbStream(t *testing.T) { func TestOdbHash(t *testing.T) { - repo := createTestRepo(t) + repo := createTestRepo(t) defer os.RemoveAll(repo.Workdir()) _, _ = seedTestRepo(t, repo) diff --git a/packbuilder.go b/packbuilder.go index 7c94926..54a8390 100644 --- a/packbuilder.go +++ b/packbuilder.go @@ -128,7 +128,7 @@ func packbuilderForEachCb(buf unsafe.Pointer, size C.size_t, payload unsafe.Poin func (pb *Packbuilder) ForEach(callback PackbuilderForeachCallback) error { data := packbuilderCbData{ callback: callback, - err: nil, + err: nil, } runtime.LockOSThread() diff --git a/status.go b/status.go index c849aca..3f5a06d 100644 --- a/status.go +++ b/status.go @@ -45,7 +45,7 @@ func statusEntryFromC(statusEntry *C.git_status_entry) StatusEntry { indexToWorkdir = diffDeltaFromC(statusEntry.index_to_workdir) } - return StatusEntry { + return StatusEntry{ Status: Status(statusEntry.status), HeadToIndex: headToIndex, IndexToWorkdir: indexToWorkdir, @@ -96,20 +96,20 @@ func (statusList *StatusList) EntryCount() (int, error) { type StatusOpt int const ( - StatusOptIncludeUntracked StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNTRACKED - StatusOptIncludeIgnored StatusOpt = C.GIT_STATUS_OPT_INCLUDE_IGNORED - StatusOptIncludeUnmodified StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNMODIFIED - StatusOptExcludeSubmodules StatusOpt = C.GIT_STATUS_OPT_EXCLUDE_SUBMODULES - StatusOptRecurseUntrackedDirs StatusOpt = C.GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS - StatusOptDisablePathspecMatch StatusOpt = C.GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH - StatusOptRecurseIgnoredDirs StatusOpt = C.GIT_STATUS_OPT_RECURSE_IGNORED_DIRS - StatusOptRenamesHeadToIndex StatusOpt = C.GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX - StatusOptRenamesIndexToWorkdir StatusOpt = C.GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR - StatusOptSortCaseSensitively StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_SENSITIVELY - StatusOptSortCaseInsensitively StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY - StatusOptRenamesFromRewrites StatusOpt = C.GIT_STATUS_OPT_RENAMES_FROM_REWRITES - StatusOptNoRefresh StatusOpt = C.GIT_STATUS_OPT_NO_REFRESH - StatusOptUpdateIndex StatusOpt = C.GIT_STATUS_OPT_UPDATE_INDEX + StatusOptIncludeUntracked StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNTRACKED + StatusOptIncludeIgnored StatusOpt = C.GIT_STATUS_OPT_INCLUDE_IGNORED + StatusOptIncludeUnmodified StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNMODIFIED + StatusOptExcludeSubmodules StatusOpt = C.GIT_STATUS_OPT_EXCLUDE_SUBMODULES + StatusOptRecurseUntrackedDirs StatusOpt = C.GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS + StatusOptDisablePathspecMatch StatusOpt = C.GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH + StatusOptRecurseIgnoredDirs StatusOpt = C.GIT_STATUS_OPT_RECURSE_IGNORED_DIRS + StatusOptRenamesHeadToIndex StatusOpt = C.GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX + StatusOptRenamesIndexToWorkdir StatusOpt = C.GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR + StatusOptSortCaseSensitively StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_SENSITIVELY + StatusOptSortCaseInsensitively StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY + StatusOptRenamesFromRewrites StatusOpt = C.GIT_STATUS_OPT_RENAMES_FROM_REWRITES + StatusOptNoRefresh StatusOpt = C.GIT_STATUS_OPT_NO_REFRESH + StatusOptUpdateIndex StatusOpt = C.GIT_STATUS_OPT_UPDATE_INDEX ) type StatusShow int @@ -173,7 +173,6 @@ func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) { return newStatusListFromC(ptr), nil } - func (v *Repository) StatusFile(path string) (Status, error) { var statusFlags C.uint cPath := C.CString(path) diff --git a/tag_test.go b/tag_test.go index 5ebd53d..126cf6e 100644 --- a/tag_test.go +++ b/tag_test.go @@ -2,8 +2,8 @@ package git import ( "os" - "time" "testing" + "time" ) func TestCreateTag(t *testing.T) { From 9eae50f29a69fa47cecf3cf4dfb032414cf27a50 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Wed, 4 Mar 2015 15:35:35 -0800 Subject: [PATCH 16/17] Add commit summary getter --- commit.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/commit.go b/commit.go index caaff74..57e1a77 100644 --- a/commit.go +++ b/commit.go @@ -21,6 +21,10 @@ func (c Commit) Message() string { return C.GoString(C.git_commit_message(c.cast_ptr)) } +func (c Commit) Summary() string { + return C.GoString(C.git_commit_summary(c.cast_ptr)) +} + func (c Commit) Tree() (*Tree, error) { var ptr *C.git_tree From 76d600f7b3633f78e5f1433c16eba4eddfdad3e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Sun, 15 Mar 2015 00:45:30 +0100 Subject: [PATCH 17/17] Correct README on what master tracks The second mention still said that master tracks master. Add a mention of next which will become the branch to track upstream tip. --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index faeb5f5..51543a8 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ git2go [![GoDoc](https://godoc.org/github.com/libgit2/git2go?status.svg)](http://godoc.org/github.com/libgit2/git2go) [![Build Status](https://travis-ci.org/libgit2/git2go.svg?branch=master)](https://travis-ci.org/libgit2/git2go) -Go bindings for [libgit2](http://libgit2.github.com/). The master branch follows the latest libgit2 release. The versioned branches indicate which libgit2 version they work against. +Go bindings for [libgit2](http://libgit2.github.com/). The `master` branch follows the latest libgit2 release. The versioned branches indicate which libgit2 version they work against. Installing ---------- @@ -20,10 +20,11 @@ to use a version of git2go which will work against libgit2 v0.22 and dynamically ### From master -The master branch follows libgit2's master branch, which means there is no stable API or ABI to link against. git2go can statically link against a vendored version of libgit2. +The `next` branch follows libgit2's master branch, which means there is no stable API or ABI to link against. git2go can statically link against a vendored version of libgit2. Run `go get -d github.com/libgit2/git2go` to download the code and go to your `$GOPATH/src/github.com/libgit2/git2go` dir. From there, we need to build the C code and put it into the resulting go binary. + git checkout next git submodule update --init # get libgit2 make install @@ -37,7 +38,7 @@ libgit2 uses OpenSSL and LibSSH2 for performing encrypted network connections. F Running the tests ----------------- -For the stable version, `go test` will work as usual. For the master branch, similarly to installing, running the tests requires linking against the local libgit2 library, so the Makefile provides a wrapper +For the stable version, `go test` will work as usual. For the `next` branch, similarly to installing, running the tests requires linking against the local libgit2 library, so the Makefile provides a wrapper make test