diff --git a/reference.go b/reference.go index a2f1636..4a839a7 100644 --- a/reference.go +++ b/reference.go @@ -134,6 +134,17 @@ func (v *Reference) Delete() error { return nil } +// Cmp compares both references, retursn 0 on equality, otherwise a +// stable sorting. +func (v *Reference) Cmp(ref2 *Reference) int { + return int(C.git_reference_cmp(v.ptr, ref2.ptr)) +} + +// Shorthand returns a "human-readable" short reference name +func (v *Reference) Shorthand() string { + return C.GoString(C.git_reference_shorthand(v.ptr)) +} + func (v *Reference) Name() string { return C.GoString(C.git_reference_name(v.ptr)) } diff --git a/reference_test.go b/reference_test.go index 156960a..ffa9f35 100644 --- a/reference_test.go +++ b/reference_test.go @@ -159,6 +159,33 @@ func TestIterator(t *testing.T) { compareStringList(t, expected, list) } +func TestUtil(t *testing.T) { + repo := createTestRepo(t) + defer os.RemoveAll(repo.Workdir()) + + commitId, _ := seedTestRepo(t, repo) + + ref, err := repo.CreateReference("refs/heads/foo", commitId, true, nil, "") + checkFatal(t, err) + + ref2, err := repo.DwimReference("foo") + checkFatal(t, err) + + if ref.Cmp(ref2) != 0 { + t.Fatalf("foo didn't dwim to the right thing") + } + + if ref.Shorthand() != "foo" { + t.Fatalf("refs/heads/foo has no foo shorthand") + } + + hasLog, err := repo.HasLog("refs/heads/foo") + checkFatal(t, err) + if !hasLog { + t.Fatalf("branches ahve logs by default") + } +} + func compareStringList(t *testing.T, expected, actual []string) { for i, v := range expected { if actual[i] != v { diff --git a/repository.go b/repository.go index 48c2b46..5f0cd0b 100644 --- a/repository.go +++ b/repository.go @@ -331,3 +331,52 @@ func (v *Repository) RevparseSingle(spec string) (Object, error) { return allocObject(ptr), 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() + + if ret := C.git_reference_ensure_log(v.ptr, cname); ret < 0 { + return LastError() + } + + 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, LastError() + } + + 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 + if ret := C.git_reference_dwim(&ptr, v.ptr, cname); ret < 0 { + return nil, LastError() + } + + return newReferenceFromC(ptr), nil +}