Fix tag checkout with libgit2

SetHeadDetached (git_repository_set_head_detached) only changes HEAD,
and does not actually checkout the files on disk. Use CheckoutHead with
the CheckoutForce Strategy to actually check the files out on disk.

Additionally add a test that validates the hash of a checked out file's
contents.

Previously, the hash of the desired tag was being reported as the
checked out revision by the GitRepository. However the wrong files were
checked out and an incorrect revision would be deployed by Flux.

Signed-off-by: Blake Burkhart <blake.burkhart@us.af.mil>
This commit is contained in:
Blake Burkhart 2021-06-28 19:50:10 -05:00
parent 76aa40d290
commit 0df2b0e0f0
2 changed files with 34 additions and 2 deletions

View File

@ -112,7 +112,14 @@ func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *git.
if err != nil {
return nil, "", fmt.Errorf("git commit '%s' not found: %w", head.Target(), err)
}
return &Commit{commit}, fmt.Sprintf("%s/%s", c.tag, head.Target().String()), nil
err = repo.CheckoutHead(&git2go.CheckoutOpts{
Strategy: git2go.CheckoutForce,
})
if err != nil {
return nil, "", fmt.Errorf("git checkout error: %w", err)
}
return &Commit{commit}, fmt.Sprintf("%s/%s", c.tag, commit.Id().String()), nil
}
type CheckoutCommit struct {
@ -218,6 +225,12 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *g
if err != nil {
return nil, "", fmt.Errorf("git commit '%s' not found: %w", head.Target().String(), err)
}
err = repo.CheckoutHead(&git2go.CheckoutOpts{
Strategy: git2go.CheckoutForce,
})
if err != nil {
return nil, "", fmt.Errorf("git checkout error: %w", err)
}
return &Commit{commit}, fmt.Sprintf("%s/%s", t, head.Target().String()), nil
return &Commit{commit}, fmt.Sprintf("%s/%s", t, commit.Id().String()), nil
}

View File

@ -18,8 +18,12 @@ package libgit2
import (
"context"
"crypto/sha256"
"encoding/hex"
"io"
"io/ioutil"
"os"
"path"
"testing"
git2go "github.com/libgit2/git2go/v31"
@ -44,6 +48,21 @@ func TestCheckoutTagSemVer_Checkout(t *testing.T) {
t.Error(err)
}
// Ensure the correct files are checked out on disk
f, err := os.Open(path.Join(tmpDir, "README.md"))
if err != nil {
t.Error(err)
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
t.Error(err)
}
fileHash := hex.EncodeToString(h.Sum(nil))
if fileHash != "2bd1707542a11f987ee24698dcc095a9f57639f401133ef6a29da97bf8f3f302" {
t.Errorf("expected files not checked out. Expected hash %s, got %s", "2bd1707542a11f987ee24698dcc095a9f57639f401133ef6a29da97bf8f3f302", fileHash)
}
semVer := CheckoutSemVer{
semVer: ">=1.0.0 <=1.7.0",
}