Skip to content

Commit b5a87fd

Browse files
committed
Reflog support (libgit2#467)
1 parent 4b2ac7c commit b5a87fd

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed

reflog.go

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package git
2+
3+
/*
4+
#include <git2.h>
5+
*/
6+
import "C"
7+
import (
8+
"runtime"
9+
"unsafe"
10+
)
11+
12+
// RefLog is a log of changes for a reference
13+
type RefLog struct {
14+
ptr *C.git_reflog
15+
repo *Repository
16+
name string
17+
}
18+
19+
func newRefLogFromC(ptr *C.git_reflog, repo *Repository, name string) *RefLog {
20+
l := &RefLog{
21+
ptr: ptr,
22+
repo: repo,
23+
name: name,
24+
}
25+
runtime.SetFinalizer(l, (*RefLog).Free)
26+
return l
27+
}
28+
29+
func (repo *Repository) ReadRefLog(name string) (*RefLog, error) {
30+
runtime.LockOSThread()
31+
defer runtime.UnlockOSThread()
32+
33+
cname := C.CString(name)
34+
defer C.free(unsafe.Pointer(cname))
35+
36+
var ptr *C.git_reflog
37+
38+
ecode := C.git_reflog_read(&ptr, repo.ptr, cname)
39+
runtime.KeepAlive(repo)
40+
if ecode < 0 {
41+
return nil, MakeGitError(ecode)
42+
}
43+
44+
return newRefLogFromC(ptr, repo, name), nil
45+
}
46+
47+
func (repo *Repository) DeleteReflog(name string) error {
48+
runtime.LockOSThread()
49+
defer runtime.UnlockOSThread()
50+
51+
cname := C.CString(name)
52+
defer C.free(unsafe.Pointer(cname))
53+
54+
ecode := C.git_reflog_delete(repo.ptr, cname)
55+
runtime.KeepAlive(repo)
56+
if ecode < 0 {
57+
return MakeGitError(ecode)
58+
}
59+
60+
return nil
61+
}
62+
63+
func (repo *Repository) RenameReflog(oldName, newName string) error {
64+
runtime.LockOSThread()
65+
defer runtime.UnlockOSThread()
66+
67+
cOldName := C.CString(oldName)
68+
defer C.free(unsafe.Pointer(cOldName))
69+
70+
cNewName := C.CString(newName)
71+
defer C.free(unsafe.Pointer(cNewName))
72+
73+
ecode := C.git_reflog_rename(repo.ptr, cOldName, cNewName)
74+
runtime.KeepAlive(repo)
75+
if ecode < 0 {
76+
return MakeGitError(ecode)
77+
}
78+
79+
return nil
80+
}
81+
82+
func (l *RefLog) Write() error {
83+
runtime.LockOSThread()
84+
defer runtime.UnlockOSThread()
85+
86+
ecode := C.git_reflog_write(l.ptr)
87+
runtime.KeepAlive(l)
88+
if ecode < 0 {
89+
return MakeGitError(ecode)
90+
}
91+
return nil
92+
}
93+
94+
func (l *RefLog) EntryCount() uint {
95+
runtime.LockOSThread()
96+
defer runtime.UnlockOSThread()
97+
98+
count := C.git_reflog_entrycount(l.ptr)
99+
runtime.KeepAlive(l)
100+
return uint(count)
101+
}
102+
103+
// RefLogEntry specifies a reference change
104+
type RefLogEntry struct {
105+
Old *Oid
106+
New *Oid
107+
Committer *Signature
108+
Message string // may be empty
109+
}
110+
111+
func newRefLogEntry(entry *C.git_reflog_entry) *RefLogEntry {
112+
return &RefLogEntry{
113+
New: newOidFromC(C.git_reflog_entry_id_new(entry)),
114+
Old: newOidFromC(C.git_reflog_entry_id_old(entry)),
115+
Committer: newSignatureFromC(C.git_reflog_entry_committer(entry)),
116+
Message: C.GoString(C.git_reflog_entry_message(entry)),
117+
}
118+
}
119+
120+
func (l *RefLog) EntryByIndex(index uint) *RefLogEntry {
121+
runtime.LockOSThread()
122+
defer runtime.UnlockOSThread()
123+
124+
entry := C.git_reflog_entry_byindex(l.ptr, C.size_t(index))
125+
if entry == nil {
126+
return nil
127+
}
128+
129+
goEntry := newRefLogEntry(entry)
130+
runtime.KeepAlive(l)
131+
132+
return goEntry
133+
}
134+
135+
func (l *RefLog) DropEntry(index uint, rewriteHistory bool) error {
136+
runtime.LockOSThread()
137+
defer runtime.UnlockOSThread()
138+
139+
var rewriteHistoryInt int
140+
if rewriteHistory {
141+
rewriteHistoryInt = 1
142+
}
143+
144+
ecode := C.git_reflog_drop(l.ptr, C.size_t(index), C.int(rewriteHistoryInt))
145+
runtime.KeepAlive(l)
146+
if ecode < 0 {
147+
return MakeGitError(ecode)
148+
}
149+
150+
return nil
151+
}
152+
153+
func (l *RefLog) AppendEntry(oid *Oid, committer *Signature, message string) error {
154+
runtime.LockOSThread()
155+
defer runtime.UnlockOSThread()
156+
157+
cSignature, err := committer.toC()
158+
if err != nil {
159+
return err
160+
}
161+
defer C.git_signature_free(cSignature)
162+
163+
cMsg := C.CString(message)
164+
defer C.free(unsafe.Pointer(cMsg))
165+
166+
C.git_reflog_append(l.ptr, oid.toC(), cSignature, cMsg)
167+
runtime.KeepAlive(l)
168+
169+
return nil
170+
}
171+
172+
func (l *RefLog) Free() {
173+
runtime.SetFinalizer(l, nil)
174+
C.git_reflog_free(l.ptr)
175+
}

0 commit comments

Comments
 (0)