func startBenchmark()

in funcbench/main.go [233:314]


func startBenchmark(env Environment, bench *Benchmarker) ([]*benchstat.Table, error) {

	wt, _ := env.Repo().Worktree()
	cmpWorkTreeDir := filepath.Join(bench.scratchWorkspaceDir)

	ref, err := env.Repo().Head()
	if err != nil {
		return nil, errors.Wrap(err, "get head")
	}

	// TODO move it into env? since GitHub env doesn't need this check.
	if _, err := bench.c.exec("sh", "-c", "git update-index -q --ignore-submodules --refresh && git diff-files --quiet --ignore-submodules --"); err != nil {
		return nil, errors.Wrap(err, "not clean worktree")
	}

	if env.CompareTarget() == "." {
		bench.logger.Println("Assuming sub-benchmarks comparison.")
		subResult, err := bench.exec(wt.Filesystem.Root(), ref.Hash())
		if err != nil {
			return nil, errors.Wrap(err, "execute sub-benchmark")
		}

		cmps, err := bench.compareSubBenchmarks(subResult)
		if err != nil {
			return nil, errors.Wrap(err, "comparing sub benchmarks")
		}
		return cmps, nil
	}

	// Get info about target.
	targetCommit := getTargetInfo(env.Repo(), env.CompareTarget())
	if targetCommit == plumbing.ZeroHash {
		return nil, fmt.Errorf("cannot find target %s", env.CompareTarget())
	}

	bench.logger.Println("Target:", targetCommit.String(), "Current Ref:", ref.Hash().String())

	if targetCommit == ref.Hash() {
		return nil, fmt.Errorf("target: %s is the same as current ref %s (or is on the same commit); No changes would be expected; Aborting", targetCommit, ref.String())
	}

	bench.logger.Println("Assuming comparing with target (clean workdir will be checked.)")

	// Execute benchmark A.
	newResult, err := bench.exec(wt.Filesystem.Root(), ref.Hash())
	if err != nil {
		return nil, errors.Wrapf(err, "execute benchmark for A: %v", ref.Name().String())
	}

	// TODO move the following part before 'Execute benchmark B.' into a function Benchmarker.switchToWorkTree.
	// Best effort cleanup and checkout new worktree.
	if err := os.RemoveAll(cmpWorkTreeDir); err != nil {
		return nil, errors.Wrapf(err, "delete worktree at %s", cmpWorkTreeDir)
	}

	// TODO (geekodour): switch to worktree remove once we decide not to support git<2.17
	if _, err := bench.c.exec("git", "worktree", "prune"); err != nil {
		return nil, errors.Wrap(err, "worktree prune")
	}

	bench.logger.Println("Checking out (in new workdir):", cmpWorkTreeDir, "commmit", targetCommit.String())
	if _, err := bench.c.exec("git", "worktree", "add", "-f", cmpWorkTreeDir, targetCommit.String()); err != nil {
		return nil, errors.Wrapf(err, "checkout %s in worktree %s", targetCommit.String(), cmpWorkTreeDir)
	}

	// Execute benchmark B.
	oldResult, err := bench.exec(cmpWorkTreeDir, targetCommit)
	if err != nil {
		return nil, errors.Wrapf(err, "execute benchmark for B: %v", env.CompareTarget())
	}

	// Compare B vs A.
	tables, err := compareBenchmarks(oldResult, newResult)
	if err != nil {
		return nil, errors.Wrap(err, "comparing benchmarks")
	}

	// Save hashes for info about benchmark.
	env.SetHashStrings(targetCommit.String(), ref.Hash().String())

	return tables, nil
}