Skip to content

Commit

Permalink
Merge pull request #4473 from jedevc/fix-git-sha-conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
jedevc authored Dec 13, 2023
2 parents f84cfe3 + 6a8d2ca commit 7eb8713
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
37 changes: 31 additions & 6 deletions source/git/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,20 +365,45 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index

// TODO: should we assume that remote tag is immutable? add a timer?

buf, err := git.Run(ctx, "ls-remote", "origin", ref)
buf, err := git.Run(ctx, "ls-remote", "origin", ref, ref+"^{}")
if err != nil {
return "", "", nil, false, errors.Wrapf(err, "failed to fetch remote %s", urlutil.RedactCredentials(remote))
}
out := string(buf)
idx := strings.Index(out, "\t")
if idx == -1 {
return "", "", nil, false, errors.Errorf("repository does not contain ref %s, output: %q", ref, string(out))
lines := strings.Split(string(buf), "\n")

var (
partialRef = "refs/" + strings.TrimPrefix(ref, "refs/")
headRef = "refs/heads/" + strings.TrimPrefix(ref, "refs/heads/")
tagRef = "refs/tags/" + strings.TrimPrefix(ref, "refs/tags/")
annotatedTagRef = tagRef + "^{}"
)
var sha, headSha, tagSha string
for _, line := range lines {
lineSha, lineRef, _ := strings.Cut(line, "\t")
switch lineRef {
case headRef:
headSha = lineSha
case tagRef, annotatedTagRef:
tagSha = lineSha
case partialRef:
sha = lineSha
}
}

sha := string(out[:idx])
// git-checkout prefers branches in case of ambiguity
if sha == "" {
sha = headSha
}
if sha == "" {
sha = tagSha
}
if sha == "" {
return "", "", nil, false, errors.Errorf("repository does not contain ref %s, output: %q", ref, string(buf))
}
if !isCommitSHA(sha) {
return "", "", nil, false, errors.Errorf("invalid commit sha %q", sha)
}

cacheKey := gs.shaToCacheKey(sha)
gs.cacheKey = cacheKey
return cacheKey, sha, nil, true, nil
Expand Down
45 changes: 41 additions & 4 deletions source/git/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ func TestFetchByTagKeepGitDir(t *testing.T) {
testFetchByTag(t, "lightweight-tag", "third", false, true, true)
}

func TestFetchByTagFull(t *testing.T) {
testFetchByTag(t, "refs/tags/lightweight-tag", "third", false, true, true)
}

func TestFetchByAnnotatedTag(t *testing.T) {
testFetchByTag(t, "v1.2.3", "second", true, false, false)
}
Expand All @@ -234,6 +238,34 @@ func TestFetchByAnnotatedTagKeepGitDir(t *testing.T) {
testFetchByTag(t, "v1.2.3", "second", true, false, true)
}

func TestFetchByAnnotatedTagFull(t *testing.T) {
testFetchByTag(t, "refs/tags/v1.2.3", "second", true, false, true)
}

func TestFetchByBranch(t *testing.T) {
testFetchByTag(t, "feature", "withsub", false, true, false)
}

func TestFetchByBranchKeepGitDir(t *testing.T) {
testFetchByTag(t, "feature", "withsub", false, true, true)
}

func TestFetchByBranchFull(t *testing.T) {
testFetchByTag(t, "refs/heads/feature", "withsub", false, true, true)
}

func TestFetchByRef(t *testing.T) {
testFetchByTag(t, "test", "feature", false, true, false)
}

func TestFetchByRefKeepGitDir(t *testing.T) {
testFetchByTag(t, "test", "feature", false, true, true)
}

func TestFetchByRefFull(t *testing.T) {
testFetchByTag(t, "refs/test", "feature", false, true, true)
}

func testFetchByTag(t *testing.T, tag, expectedCommitSubject string, isAnnotatedTag, hasFoo13File, keepGitDir bool) {
if runtime.GOOS == "windows" {
t.Skip("Depends on unimplemented containerd bind-mount support on Windows")
Expand Down Expand Up @@ -297,15 +329,18 @@ func testFetchByTag(t *testing.T, tag, expectedCommitSubject string, isAnnotated
gitutil.WithWorkTree(dir),
)

// get current commit sha
headCommit, err := git.Run(ctx, "rev-parse", "HEAD")
require.NoError(t, err)

// ensure that we checked out the same commit as was in the cache key
require.Equal(t, strings.TrimSpace(string(headCommit)), pin1)

if isAnnotatedTag {
// get commit sha that the annotated tag points to
annotatedTagCommit, err := git.Run(ctx, "rev-list", "-n", "1", tag)
require.NoError(t, err)

// get current commit sha
headCommit, err := git.Run(ctx, "rev-parse", "HEAD")
require.NoError(t, err)

// HEAD should match the actual commit sha (and not the sha of the annotated tag,
// since it's not possible to checkout a non-commit object)
require.Equal(t, string(annotatedTagCommit), string(headCommit))
Expand Down Expand Up @@ -583,6 +618,7 @@ func setupGitRepo(t *testing.T) gitRepoFixture {
"echo foo > abc",
"git add abc",
"git commit -m initial",
"git tag --no-sign a/v1.2.3",
"echo bar > def",
"git add def",
"git commit -m second",
Expand All @@ -595,6 +631,7 @@ func setupGitRepo(t *testing.T) gitRepoFixture {
"echo baz > ghi",
"git add ghi",
"git commit -m feature",
"git update-ref refs/test $(git rev-parse HEAD)",
"git submodule add "+fixture.subURL+" sub",
"git add -A",
"git commit -m withsub",
Expand Down

0 comments on commit 7eb8713

Please sign in to comment.