Skip to content

Commit

Permalink
gogit: check if revision changed before cloning in checkout branch (f…
Browse files Browse the repository at this point in the history
…luxcd#694)

* Check if revision has changed in gogit CheckoutBranch

Signed-off-by: Somtochi Onyekwere <somtochionyekwere@gmail.com>
  • Loading branch information
somtochiama authored and Paulo Gomes committed May 6, 2022
1 parent 1c8271a commit 993060c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 4 deletions.
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func main() {
ControllerName: controllerName,
Cache: c,
TTL: ttl,
CacheRecorder: cacheRecorder,
CacheRecorder: cacheRecorder,
}).SetupWithManagerAndOptions(mgr, controllers.HelmChartReconcilerOptions{
MaxConcurrentReconciles: concurrent,
RateLimiter: helper.GetRateLimiter(rateLimiterOptions),
Expand Down
39 changes: 38 additions & 1 deletion pkg/git/gogit/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -50,21 +52,46 @@ 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) {
authMethod, err := transportAuth(opts)
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,
Expand Down Expand Up @@ -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 ""
}
15 changes: 13 additions & 2 deletions pkg/git/gogit/checkout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package gogit
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -60,6 +61,7 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
filesCreated map[string]string
expectedCommit string
expectedErr string
lastRevision string
}{
{
name: "Default branch",
Expand All @@ -68,10 +70,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",
Expand All @@ -85,7 +95,8 @@ func TestCheckoutBranch_Checkout(t *testing.T) {
g := NewWithT(t)

branch := CheckoutBranch{
Branch: tt.branch,
Branch: tt.branch,
LastRevision: tt.lastRevision,
}
tmpDir := t.TempDir()

Expand Down

0 comments on commit 993060c

Please sign in to comment.