Create a ReferenceCollection for managing references

As with the other commits, this clears up the clutter in naming and
around the Repository's API.
This commit is contained in:
Carlos Martín Nieto 2015-06-28 01:12:32 +02:00
parent d2808d1610
commit 01a2d8d38d
7 changed files with 147 additions and 139 deletions

View File

@ -10,7 +10,7 @@ func TestMergeWithSelf(t *testing.T) {
seedTestRepo(t, repo)
master, err := repo.LookupReference("refs/heads/master")
master, err := repo.References.Lookup("refs/heads/master")
checkFatal(t, err)
mergeHead, err := repo.AnnotatedCommitFromRef(master)
@ -28,7 +28,7 @@ func TestMergeAnalysisWithSelf(t *testing.T) {
seedTestRepo(t, repo)
master, err := repo.LookupReference("refs/heads/master")
master, err := repo.References.Lookup("refs/heads/master")
checkFatal(t, err)
mergeHead, err := repo.AnnotatedCommitFromRef(master)

View File

@ -19,9 +19,9 @@ func TestRemotePush(t *testing.T) {
err = remote.Push([]string{"refs/heads/master"}, nil)
checkFatal(t, err)
_, err = localRepo.LookupReference("refs/remotes/test_push/master")
_, err = localRepo.References.Lookup("refs/remotes/test_push/master")
checkFatal(t, err)
_, err = repo.LookupReference("refs/heads/master")
_, err = repo.References.Lookup("refs/heads/master")
checkFatal(t, err)
}

View File

@ -21,6 +21,130 @@ type Reference struct {
repo *Repository
}
type ReferenceCollection struct {
repo *Repository
}
func (c *ReferenceCollection) Lookup(name string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_lookup(&ptr, c.repo.ptr, cname)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, c.repo), nil
}
func (c *ReferenceCollection) Create(name string, id *Oid, force bool, msg string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
var cmsg *C.char
if msg == "" {
cmsg = nil
} else {
cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))
}
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_create(&ptr, c.repo.ptr, cname, id.toC(), cbool(force), cmsg)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, c.repo), nil
}
func (c *ReferenceCollection) CreateSymbolic(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))
var cmsg *C.char
if msg == "" {
cmsg = nil
} else {
cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))
}
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_symbolic_create(&ptr, c.repo.ptr, cname, ctarget, cbool(force), cmsg)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, c.repo), nil
}
// EnsureLog ensures that there is a reflog for the given reference
// name and creates an empty one if necessary.
func (c *ReferenceCollection) EnsureLog(name string) error {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_ensure_log(c.repo.ptr, cname)
if ret < 0 {
return MakeGitError(ret)
}
return nil
}
// HasLog returns whether there is a reflog for the given reference
// name
func (c *ReferenceCollection) HasLog(name string) (bool, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_has_log(c.repo.ptr, cname)
if ret < 0 {
return false, MakeGitError(ret)
}
return ret == 1, nil
}
// Dwim looks up a reference by DWIMing its short name
func (c *ReferenceCollection) Dwim(name string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var ptr *C.git_reference
ret := C.git_reference_dwim(&ptr, c.repo.ptr, cname)
if ret < 0 {
return nil, MakeGitError(ret)
}
return newReferenceFromC(ptr, c.repo), nil
}
func newReferenceFromC(ptr *C.git_reference, repo *Repository) *Reference {
ref := &Reference{ptr: ptr, repo: repo}
runtime.SetFinalizer(ref, (*Reference).Free)

View File

@ -13,14 +13,14 @@ func TestRefModification(t *testing.T) {
commitId, treeId := seedTestRepo(t, repo)
_, err := repo.CreateReference("refs/tags/tree", treeId, true, "testTreeTag")
_, err := repo.References.Create("refs/tags/tree", treeId, true, "testTreeTag")
checkFatal(t, err)
tag, err := repo.LookupReference("refs/tags/tree")
tag, err := repo.References.Lookup("refs/tags/tree")
checkFatal(t, err)
checkRefType(t, tag, ReferenceOid)
ref, err := repo.LookupReference("HEAD")
ref, err := repo.References.Lookup("HEAD")
checkFatal(t, err)
checkRefType(t, ref, ReferenceSymbolic)
@ -46,7 +46,7 @@ func TestRefModification(t *testing.T) {
_, err = tag.Rename("refs/tags/renamed", false, "")
checkFatal(t, err)
tag, err = repo.LookupReference("refs/tags/renamed")
tag, err = repo.References.Lookup("refs/tags/renamed")
checkFatal(t, err)
checkRefType(t, ref, ReferenceOid)
@ -77,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, "headOne")
_, err = repo.References.Create("refs/heads/one", commitId, true, "headOne")
checkFatal(t, err)
_, err = repo.CreateReference("refs/heads/two", commitId, true, "headTwo")
_, err = repo.References.Create("refs/heads/two", commitId, true, "headTwo")
checkFatal(t, err)
_, err = repo.CreateReference("refs/heads/three", commitId, true, "headThree")
_, err = repo.References.Create("refs/heads/three", commitId, true, "headThree")
checkFatal(t, err)
iter, err := repo.NewReferenceIterator()
@ -136,7 +136,7 @@ func TestReferenceOwner(t *testing.T) {
commitId, _ := seedTestRepo(t, repo)
ref, err := repo.CreateReference("refs/heads/foo", commitId, true, "")
ref, err := repo.References.Create("refs/heads/foo", commitId, true, "")
checkFatal(t, err)
owner := ref.Owner()
@ -155,10 +155,10 @@ func TestUtil(t *testing.T) {
commitId, _ := seedTestRepo(t, repo)
ref, err := repo.CreateReference("refs/heads/foo", commitId, true, "")
ref, err := repo.References.Create("refs/heads/foo", commitId, true, "")
checkFatal(t, err)
ref2, err := repo.DwimReference("foo")
ref2, err := repo.References.Dwim("foo")
checkFatal(t, err)
if ref.Cmp(ref2) != 0 {
@ -169,7 +169,7 @@ func TestUtil(t *testing.T) {
t.Fatalf("refs/heads/foo has no foo shorthand")
}
hasLog, err := repo.HasLog("refs/heads/foo")
hasLog, err := repo.References.HasLog("refs/heads/foo")
checkFatal(t, err)
if !hasLog {
t.Fatalf("branches have logs by default")

View File

@ -154,7 +154,7 @@ func TestRemotePrune(t *testing.T) {
err = remote.Fetch([]string{"test-prune"}, nil, "")
checkFatal(t, err)
_, err = repo.CreateReference("refs/remotes/origin/test-prune", head, true, "remote reference")
_, err = repo.References.Create("refs/remotes/origin/test-prune", head, true, "remote reference")
checkFatal(t, err)
err = remoteRef.Delete()
@ -172,7 +172,7 @@ func TestRemotePrune(t *testing.T) {
err = rr.Prune(nil)
checkFatal(t, err)
_, err = repo.LookupReference("refs/remotes/origin/test-prune")
_, err = repo.References.Lookup("refs/remotes/origin/test-prune")
if err == nil {
t.Fatal("Expected error getting a pruned reference")
}

View File

@ -17,15 +17,19 @@ type Repository struct {
// used to add, remove and configure remotes for this
// repository.
Remotes RemoteCollection
// Submodules represents the collectin of submodules and can
// Submodules represents the collection of submodules and can
// be used to add, remove and configure submodules in this
// repostiory.
Submodules SubmoduleCollection
// References represents the collection of references and can
// be used to create, remove or update refernces for this repository.
References ReferenceCollection
}
func initRepositoryObject(repo *Repository) {
repo.Remotes.repo = repo
repo.Submodules.repo = repo
repo.References.repo = repo
runtime.SetFinalizer(repo, (*Repository).Free)
}
@ -190,22 +194,6 @@ func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
return obj.(*Tag), nil
}
func (v *Repository) LookupReference(name string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_lookup(&ptr, v.ptr, cname)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, v), nil
}
func (v *Repository) Head() (*Reference, error) {
var ptr *C.git_reference
@ -245,59 +233,6 @@ func (v *Repository) SetHeadDetached(id *Oid) error {
return nil
}
func (v *Repository) CreateReference(name string, id *Oid, force bool, msg string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
var cmsg *C.char
if msg == "" {
cmsg = nil
} else {
cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))
}
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_create(&ptr, v.ptr, cname, id.toC(), cbool(force), cmsg)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, v), nil
}
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))
var cmsg *C.char
if msg == "" {
cmsg = nil
} else {
cmsg = C.CString(msg)
defer C.free(unsafe.Pointer(cmsg))
}
var ptr *C.git_reference
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ecode := C.git_reference_symbolic_create(&ptr, v.ptr, cname, ctarget, cbool(force), cmsg)
if ecode < 0 {
return nil, MakeGitError(ecode)
}
return newReferenceFromC(ptr, v), nil
}
func (v *Repository) Walk() (*RevWalk, error) {
var walkPtr *C.git_revwalk
@ -479,57 +414,6 @@ func (v *Repository) TreeBuilderFromTree(tree *Tree) (*TreeBuilder, error) {
return bld, nil
}
// EnsureLog ensures that there is a reflog for the given reference
// name and creates an empty one if necessary.
func (v *Repository) EnsureLog(name string) error {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_ensure_log(v.ptr, cname)
if ret < 0 {
return MakeGitError(ret)
}
return nil
}
// HasLog returns whether there is a reflog for the given reference
// name
func (v *Repository) HasLog(name string) (bool, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
ret := C.git_reference_has_log(v.ptr, cname)
if ret < 0 {
return false, MakeGitError(ret)
}
return ret == 1, nil
}
// DwimReference looks up a reference by DWIMing its short name
func (v *Repository) DwimReference(name string) (*Reference, error) {
cname := C.CString(name)
defer C.free(unsafe.Pointer(cname))
runtime.LockOSThread()
defer runtime.UnlockOSThread()
var ptr *C.git_reference
ret := C.git_reference_dwim(&ptr, v.ptr, cname)
if ret < 0 {
return nil, MakeGitError(ret)
}
return newReferenceFromC(ptr, v), nil
}
// CreateNote adds a note for an object
func (v *Repository) CreateNote(
ref string, author, committer *Signature, id *Oid,

View File

@ -34,7 +34,7 @@ func TestRevparseExt(t *testing.T) {
_, treeId := seedTestRepo(t, repo)
ref, err := repo.CreateReference("refs/heads/master", treeId, true, "")
ref, err := repo.References.Create("refs/heads/master", treeId, true, "")
checkFatal(t, err)
obj, ref, err := repo.RevparseExt("master")