mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 19:39:40 +00:00
pkg/git: add bisection functionality
Bisect bisects good..bad commit range against the provided predicate (wrapper around git bisect). The predicate should return an error only if there is no way to proceed (it will abort the process), if possible it should prefer to return BisectSkip. Progress of the process is streamed to the provided trace. Returns the first commit on which the predicate returns BisectBad. Update #501
This commit is contained in:
parent
b4df103f78
commit
acfd774f46
@ -30,6 +30,7 @@ const (
|
|||||||
// This involves fetching/resetting/cloning as necessary to recover from all possible problems.
|
// This involves fetching/resetting/cloning as necessary to recover from all possible problems.
|
||||||
// Returns hash of the HEAD commit in the specified branch.
|
// Returns hash of the HEAD commit in the specified branch.
|
||||||
func Poll(dir, repo, branch string) (*Commit, error) {
|
func Poll(dir, repo, branch string) (*Commit, error) {
|
||||||
|
runSandboxed(dir, "git", "bisect", "reset")
|
||||||
runSandboxed(dir, "git", "reset", "--hard")
|
runSandboxed(dir, "git", "reset", "--hard")
|
||||||
origin, err := runSandboxed(dir, "git", "remote", "get-url", "origin")
|
origin, err := runSandboxed(dir, "git", "remote", "get-url", "origin")
|
||||||
if err != nil || strings.TrimSpace(string(origin)) != repo {
|
if err != nil || strings.TrimSpace(string(origin)) != repo {
|
||||||
@ -61,6 +62,7 @@ func Poll(dir, repo, branch string) (*Commit, error) {
|
|||||||
|
|
||||||
// CheckoutBranch checkouts the specified repository/branch in dir.
|
// CheckoutBranch checkouts the specified repository/branch in dir.
|
||||||
func CheckoutBranch(dir, repo, branch string) (*Commit, error) {
|
func CheckoutBranch(dir, repo, branch string) (*Commit, error) {
|
||||||
|
runSandboxed(dir, "git", "bisect", "reset")
|
||||||
if _, err := runSandboxed(dir, "git", "reset", "--hard"); err != nil {
|
if _, err := runSandboxed(dir, "git", "reset", "--hard"); err != nil {
|
||||||
if err := initRepo(dir); err != nil {
|
if err := initRepo(dir); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -78,6 +80,7 @@ func CheckoutBranch(dir, repo, branch string) (*Commit, error) {
|
|||||||
|
|
||||||
// CheckoutCommit checkouts the specified repository on the specified commit in dir.
|
// CheckoutCommit checkouts the specified repository on the specified commit in dir.
|
||||||
func CheckoutCommit(dir, repo, commit string) (*Commit, error) {
|
func CheckoutCommit(dir, repo, commit string) (*Commit, error) {
|
||||||
|
runSandboxed(dir, "git", "bisect", "reset")
|
||||||
if _, err := runSandboxed(dir, "git", "reset", "--hard"); err != nil {
|
if _, err := runSandboxed(dir, "git", "reset", "--hard"); err != nil {
|
||||||
if err := initRepo(dir); err != nil {
|
if err := initRepo(dir); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -318,6 +321,65 @@ func Patch(dir string, patch []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BisectResult int
|
||||||
|
|
||||||
|
const (
|
||||||
|
BisectBad BisectResult = iota
|
||||||
|
BisectGood
|
||||||
|
BisectSkip
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bisect bisects good..bad commit range against the provided predicate (wrapper around git bisect).
|
||||||
|
// The predicate should return an error only if there is no way to proceed
|
||||||
|
// (it will abort the process), if possible it should prefer to return BisectSkip.
|
||||||
|
// Progress of the process is streamed to the provided trace.
|
||||||
|
// Returns the first commit on which the predicate returns BisectBad.
|
||||||
|
func Bisect(dir, bad, good string, trace io.Writer, pred func() (BisectResult, error)) (*Commit, error) {
|
||||||
|
runSandboxed(dir, "git", "bisect", "reset")
|
||||||
|
runSandboxed(dir, "git", "reset", "--hard")
|
||||||
|
firstBad, err := GetCommit(dir, bad)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
output, err := runSandboxed(dir, "git", "bisect", "start", bad, good)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer runSandboxed(dir, "git", "bisect", "reset")
|
||||||
|
fmt.Fprintf(trace, "# git bisect start %v %v\n%s", bad, good, output)
|
||||||
|
current, err := HeadCommit(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var bisectTerms = [...]string{
|
||||||
|
BisectBad: "bad",
|
||||||
|
BisectGood: "good",
|
||||||
|
BisectSkip: "skip",
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
res, err := pred()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if res == BisectBad {
|
||||||
|
firstBad = current
|
||||||
|
}
|
||||||
|
output, err = runSandboxed(dir, "git", "bisect", bisectTerms[res])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fmt.Fprintf(trace, "# git bisect %v %v\n%s", bisectTerms[res], current.Hash, output)
|
||||||
|
next, err := HeadCommit(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if current.Hash == next.Hash {
|
||||||
|
return firstBad, nil
|
||||||
|
}
|
||||||
|
current = next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PreviousReleaseTags returns list of preceding release tags that are reachable from the given commit.
|
// PreviousReleaseTags returns list of preceding release tags that are reachable from the given commit.
|
||||||
// Note: linux-specific.
|
// Note: linux-specific.
|
||||||
func PreviousReleaseTags(dir, commit string) ([]string, error) {
|
func PreviousReleaseTags(dir, commit string) ([]string, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user