diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-03-30 16:44:25 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2023-04-06 13:59:25 +0200 |
| commit | 139c4ef69fd5289588228c700717631d8f1731d0 (patch) | |
| tree | 05712e02c03b1269f11cd89d696de38e07c95702 /pkg/vcs | |
| parent | 0870752005424bd8737bdea302071167f4f0026d (diff) | |
pkg/vcs: add two more vcs.Repo methods
1) ListCommitHashes, which lists all commit hashes reachable from the
specified commit.
2) Object, which allows to query the contents of an object at the
specified revision.
Diffstat (limited to 'pkg/vcs')
| -rw-r--r-- | pkg/vcs/fuchsia.go | 8 | ||||
| -rw-r--r-- | pkg/vcs/git.go | 12 | ||||
| -rw-r--r-- | pkg/vcs/git_test.go | 79 | ||||
| -rw-r--r-- | pkg/vcs/git_test_util.go | 1 | ||||
| -rw-r--r-- | pkg/vcs/vcs.go | 10 |
5 files changed, 110 insertions, 0 deletions
diff --git a/pkg/vcs/fuchsia.go b/pkg/vcs/fuchsia.go index 188c5c839..14fb743f9 100644 --- a/pkg/vcs/fuchsia.go +++ b/pkg/vcs/fuchsia.go @@ -95,3 +95,11 @@ func (ctx *fuchsia) ReleaseTag(commit string) (string, error) { func (ctx *fuchsia) Contains(commit string) (bool, error) { return false, fmt.Errorf("not implemented for fuchsia") } + +func (ctx *fuchsia) ListCommitHashes(base string) ([]string, error) { + return ctx.repo.ListCommitHashes(base) +} + +func (ctx *fuchsia) Object(name, commit string) ([]byte, error) { + return ctx.repo.Object(name, commit) +} diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go index 4872e88cf..bd9738517 100644 --- a/pkg/vcs/git.go +++ b/pkg/vcs/git.go @@ -358,6 +358,14 @@ func (git *git) ListRecentCommits(baseCommit string) ([]string, error) { return strings.Split(string(output), "\n"), nil } +func (git *git) ListCommitHashes(baseCommit string) ([]string, error) { + output, err := git.git("log", "--pretty=format:%h", baseCommit) + if err != nil { + return nil, err + } + return strings.Split(string(output), "\n"), nil +} + func (git *git) ExtractFixTagsFromCommits(baseCommit, email string) ([]*Commit, error) { user, domain, err := splitEmail(email) if err != nil { @@ -576,3 +584,7 @@ func (git *git) IsRelease(commit string) (bool, error) { } return len(tags1) != len(tags2), nil } + +func (git *git) Object(name, commit string) ([]byte, error) { + return git.git("show", fmt.Sprintf("%s:%s", commit, name)) +} diff --git a/pkg/vcs/git_test.go b/pkg/vcs/git_test.go index b216ddf75..24d4cab58 100644 --- a/pkg/vcs/git_test.go +++ b/pkg/vcs/git_test.go @@ -4,6 +4,7 @@ package vcs import ( + "os" "reflect" "testing" "time" @@ -236,3 +237,81 @@ func TestContains(t *testing.T) { t.Fatalf("contains found commit that is not in current branch") } } + +func TestCommitHashes(t *testing.T) { + baseDir := t.TempDir() + repo := MakeTestRepo(t, baseDir) + + repo.Git("checkout", "-b", "branch-a") + repo.Git("commit", "--no-edit", "--allow-empty", "-m", "target") + repo.Git("checkout", "-b", "branch-b") + repo.Git("commit", "--no-edit", "--allow-empty", "-m", "target") + got, err := repo.repo.ListCommitHashes("HEAD") + if err != nil { + t.Fatal(err) + } + if len(got) != 2 { + t.Fatalf("expected 2 commits") + } + for i, commit := range got { + if contained, _ := repo.repo.Contains(commit); !contained { + t.Fatalf("commit %d is not contained", i) + } + } + + // Now change HEAD. + repo.Git("checkout", "branch-a") + got, err = repo.repo.ListCommitHashes("HEAD") + if err != nil { + t.Fatal(err) + } + if len(got) != 1 { + t.Fatalf("expected 1 commit, got %d", len(got)) + } + if contained, _ := repo.repo.Contains(got[0]); !contained { + t.Fatalf("commit in branch-b is not contained") + } +} + +func TestObject(t *testing.T) { + baseDir := t.TempDir() + repo := MakeTestRepo(t, baseDir) + firstRev := []byte("First revision") + secondRev := []byte("Second revision") + + if err := os.WriteFile(baseDir+"/object.txt", firstRev, 0644); err != nil { + t.Fatal(err) + } + repo.Git("add", "object.txt") + repo.Git("commit", "--no-edit", "--allow-empty", "-m", "target") + + if err := os.WriteFile(baseDir+"/object.txt", secondRev, 0644); err != nil { + t.Fatal(err) + } + repo.Git("add", "object.txt") + repo.Git("commit", "--no-edit", "--allow-empty", "-m", "target") + + commits, err := repo.repo.ListCommitHashes("HEAD") + if err != nil { + t.Fatal(err) + } + if len(commits) != 2 { + t.Fatalf("expected 2 commits, got %d", len(commits)) + } + // Verify file's contents at the first revision. + data, err := repo.repo.Object("object.txt", commits[1]) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(data, firstRev); diff != "" { + t.Fatal(diff) + } + // And at the second one. + data, err = repo.repo.Object("object.txt", commits[0]) + if err != nil { + t.Fatal(err) + } + if diff := cmp.Diff(data, secondRev); diff != "" { + t.Fatal(diff) + } +} diff --git a/pkg/vcs/git_test_util.go b/pkg/vcs/git_test_util.go index 3d3de8907..d341c6144 100644 --- a/pkg/vcs/git_test_util.go +++ b/pkg/vcs/git_test_util.go @@ -28,6 +28,7 @@ type TestRepo struct { } func (repo *TestRepo) Git(args ...string) { + repo.t.Helper() cmd := osutil.Command("git", args...) cmd.Dir = repo.Dir cmd.Env = filterEnv() diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go index 4b4f26e06..8d8c0302b 100644 --- a/pkg/vcs/vcs.go +++ b/pkg/vcs/vcs.go @@ -61,6 +61,12 @@ type Repo interface { // Remote is not fetched and only commits reachable from the checked out HEAD are searched // (e.g. do CheckoutBranch before). Contains(commit string) (bool, error) + + // ListCommitHashes lists all commit hashes reachable from baseCommit. + ListCommitHashes(baseCommit string) ([]string, error) + + // Object returns the contents of a git repository object at the particular moment in history. + Object(name, commit string) ([]byte, error) } // Bisecter may be optionally implemented by Repo. @@ -202,6 +208,10 @@ func NewSyzkallerRepo(dir string, opts ...RepoOpt) Repo { return git } +func NewLKMLRepo(dir string) Repo { + return newGit(dir, nil, []RepoOpt{OptDontSandbox}) +} + func Patch(dir string, patch []byte) error { // Do --dry-run first to not mess with partially consistent state. cmd := osutil.Command("patch", "-p1", "--force", "--ignore-whitespace", "--dry-run") |
