aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-12-16 16:18:06 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-12-16 16:18:06 +0100
commitce6744512e81ac2e291fea247d55fb0bf8e703e2 (patch)
tree7670f0ced49db9f4e05b96812b322eb608314c77 /pkg
parentc7e64e2b4f3a9d7734a92aebc53f285cd6afd94b (diff)
pkg/vcs: fix fetching of commits on non master branch
Fixes #728
Diffstat (limited to 'pkg')
-rw-r--r--pkg/vcs/git.go12
-rw-r--r--pkg/vcs/git_repo_test.go163
2 files changed, 173 insertions, 2 deletions
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go
index bc0e05373..f73c47c58 100644
--- a/pkg/vcs/git.go
+++ b/pkg/vcs/git.go
@@ -16,6 +16,7 @@ import (
"strings"
"time"
+ "github.com/google/syzkaller/pkg/hash"
"github.com/google/syzkaller/pkg/osutil"
)
@@ -87,13 +88,20 @@ func (git *git) CheckoutCommit(repo, commit string) (*Commit, error) {
return nil, err
}
}
- _, err := runSandboxed(dir, "git", "fetch", repo)
- if err != nil {
+ if err := git.fetchRemote(repo); err != nil {
return nil, err
}
return git.SwitchCommit(commit)
}
+func (git *git) fetchRemote(repo string) error {
+ repoHash := hash.String([]byte(repo))
+ // Ignore error as we can double add the same remote and that will fail.
+ runSandboxed(git.dir, "git", "remote", "add", repoHash, repo)
+ _, err := runSandboxed(git.dir, "git", "fetch", repoHash)
+ return err
+}
+
func (git *git) SwitchCommit(commit string) (*Commit, error) {
dir := git.dir
if _, err := runSandboxed(dir, "git", "checkout", commit); err != nil {
diff --git a/pkg/vcs/git_repo_test.go b/pkg/vcs/git_repo_test.go
new file mode 100644
index 000000000..e6f94c117
--- /dev/null
+++ b/pkg/vcs/git_repo_test.go
@@ -0,0 +1,163 @@
+// Copyright 2017 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package vcs
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/google/go-cmp/cmp"
+ "github.com/google/syzkaller/pkg/osutil"
+)
+
+func TestGitRepo(t *testing.T) {
+ baseDir, err := ioutil.TempDir("", "syz-git-test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(baseDir)
+ repo1 := createTestRepo(t, baseDir, "repo1")
+ repo2 := createTestRepo(t, baseDir, "repo2")
+ repo := newGit(filepath.Join(baseDir, "repo"))
+ {
+ com, err := repo.Poll(repo1.dir, "master")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, repo1.commits["master"]["1"]); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ com, err := repo.CheckoutBranch(repo1.dir, "branch1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, repo1.commits["branch1"]["1"]); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ want := repo1.commits["branch1"]["0"]
+ com, err := repo.CheckoutCommit(repo1.dir, want.Hash)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, want); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ commits, err := repo.ListRecentCommits(repo1.commits["branch1"]["1"].Hash)
+ if err != nil {
+ t.Fatal(err)
+ }
+ want := []string{"repo1-branch1-1", "repo1-branch1-0", "repo1-master-0"}
+ if diff := cmp.Diff(commits, want); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ want := repo2.commits["branch1"]["0"]
+ com, err := repo.CheckoutCommit(repo2.dir, want.Hash)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, want); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ want := repo2.commits["branch1"]["1"]
+ com, err := repo.CheckoutCommit(repo2.dir, want.Hash)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, want); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ com, err := repo.CheckoutBranch(repo2.dir, "branch2")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, repo2.commits["branch2"]["1"]); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+ {
+ want := repo2.commits["branch2"]["0"]
+ com, err := repo.SwitchCommit(want.Hash)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if diff := cmp.Diff(com, want); diff != "" {
+ t.Fatal(diff)
+ }
+ }
+}
+
+func createTestRepo(t *testing.T, baseDir, name string) *testRepo {
+ repo := makeTestRepo(t, filepath.Join(baseDir, name))
+ repo.git("checkout", "-b", "master")
+ repo.commitFileChange("master", "0")
+ for _, branch := range []string{"branch1", "branch2"} {
+ repo.git("checkout", "-b", branch, "master")
+ repo.commitFileChange(branch, "0")
+ repo.commitFileChange(branch, "1")
+ }
+ repo.git("checkout", "master")
+ repo.commitFileChange("master", "1")
+ return repo
+}
+
+type testRepo struct {
+ t *testing.T
+ dir string
+ name string
+ commits map[string]map[string]*Commit
+}
+
+func makeTestRepo(t *testing.T, dir string) *testRepo {
+ if err := osutil.MkdirAll(dir); err != nil {
+ t.Fatal(err)
+ }
+ repo := &testRepo{
+ t: t,
+ dir: dir,
+ name: filepath.Base(dir),
+ commits: make(map[string]map[string]*Commit),
+ }
+ repo.git("init")
+ return repo
+}
+
+func (repo *testRepo) git(args ...string) {
+ if _, err := osutil.RunCmd(time.Minute, repo.dir, "git", args...); err != nil {
+ repo.t.Fatal(err)
+ }
+}
+
+func (repo *testRepo) commitFileChange(branch, change string) {
+ id := fmt.Sprintf("%v-%v-%v", repo.name, branch, change)
+ file := filepath.Join(repo.dir, "file")
+ if err := osutil.WriteFile(file, []byte(id)); err != nil {
+ repo.t.Fatal(err)
+ }
+ repo.git("add", file)
+ repo.git("commit", "-m", id)
+ if repo.commits[branch] == nil {
+ repo.commits[branch] = make(map[string]*Commit)
+ }
+ com, err := newGit(repo.dir).HeadCommit()
+ if err != nil {
+ repo.t.Fatal(err)
+ }
+ repo.commits[branch][change] = com
+}