Merge branch 'next'
This commit is contained in:
commit
2ae7d13ba1
6
blame.go
6
blame.go
|
@ -58,8 +58,8 @@ func (v *Repository) BlameFile(path string, opts *BlameOptions) (*Blame, error)
|
||||||
version: C.GIT_BLAME_OPTIONS_VERSION,
|
version: C.GIT_BLAME_OPTIONS_VERSION,
|
||||||
flags: C.uint32_t(opts.Flags),
|
flags: C.uint32_t(opts.Flags),
|
||||||
min_match_characters: C.uint16_t(opts.MinMatchCharacters),
|
min_match_characters: C.uint16_t(opts.MinMatchCharacters),
|
||||||
min_line: C.uint32_t(opts.MinLine),
|
min_line: C.size_t(opts.MinLine),
|
||||||
max_line: C.uint32_t(opts.MaxLine),
|
max_line: C.size_t(opts.MaxLine),
|
||||||
}
|
}
|
||||||
if opts.NewestCommit != nil {
|
if opts.NewestCommit != nil {
|
||||||
copts.newest_commit = *opts.NewestCommit.toC()
|
copts.newest_commit = *opts.NewestCommit.toC()
|
||||||
|
@ -100,7 +100,7 @@ func (blame *Blame) HunkByIndex(index int) (BlameHunk, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blame *Blame) HunkByLine(lineno int) (BlameHunk, error) {
|
func (blame *Blame) HunkByLine(lineno int) (BlameHunk, error) {
|
||||||
ptr := C.git_blame_get_hunk_byline(blame.ptr, C.uint32_t(lineno))
|
ptr := C.git_blame_get_hunk_byline(blame.ptr, C.size_t(lineno))
|
||||||
if ptr == nil {
|
if ptr == nil {
|
||||||
return BlameHunk{}, ErrInvalid
|
return BlameHunk{}, ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
2
blob.go
2
blob.go
|
@ -18,7 +18,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Blob struct {
|
type Blob struct {
|
||||||
gitObject
|
Object
|
||||||
cast_ptr *C.git_blob
|
cast_ptr *C.git_blob
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
|
|
||||||
// Commit
|
// Commit
|
||||||
type Commit struct {
|
type Commit struct {
|
||||||
gitObject
|
Object
|
||||||
cast_ptr *C.git_commit
|
cast_ptr *C.git_commit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ func (c Commit) Tree() (*Tree, error) {
|
||||||
return nil, MakeGitError(err)
|
return nil, MakeGitError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocObject((*C.git_object)(ptr), c.repo).(*Tree), nil
|
return allocTree(ptr, c.repo), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Commit) TreeId() *Oid {
|
func (c Commit) TreeId() *Oid {
|
||||||
|
@ -61,7 +61,7 @@ func (c *Commit) Parent(n uint) *Commit {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return allocObject((*C.git_object)(cobj), c.repo).(*Commit)
|
return allocCommit(cobj, c.repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commit) ParentId(n uint) *Oid {
|
func (c *Commit) ParentId(n uint) *Oid {
|
||||||
|
|
21
config.go
21
config.go
|
@ -12,6 +12,9 @@ import (
|
||||||
type ConfigLevel int
|
type ConfigLevel int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// System-wide on Windows, for compatibility with portable git
|
||||||
|
ConfigLevelProgramdata ConfigLevel = C.GIT_CONFIG_LEVEL_PROGRAMDATA
|
||||||
|
|
||||||
// System-wide configuration file; /etc/gitconfig on Linux systems
|
// System-wide configuration file; /etc/gitconfig on Linux systems
|
||||||
ConfigLevelSystem ConfigLevel = C.GIT_CONFIG_LEVEL_SYSTEM
|
ConfigLevelSystem ConfigLevel = C.GIT_CONFIG_LEVEL_SYSTEM
|
||||||
|
|
||||||
|
@ -412,3 +415,21 @@ func ConfigFindXDG() (string, error) {
|
||||||
|
|
||||||
return C.GoString(buf.ptr), nil
|
return C.GoString(buf.ptr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigFindProgramdata locate the path to the configuration file in ProgramData.
|
||||||
|
//
|
||||||
|
// Look for the file in %PROGRAMDATA%\Git\config used by portable git.
|
||||||
|
func ConfigFindProgramdata() (string, error) {
|
||||||
|
var buf C.git_buf
|
||||||
|
defer C.git_buf_free(&buf)
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
ret := C.git_config_find_programdata(&buf)
|
||||||
|
if ret < 0 {
|
||||||
|
return "", MakeGitError(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
return C.GoString(buf.ptr), nil
|
||||||
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (c *Commit) Describe(opts *DescribeOptions) (*DescribeResult, error) {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
ecode := C.git_describe_commit(&resultPtr, c.gitObject.ptr, cDescribeOpts)
|
ecode := C.git_describe_commit(&resultPtr, c.ptr, cDescribeOpts)
|
||||||
if ecode < 0 {
|
if ecode < 0 {
|
||||||
return nil, MakeGitError(ecode)
|
return nil, MakeGitError(ecode)
|
||||||
}
|
}
|
||||||
|
|
6
diff.go
6
diff.go
|
@ -550,7 +550,7 @@ func diffOptionsToC(opts *DiffOptions) (copts *C.git_diff_options, notifyData *d
|
||||||
|
|
||||||
if opts.NotifyCallback != nil {
|
if opts.NotifyCallback != nil {
|
||||||
C._go_git_setup_diff_notify_callbacks(copts)
|
C._go_git_setup_diff_notify_callbacks(copts)
|
||||||
copts.notify_payload = pointerHandles.Track(notifyData)
|
copts.payload = pointerHandles.Track(notifyData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -562,8 +562,8 @@ func freeDiffOptions(copts *C.git_diff_options) {
|
||||||
freeStrarray(&cpathspec)
|
freeStrarray(&cpathspec)
|
||||||
C.free(unsafe.Pointer(copts.old_prefix))
|
C.free(unsafe.Pointer(copts.old_prefix))
|
||||||
C.free(unsafe.Pointer(copts.new_prefix))
|
C.free(unsafe.Pointer(copts.new_prefix))
|
||||||
if copts.notify_payload != nil {
|
if copts.payload != nil {
|
||||||
pointerHandles.Untrack(copts.notify_payload)
|
pointerHandles.Untrack(copts.payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
git.go
22
git.go
|
@ -53,6 +53,7 @@ const (
|
||||||
|
|
||||||
// No error
|
// No error
|
||||||
ErrOk ErrorCode = C.GIT_OK
|
ErrOk ErrorCode = C.GIT_OK
|
||||||
|
|
||||||
// Generic error
|
// Generic error
|
||||||
ErrGeneric ErrorCode = C.GIT_ERROR
|
ErrGeneric ErrorCode = C.GIT_ERROR
|
||||||
// Requested object could not be found
|
// Requested object could not be found
|
||||||
|
@ -63,10 +64,12 @@ const (
|
||||||
ErrAmbigious ErrorCode = C.GIT_EAMBIGUOUS
|
ErrAmbigious ErrorCode = C.GIT_EAMBIGUOUS
|
||||||
// Output buffer too short to hold data
|
// Output buffer too short to hold data
|
||||||
ErrBuffs ErrorCode = C.GIT_EBUFS
|
ErrBuffs ErrorCode = C.GIT_EBUFS
|
||||||
|
|
||||||
// GIT_EUSER is a special error that is never generated by libgit2
|
// GIT_EUSER is a special error that is never generated by libgit2
|
||||||
// code. You can return it from a callback (e.g to stop an iteration)
|
// code. You can return it from a callback (e.g to stop an iteration)
|
||||||
// to know that it was generated by the callback and not by libgit2.
|
// to know that it was generated by the callback and not by libgit2.
|
||||||
ErrUser ErrorCode = C.GIT_EUSER
|
ErrUser ErrorCode = C.GIT_EUSER
|
||||||
|
|
||||||
// Operation not allowed on bare repository
|
// Operation not allowed on bare repository
|
||||||
ErrBareRepo ErrorCode = C.GIT_EBAREREPO
|
ErrBareRepo ErrorCode = C.GIT_EBAREREPO
|
||||||
// HEAD refers to branch with no commits
|
// HEAD refers to branch with no commits
|
||||||
|
@ -83,12 +86,27 @@ const (
|
||||||
ErrLocked ErrorCode = C.GIT_ELOCKED
|
ErrLocked ErrorCode = C.GIT_ELOCKED
|
||||||
// Reference value does not match expected
|
// Reference value does not match expected
|
||||||
ErrModified ErrorCode = C.GIT_EMODIFIED
|
ErrModified ErrorCode = C.GIT_EMODIFIED
|
||||||
|
// Authentication failed
|
||||||
|
ErrAuth ErrorCode = C.GIT_EAUTH
|
||||||
|
// Server certificate is invalid
|
||||||
|
ErrCertificate ErrorCode = C.GIT_ECERTIFICATE
|
||||||
|
// Patch/merge has already been applied
|
||||||
|
ErrApplied ErrorCode = C.GIT_EAPPLIED
|
||||||
|
// The requested peel operation is not possible
|
||||||
|
ErrPeel ErrorCode = C.GIT_EPEEL
|
||||||
|
// Unexpected EOF
|
||||||
|
ErrEOF ErrorCode = C.GIT_EEOF
|
||||||
|
// Uncommitted changes in index prevented operation
|
||||||
|
ErrUncommitted ErrorCode = C.GIT_EUNCOMMITTED
|
||||||
|
// The operation is not valid for a directory
|
||||||
|
ErrDirectory ErrorCode = C.GIT_EDIRECTORY
|
||||||
|
// A merge conflict exists and cannot continue
|
||||||
|
ErrMergeConflict ErrorCode = C.GIT_EMERGECONFLICT
|
||||||
|
|
||||||
// Internal only
|
// Internal only
|
||||||
ErrPassthrough ErrorCode = C.GIT_PASSTHROUGH
|
ErrPassthrough ErrorCode = C.GIT_PASSTHROUGH
|
||||||
// Signals end of iteration with iterator
|
// Signals end of iteration with iterator
|
||||||
ErrIterOver ErrorCode = C.GIT_ITEROVER
|
ErrIterOver ErrorCode = C.GIT_ITEROVER
|
||||||
// Authentication failed
|
|
||||||
ErrAuth ErrorCode = C.GIT_EAUTH
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package git
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <git2.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v *Repository) AddIgnoreRule(rules string) error {
|
||||||
|
crules := C.CString(rules)
|
||||||
|
defer C.free(unsafe.Pointer(crules))
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
ret := C.git_ignore_add_rule(v.ptr, crules)
|
||||||
|
if ret < 0 {
|
||||||
|
return MakeGitError(ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Repository) ClearInternalIgnoreRules() error {
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
ret := C.git_ignore_clear_internal_rules(v.ptr)
|
||||||
|
if ret < 0 {
|
||||||
|
return MakeGitError(ret)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Repository) IsPathIgnored(path string) (bool, error) {
|
||||||
|
var ignored C.int
|
||||||
|
|
||||||
|
cpath := C.CString(path)
|
||||||
|
defer C.free(unsafe.Pointer(cpath))
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
ret := C.git_ignore_path_is_ignored(&ignored, v.ptr, cpath)
|
||||||
|
if ret < 0 {
|
||||||
|
return false, MakeGitError(ret)
|
||||||
|
}
|
||||||
|
return ignored == 1, nil
|
||||||
|
}
|
68
index.go
68
index.go
|
@ -26,6 +26,24 @@ const (
|
||||||
IndexAddCheckPathspec IndexAddOpts = C.GIT_INDEX_ADD_CHECK_PATHSPEC
|
IndexAddCheckPathspec IndexAddOpts = C.GIT_INDEX_ADD_CHECK_PATHSPEC
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type IndexStageOpts int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// IndexStageAny matches any index stage.
|
||||||
|
//
|
||||||
|
// Some index APIs take a stage to match; pass this value to match
|
||||||
|
// any entry matching the path regardless of stage.
|
||||||
|
IndexStageAny IndexStageOpts = C.GIT_INDEX_STAGE_ANY
|
||||||
|
// IndexStageNormal is a normal staged file in the index.
|
||||||
|
IndexStageNormal IndexStageOpts = C.GIT_INDEX_STAGE_NORMAL
|
||||||
|
// IndexStageAncestor is the ancestor side of a conflict.
|
||||||
|
IndexStageAncestor IndexStageOpts = C.GIT_INDEX_STAGE_ANCESTOR
|
||||||
|
// IndexStageOurs is the "ours" side of a conflict.
|
||||||
|
IndexStageOurs IndexStageOpts = C.GIT_INDEX_STAGE_OURS
|
||||||
|
// IndexStageTheirs is the "theirs" side of a conflict.
|
||||||
|
IndexStageTheirs IndexStageOpts = C.GIT_INDEX_STAGE_THEIRS
|
||||||
|
)
|
||||||
|
|
||||||
type Index struct {
|
type Index struct {
|
||||||
ptr *C.git_index
|
ptr *C.git_index
|
||||||
}
|
}
|
||||||
|
@ -51,8 +69,8 @@ func newIndexEntryFromC(entry *C.git_index_entry) *IndexEntry {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &IndexEntry{
|
return &IndexEntry{
|
||||||
IndexTime { int32(entry.ctime.seconds), uint32(entry.ctime.nanoseconds) },
|
IndexTime{int32(entry.ctime.seconds), uint32(entry.ctime.nanoseconds)},
|
||||||
IndexTime { int32(entry.mtime.seconds), uint32(entry.mtime.nanoseconds) },
|
IndexTime{int32(entry.mtime.seconds), uint32(entry.mtime.nanoseconds)},
|
||||||
Filemode(entry.mode),
|
Filemode(entry.mode),
|
||||||
uint32(entry.uid),
|
uint32(entry.uid),
|
||||||
uint32(entry.gid),
|
uint32(entry.gid),
|
||||||
|
@ -280,7 +298,7 @@ func (v *Index) ReadTree(tree *Tree) error {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
ret := C.git_index_read_tree(v.ptr, tree.cast_ptr);
|
ret := C.git_index_read_tree(v.ptr, tree.cast_ptr)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return MakeGitError(ret)
|
return MakeGitError(ret)
|
||||||
}
|
}
|
||||||
|
@ -331,6 +349,50 @@ func (v *Index) EntryByIndex(index uint) (*IndexEntry, error) {
|
||||||
return newIndexEntryFromC(centry), nil
|
return newIndexEntryFromC(centry), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Index) EntryByPath(path string, stage int) (*IndexEntry, error) {
|
||||||
|
cpath := C.CString(path)
|
||||||
|
defer C.free(unsafe.Pointer(cpath))
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
centry := C.git_index_get_bypath(v.ptr, cpath, C.int(stage))
|
||||||
|
if centry == nil {
|
||||||
|
return nil, MakeGitError(C.GIT_ENOTFOUND)
|
||||||
|
}
|
||||||
|
return newIndexEntryFromC(centry), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Index) Find(path string) (uint, error) {
|
||||||
|
cpath := C.CString(path)
|
||||||
|
defer C.free(unsafe.Pointer(cpath))
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
var pos C.size_t
|
||||||
|
ret := C.git_index_find(&pos, v.ptr, cpath)
|
||||||
|
if ret < 0 {
|
||||||
|
return uint(0), MakeGitError(ret)
|
||||||
|
}
|
||||||
|
return uint(pos), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Index) FindPrefix(prefix string) (uint, error) {
|
||||||
|
cprefix := C.CString(prefix)
|
||||||
|
defer C.free(unsafe.Pointer(cprefix))
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
var pos C.size_t
|
||||||
|
ret := C.git_index_find_prefix(&pos, v.ptr, cprefix)
|
||||||
|
if ret < 0 {
|
||||||
|
return uint(0), MakeGitError(ret)
|
||||||
|
}
|
||||||
|
return uint(pos), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Index) HasConflicts() bool {
|
func (v *Index) HasConflicts() bool {
|
||||||
return C.git_index_has_conflicts(v.ptr) != 0
|
return C.git_index_has_conflicts(v.ptr) != 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,11 @@ func TestIndexReadTree(t *testing.T) {
|
||||||
ref, err := repo.Head()
|
ref, err := repo.Head()
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
obj, err := ref.Peel(ObjectTree);
|
obj, err := ref.Peel(ObjectTree)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
tree := obj.(*Tree)
|
tree, err := obj.AsTree()
|
||||||
|
checkFatal(t, err)
|
||||||
|
|
||||||
idx, err := NewIndex()
|
idx, err := NewIndex()
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
25
merge.go
25
merge.go
|
@ -82,12 +82,19 @@ func (r *Repository) AnnotatedCommitFromRef(ref *Reference) (*AnnotatedCommit, e
|
||||||
type MergeTreeFlag int
|
type MergeTreeFlag int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MergeTreeFindRenames MergeTreeFlag = C.GIT_MERGE_TREE_FIND_RENAMES
|
// Detect renames that occur between the common ancestor and the "ours"
|
||||||
|
// side or the common ancestor and the "theirs" side. This will enable
|
||||||
|
// the ability to merge between a modified and renamed file.
|
||||||
|
MergeTreeFindRenames MergeTreeFlag = C.GIT_MERGE_FIND_RENAMES
|
||||||
|
// If a conflict occurs, exit immediately instead of attempting to
|
||||||
|
// continue resolving conflicts. The merge operation will fail with
|
||||||
|
// GIT_EMERGECONFLICT and no index will be returned.
|
||||||
|
MergeTreeFailOnConflict MergeTreeFlag = C.GIT_MERGE_FAIL_ON_CONFLICT
|
||||||
)
|
)
|
||||||
|
|
||||||
type MergeOptions struct {
|
type MergeOptions struct {
|
||||||
Version uint
|
Version uint
|
||||||
TreeFlags MergeTreeFlag
|
TreeFlags MergeTreeFlag
|
||||||
|
|
||||||
RenameThreshold uint
|
RenameThreshold uint
|
||||||
TargetLimit uint
|
TargetLimit uint
|
||||||
|
@ -99,7 +106,7 @@ type MergeOptions struct {
|
||||||
func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions {
|
func mergeOptionsFromC(opts *C.git_merge_options) MergeOptions {
|
||||||
return MergeOptions{
|
return MergeOptions{
|
||||||
Version: uint(opts.version),
|
Version: uint(opts.version),
|
||||||
TreeFlags: MergeTreeFlag(opts.tree_flags),
|
TreeFlags: MergeTreeFlag(opts.flags),
|
||||||
RenameThreshold: uint(opts.rename_threshold),
|
RenameThreshold: uint(opts.rename_threshold),
|
||||||
TargetLimit: uint(opts.target_limit),
|
TargetLimit: uint(opts.target_limit),
|
||||||
FileFavor: MergeFileFavor(opts.file_favor),
|
FileFavor: MergeFileFavor(opts.file_favor),
|
||||||
|
@ -125,7 +132,7 @@ func (mo *MergeOptions) toC() *C.git_merge_options {
|
||||||
}
|
}
|
||||||
return &C.git_merge_options{
|
return &C.git_merge_options{
|
||||||
version: C.uint(mo.Version),
|
version: C.uint(mo.Version),
|
||||||
tree_flags: C.git_merge_tree_flag_t(mo.TreeFlags),
|
flags: C.git_merge_flag_t(mo.TreeFlags),
|
||||||
rename_threshold: C.uint(mo.RenameThreshold),
|
rename_threshold: C.uint(mo.RenameThreshold),
|
||||||
target_limit: C.uint(mo.TargetLimit),
|
target_limit: C.uint(mo.TargetLimit),
|
||||||
file_favor: C.git_merge_file_favor_t(mo.FileFavor),
|
file_favor: C.git_merge_file_favor_t(mo.FileFavor),
|
||||||
|
@ -263,10 +270,10 @@ func (r *Repository) MergeBases(one, two *Oid) ([]*Oid, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
oids := make([]*Oid, coids.count)
|
oids := make([]*Oid, coids.count)
|
||||||
hdr := reflect.SliceHeader {
|
hdr := reflect.SliceHeader{
|
||||||
Data: uintptr(unsafe.Pointer(coids.ids)),
|
Data: uintptr(unsafe.Pointer(coids.ids)),
|
||||||
Len: int(coids.count),
|
Len: int(coids.count),
|
||||||
Cap: int(coids.count),
|
Cap: int(coids.count),
|
||||||
}
|
}
|
||||||
|
|
||||||
goSlice := *(*[]C.git_oid)(unsafe.Pointer(&hdr))
|
goSlice := *(*[]C.git_oid)(unsafe.Pointer(&hdr))
|
||||||
|
@ -354,7 +361,7 @@ func populateCMergeFileOptions(c *C.git_merge_file_options, options MergeFileOpt
|
||||||
c.our_label = C.CString(options.OurLabel)
|
c.our_label = C.CString(options.OurLabel)
|
||||||
c.their_label = C.CString(options.TheirLabel)
|
c.their_label = C.CString(options.TheirLabel)
|
||||||
c.favor = C.git_merge_file_favor_t(options.Favor)
|
c.favor = C.git_merge_file_favor_t(options.Favor)
|
||||||
c.flags = C.uint(options.Flags)
|
c.flags = C.git_merge_file_flag_t(options.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func freeCMergeFileOptions(c *C.git_merge_file_options) {
|
func freeCMergeFileOptions(c *C.git_merge_file_options) {
|
||||||
|
|
|
@ -115,7 +115,10 @@ func appendCommit(t *testing.T, repo *Repository) (*Oid, *Oid) {
|
||||||
parent, err := ref.Peel(ObjectCommit)
|
parent, err := ref.Peel(ObjectCommit)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
commitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree, parent.(*Commit))
|
parentCommit, err := parent.AsCommit()
|
||||||
|
checkFatal(t, err)
|
||||||
|
|
||||||
|
commitId, err := repo.CreateCommit("HEAD", sig, sig, message, tree, parentCommit)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
return commitId, treeId
|
return commitId, treeId
|
||||||
|
|
173
object.go
173
object.go
|
@ -4,7 +4,11 @@ package git
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import "runtime"
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
type ObjectType int
|
type ObjectType int
|
||||||
|
|
||||||
|
@ -17,15 +21,7 @@ const (
|
||||||
ObjectTag ObjectType = C.GIT_OBJ_TAG
|
ObjectTag ObjectType = C.GIT_OBJ_TAG
|
||||||
)
|
)
|
||||||
|
|
||||||
type Object interface {
|
type Object struct {
|
||||||
Free()
|
|
||||||
Id() *Oid
|
|
||||||
Type() ObjectType
|
|
||||||
Owner() *Repository
|
|
||||||
Peel(t ObjectType) (Object, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type gitObject struct {
|
|
||||||
ptr *C.git_object
|
ptr *C.git_object
|
||||||
repo *Repository
|
repo *Repository
|
||||||
}
|
}
|
||||||
|
@ -49,23 +45,128 @@ func (t ObjectType) String() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o gitObject) Id() *Oid {
|
func (o *Object) Id() *Oid {
|
||||||
return newOidFromC(C.git_object_id(o.ptr))
|
return newOidFromC(C.git_object_id(o.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o gitObject) Type() ObjectType {
|
func (o *Object) Type() ObjectType {
|
||||||
return ObjectType(C.git_object_type(o.ptr))
|
return ObjectType(C.git_object_type(o.ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Owner returns a weak reference to the repository which owns this
|
// Owner returns a weak reference to the repository which owns this
|
||||||
// object
|
// object. This won't keep the underlying repository alive.
|
||||||
func (o gitObject) Owner() *Repository {
|
func (o *Object) Owner() *Repository {
|
||||||
return &Repository{
|
return &Repository{
|
||||||
ptr: C.git_object_owner(o.ptr),
|
ptr: C.git_object_owner(o.ptr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *gitObject) Free() {
|
func dupObject(obj *Object, kind ObjectType) (*C.git_object, error) {
|
||||||
|
if obj.Type() != kind {
|
||||||
|
return nil, errors.New(fmt.Sprintf("object is not a %v", kind))
|
||||||
|
}
|
||||||
|
|
||||||
|
var cobj *C.git_object
|
||||||
|
|
||||||
|
runtime.LockOSThread()
|
||||||
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
|
if err := C.git_object_dup(&cobj, obj.ptr); err < 0 {
|
||||||
|
return nil, MakeGitError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cobj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func allocTree(ptr *C.git_tree, repo *Repository) *Tree {
|
||||||
|
tree := &Tree{
|
||||||
|
Object: Object{
|
||||||
|
ptr: (*C.git_object)(ptr),
|
||||||
|
repo: repo,
|
||||||
|
},
|
||||||
|
cast_ptr: ptr,
|
||||||
|
}
|
||||||
|
runtime.SetFinalizer(tree, (*Tree).Free)
|
||||||
|
|
||||||
|
return tree
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) AsTree() (*Tree, error) {
|
||||||
|
cobj, err := dupObject(o, ObjectTree)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocTree((*C.git_tree)(cobj), o.repo), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func allocCommit(ptr *C.git_commit, repo *Repository) *Commit {
|
||||||
|
commit := &Commit{
|
||||||
|
Object: Object{
|
||||||
|
ptr: (*C.git_object)(ptr),
|
||||||
|
repo: repo,
|
||||||
|
},
|
||||||
|
cast_ptr: ptr,
|
||||||
|
}
|
||||||
|
runtime.SetFinalizer(commit, (*Commit).Free)
|
||||||
|
|
||||||
|
return commit
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) AsCommit() (*Commit, error) {
|
||||||
|
cobj, err := dupObject(o, ObjectCommit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocCommit((*C.git_commit)(cobj), o.repo), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func allocBlob(ptr *C.git_blob, repo *Repository) *Blob {
|
||||||
|
blob := &Blob{
|
||||||
|
Object: Object{
|
||||||
|
ptr: (*C.git_object)(ptr),
|
||||||
|
repo: repo,
|
||||||
|
},
|
||||||
|
cast_ptr: ptr,
|
||||||
|
}
|
||||||
|
runtime.SetFinalizer(blob, (*Blob).Free)
|
||||||
|
|
||||||
|
return blob
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) AsBlob() (*Blob, error) {
|
||||||
|
cobj, err := dupObject(o, ObjectBlob)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocBlob((*C.git_blob)(cobj), o.repo), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func allocTag(ptr *C.git_tag, repo *Repository) *Tag {
|
||||||
|
tag := &Tag{
|
||||||
|
Object: Object{
|
||||||
|
ptr: (*C.git_object)(ptr),
|
||||||
|
repo: repo,
|
||||||
|
},
|
||||||
|
cast_ptr: ptr,
|
||||||
|
}
|
||||||
|
runtime.SetFinalizer(tag, (*Tag).Free)
|
||||||
|
|
||||||
|
return tag
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) AsTag() (*Tag, error) {
|
||||||
|
cobj, err := dupObject(o, ObjectTag)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return allocTag((*C.git_tag)(cobj), o.repo), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Object) Free() {
|
||||||
runtime.SetFinalizer(o, nil)
|
runtime.SetFinalizer(o, nil)
|
||||||
C.git_object_free(o.ptr)
|
C.git_object_free(o.ptr)
|
||||||
}
|
}
|
||||||
|
@ -82,7 +183,7 @@ func (o *gitObject) Free() {
|
||||||
//
|
//
|
||||||
// If peeling a tag we discover an object which cannot be peeled to the target
|
// If peeling a tag we discover an object which cannot be peeled to the target
|
||||||
// type due to the object model, an error will be returned.
|
// type due to the object model, an error will be returned.
|
||||||
func (o *gitObject) Peel(t ObjectType) (Object, error) {
|
func (o *Object) Peel(t ObjectType) (*Object, error) {
|
||||||
var cobj *C.git_object
|
var cobj *C.git_object
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
@ -95,44 +196,12 @@ func (o *gitObject) Peel(t ObjectType) (Object, error) {
|
||||||
return allocObject(cobj, o.repo), nil
|
return allocObject(cobj, o.repo), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func allocObject(cobj *C.git_object, repo *Repository) Object {
|
func allocObject(cobj *C.git_object, repo *Repository) *Object {
|
||||||
obj := gitObject{
|
obj := &Object{
|
||||||
ptr: cobj,
|
ptr: cobj,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
}
|
}
|
||||||
|
runtime.SetFinalizer(obj, (*Object).Free)
|
||||||
|
|
||||||
switch ObjectType(C.git_object_type(cobj)) {
|
return obj
|
||||||
case ObjectCommit:
|
|
||||||
commit := &Commit{
|
|
||||||
gitObject: obj,
|
|
||||||
cast_ptr: (*C.git_commit)(cobj),
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(commit, (*Commit).Free)
|
|
||||||
return commit
|
|
||||||
|
|
||||||
case ObjectTree:
|
|
||||||
tree := &Tree{
|
|
||||||
gitObject: obj,
|
|
||||||
cast_ptr: (*C.git_tree)(cobj),
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(tree, (*Tree).Free)
|
|
||||||
return tree
|
|
||||||
|
|
||||||
case ObjectBlob:
|
|
||||||
blob := &Blob{
|
|
||||||
gitObject: obj,
|
|
||||||
cast_ptr: (*C.git_blob)(cobj),
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(blob, (*Blob).Free)
|
|
||||||
return blob
|
|
||||||
case ObjectTag:
|
|
||||||
tag := &Tag{
|
|
||||||
gitObject: obj,
|
|
||||||
cast_ptr: (*C.git_tag)(cobj),
|
|
||||||
}
|
|
||||||
runtime.SetFinalizer(tag, (*Tag).Free)
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,12 @@ func TestObjectPoymorphism(t *testing.T) {
|
||||||
|
|
||||||
commitId, treeId := seedTestRepo(t, repo)
|
commitId, treeId := seedTestRepo(t, repo)
|
||||||
|
|
||||||
var obj Object
|
var obj *Object
|
||||||
|
|
||||||
commit, err := repo.LookupCommit(commitId)
|
commit, err := repo.LookupCommit(commitId)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
obj = commit
|
obj = &commit.Object
|
||||||
if obj.Type() != ObjectCommit {
|
if obj.Type() != ObjectCommit {
|
||||||
t.Fatalf("Wrong object type, expected commit, have %v", obj.Type())
|
t.Fatalf("Wrong object type, expected commit, have %v", obj.Type())
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,13 @@ func TestObjectPoymorphism(t *testing.T) {
|
||||||
tree, err := repo.LookupTree(treeId)
|
tree, err := repo.LookupTree(treeId)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
obj = tree
|
obj = &tree.Object
|
||||||
if obj.Type() != ObjectTree {
|
if obj.Type() != ObjectTree {
|
||||||
t.Fatalf("Wrong object type, expected tree, have %v", obj.Type())
|
t.Fatalf("Wrong object type, expected tree, have %v", obj.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
tree2, ok := obj.(*Tree)
|
tree2, err := obj.AsTree()
|
||||||
if !ok {
|
if err != nil {
|
||||||
t.Fatalf("Converting back to *Tree is not ok")
|
t.Fatalf("Converting back to *Tree is not ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,16 +46,16 @@ func TestObjectPoymorphism(t *testing.T) {
|
||||||
t.Fatal("Wrong filemode for \"README\"")
|
t.Fatal("Wrong filemode for \"README\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok = obj.(*Commit)
|
_, err = obj.AsCommit()
|
||||||
if ok {
|
if err == nil {
|
||||||
t.Fatalf("*Tree is somehow the same as *Commit")
|
t.Fatalf("*Tree is somehow the same as *Commit")
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err = repo.Lookup(tree.Id())
|
obj, err = repo.Lookup(tree.Id())
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
_, ok = obj.(*Tree)
|
_, err = obj.AsTree()
|
||||||
if !ok {
|
if err != nil {
|
||||||
t.Fatalf("Lookup creates the wrong type")
|
t.Fatalf("Lookup creates the wrong type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ func TestObjectOwner(t *testing.T) {
|
||||||
tree, err := repo.LookupTree(treeId)
|
tree, err := repo.LookupTree(treeId)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
checkOwner(t, repo, commit)
|
checkOwner(t, repo, commit.Object)
|
||||||
checkOwner(t, repo, tree)
|
checkOwner(t, repo, tree.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectPeel(t *testing.T) {
|
func TestObjectPeel(t *testing.T) {
|
||||||
|
@ -109,7 +109,7 @@ func TestObjectPeel(t *testing.T) {
|
||||||
|
|
||||||
commitID, treeID := seedTestRepo(t, repo)
|
commitID, treeID := seedTestRepo(t, repo)
|
||||||
|
|
||||||
var obj Object
|
var obj *Object
|
||||||
|
|
||||||
commit, err := repo.LookupCommit(commitID)
|
commit, err := repo.LookupCommit(commitID)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
|
@ -263,7 +263,7 @@ func (v *Reference) Delete() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Reference) Peel(t ObjectType) (Object, error) {
|
func (v *Reference) Peel(t ObjectType) (*Object, error) {
|
||||||
var cobj *C.git_object
|
var cobj *C.git_object
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
64
remote.go
64
remote.go
|
@ -72,12 +72,12 @@ type RemoteCallbacks struct {
|
||||||
type FetchPrune uint
|
type FetchPrune uint
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Use the setting from the configuration
|
// Use the setting from the configuration
|
||||||
FetchPruneUnspecified FetchPrune = C.GIT_FETCH_PRUNE_UNSPECIFIED
|
FetchPruneUnspecified FetchPrune = C.GIT_FETCH_PRUNE_UNSPECIFIED
|
||||||
// Force pruning on
|
// Force pruning on
|
||||||
FetchPruneOn FetchPrune = C.GIT_FETCH_PRUNE
|
FetchPruneOn FetchPrune = C.GIT_FETCH_PRUNE
|
||||||
// Force pruning off
|
// Force pruning off
|
||||||
FetchNoPrune FetchPrune = C.GIT_FETCH_NO_PRUNE
|
FetchNoPrune FetchPrune = C.GIT_FETCH_NO_PRUNE
|
||||||
)
|
)
|
||||||
|
|
||||||
type DownloadTags uint
|
type DownloadTags uint
|
||||||
|
@ -88,20 +88,20 @@ const (
|
||||||
DownloadTagsUnspecified DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED
|
DownloadTagsUnspecified DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_UNSPECIFIED
|
||||||
// Ask the server for tags pointing to objects we're already
|
// Ask the server for tags pointing to objects we're already
|
||||||
// downloading.
|
// downloading.
|
||||||
DownloadTagsAuto DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_AUTO
|
DownloadTagsAuto DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_AUTO
|
||||||
|
|
||||||
// Don't ask for any tags beyond the refspecs.
|
// Don't ask for any tags beyond the refspecs.
|
||||||
DownloadTagsNone DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_NONE
|
DownloadTagsNone DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_NONE
|
||||||
|
|
||||||
// Ask for the all the tags.
|
// Ask for the all the tags.
|
||||||
DownloadTagsAll DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_ALL
|
DownloadTagsAll DownloadTags = C.GIT_REMOTE_DOWNLOAD_TAGS_ALL
|
||||||
)
|
)
|
||||||
|
|
||||||
type FetchOptions struct {
|
type FetchOptions struct {
|
||||||
// Callbacks to use for this fetch operation
|
// Callbacks to use for this fetch operation
|
||||||
RemoteCallbacks RemoteCallbacks
|
RemoteCallbacks RemoteCallbacks
|
||||||
// Whether to perform a prune after the fetch
|
// Whether to perform a prune after the fetch
|
||||||
Prune FetchPrune
|
Prune FetchPrune
|
||||||
// Whether to write the results to FETCH_HEAD. Defaults to
|
// Whether to write the results to FETCH_HEAD. Defaults to
|
||||||
// on. Leave this default in order to behave like git.
|
// on. Leave this default in order to behave like git.
|
||||||
UpdateFetchhead bool
|
UpdateFetchhead bool
|
||||||
|
@ -111,7 +111,10 @@ type FetchOptions struct {
|
||||||
// downloading all of them.
|
// downloading all of them.
|
||||||
//
|
//
|
||||||
// The default is to auto-follow tags.
|
// The default is to auto-follow tags.
|
||||||
DownloadTags DownloadTags
|
DownloadTags DownloadTags
|
||||||
|
|
||||||
|
// Headers are extra headers for the fetch operation.
|
||||||
|
Headers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Remote struct {
|
type Remote struct {
|
||||||
|
@ -157,6 +160,9 @@ type PushOptions struct {
|
||||||
RemoteCallbacks RemoteCallbacks
|
RemoteCallbacks RemoteCallbacks
|
||||||
|
|
||||||
PbParallelism uint
|
PbParallelism uint
|
||||||
|
|
||||||
|
// Headers are extra headers for the push operation.
|
||||||
|
Headers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RemoteHead struct {
|
type RemoteHead struct {
|
||||||
|
@ -588,12 +594,16 @@ func (o *Remote) RefspecCount() uint {
|
||||||
func populateFetchOptions(options *C.git_fetch_options, opts *FetchOptions) {
|
func populateFetchOptions(options *C.git_fetch_options, opts *FetchOptions) {
|
||||||
C.git_fetch_init_options(options, C.GIT_FETCH_OPTIONS_VERSION)
|
C.git_fetch_init_options(options, C.GIT_FETCH_OPTIONS_VERSION)
|
||||||
if opts == nil {
|
if opts == nil {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
populateRemoteCallbacks(&options.callbacks, &opts.RemoteCallbacks)
|
populateRemoteCallbacks(&options.callbacks, &opts.RemoteCallbacks)
|
||||||
options.prune = C.git_fetch_prune_t(opts.Prune)
|
options.prune = C.git_fetch_prune_t(opts.Prune)
|
||||||
options.update_fetchhead = cbool(opts.UpdateFetchhead)
|
options.update_fetchhead = cbool(opts.UpdateFetchhead)
|
||||||
options.download_tags = C.git_remote_autotag_option_t(opts.DownloadTags)
|
options.download_tags = C.git_remote_autotag_option_t(opts.DownloadTags)
|
||||||
|
|
||||||
|
options.custom_headers = C.git_strarray{}
|
||||||
|
options.custom_headers.count = C.size_t(len(opts.Headers))
|
||||||
|
options.custom_headers.strings = makeCStringsFromStrings(opts.Headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func populatePushOptions(options *C.git_push_options, opts *PushOptions) {
|
func populatePushOptions(options *C.git_push_options, opts *PushOptions) {
|
||||||
|
@ -604,6 +614,10 @@ func populatePushOptions(options *C.git_push_options, opts *PushOptions) {
|
||||||
|
|
||||||
options.pb_parallelism = C.uint(opts.PbParallelism)
|
options.pb_parallelism = C.uint(opts.PbParallelism)
|
||||||
|
|
||||||
|
options.custom_headers = C.git_strarray{}
|
||||||
|
options.custom_headers.count = C.size_t(len(opts.Headers))
|
||||||
|
options.custom_headers.strings = makeCStringsFromStrings(opts.Headers)
|
||||||
|
|
||||||
populateRemoteCallbacks(&options.callbacks, &opts.RemoteCallbacks)
|
populateRemoteCallbacks(&options.callbacks, &opts.RemoteCallbacks)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +625,7 @@ func populatePushOptions(options *C.git_push_options, opts *PushOptions) {
|
||||||
// to use for this fetch, use an empty list to use the refspecs from
|
// to use for this fetch, use an empty list to use the refspecs from
|
||||||
// the configuration; msg specifies what to use for the reflog
|
// the configuration; msg specifies what to use for the reflog
|
||||||
// entries. Leave "" to use defaults.
|
// entries. Leave "" to use defaults.
|
||||||
func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error {
|
func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error {
|
||||||
var cmsg *C.char = nil
|
var cmsg *C.char = nil
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
cmsg = C.CString(msg)
|
cmsg = C.CString(msg)
|
||||||
|
@ -628,6 +642,7 @@ func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error
|
||||||
|
|
||||||
populateFetchOptions(coptions, opts)
|
populateFetchOptions(coptions, opts)
|
||||||
defer untrackCalbacksPayload(&coptions.callbacks)
|
defer untrackCalbacksPayload(&coptions.callbacks)
|
||||||
|
defer freeStrarray(&coptions.custom_headers)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
@ -639,22 +654,34 @@ func (o *Remote) Fetch(refspecs []string, opts *FetchOptions, msg string) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Remote) ConnectFetch(callbacks *RemoteCallbacks) error {
|
func (o *Remote) ConnectFetch(callbacks *RemoteCallbacks, headers []string) error {
|
||||||
return o.Connect(ConnectDirectionFetch, callbacks)
|
return o.Connect(ConnectDirectionFetch, callbacks, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Remote) ConnectPush(callbacks *RemoteCallbacks) error {
|
func (o *Remote) ConnectPush(callbacks *RemoteCallbacks, headers []string) error {
|
||||||
return o.Connect(ConnectDirectionPush, callbacks)
|
return o.Connect(ConnectDirectionPush, callbacks, headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Remote) Connect(direction ConnectDirection, callbacks *RemoteCallbacks) error {
|
// Connect opens a connection to a remote.
|
||||||
var ccallbacks C.git_remote_callbacks;
|
//
|
||||||
|
// The transport is selected based on the URL. The direction argument
|
||||||
|
// is due to a limitation of the git protocol (over TCP or SSH) which
|
||||||
|
// starts up a specific binary which can only do the one or the other.
|
||||||
|
//
|
||||||
|
// 'headers' are extra HTTP headers to use in this connection.
|
||||||
|
func (o *Remote) Connect(direction ConnectDirection, callbacks *RemoteCallbacks, headers []string) error {
|
||||||
|
var ccallbacks C.git_remote_callbacks
|
||||||
populateRemoteCallbacks(&ccallbacks, callbacks)
|
populateRemoteCallbacks(&ccallbacks, callbacks)
|
||||||
|
|
||||||
|
cheaders := C.git_strarray{}
|
||||||
|
cheaders.count = C.size_t(len(headers))
|
||||||
|
cheaders.strings = makeCStringsFromStrings(headers)
|
||||||
|
defer freeStrarray(&cheaders)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
if ret := C.git_remote_connect(o.ptr, C.git_direction(direction), &ccallbacks); ret != 0 {
|
if ret := C.git_remote_connect(o.ptr, C.git_direction(direction), &ccallbacks, &cheaders); ret != 0 {
|
||||||
return MakeGitError(ret)
|
return MakeGitError(ret)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -717,6 +744,7 @@ func (o *Remote) Push(refspecs []string, opts *PushOptions) error {
|
||||||
|
|
||||||
populatePushOptions(coptions, opts)
|
populatePushOptions(coptions, opts)
|
||||||
defer untrackCalbacksPayload(&coptions.callbacks)
|
defer untrackCalbacksPayload(&coptions.callbacks)
|
||||||
|
defer freeStrarray(&coptions.custom_headers)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
@ -733,7 +761,7 @@ func (o *Remote) PruneRefs() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Remote) Prune(callbacks *RemoteCallbacks) error {
|
func (o *Remote) Prune(callbacks *RemoteCallbacks) error {
|
||||||
var ccallbacks C.git_remote_callbacks;
|
var ccallbacks C.git_remote_callbacks
|
||||||
populateRemoteCallbacks(&ccallbacks, callbacks)
|
populateRemoteCallbacks(&ccallbacks, callbacks)
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
|
@ -39,7 +39,7 @@ func TestCertificateCheck(t *testing.T) {
|
||||||
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
options := FetchOptions {
|
options := FetchOptions{
|
||||||
RemoteCallbacks: RemoteCallbacks{
|
RemoteCallbacks: RemoteCallbacks{
|
||||||
CertificateCheckCallback: func(cert *Certificate, valid bool, hostname string) ErrorCode {
|
CertificateCheckCallback: func(cert *Certificate, valid bool, hostname string) ErrorCode {
|
||||||
return assertHostname(cert, valid, hostname, t)
|
return assertHostname(cert, valid, hostname, t)
|
||||||
|
@ -58,7 +58,7 @@ func TestRemoteConnect(t *testing.T) {
|
||||||
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = remote.ConnectFetch(nil)
|
err = remote.ConnectFetch(nil, nil)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ func TestRemoteLs(t *testing.T) {
|
||||||
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = remote.ConnectFetch(nil)
|
err = remote.ConnectFetch(nil, nil)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
heads, err := remote.Ls()
|
heads, err := remote.Ls()
|
||||||
|
@ -87,7 +87,7 @@ func TestRemoteLsFiltering(t *testing.T) {
|
||||||
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
remote, err := repo.Remotes.Create("origin", "https://github.com/libgit2/TestGitRepository")
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = remote.ConnectFetch(nil)
|
err = remote.ConnectFetch(nil, nil)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
heads, err := remote.Ls("master")
|
heads, err := remote.Ls("master")
|
||||||
|
@ -166,7 +166,7 @@ func TestRemotePrune(t *testing.T) {
|
||||||
rr, err := repo.Remotes.Lookup("origin")
|
rr, err := repo.Remotes.Lookup("origin")
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = rr.ConnectFetch(nil)
|
err = rr.ConnectFetch(nil, nil)
|
||||||
checkFatal(t, err)
|
checkFatal(t, err)
|
||||||
|
|
||||||
err = rr.Prune(nil)
|
err = rr.Prune(nil)
|
||||||
|
|
|
@ -12,11 +12,11 @@ import (
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
type Repository struct {
|
type Repository struct {
|
||||||
ptr *C.git_repository
|
ptr *C.git_repository
|
||||||
// Remotes represents the collection of remotes and can be
|
// Remotes represents the collection of remotes and can be
|
||||||
// used to add, remove and configure remotes for this
|
// used to add, remove and configure remotes for this
|
||||||
// repository.
|
// repository.
|
||||||
Remotes RemoteCollection
|
Remotes RemoteCollection
|
||||||
// Submodules represents the collection of submodules and can
|
// Submodules represents the collection of submodules and can
|
||||||
// be used to add, remove and configure submodules in this
|
// be used to add, remove and configure submodules in this
|
||||||
// repostiory.
|
// repostiory.
|
||||||
|
@ -26,7 +26,7 @@ type Repository struct {
|
||||||
References ReferenceCollection
|
References ReferenceCollection
|
||||||
// Notes represents the collection of notes and can be used to
|
// Notes represents the collection of notes and can be used to
|
||||||
// read, write and delete notes from this repository.
|
// read, write and delete notes from this repository.
|
||||||
Notes NoteCollection
|
Notes NoteCollection
|
||||||
// Tags represents the collection of tags and can be used to create,
|
// Tags represents the collection of tags and can be used to create,
|
||||||
// list and iterate tags in this repository.
|
// list and iterate tags in this repository.
|
||||||
Tags TagsCollection
|
Tags TagsCollection
|
||||||
|
@ -35,10 +35,10 @@ type Repository struct {
|
||||||
func newRepositoryFromC(ptr *C.git_repository) *Repository {
|
func newRepositoryFromC(ptr *C.git_repository) *Repository {
|
||||||
repo := &Repository{ptr: ptr}
|
repo := &Repository{ptr: ptr}
|
||||||
|
|
||||||
repo.Remotes.repo = repo
|
repo.Remotes.repo = repo
|
||||||
repo.Submodules.repo = repo
|
repo.Submodules.repo = repo
|
||||||
repo.References.repo = repo
|
repo.References.repo = repo
|
||||||
repo.Notes.repo = repo
|
repo.Notes.repo = repo
|
||||||
repo.Tags.repo = repo
|
repo.Tags.repo = repo
|
||||||
|
|
||||||
runtime.SetFinalizer(repo, (*Repository).Free)
|
runtime.SetFinalizer(repo, (*Repository).Free)
|
||||||
|
@ -62,15 +62,29 @@ func OpenRepository(path string) (*Repository, error) {
|
||||||
return newRepositoryFromC(ptr), nil
|
return newRepositoryFromC(ptr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func OpenRepositoryExtended(path string) (*Repository, error) {
|
type RepositoryOpenFlag int
|
||||||
|
|
||||||
|
const (
|
||||||
|
RepositoryOpenNoSearch RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_NO_SEARCH
|
||||||
|
RepositoryOpenCrossFs RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_CROSS_FS
|
||||||
|
RepositoryOpenBare RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_BARE
|
||||||
|
)
|
||||||
|
|
||||||
|
func OpenRepositoryExtended(path string, flags RepositoryOpenFlag, ceiling string) (*Repository, error) {
|
||||||
cpath := C.CString(path)
|
cpath := C.CString(path)
|
||||||
defer C.free(unsafe.Pointer(cpath))
|
defer C.free(unsafe.Pointer(cpath))
|
||||||
|
|
||||||
|
var cceiling *C.char = nil
|
||||||
|
if len(ceiling) > 0 {
|
||||||
|
cceiling = C.CString(ceiling)
|
||||||
|
defer C.free(unsafe.Pointer(cceiling))
|
||||||
|
}
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
||||||
var ptr *C.git_repository
|
var ptr *C.git_repository
|
||||||
ret := C.git_repository_open_ext(&ptr, cpath, 0, nil)
|
ret := C.git_repository_open_ext(&ptr, cpath, C.uint(flags), cceiling)
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return nil, MakeGitError(ret)
|
return nil, MakeGitError(ret)
|
||||||
}
|
}
|
||||||
|
@ -145,7 +159,7 @@ func (v *Repository) Index() (*Index, error) {
|
||||||
return newIndexFromC(ptr), nil
|
return newIndexFromC(ptr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) lookupType(id *Oid, t ObjectType) (Object, error) {
|
func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) {
|
||||||
var ptr *C.git_object
|
var ptr *C.git_object
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
@ -159,7 +173,7 @@ func (v *Repository) lookupType(id *Oid, t ObjectType) (Object, error) {
|
||||||
return allocObject(ptr, v), nil
|
return allocObject(ptr, v), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) Lookup(id *Oid) (Object, error) {
|
func (v *Repository) Lookup(id *Oid) (*Object, error) {
|
||||||
return v.lookupType(id, ObjectAny)
|
return v.lookupType(id, ObjectAny)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +183,7 @@ func (v *Repository) LookupTree(id *Oid) (*Tree, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj.(*Tree), nil
|
return obj.AsTree()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
|
func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
|
||||||
|
@ -178,7 +192,7 @@ func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj.(*Commit), nil
|
return obj.AsCommit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
|
func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
|
||||||
|
@ -187,7 +201,7 @@ func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj.(*Blob), nil
|
return obj.AsBlob()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
|
func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
|
||||||
|
@ -196,7 +210,7 @@ func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj.(*Tag), nil
|
return obj.AsTag()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) Head() (*Reference, error) {
|
func (v *Repository) Head() (*Reference, error) {
|
||||||
|
|
2
reset.go
2
reset.go
|
@ -17,7 +17,7 @@ const (
|
||||||
func (r *Repository) ResetToCommit(commit *Commit, resetType ResetType, opts *CheckoutOpts) error {
|
func (r *Repository) ResetToCommit(commit *Commit, resetType ResetType, opts *CheckoutOpts) error {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
ret := C.git_reset(r.ptr, commit.gitObject.ptr, C.git_reset_t(resetType), opts.toC())
|
ret := C.git_reset(r.ptr, commit.ptr, C.git_reset_t(resetType), opts.toC())
|
||||||
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
return MakeGitError(ret)
|
return MakeGitError(ret)
|
||||||
|
|
16
revparse.go
16
revparse.go
|
@ -20,16 +20,16 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Revspec struct {
|
type Revspec struct {
|
||||||
to Object
|
to *Object
|
||||||
from Object
|
from *Object
|
||||||
flags RevparseFlag
|
flags RevparseFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *Revspec) To() Object {
|
func (rs *Revspec) To() *Object {
|
||||||
return rs.to
|
return rs.to
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *Revspec) From() Object {
|
func (rs *Revspec) From() *Object {
|
||||||
return rs.from
|
return rs.from
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@ func (rs *Revspec) Flags() RevparseFlag {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRevspecFromC(ptr *C.git_revspec, repo *Repository) *Revspec {
|
func newRevspecFromC(ptr *C.git_revspec, repo *Repository) *Revspec {
|
||||||
var to Object
|
var to *Object
|
||||||
var from Object
|
var from *Object
|
||||||
|
|
||||||
if ptr.to != nil {
|
if ptr.to != nil {
|
||||||
to = allocObject(ptr.to, repo)
|
to = allocObject(ptr.to, repo)
|
||||||
|
@ -73,7 +73,7 @@ func (r *Repository) Revparse(spec string) (*Revspec, error) {
|
||||||
return newRevspecFromC(&crevspec, r), nil
|
return newRevspecFromC(&crevspec, r), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Repository) RevparseSingle(spec string) (Object, error) {
|
func (v *Repository) RevparseSingle(spec string) (*Object, error) {
|
||||||
cspec := C.CString(spec)
|
cspec := C.CString(spec)
|
||||||
defer C.free(unsafe.Pointer(cspec))
|
defer C.free(unsafe.Pointer(cspec))
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ func (v *Repository) RevparseSingle(spec string) (Object, error) {
|
||||||
return allocObject(ptr, v), nil
|
return allocObject(ptr, v), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Repository) RevparseExt(spec string) (Object, *Reference, error) {
|
func (r *Repository) RevparseExt(spec string) (*Object, *Reference, error) {
|
||||||
cspec := C.CString(spec)
|
cspec := C.CString(spec)
|
||||||
defer C.free(unsafe.Pointer(cspec))
|
defer C.free(unsafe.Pointer(cspec))
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ func TestRevparseExt(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkObject(t *testing.T, obj Object, id *Oid) {
|
func checkObject(t *testing.T, obj *Object, id *Oid) {
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
t.Fatalf("bad object")
|
t.Fatalf("bad object")
|
||||||
}
|
}
|
||||||
|
|
8
tag.go
8
tag.go
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
// Tag
|
// Tag
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
gitObject
|
Object
|
||||||
cast_ptr *C.git_tag
|
cast_ptr *C.git_tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func (t Tag) Tagger() *Signature {
|
||||||
return newSignatureFromC(cast_ptr)
|
return newSignatureFromC(cast_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Tag) Target() Object {
|
func (t Tag) Target() *Object {
|
||||||
var ptr *C.git_object
|
var ptr *C.git_object
|
||||||
ret := C.git_tag_target(&ptr, t.cast_ptr)
|
ret := C.git_tag_target(&ptr, t.cast_ptr)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ func (c *TagsCollection) Create(
|
||||||
}
|
}
|
||||||
defer C.git_signature_free(taggerSig)
|
defer C.git_signature_free(taggerSig)
|
||||||
|
|
||||||
ctarget := commit.gitObject.ptr
|
ctarget := commit.ptr
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
@ -102,7 +102,7 @@ func (c *TagsCollection) CreateLightweight(name string, commit *Commit, force bo
|
||||||
cname := C.CString(name)
|
cname := C.CString(name)
|
||||||
defer C.free(unsafe.Pointer(cname))
|
defer C.free(unsafe.Pointer(cname))
|
||||||
|
|
||||||
ctarget := commit.gitObject.ptr
|
ctarget := commit.ptr
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
defer runtime.UnlockOSThread()
|
defer runtime.UnlockOSThread()
|
||||||
|
|
4
tree.go
4
tree.go
|
@ -23,7 +23,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Tree struct {
|
type Tree struct {
|
||||||
gitObject
|
Object
|
||||||
cast_ptr *C.git_tree
|
cast_ptr *C.git_tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ func (v *TreeBuilder) Free() {
|
||||||
C.git_treebuilder_free(v.ptr)
|
C.git_treebuilder_free(v.ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode int) error {
|
func (v *TreeBuilder) Insert(filename string, id *Oid, filemode Filemode) error {
|
||||||
cfilename := C.CString(filename)
|
cfilename := C.CString(filename)
|
||||||
defer C.free(unsafe.Pointer(cfilename))
|
defer C.free(unsafe.Pointer(cfilename))
|
||||||
|
|
||||||
|
|
41
tree_test.go
41
tree_test.go
|
@ -20,3 +20,44 @@ func TestTreeEntryById(t *testing.T) {
|
||||||
t.Fatalf("entry id %v was not found", id)
|
t.Fatalf("entry id %v was not found", id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTreeBuilderInsert(t *testing.T) {
|
||||||
|
repo := createTestRepo(t)
|
||||||
|
defer cleanupTestRepo(t, repo)
|
||||||
|
|
||||||
|
subTree, err := repo.TreeBuilder()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TreeBuilder: %v", err)
|
||||||
|
}
|
||||||
|
defer subTree.Free()
|
||||||
|
|
||||||
|
odb, err := repo.Odb()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("repo.Odb: %v", err)
|
||||||
|
}
|
||||||
|
blobId, err := odb.Write([]byte("hello"), ObjectBlob)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("odb.Write: %v", err)
|
||||||
|
}
|
||||||
|
if err = subTree.Insert("subfile", blobId, FilemodeBlobExecutable); err != nil {
|
||||||
|
t.Fatalf("TreeBuilder.Insert: %v", err)
|
||||||
|
}
|
||||||
|
treeID, err := subTree.Write()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("TreeBuilder.Write: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := repo.LookupTree(treeID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("LookupTree: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
entry, err := tree.EntryByPath("subfile")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("tree.EntryByPath(%q): %v", "subfile", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !entry.Id.Equal(blobId) {
|
||||||
|
t.Fatalf("got oid %v, want %v", entry.Id, blobId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue