174
diff.go
174
diff.go
|
@ -3,7 +3,6 @@ package git
|
||||||
/*
|
/*
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
extern void _go_git_populate_apply_cb(git_apply_options *options);
|
|
||||||
extern int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLine, void *payload);
|
extern int _go_git_diff_foreach(git_diff *diff, int eachFile, int eachHunk, int eachLine, void *payload);
|
||||||
extern void _go_git_setup_diff_notify_callbacks(git_diff_options* opts);
|
extern void _go_git_setup_diff_notify_callbacks(git_diff_options* opts);
|
||||||
extern int _go_git_diff_blobs(git_blob *old, const char *old_path, git_blob *new, const char *new_path, git_diff_options *opts, int eachFile, int eachHunk, int eachLine, void *payload);
|
extern int _go_git_diff_blobs(git_blob *old, const char *old_path, git_blob *new, const char *new_path, git_diff_options *opts, int eachFile, int eachHunk, int eachLine, void *payload);
|
||||||
|
@ -551,7 +550,7 @@ const (
|
||||||
DiffFindRemoveUnmodified DiffFindOptionsFlag = C.GIT_DIFF_FIND_REMOVE_UNMODIFIED
|
DiffFindRemoveUnmodified DiffFindOptionsFlag = C.GIT_DIFF_FIND_REMOVE_UNMODIFIED
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO implement git_diff_similarity_metric
|
//TODO implement git_diff_similarity_metric
|
||||||
type DiffFindOptions struct {
|
type DiffFindOptions struct {
|
||||||
Flags DiffFindOptionsFlag
|
Flags DiffFindOptionsFlag
|
||||||
RenameThreshold uint16
|
RenameThreshold uint16
|
||||||
|
@ -848,174 +847,3 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string,
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyHunkCallback is a callback that will be made per delta (file) when applying a patch.
|
|
||||||
type ApplyHunkCallback func(*DiffHunk) (apply bool, err error)
|
|
||||||
|
|
||||||
// ApplyDeltaCallback is a callback that will be made per hunk when applying a patch.
|
|
||||||
type ApplyDeltaCallback func(*DiffDelta) (apply bool, err error)
|
|
||||||
|
|
||||||
// ApplyOptions has 2 callbacks that are called for hunks or deltas
|
|
||||||
// If these functions return an error, abort the apply process immediately.
|
|
||||||
// If the first return value is true, the delta/hunk will be applied. If it is false, the delta/hunk will not be applied. In either case, the rest of the apply process will continue.
|
|
||||||
type ApplyOptions struct {
|
|
||||||
ApplyHunkCallback ApplyHunkCallback
|
|
||||||
ApplyDeltaCallback ApplyDeltaCallback
|
|
||||||
Flags uint
|
|
||||||
}
|
|
||||||
|
|
||||||
//export hunkApplyCallback
|
|
||||||
func hunkApplyCallback(_hunk *C.git_diff_hunk, _payload unsafe.Pointer) C.int {
|
|
||||||
opts, ok := pointerHandles.Get(_payload).(*ApplyOptions)
|
|
||||||
if !ok {
|
|
||||||
panic("invalid apply options payload")
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.ApplyHunkCallback == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
hunk := diffHunkFromC(_hunk)
|
|
||||||
|
|
||||||
apply, err := opts.ApplyHunkCallback(&hunk)
|
|
||||||
if err != nil {
|
|
||||||
if gitError, ok := err.(*GitError); ok {
|
|
||||||
return C.int(gitError.Code)
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
} else if apply {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//export deltaApplyCallback
|
|
||||||
func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int {
|
|
||||||
opts, ok := pointerHandles.Get(_payload).(*ApplyOptions)
|
|
||||||
if !ok {
|
|
||||||
panic("invalid apply options payload")
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.ApplyDeltaCallback == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
delta := diffDeltaFromC(_delta)
|
|
||||||
|
|
||||||
apply, err := opts.ApplyDeltaCallback(&delta)
|
|
||||||
if err != nil {
|
|
||||||
if gitError, ok := err.(*GitError); ok {
|
|
||||||
return C.int(gitError.Code)
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
} else if apply {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultApplyOptions returns default options for applying diffs or patches.
|
|
||||||
func DefaultApplyOptions() (*ApplyOptions, error) {
|
|
||||||
opts := C.git_apply_options{}
|
|
||||||
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
ecode := C.git_apply_options_init(&opts, C.GIT_APPLY_OPTIONS_VERSION)
|
|
||||||
if int(ecode) != 0 {
|
|
||||||
|
|
||||||
return nil, MakeGitError(ecode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return applyOptionsFromC(&opts), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApplyOptions) toC() *C.git_apply_options {
|
|
||||||
if a == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := &C.git_apply_options{
|
|
||||||
version: C.GIT_APPLY_OPTIONS_VERSION,
|
|
||||||
flags: C.uint(a.Flags),
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.ApplyDeltaCallback != nil || a.ApplyHunkCallback != nil {
|
|
||||||
C._go_git_populate_apply_cb(opts)
|
|
||||||
opts.payload = pointerHandles.Track(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
return opts
|
|
||||||
}
|
|
||||||
|
|
||||||
func applyOptionsFromC(opts *C.git_apply_options) *ApplyOptions {
|
|
||||||
return &ApplyOptions{
|
|
||||||
Flags: uint(opts.flags),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyLocation represents the possible application locations for applying
|
|
||||||
// diffs.
|
|
||||||
type ApplyLocation int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ApplyLocationWorkdir applies the patch to the workdir, leaving the
|
|
||||||
// index untouched. This is the equivalent of `git apply` with no location
|
|
||||||
// argument.
|
|
||||||
ApplyLocationWorkdir ApplyLocation = C.GIT_APPLY_LOCATION_WORKDIR
|
|
||||||
// ApplyLocationIndex applies the patch to the index, leaving the working
|
|
||||||
// directory untouched. This is the equivalent of `git apply --cached`.
|
|
||||||
ApplyLocationIndex ApplyLocation = C.GIT_APPLY_LOCATION_INDEX
|
|
||||||
// ApplyLocationBoth applies the patch to both the working directory and
|
|
||||||
// the index. This is the equivalent of `git apply --index`.
|
|
||||||
ApplyLocationBoth ApplyLocation = C.GIT_APPLY_LOCATION_BOTH
|
|
||||||
)
|
|
||||||
|
|
||||||
// ApplyDiff appllies a Diff to the given repository, making changes directly
|
|
||||||
// in the working directory, the index, or both.
|
|
||||||
func (v *Repository) ApplyDiff(diff *Diff, location ApplyLocation, opts *ApplyOptions) error {
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
cOpts := opts.toC()
|
|
||||||
ecode := C.git_apply(v.ptr, diff.ptr, C.git_apply_location_t(location), cOpts)
|
|
||||||
runtime.KeepAlive(v)
|
|
||||||
runtime.KeepAlive(diff)
|
|
||||||
runtime.KeepAlive(cOpts)
|
|
||||||
if ecode < 0 {
|
|
||||||
return MakeGitError(ecode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DiffFromBuffer reads the contents of a git patch file into a Diff object.
|
|
||||||
//
|
|
||||||
// The diff object produced is similar to the one that would be produced if you
|
|
||||||
// actually produced it computationally by comparing two trees, however there
|
|
||||||
// may be subtle differences. For example, a patch file likely contains
|
|
||||||
// abbreviated object IDs, so the object IDs in a git_diff_delta produced by
|
|
||||||
// this function will also be abbreviated.
|
|
||||||
//
|
|
||||||
// This function will only read patch files created by a git implementation, it
|
|
||||||
// will not read unified diffs produced by the diff program, nor any other
|
|
||||||
// types of patch files.
|
|
||||||
func DiffFromBuffer(buffer []byte, repo *Repository) (*Diff, error) {
|
|
||||||
var diff *C.git_diff
|
|
||||||
|
|
||||||
cBuffer := C.CBytes(buffer)
|
|
||||||
defer C.free(unsafe.Pointer(cBuffer))
|
|
||||||
|
|
||||||
runtime.LockOSThread()
|
|
||||||
defer runtime.UnlockOSThread()
|
|
||||||
|
|
||||||
ecode := C.git_diff_from_buffer(&diff, (*C.char)(cBuffer), C.size_t(len(buffer)))
|
|
||||||
if ecode < 0 {
|
|
||||||
return nil, MakeGitError(ecode)
|
|
||||||
}
|
|
||||||
runtime.KeepAlive(diff)
|
|
||||||
|
|
||||||
return newDiffFromC(diff, repo), nil
|
|
||||||
}
|
|
||||||
|
|
307
diff_test.go
307
diff_test.go
|
@ -2,9 +2,6 @@ package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -239,307 +236,3 @@ func TestDiffBlobs(t *testing.T) {
|
||||||
t.Fatalf("Bad number of lines iterated")
|
t.Fatalf("Bad number of lines iterated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApplyDiffAddfile(t *testing.T) {
|
|
||||||
repo := createTestRepo(t)
|
|
||||||
defer cleanupTestRepo(t, repo)
|
|
||||||
|
|
||||||
seedTestRepo(t, repo)
|
|
||||||
|
|
||||||
addFirstFileCommit, addFileTree := addAndGetTree(t, repo, "file1", `hello`)
|
|
||||||
addSecondFileCommit, addSecondFileTree := addAndGetTree(t, repo, "file2", `hello2`)
|
|
||||||
|
|
||||||
diff, err := repo.DiffTreeToTree(addFileTree, addSecondFileTree, nil)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
t.Run("check does not apply to current tree because file exists", func(t *testing.T) {
|
|
||||||
err = repo.ResetToCommit(addSecondFileCommit, ResetHard, &CheckoutOpts{})
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, nil)
|
|
||||||
if err == nil {
|
|
||||||
t.Error("expecting applying patch to current repo to fail")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("check apply to correct commit", func(t *testing.T) {
|
|
||||||
err = repo.ResetToCommit(addFirstFileCommit, ResetHard, &CheckoutOpts{})
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, nil)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
t.Run("Check that diff only changed one file", func(t *testing.T) {
|
|
||||||
checkSecondFileStaged(t, repo)
|
|
||||||
|
|
||||||
index, err := repo.Index()
|
|
||||||
checkFatal(t, err)
|
|
||||||
defer index.Free()
|
|
||||||
|
|
||||||
newTreeOID, err := index.WriteTreeTo(repo)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
newTree, err := repo.LookupTree(newTreeOID)
|
|
||||||
checkFatal(t, err)
|
|
||||||
defer newTree.Free()
|
|
||||||
|
|
||||||
_, err = repo.CreateCommit("HEAD", signature(), signature(), fmt.Sprintf("patch apply"), newTree, addFirstFileCommit)
|
|
||||||
checkFatal(t, err)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("test applying patch produced the same diff", func(t *testing.T) {
|
|
||||||
head, err := repo.Head()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
commit, err := repo.LookupCommit(head.Target())
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
tree, err := commit.Tree()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
newDiff, err := repo.DiffTreeToTree(addFileTree, tree, nil)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
raw1b, err := diff.ToBuf(DiffFormatPatch)
|
|
||||||
checkFatal(t, err)
|
|
||||||
raw2b, err := newDiff.ToBuf(DiffFormatPatch)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
raw1 := string(raw1b)
|
|
||||||
raw2 := string(raw2b)
|
|
||||||
|
|
||||||
if raw1 != raw2 {
|
|
||||||
t.Error("diffs should be the same")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("check convert to raw buffer and apply", func(t *testing.T) {
|
|
||||||
err = repo.ResetToCommit(addFirstFileCommit, ResetHard, &CheckoutOpts{})
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
raw, err := diff.ToBuf(DiffFormatPatch)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if len(raw) == 0 {
|
|
||||||
t.Error("empty diff created")
|
|
||||||
}
|
|
||||||
|
|
||||||
diff2, err := DiffFromBuffer(raw, repo)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff2, ApplyLocationBoth, nil)
|
|
||||||
checkFatal(t, err)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("check apply callbacks work", func(t *testing.T) {
|
|
||||||
// reset the state and get new default options for test
|
|
||||||
resetAndGetOpts := func(t *testing.T) *ApplyOptions {
|
|
||||||
err = repo.ResetToCommit(addFirstFileCommit, ResetHard, &CheckoutOpts{})
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
opts, err := DefaultApplyOptions()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
return opts
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("Check hunk callback working applies patch", func(t *testing.T) {
|
|
||||||
opts := resetAndGetOpts(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
opts.ApplyHunkCallback = func(hunk *DiffHunk) (apply bool, err error) {
|
|
||||||
called = true
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, opts)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if called == false {
|
|
||||||
t.Error("apply hunk callback was not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
checkSecondFileStaged(t, repo)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Check delta callback working applies patch", func(t *testing.T) {
|
|
||||||
opts := resetAndGetOpts(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
opts.ApplyDeltaCallback = func(hunk *DiffDelta) (apply bool, err error) {
|
|
||||||
if hunk.NewFile.Path != "file2" {
|
|
||||||
t.Error("Unexpected delta in diff application")
|
|
||||||
}
|
|
||||||
called = true
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, opts)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if called == false {
|
|
||||||
t.Error("apply hunk callback was not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
checkSecondFileStaged(t, repo)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Check delta callback returning false does not apply patch", func(t *testing.T) {
|
|
||||||
opts := resetAndGetOpts(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
opts.ApplyDeltaCallback = func(hunk *DiffDelta) (apply bool, err error) {
|
|
||||||
if hunk.NewFile.Path != "file2" {
|
|
||||||
t.Error("Unexpected hunk in diff application")
|
|
||||||
}
|
|
||||||
called = true
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, opts)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if called == false {
|
|
||||||
t.Error("apply hunk callback was not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNoFilesStaged(t, repo)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Check hunk callback returning causes application to fail", func(t *testing.T) {
|
|
||||||
opts := resetAndGetOpts(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
opts.ApplyHunkCallback = func(hunk *DiffHunk) (apply bool, err error) {
|
|
||||||
called = true
|
|
||||||
return false, errors.New("something happened")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, opts)
|
|
||||||
if err == nil {
|
|
||||||
t.Error("expected an error after trying to apply")
|
|
||||||
}
|
|
||||||
|
|
||||||
if called == false {
|
|
||||||
t.Error("apply hunk callback was not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNoFilesStaged(t, repo)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Check delta callback returning causes application to fail", func(t *testing.T) {
|
|
||||||
opts := resetAndGetOpts(t)
|
|
||||||
|
|
||||||
called := false
|
|
||||||
opts.ApplyDeltaCallback = func(hunk *DiffDelta) (apply bool, err error) {
|
|
||||||
if hunk.NewFile.Path != "file2" {
|
|
||||||
t.Error("Unexpected delta in diff application")
|
|
||||||
}
|
|
||||||
called = true
|
|
||||||
return false, errors.New("something happened")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = repo.ApplyDiff(diff, ApplyLocationBoth, opts)
|
|
||||||
if err == nil {
|
|
||||||
t.Error("expected an error after trying to apply")
|
|
||||||
}
|
|
||||||
|
|
||||||
if called == false {
|
|
||||||
t.Error("apply hunk callback was not called")
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNoFilesStaged(t, repo)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkSecondFileStaged checks that there is a single file called "file2" uncommitted in the repo
|
|
||||||
func checkSecondFileStaged(t *testing.T, repo *Repository) {
|
|
||||||
opts := StatusOptions{
|
|
||||||
Show: StatusShowIndexAndWorkdir,
|
|
||||||
Flags: StatusOptIncludeUntracked,
|
|
||||||
}
|
|
||||||
|
|
||||||
statuses, err := repo.StatusList(&opts)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
count, err := statuses.EntryCount()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if count != 1 {
|
|
||||||
t.Error("diff should affect exactly one file")
|
|
||||||
}
|
|
||||||
if count == 0 {
|
|
||||||
t.Fatal("no statuses, cannot continue test")
|
|
||||||
}
|
|
||||||
|
|
||||||
entry, err := statuses.ByIndex(0)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if entry.Status != StatusIndexNew {
|
|
||||||
t.Error("status should be 'new' as file has been added between commits")
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry.HeadToIndex.NewFile.Path != "file2" {
|
|
||||||
t.Error("new file should be 'file2")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNoFilesStaged checks that there is a single file called "file2" uncommitted in the repo
|
|
||||||
func checkNoFilesStaged(t *testing.T, repo *Repository) {
|
|
||||||
opts := StatusOptions{
|
|
||||||
Show: StatusShowIndexAndWorkdir,
|
|
||||||
Flags: StatusOptIncludeUntracked,
|
|
||||||
}
|
|
||||||
|
|
||||||
statuses, err := repo.StatusList(&opts)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
count, err := statuses.EntryCount()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
if count != 0 {
|
|
||||||
t.Error("files changed unexpectedly")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// addAndGetTree creates a file and commits it, returning the commit and tree
|
|
||||||
func addAndGetTree(t *testing.T, repo *Repository, filename string, content string) (*Commit, *Tree) {
|
|
||||||
headCommit, err := headCommit(repo)
|
|
||||||
checkFatal(t, err)
|
|
||||||
defer headCommit.Free()
|
|
||||||
|
|
||||||
p := repo.Path()
|
|
||||||
p = strings.TrimSuffix(p, ".git")
|
|
||||||
p = strings.TrimSuffix(p, ".git/")
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(path.Join(p, filename), []byte((content)), 0777)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
index, err := repo.Index()
|
|
||||||
checkFatal(t, err)
|
|
||||||
defer index.Free()
|
|
||||||
|
|
||||||
err = index.AddByPath(filename)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
newTreeOID, err := index.WriteTreeTo(repo)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
newTree, err := repo.LookupTree(newTreeOID)
|
|
||||||
checkFatal(t, err)
|
|
||||||
defer newTree.Free()
|
|
||||||
|
|
||||||
commitId, err := repo.CreateCommit("HEAD", signature(), signature(), fmt.Sprintf("add %s", filename), newTree, headCommit)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
commit, err := repo.LookupCommit(commitId)
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
tree, err := commit.Tree()
|
|
||||||
checkFatal(t, err)
|
|
||||||
|
|
||||||
return commit, tree
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,12 +5,6 @@
|
||||||
|
|
||||||
typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload);
|
typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload);
|
||||||
|
|
||||||
void _go_git_populate_apply_cb(git_apply_options *options)
|
|
||||||
{
|
|
||||||
options->delta_cb = (git_apply_delta_cb)deltaApplyCallback;
|
|
||||||
options->hunk_cb = (git_apply_hunk_cb)hunkApplyCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _go_git_populate_remote_cb(git_clone_options *opts)
|
void _go_git_populate_remote_cb(git_clone_options *opts)
|
||||||
{
|
{
|
||||||
opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
|
opts->remote_cb = (git_remote_create_cb)remoteCreateCallback;
|
||||||
|
|
Loading…
Reference in New Issue