gogit: check if revision changed before cloning in checkout branch (#694)
* Check if revision has changed in gogit CheckoutBranch Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
This commit is contained in:
parent
6a793a55f6
commit
8a3df9da42
|
@ -26,8 +26,10 @@ import (
|
|||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
extgogit "github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/config"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/go-git/go-git/v5/storage/memory"
|
||||
|
||||
"github.com/fluxcd/pkg/gitutil"
|
||||
"github.com/fluxcd/pkg/version"
|
||||
|
@ -50,13 +52,14 @@ func CheckoutStrategyForOptions(_ context.Context, opts git.CheckoutOptions) git
|
|||
if branch == "" {
|
||||
branch = git.DefaultBranch
|
||||
}
|
||||
return &CheckoutBranch{Branch: branch, RecurseSubmodules: opts.RecurseSubmodules}
|
||||
return &CheckoutBranch{Branch: branch, RecurseSubmodules: opts.RecurseSubmodules, LastRevision: opts.LastRevision}
|
||||
}
|
||||
}
|
||||
|
||||
type CheckoutBranch struct {
|
||||
Branch string
|
||||
RecurseSubmodules bool
|
||||
LastRevision string
|
||||
}
|
||||
|
||||
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *git.AuthOptions) (*git.Commit, error) {
|
||||
|
@ -64,7 +67,31 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to construct auth method with options: %w", err)
|
||||
}
|
||||
|
||||
ref := plumbing.NewBranchReferenceName(c.Branch)
|
||||
// check if previous revision has changed before attempting to clone
|
||||
if c.LastRevision != "" {
|
||||
config := &config.RemoteConfig{
|
||||
Name: git.DefaultOrigin,
|
||||
URLs: []string{url},
|
||||
}
|
||||
rem := extgogit.NewRemote(memory.NewStorage(), config)
|
||||
refs, err := rem.List(&extgogit.ListOptions{
|
||||
Auth: authMethod,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to list remote for '%s': %w", url, err)
|
||||
}
|
||||
|
||||
currentRevision := filterRefs(refs, ref)
|
||||
if currentRevision != "" && currentRevision == c.LastRevision {
|
||||
return nil, git.NoChangesError{
|
||||
Message: "no changes since last reconcilation",
|
||||
ObservedRevision: currentRevision,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repo, err := extgogit.PlainCloneContext(ctx, path, false, &extgogit.CloneOptions{
|
||||
URL: url,
|
||||
Auth: authMethod,
|
||||
|
@ -333,3 +360,13 @@ func recurseSubmodules(recurse bool) extgogit.SubmoduleRescursivity {
|
|||
}
|
||||
return extgogit.NoRecurseSubmodules
|
||||
}
|
||||
|
||||
func filterRefs(refs []*plumbing.Reference, currentRef plumbing.ReferenceName) string {
|
||||
for _, ref := range refs {
|
||||
if ref.Name().String() == currentRef.String() {
|
||||
return fmt.Sprintf("%s/%s", currentRef.Short(), ref.Hash().String())
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
|
|||
filesCreated map[string]string
|
||||
expectedCommit string
|
||||
expectedErr string
|
||||
lastRevision string
|
||||
}{
|
||||
{
|
||||
name: "Default branch",
|
||||
|
@ -80,10 +81,18 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
|
|||
expectedCommit: firstCommit.String(),
|
||||
},
|
||||
{
|
||||
name: "Other branch",
|
||||
name: "skip clone if LastRevision hasn't changed",
|
||||
branch: "master",
|
||||
filesCreated: map[string]string{"branch": "init"},
|
||||
expectedErr: fmt.Sprintf("no changes since last reconcilation: observed revision 'master/%s'", firstCommit.String()),
|
||||
lastRevision: fmt.Sprintf("master/%s", firstCommit.String()),
|
||||
},
|
||||
{
|
||||
name: "Other branch - revision has changed",
|
||||
branch: "test",
|
||||
filesCreated: map[string]string{"branch": "second"},
|
||||
expectedCommit: secondCommit.String(),
|
||||
lastRevision: fmt.Sprintf("master/%s", firstCommit.String()),
|
||||
},
|
||||
{
|
||||
name: "Non existing branch",
|
||||
|
@ -97,7 +106,8 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
|
|||
g := NewWithT(t)
|
||||
|
||||
branch := CheckoutBranch{
|
||||
Branch: tt.branch,
|
||||
Branch: tt.branch,
|
||||
LastRevision: tt.lastRevision,
|
||||
}
|
||||
tmpDir := t.TempDir()
|
||||
|
||||
|
|
Loading…
Reference in New Issue