Skip to content

Commit

Permalink
fix incorrect commits when files are deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
choffmeister committed Feb 4, 2022
1 parent af9345c commit 0664a9a
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 35 deletions.
47 changes: 47 additions & 0 deletions internal/git.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package internal

import (
"time"

"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
"github.com/go-git/go-git/v5/plumbing/object"
)

type Git struct {
Provider GitProvider
}
Expand All @@ -16,3 +26,40 @@ type GitAuthor struct {
}

const branchPrefix = "git-ops-update"

func applyChangesAsCommit(worktree git.Worktree, dir string, changes Changes, message string, author GitAuthor, callbacks ...func() error) (*plumbing.Hash, error) {
err := changes.Push(dir)
if err != nil {
return nil, err
}
err = runCallbacks(callbacks)
if err != nil {
return nil, err
}
excludes, err := gitignore.ReadPatterns(osfs.New(dir), []string{})
if err != nil {
return nil, err
}
worktree.Excludes = excludes

status, err := worktree.Status()
if err != nil {
return nil, err
}
for path, status := range status {
if status.Worktree != git.Unmodified || status.Staging != git.Unmodified {
_, err := worktree.Add(path)
if err != nil {
return nil, err
}
}
}

signature := object.Signature{Name: author.Name, Email: author.Email, When: time.Now()}
commit, err := worktree.Commit(message, &git.CommitOptions{Author: &signature})
if err != nil {
return nil, err
}

return &commit, nil
}
36 changes: 1 addition & 35 deletions internal/git_github.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,9 @@ import (
"fmt"
"regexp"
"strings"
"time"

"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/transport/http"

"github.com/google/go-github/v40/github"
Expand Down Expand Up @@ -116,7 +112,7 @@ func (p GitHubGitProvider) Request(dir string, changes Changes, callbacks ...fun

err = worktree.Checkout(&git.CheckoutOptions{Branch: baseBranch.Name()})
if err != nil {
return fmt.Errorf("unable to checkout to bae branch: %w", err)
return fmt.Errorf("unable to checkout to base branch: %w", err)
}
return nil
}
Expand Down Expand Up @@ -150,36 +146,6 @@ func (p GitHubGitProvider) AlreadyRequested(dir string, changes Changes) bool {
return targetBranchExists
}

func applyChangesAsCommit(worktree git.Worktree, dir string, changes Changes, message string, author GitAuthor, callbacks ...func() error) (*plumbing.Hash, error) {
err := changes.Push(dir)
if err != nil {
return nil, err
}
err = runCallbacks(callbacks)
if err != nil {
return nil, err
}
excludes, err := gitignore.ReadPatterns(osfs.New(dir), []string{})
if err != nil {
return nil, err
}
worktree.Excludes = excludes
err = worktree.AddWithOptions(&git.AddOptions{
All: true,
})
if err != nil {
return nil, err
}

signature := object.Signature{Name: author.Name, Email: author.Email, When: time.Now()}
commit, err := worktree.Commit(message, &git.CommitOptions{Author: &signature})
if err != nil {
return nil, err
}

return &commit, nil
}

func extractGitHubOwnerRepoFromRemote(remote git.Remote) (*string, *string, error) {
httpRegex := regexp.MustCompile(`^https://github.com/(?P<owner>[^/]+)/(?P<repo>.*)$`)
sshRegex := regexp.MustCompile(`^git@github.com:(?P<owner>[^/]+)/(?P<repo>.*)$`)
Expand Down
70 changes: 70 additions & 0 deletions internal/git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package internal

import (
"io/ioutil"
"os"
"path"
"testing"

"github.com/go-git/go-git/v5"
"github.com/stretchr/testify/assert"
)

func TestApplyChangesAsCommit(t *testing.T) {
dir, err := ioutil.TempDir(os.TempDir(), "git-ops-update-")
assert.NoError(t, err)
defer os.RemoveAll(dir)
file := path.Join(dir, "file")

repo, err := git.PlainInit(dir, false)
assert.NoError(t, err)

worktree, err := repo.Worktree()
assert.NoError(t, err)

status, err := worktree.Status()
assert.NoError(t, err)
assert.Equal(t, true, status.IsClean())

err = os.WriteFile(file, []byte("1"), 0o664)
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, false, status.IsClean())

_, err = applyChangesAsCommit(*worktree, dir, Changes{}, "commit", GitAuthor{Name: "test", Email: "test"})
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, true, status.IsClean())

err = os.WriteFile(file, []byte("2"), 0o664)
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, false, status.IsClean())

_, err = applyChangesAsCommit(*worktree, dir, Changes{}, "commit", GitAuthor{Name: "test", Email: "test"})
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, true, status.IsClean())

err = os.Remove(file)
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, false, status.IsClean())

_, err = applyChangesAsCommit(*worktree, dir, Changes{}, "commit", GitAuthor{Name: "test", Email: "test"})
assert.NoError(t, err)

status, err = worktree.Status()
assert.NoError(t, err)
assert.Equal(t, true, status.IsClean())
}

0 comments on commit 0664a9a

Please sign in to comment.