aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/vcs
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-12-15 15:08:02 +0100
committerDmitry Vyukov <dvyukov@google.com>2020-12-25 10:12:41 +0100
commit5b90407edc5f3cd1eaf9e5667b96f8e155fe0118 (patch)
tree1c1f550de443b15fd5f6d3b30ce156b824124c01 /pkg/vcs
parent51cfe8e5099c61aa64746eb323891f0ee28b67c9 (diff)
pkg/vcs: add repo.Contains method
Returns true if the current tree contains the specified commit (the commit is reachable from the current HEAD). Cntains(commit string) (bool, error)
Diffstat (limited to 'pkg/vcs')
-rw-r--r--pkg/vcs/fuchsia.go4
-rw-r--r--pkg/vcs/git.go5
-rw-r--r--pkg/vcs/git_repo_test.go29
-rw-r--r--pkg/vcs/vcs.go4
4 files changed, 42 insertions, 0 deletions
diff --git a/pkg/vcs/fuchsia.go b/pkg/vcs/fuchsia.go
index a604ec51b..188c5c839 100644
--- a/pkg/vcs/fuchsia.go
+++ b/pkg/vcs/fuchsia.go
@@ -91,3 +91,7 @@ func (ctx *fuchsia) ExtractFixTagsFromCommits(baseCommit, email string) ([]*Comm
func (ctx *fuchsia) ReleaseTag(commit string) (string, error) {
return "", fmt.Errorf("not implemented for fuchsia")
}
+
+func (ctx *fuchsia) Contains(commit string) (bool, error) {
+ return false, fmt.Errorf("not implemented for fuchsia")
+}
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go
index 163f3e497..22a665b37 100644
--- a/pkg/vcs/git.go
+++ b/pkg/vcs/git.go
@@ -197,6 +197,11 @@ func (git *git) initRepo(reason error) error {
return nil
}
+func (git *git) Contains(commit string) (bool, error) {
+ _, err := git.git("merge-base", "--is-ancestor", commit, "HEAD")
+ return err == nil, nil
+}
+
func (git *git) HeadCommit() (*Commit, error) {
return git.getCommit("HEAD")
}
diff --git a/pkg/vcs/git_repo_test.go b/pkg/vcs/git_repo_test.go
index 9a044e870..41564fda6 100644
--- a/pkg/vcs/git_repo_test.go
+++ b/pkg/vcs/git_repo_test.go
@@ -107,6 +107,35 @@ func TestGitRepo(t *testing.T) {
t.Fatal(diff)
}
}
+ {
+ type Test struct {
+ head *Commit
+ commit *Commit
+ contains bool
+ }
+ tests := []Test{
+ {repo2.Commits["branch2"]["1"], repo2.Commits["branch2"]["1"], true},
+ {repo2.Commits["branch2"]["1"], repo2.Commits["branch2"]["0"], true},
+ {repo2.Commits["branch2"]["1"], repo2.Commits["master"]["0"], true},
+ {repo2.Commits["branch2"]["1"], repo2.Commits["master"]["1"], false},
+ {repo2.Commits["branch2"]["1"], repo2.Commits["branch1"]["0"], false},
+ {repo2.Commits["branch2"]["1"], repo2.Commits["branch1"]["1"], false},
+ {repo2.Commits["branch2"]["0"], repo2.Commits["branch2"]["0"], true},
+ {repo2.Commits["branch2"]["0"], repo2.Commits["branch2"]["1"], false},
+ {repo2.Commits["branch2"]["0"], repo2.Commits["master"]["0"], true},
+ {repo2.Commits["branch2"]["0"], repo2.Commits["master"]["1"], false},
+ }
+ for i, test := range tests {
+ if _, err := repo.SwitchCommit(test.head.Hash); err != nil {
+ t.Fatal(err)
+ }
+ if contains, err := repo.Contains(test.commit.Hash); err != nil {
+ t.Fatal(err)
+ } else if contains != test.contains {
+ t.Errorf("test %v: got %v, want %v", i, contains, test.contains)
+ }
+ }
+ }
}
func TestMetadata(t *testing.T) {
diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go
index 7ede983f6..e698867a4 100644
--- a/pkg/vcs/vcs.go
+++ b/pkg/vcs/vcs.go
@@ -106,6 +106,10 @@ type Repo interface {
// ReleaseTag returns the latest release tag that is reachable from the given commit.
ReleaseTag(commit string) (string, error)
+
+ // Returns true if the current tree contains the specified commit
+ // (the commit is reachable from the current HEAD).
+ Contains(commit string) (bool, error)
}
// Bisecter may be optionally implemented by Repo.