diff options
| -rw-r--r-- | pkg/vcs/git.go | 10 | ||||
| -rw-r--r-- | pkg/vcs/git_test.go | 55 | ||||
| -rw-r--r-- | pkg/vcs/linux.go | 2 |
3 files changed, 63 insertions, 4 deletions
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go index 71fcac97a..0bd72d9a6 100644 --- a/pkg/vcs/git.go +++ b/pkg/vcs/git.go @@ -134,17 +134,21 @@ func (git *git) CheckoutCommit(repo, commit string) (*Commit, error) { if err := git.repair(); err != nil { return nil, err } - if err := git.fetchRemote(repo); err != nil { + if err := git.fetchRemote(repo, commit); err != nil { return nil, err } return git.SwitchCommit(commit) } -func (git *git) fetchRemote(repo string) error { +func (git *git) fetchRemote(repo, commit string) error { repoHash := hash.String([]byte(repo)) // Ignore error as we can double add the same remote and that will fail. git.git("remote", "add", repoHash, repo) - _, err := git.git("fetch", "--force", "--tags", repoHash) + fetchArgs := []string{"fetch", "--force", "--tags", repoHash} + if commit != "" { + fetchArgs = append(fetchArgs, commit) + } + _, err := git.git(fetchArgs...) if err != nil { var verbose *osutil.VerboseError if errors.As(err, &verbose) && diff --git a/pkg/vcs/git_test.go b/pkg/vcs/git_test.go index 264cb54d8..5e9d30fa7 100644 --- a/pkg/vcs/git_test.go +++ b/pkg/vcs/git_test.go @@ -6,10 +6,12 @@ package vcs import ( "os" "reflect" + "sort" "testing" "time" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" ) func TestGitParseCommit(t *testing.T) { @@ -371,3 +373,56 @@ func TestMergeBase(t *testing.T) { t.Fatalf("expected base commit, got %v", mergeCommits) } } + +func TestGitCustomRefs(t *testing.T) { + remoteRepoDir := t.TempDir() + remote := MakeTestRepo(t, remoteRepoDir) + remote.Git("commit", "--no-edit", "--allow-empty", "-m", "base commit") + remote.Git("checkout", "-b", "base_branch") + remote.Git("tag", "base_tag") + + // Create a commit non reachable from any branch or tag. + remote.Git("checkout", "base_branch") + remote.Git("checkout", "-b", "temp_branch") + remote.Git("commit", "--no-edit", "--allow-empty", "-m", "detached commit") + // Add a ref to prevent the commit from getting garbage collected. + remote.Git("update-ref", "refs/custom/test", "temp_branch") + refCommit, _ := remote.repo.HeadCommit() + + // Remove the branch, let the commit stay only in refs. + remote.Git("checkout", "base_branch") + remote.Git("branch", "-D", "temp_branch") + + // Create a local repo. + localRepoDir := t.TempDir() + local := newGit(localRepoDir, nil, nil) + + // Fetch the commit from the custom ref. + _, err := local.CheckoutCommit(remoteRepoDir, refCommit.Hash) + assert.NoError(t, err) +} + +func TestGitRemoteTags(t *testing.T) { + remoteRepoDir := t.TempDir() + remote := MakeTestRepo(t, remoteRepoDir) + remote.Git("commit", "--no-edit", "--allow-empty", "-m", "base commit") + remote.Git("checkout", "-b", "base_branch") + remote.Git("tag", "v1.0") + + // Diverge sub_branch and add a tag. + remote.Git("commit", "--no-edit", "--allow-empty", "-m", "sub-branch") + remote.Git("checkout", "-b", "sub_branch") + remote.Git("tag", "v2.0") + + // Create a local repo. + localRepoDir := t.TempDir() + local := newGit(localRepoDir, nil, nil) + + // Ensure all tags were fetched. + commit, err := local.CheckoutCommit(remoteRepoDir, "sub_branch") + assert.NoError(t, err) + tags, err := local.previousReleaseTags(commit.Hash, true, false, false) + assert.NoError(t, err) + sort.Strings(tags) + assert.Equal(t, []string{"v1.0", "v2.0"}, tags) +} diff --git a/pkg/vcs/linux.go b/pkg/vcs/linux.go index 62319096d..98ae07cda 100644 --- a/pkg/vcs/linux.go +++ b/pkg/vcs/linux.go @@ -195,7 +195,7 @@ func (ctx *linux) PrepareBisect() error { if ctx.vmType != "gvisor" { // Some linux repos we fuzz don't import the upstream release git tags. We need tags // to decide which compiler versions to use. Let's fetch upstream for its tags. - err := ctx.git.fetchRemote("https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git") + err := ctx.git.fetchRemote("https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", "") if err != nil { return fmt.Errorf("fetching upstream linux failed: %w", err) } |
