From de24abbdae38bfa7371cfa5f92c5223012c96b0e Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 10 Aug 2020 16:57:46 +0100 Subject: [PATCH 01/23] Add functionality for converting Diff objects to a buffer and back --- diff.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ diff_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/diff.go b/diff.go index e022b47..d9bceac 100644 --- a/diff.go +++ b/diff.go @@ -3,6 +3,7 @@ package git /* #include +extern void _go_git_apply_init_options(git_apply_options *options); 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 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); @@ -847,3 +848,76 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, return nil } + +type ApplyOptions struct { + Version uint + Flags uint + // TODO: there are some more flags, not currently used +} + +func DefaultApplyOptions() (*ApplyOptions, error) { + opts := C.git_apply_options{} + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + C._go_git_apply_init_options(&opts) + + return applyOptionsFromC(&opts), nil +} + +func (a *ApplyOptions) toC() *C.git_apply_options { + if a == nil { + return nil + } + + opts := &C.git_apply_options{ + version: C.uint(a.Version), + flags: C.uint(a.Flags), + } + + return opts +} + +func applyOptionsFromC(opts *C.git_apply_options) *ApplyOptions { + return &ApplyOptions{ + Version: uint(opts.version), + Flags: uint(opts.flags), + } +} + +type GitApplyLocation int + +const ( + GitApplyLocationWorkdir GitApplyLocation = C.GIT_APPLY_LOCATION_WORKDIR + GitApplyLocationIndex GitApplyLocation = C.GIT_APPLY_LOCATION_INDEX + GitApplyLocationBoth GitApplyLocation = C.GIT_APPLY_LOCATION_BOTH +) + +func (v *Repository) ApplyDiff(diff *Diff, location GitApplyLocation, opts *ApplyOptions) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_apply(v.ptr, diff.ptr, C.git_apply_location_t(location), opts.toC()) + runtime.KeepAlive(v) + if ecode < 0 { + return MakeGitError(ecode) + } + + return nil +} + +func DiffFromBuffer(buffer []byte, repo *Repository) (*Diff, error) { + var diff *C.git_diff + + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + ecode := C.git_diff_from_buffer(&diff, C.CString(string(buffer)), C.size_t(len(buffer))) + if ecode < 0 { + return nil, MakeGitError(ecode) + } + runtime.KeepAlive(diff) + + return newDiffFromC(diff, repo), nil +} diff --git a/diff_test.go b/diff_test.go index 6fbad51..1a6797f 100644 --- a/diff_test.go +++ b/diff_test.go @@ -236,3 +236,65 @@ func TestDiffBlobs(t *testing.T) { t.Fatalf("Bad number of lines iterated") } } + +func Test_ApplyDiff_Addfile(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, GitApplyLocationBoth, 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, GitApplyLocationBoth, nil) + checkFatal(t, err) + }) + + 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, GitApplyLocationBoth, nil) + checkFatal(t, err) + }) +} + +func addAndGetTree(t *testing.T, repo *Repository, filename string, content string) (*Commit, *Tree) { + commitId, err := commitSomething(repo, filename, content) + checkFatal(t, err) + + commit, err := repo.LookupCommit(commitId) + checkFatal(t, err) + + tree, err := commit.Tree() + checkFatal(t, err) + + return commit, tree +} -- 2.45.2 From 9bbbbb4a52a6cde948850621b3ac3aab9492fe0e Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 08:36:40 +0100 Subject: [PATCH 02/23] Fix missing func --- wrapper.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wrapper.c b/wrapper.c index c4a5ff0..b80e09f 100644 --- a/wrapper.c +++ b/wrapper.c @@ -6,6 +6,12 @@ typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload); +void _go_git_apply_init_options(git_apply_options *options) +{ + git_apply_options opts = GIT_APPLY_OPTIONS_INIT; + *options = opts; +} + void _go_git_populate_remote_cb(git_clone_options *opts) { opts->remote_cb = (git_remote_create_cb)remoteCreateCallback; -- 2.45.2 From 1352980b36d621e085d4c288b2b5b919a82e0c46 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 09:17:13 +0100 Subject: [PATCH 03/23] Add support for callback on hunks/apply --- diff.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- wrapper.c | 6 ++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/diff.go b/diff.go index d9bceac..3c18e56 100644 --- a/diff.go +++ b/diff.go @@ -551,7 +551,7 @@ const ( DiffFindRemoveUnmodified DiffFindOptionsFlag = C.GIT_DIFF_FIND_REMOVE_UNMODIFIED ) -//TODO implement git_diff_similarity_metric +// TODO implement git_diff_similarity_metric type DiffFindOptions struct { Flags DiffFindOptionsFlag RenameThreshold uint16 @@ -849,10 +849,63 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, return nil } +type ApplyHunkCallback func(*DiffHunk) (apply bool, err error) +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 resutnr 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 { Version uint - Flags uint - // TODO: there are some more flags, not currently used + ApplyHunkCallback + 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 { + 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 { + return -1 + } else if apply { + return 0 + } else { + return 1 + } } func DefaultApplyOptions() (*ApplyOptions, error) { @@ -876,6 +929,11 @@ func (a *ApplyOptions) toC() *C.git_apply_options { 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 } diff --git a/wrapper.c b/wrapper.c index b80e09f..a65c2ab 100644 --- a/wrapper.c +++ b/wrapper.c @@ -12,6 +12,12 @@ void _go_git_apply_init_options(git_apply_options *options) *options = opts; } +void _go_git_populate_apply_cb(git_apply_options *options) +{ + opts->delta_cb = (git_apply_delta_cb)deltaApplyCallback; + opts->hunk_cb = (git_apply_hunk_cb)hunkApplyCallback; +} + void _go_git_populate_remote_cb(git_clone_options *opts) { opts->remote_cb = (git_remote_create_cb)remoteCreateCallback; -- 2.45.2 From 887d2d9eebceeff3c45aed8081ef7119262b3b63 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 09:18:48 +0100 Subject: [PATCH 04/23] Fix missing extern --- diff.go | 1 + 1 file changed, 1 insertion(+) diff --git a/diff.go b/diff.go index 3c18e56..94f5da5 100644 --- a/diff.go +++ b/diff.go @@ -3,6 +3,7 @@ package git /* #include +extern void _go_git_populate_apply_cb(git_apply_options *options); extern void _go_git_apply_init_options(git_apply_options *options); 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); -- 2.45.2 From c5985ee1a37a0da25ccc41c250c0756a3fe1495b Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 10:27:20 +0100 Subject: [PATCH 05/23] fix tests --- diff_test.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++- wrapper.c | 4 +- 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/diff_test.go b/diff_test.go index 1a6797f..db8917d 100644 --- a/diff_test.go +++ b/diff_test.go @@ -2,6 +2,9 @@ package git import ( "errors" + "fmt" + "io/ioutil" + "path" "strings" "testing" ) @@ -249,6 +252,11 @@ func Test_ApplyDiff_Addfile(t *testing.T) { diff, err := repo.DiffTreeToTree(addFileTree, addSecondFileTree, nil) checkFatal(t, err) + opts := StatusOptions{ + Show: StatusShowIndexAndWorkdir, + Flags: StatusOptIncludeUntracked, + } + 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) @@ -265,6 +273,72 @@ func Test_ApplyDiff_Addfile(t *testing.T) { err = repo.ApplyDiff(diff, GitApplyLocationBoth, nil) checkFatal(t, err) + + t.Run("Check that diff only changed one file", func(t *testing.T) { + 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") + } + + 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) { @@ -287,7 +361,32 @@ func Test_ApplyDiff_Addfile(t *testing.T) { } func addAndGetTree(t *testing.T, repo *Repository, filename string, content string) (*Commit, *Tree) { - commitId, err := commitSomething(repo, filename, content) + 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) diff --git a/wrapper.c b/wrapper.c index a65c2ab..c38d4cd 100644 --- a/wrapper.c +++ b/wrapper.c @@ -14,8 +14,8 @@ void _go_git_apply_init_options(git_apply_options *options) void _go_git_populate_apply_cb(git_apply_options *options) { - opts->delta_cb = (git_apply_delta_cb)deltaApplyCallback; - opts->hunk_cb = (git_apply_hunk_cb)hunkApplyCallback; + 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) -- 2.45.2 From adfb859419caa4762a71a478225e2452eeb231e7 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 10:27:32 +0100 Subject: [PATCH 06/23] Fix nuill pointer dereference --- status.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/status.go b/status.go index e37a96d..c61aedb 100644 --- a/status.go +++ b/status.go @@ -86,6 +86,9 @@ func (statusList *StatusList) ByIndex(index int) (StatusEntry, error) { return StatusEntry{}, ErrInvalid } ptr := C.git_status_byindex(statusList.ptr, C.size_t(index)) + if ptr == nil { + return StatusEntry{}, MakeGitError(C.int(ErrNotFound)) + } entry := statusEntryFromC(ptr) runtime.KeepAlive(statusList) -- 2.45.2 From 315a4855f10c10c665ebaa8d80755bf14650432c Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 10:54:58 +0100 Subject: [PATCH 07/23] Add more tests and deduplicate some test code --- diff_test.go | 202 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 174 insertions(+), 28 deletions(-) diff --git a/diff_test.go b/diff_test.go index db8917d..2891615 100644 --- a/diff_test.go +++ b/diff_test.go @@ -252,11 +252,6 @@ func Test_ApplyDiff_Addfile(t *testing.T) { diff, err := repo.DiffTreeToTree(addFileTree, addSecondFileTree, nil) checkFatal(t, err) - opts := StatusOptions{ - Show: StatusShowIndexAndWorkdir, - Flags: StatusOptIncludeUntracked, - } - 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) @@ -275,29 +270,7 @@ func Test_ApplyDiff_Addfile(t *testing.T) { checkFatal(t, err) t.Run("Check that diff only changed one file", func(t *testing.T) { - 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") - } + checkSecondFileStaged(t, repo) index, err := repo.Index() checkFatal(t, err) @@ -358,8 +331,181 @@ func Test_ApplyDiff_Addfile(t *testing.T) { err = repo.ApplyDiff(diff2, GitApplyLocationBoth, 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, GitApplyLocationBoth, 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, GitApplyLocationBoth, 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, GitApplyLocationBoth, 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, GitApplyLocationBoth, 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, GitApplyLocationBoth, 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) -- 2.45.2 From 87433ff8a8636fd0aebce7a7257d1cac776a9424 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Fri, 14 Aug 2020 11:12:33 +0100 Subject: [PATCH 08/23] Remove changed fixed in other branch --- status.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/status.go b/status.go index c61aedb..e37a96d 100644 --- a/status.go +++ b/status.go @@ -86,9 +86,6 @@ func (statusList *StatusList) ByIndex(index int) (StatusEntry, error) { return StatusEntry{}, ErrInvalid } ptr := C.git_status_byindex(statusList.ptr, C.size_t(index)) - if ptr == nil { - return StatusEntry{}, MakeGitError(C.int(ErrNotFound)) - } entry := statusEntryFromC(ptr) runtime.KeepAlive(statusList) -- 2.45.2 From bbaf9746f96d8b6e7dcd623ae47e18db73840ec8 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Sat, 15 Aug 2020 19:27:43 -0700 Subject: [PATCH 09/23] Add two more GitHub Actions workflows This change adds: * `tag.yml`: Creates a new tag every time the master or a release branch is pushed. * `backport.yml`: Creates a cherry-pick in older release branches to keep them up to date with little cost. --- .github/workflows/backport.yml | 53 ++++++++++++++++++++++++++++++++++ .github/workflows/tag.yml | 28 ++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 .github/workflows/backport.yml create mode 100644 .github/workflows/tag.yml diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 0000000..4337fb1 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,53 @@ +name: Backport to older releases +on: + push: + branches: + - master + +jobs: + + backport: + strategy: + fail-fast: false + matrix: + branch: [ 'release-0.28', 'release-0.27' ] + name: Backport change to branch ${{ matrix.branch }} + + runs-on: ubuntu-20.04 + + steps: + - name: Check out code + uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: Create a cherry-pick PR + run: | + if ! git diff --quiet HEAD^ HEAD -- vendor/libgit2; then + echo '::warning::Skipping cherry-pick since it is a vendored libgit2 bump' + exit 0 + fi + + BRANCH_NAME="cherry-pick-${{ github.run_id }}-${{ matrix.branch }}" + + # Setup usernames and authentication + git config --global user.name "${{ github.actor }}" + git config --global user.email "${{ github.actor }}@users.noreply.github.com" + cat <<- EOF > $HOME/.netrc + machine github.com + login ${{ github.actor }} + password ${{ secrets.GITHUB_TOKEN }} + machine api.github.com + login ${{ github.actor }} + password ${{ secrets.GITHUB_TOKEN }} + EOF + chmod 600 $HOME/.netrc + + # Create the cherry-pick commit and create the PR for it. + git checkout "${{ matrix.branch }}" + git switch -c "${BRANCH_NAME}" + git cherry-pick -x "${{ github.sha }}" + git push --set-upstream origin "${BRANCH_NAME}" + GITHUB_TOKEN="${{ secrets.GITHUB_TOKEN }}" gh pr create \ + --base "${{ matrix.branch }}" \ + --title "$(git --no-pager show --format="%s" --no-patch HEAD)" \ + --body "$(git --no-pager show --format="%b" --no-patch HEAD)" diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 0000000..b293274 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,28 @@ +name: Tag new releases +on: + push: + branches: + - master + - release-* + +jobs: + + tag-release: + name: Bump tag in ${{ github.ref }} + + runs-on: ubuntu-20.04 + + steps: + - name: Check out code + uses: actions/checkout@v1 + with: + fetch-depth: 0 + - name: Bump version and push tag + id: bump-version + uses: anothrNick/github-tag-action@9aaabdb5e989894e95288328d8b17a6347217ae3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WITH_V: true + DEFAULT_BUMP: patch + TAG_CONTEXT: branch + RELEASE_BRANCHES: .* -- 2.45.2 From ad65e109e4bc99d099a501de14c8b8bdb32724ca Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:02:18 +0100 Subject: [PATCH 10/23] Do not embed callbacks in struct and give them more appropriate type names --- diff.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/diff.go b/diff.go index 94f5da5..1412ca9 100644 --- a/diff.go +++ b/diff.go @@ -850,17 +850,17 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, return nil } -type ApplyHunkCallback func(*DiffHunk) (apply bool, err error) -type ApplyDeltaCallback func(*DiffDelta) (apply bool, err error) +type ApplyHunkCb func(*DiffHunk) (apply bool, err error) +type ApplyDeltaCb 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 resutnr 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. +// 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 { - Version uint - ApplyHunkCallback - ApplyDeltaCallback - Flags uint + Version uint + ApplyHunkCallback ApplyHunkCb + ApplyDeltaCallback ApplyDeltaCb + Flags uint } //export hunkApplyCallback -- 2.45.2 From 067989fe994dd9d33a4b38e42f194e51e0f3438c Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:05:44 +0100 Subject: [PATCH 11/23] Fix some missing keepalives --- diff.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/diff.go b/diff.go index 1412ca9..2bd3cf0 100644 --- a/diff.go +++ b/diff.go @@ -957,8 +957,11 @@ func (v *Repository) ApplyDiff(diff *Diff, location GitApplyLocation, opts *Appl runtime.LockOSThread() defer runtime.UnlockOSThread() - ecode := C.git_apply(v.ptr, diff.ptr, C.git_apply_location_t(location), opts.toC()) + 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) } -- 2.45.2 From 97267d3f6e3d8d70efe80395b232d37744a39106 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:07:06 +0100 Subject: [PATCH 12/23] Remove uneeded locking of os thread in calling local C function --- diff.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/diff.go b/diff.go index 2bd3cf0..ff83ee2 100644 --- a/diff.go +++ b/diff.go @@ -912,9 +912,6 @@ func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int func DefaultApplyOptions() (*ApplyOptions, error) { opts := C.git_apply_options{} - runtime.LockOSThread() - defer runtime.UnlockOSThread() - C._go_git_apply_init_options(&opts) return applyOptionsFromC(&opts), nil -- 2.45.2 From 2edef4dbea041559bbb45c603610e4098042c5a4 Mon Sep 17 00:00:00 2001 From: michael boulton <61595820+mbfr@users.noreply.github.com> Date: Mon, 17 Aug 2020 08:08:06 +0100 Subject: [PATCH 13/23] Update wrapper.c Fix spaces->tabs Co-authored-by: lhchavez --- wrapper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wrapper.c b/wrapper.c index c38d4cd..c19d035 100644 --- a/wrapper.c +++ b/wrapper.c @@ -14,8 +14,8 @@ void _go_git_apply_init_options(git_apply_options *options) 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; + 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) -- 2.45.2 From d8f155f97105db4a68088d2fdb0dcac421da8bf8 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:15:14 +0100 Subject: [PATCH 14/23] Convert diff contents to CBuffer and free it instead of using a CString --- diff.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/diff.go b/diff.go index ff83ee2..f4be2ab 100644 --- a/diff.go +++ b/diff.go @@ -969,10 +969,13 @@ func (v *Repository) ApplyDiff(diff *Diff, location GitApplyLocation, opts *Appl 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.CString(string(buffer)), C.size_t(len(buffer))) + ecode := C.git_diff_from_buffer(&diff, (*C.char)(cBuffer), C.size_t(len(buffer))) if ecode < 0 { return nil, MakeGitError(ecode) } -- 2.45.2 From fff6c9d8aeda8515ccc214370e90e9e62e6d1955 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:17:58 +0100 Subject: [PATCH 15/23] Store pointer to apply options instead of copying the struct --- diff.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/diff.go b/diff.go index f4be2ab..ef295cf 100644 --- a/diff.go +++ b/diff.go @@ -865,7 +865,7 @@ type ApplyOptions struct { //export hunkApplyCallback func hunkApplyCallback(_hunk *C.git_diff_hunk, _payload unsafe.Pointer) C.int { - opts, ok := pointerHandles.Get(_payload).(ApplyOptions) + opts, ok := pointerHandles.Get(_payload).(*ApplyOptions) if !ok { panic("invalid apply options payload") } @@ -888,7 +888,7 @@ func hunkApplyCallback(_hunk *C.git_diff_hunk, _payload unsafe.Pointer) C.int { //export deltaApplyCallback func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int { - opts, ok := pointerHandles.Get(_payload).(ApplyOptions) + opts, ok := pointerHandles.Get(_payload).(*ApplyOptions) if !ok { panic("invalid apply options payload") } @@ -929,7 +929,7 @@ func (a *ApplyOptions) toC() *C.git_apply_options { if a.ApplyDeltaCallback != nil || a.ApplyHunkCallback != nil { C._go_git_populate_apply_cb(opts) - opts.payload = pointerHandles.Track(*a) + opts.payload = pointerHandles.Track(a) } return opts -- 2.45.2 From 7f3d112fbedbd1abd01d20744bdf93732f7f214d Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:20:36 +0100 Subject: [PATCH 16/23] Make it possible to use a git2go error as a return value from a diff callback and have it propagate --- diff.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/diff.go b/diff.go index ef295cf..b03a475 100644 --- a/diff.go +++ b/diff.go @@ -878,6 +878,9 @@ func hunkApplyCallback(_hunk *C.git_diff_hunk, _payload unsafe.Pointer) C.int { 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 @@ -901,6 +904,9 @@ func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int 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 -- 2.45.2 From d1d3dccd8a123a41e199ae8c92098df8930fddf2 Mon Sep 17 00:00:00 2001 From: michael boulton <61595820+mbfr@users.noreply.github.com> Date: Mon, 17 Aug 2020 08:21:39 +0100 Subject: [PATCH 17/23] Update diff_test.go Make test naming consistent Co-authored-by: lhchavez --- diff_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/diff_test.go b/diff_test.go index 2891615..020ec7f 100644 --- a/diff_test.go +++ b/diff_test.go @@ -240,7 +240,7 @@ func TestDiffBlobs(t *testing.T) { } } -func Test_ApplyDiff_Addfile(t *testing.T) { +func TestApplyDiffAddfile(t *testing.T) { repo := createTestRepo(t) defer cleanupTestRepo(t, repo) -- 2.45.2 From 37e56c28a8756a4b532168b1c39344a5d6ee9b0f Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Mon, 17 Aug 2020 08:36:02 +0100 Subject: [PATCH 18/23] Remove C wrapper for initialising apply opptions --- diff.go | 9 +++++++-- wrapper.c | 6 ------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/diff.go b/diff.go index b03a475..2e9bf58 100644 --- a/diff.go +++ b/diff.go @@ -4,7 +4,6 @@ package git #include extern void _go_git_populate_apply_cb(git_apply_options *options); -extern void _go_git_apply_init_options(git_apply_options *options); 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 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); @@ -918,7 +917,13 @@ func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int func DefaultApplyOptions() (*ApplyOptions, error) { opts := C.git_apply_options{} - C._go_git_apply_init_options(&opts) + ecode := C.git_apply_options_init(&opts, C.GIT_APPLY_OPTIONS_VERSION) + if int(ecode) != 0 { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + return nil, MakeGitError(ecode) + } return applyOptionsFromC(&opts), nil } diff --git a/wrapper.c b/wrapper.c index c19d035..4308ae4 100644 --- a/wrapper.c +++ b/wrapper.c @@ -6,12 +6,6 @@ typedef int (*gogit_submodule_cbk)(git_submodule *sm, const char *name, void *payload); -void _go_git_apply_init_options(git_apply_options *options) -{ - git_apply_options opts = GIT_APPLY_OPTIONS_INIT; - *options = opts; -} - void _go_git_populate_apply_cb(git_apply_options *options) { options->delta_cb = (git_apply_delta_cb)deltaApplyCallback; -- 2.45.2 From 6dc764106962a029d7dd9b1af1efd5521ce70b0a Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Tue, 18 Aug 2020 08:11:15 +0100 Subject: [PATCH 19/23] Make apply callback types have more conssitent names --- diff.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/diff.go b/diff.go index 2e9bf58..abb2ec1 100644 --- a/diff.go +++ b/diff.go @@ -849,16 +849,16 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, return nil } -type ApplyHunkCb func(*DiffHunk) (apply bool, err error) -type ApplyDeltaCb func(*DiffDelta) (apply bool, err error) +type ApplyHunkCallback func(*DiffHunk) (apply bool, err error) +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 { Version uint - ApplyHunkCallback ApplyHunkCb - ApplyDeltaCallback ApplyDeltaCb + ApplyHunkCallback ApplyHunkCallback + ApplyDeltaCallback ApplyDeltaCallback Flags uint } -- 2.45.2 From 633f7639dbe50390b31520aa54b8539d145a03c4 Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Tue, 18 Aug 2020 08:14:20 +0100 Subject: [PATCH 20/23] Hardcode version in apply options which should never change --- diff.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/diff.go b/diff.go index abb2ec1..42fc7b5 100644 --- a/diff.go +++ b/diff.go @@ -856,7 +856,6 @@ type ApplyDeltaCallback func(*DiffDelta) (apply bool, err error) // 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 { - Version uint ApplyHunkCallback ApplyHunkCallback ApplyDeltaCallback ApplyDeltaCallback Flags uint @@ -934,7 +933,7 @@ func (a *ApplyOptions) toC() *C.git_apply_options { } opts := &C.git_apply_options{ - version: C.uint(a.Version), + version: C.GIT_APPLY_OPTIONS_VERSION, flags: C.uint(a.Flags), } @@ -948,8 +947,7 @@ func (a *ApplyOptions) toC() *C.git_apply_options { func applyOptionsFromC(opts *C.git_apply_options) *ApplyOptions { return &ApplyOptions{ - Version: uint(opts.version), - Flags: uint(opts.flags), + Flags: uint(opts.flags), } } -- 2.45.2 From 05a41f164ce918e43bb81ed038014d63de81945f Mon Sep 17 00:00:00 2001 From: Michael Boulton Date: Tue, 18 Aug 2020 08:16:29 +0100 Subject: [PATCH 21/23] Move os thread lock to outer scope in defaultapplyoptions --- diff.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/diff.go b/diff.go index 42fc7b5..fb29f49 100644 --- a/diff.go +++ b/diff.go @@ -916,10 +916,11 @@ func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int 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 { - runtime.LockOSThread() - defer runtime.UnlockOSThread() return nil, MakeGitError(ecode) } -- 2.45.2 From 03e0cb481d3915e0ae655cdc7d0d107492fccf5b Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 18 Aug 2020 06:06:36 -0700 Subject: [PATCH 22/23] Added docstrings and fixed a golint violation I missed this during the review u_u. --- diff.go | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/diff.go b/diff.go index fb29f49..9d17dd7 100644 --- a/diff.go +++ b/diff.go @@ -849,7 +849,10 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string, 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 @@ -913,6 +916,7 @@ func deltaApplyCallback(_delta *C.git_diff_delta, _payload unsafe.Pointer) C.int } } +// DefaultApplyOptions returns default options for applying diffs or patches. func DefaultApplyOptions() (*ApplyOptions, error) { opts := C.git_apply_options{} @@ -952,15 +956,26 @@ func applyOptionsFromC(opts *C.git_apply_options) *ApplyOptions { } } -type GitApplyLocation int +// ApplyLocation represents the possible application locations for applying +// diffs. +type ApplyLocation int const ( - GitApplyLocationWorkdir GitApplyLocation = C.GIT_APPLY_LOCATION_WORKDIR - GitApplyLocationIndex GitApplyLocation = C.GIT_APPLY_LOCATION_INDEX - GitApplyLocationBoth GitApplyLocation = C.GIT_APPLY_LOCATION_BOTH + // 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 ) -func (v *Repository) ApplyDiff(diff *Diff, location GitApplyLocation, opts *ApplyOptions) error { +// 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() @@ -976,6 +991,17 @@ func (v *Repository) ApplyDiff(diff *Diff, location GitApplyLocation, opts *Appl 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 -- 2.45.2 From c64de3690154fd869eaff62b0b06821c42e04655 Mon Sep 17 00:00:00 2001 From: lhchavez Date: Tue, 18 Aug 2020 06:10:40 -0700 Subject: [PATCH 23/23] Fix the tests Pro tip: run tests before pushing. --- diff_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/diff_test.go b/diff_test.go index 020ec7f..394a4c1 100644 --- a/diff_test.go +++ b/diff_test.go @@ -256,7 +256,7 @@ func TestApplyDiffAddfile(t *testing.T) { err = repo.ResetToCommit(addSecondFileCommit, ResetHard, &CheckoutOpts{}) checkFatal(t, err) - err = repo.ApplyDiff(diff, GitApplyLocationBoth, nil) + err = repo.ApplyDiff(diff, ApplyLocationBoth, nil) if err == nil { t.Error("expecting applying patch to current repo to fail") } @@ -266,7 +266,7 @@ func TestApplyDiffAddfile(t *testing.T) { err = repo.ResetToCommit(addFirstFileCommit, ResetHard, &CheckoutOpts{}) checkFatal(t, err) - err = repo.ApplyDiff(diff, GitApplyLocationBoth, nil) + err = repo.ApplyDiff(diff, ApplyLocationBoth, nil) checkFatal(t, err) t.Run("Check that diff only changed one file", func(t *testing.T) { @@ -328,7 +328,7 @@ func TestApplyDiffAddfile(t *testing.T) { diff2, err := DiffFromBuffer(raw, repo) checkFatal(t, err) - err = repo.ApplyDiff(diff2, GitApplyLocationBoth, nil) + err = repo.ApplyDiff(diff2, ApplyLocationBoth, nil) checkFatal(t, err) }) @@ -353,7 +353,7 @@ func TestApplyDiffAddfile(t *testing.T) { return true, nil } - err = repo.ApplyDiff(diff, GitApplyLocationBoth, opts) + err = repo.ApplyDiff(diff, ApplyLocationBoth, opts) checkFatal(t, err) if called == false { @@ -375,7 +375,7 @@ func TestApplyDiffAddfile(t *testing.T) { return true, nil } - err = repo.ApplyDiff(diff, GitApplyLocationBoth, opts) + err = repo.ApplyDiff(diff, ApplyLocationBoth, opts) checkFatal(t, err) if called == false { @@ -397,7 +397,7 @@ func TestApplyDiffAddfile(t *testing.T) { return false, nil } - err = repo.ApplyDiff(diff, GitApplyLocationBoth, opts) + err = repo.ApplyDiff(diff, ApplyLocationBoth, opts) checkFatal(t, err) if called == false { @@ -416,7 +416,7 @@ func TestApplyDiffAddfile(t *testing.T) { return false, errors.New("something happened") } - err = repo.ApplyDiff(diff, GitApplyLocationBoth, opts) + err = repo.ApplyDiff(diff, ApplyLocationBoth, opts) if err == nil { t.Error("expected an error after trying to apply") } @@ -440,7 +440,7 @@ func TestApplyDiffAddfile(t *testing.T) { return false, errors.New("something happened") } - err = repo.ApplyDiff(diff, GitApplyLocationBoth, opts) + err = repo.ApplyDiff(diff, ApplyLocationBoth, opts) if err == nil { t.Error("expected an error after trying to apply") } -- 2.45.2