More assert functions for repo_harness

Added two assert functions to the repo_harness package.
This of course required adding a number of helper functions to
different libraries.

BUG=chromium:980346
TEST=run_tests.sh

Change-Id: I062638741d9d8e527ab436807f5152e2937b649f
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/go/+/1716140
Reviewed-by: Benjamin Gordon <bmgordon@chromium.org>
Reviewed-by: Evan Hernandez <evanhernandez@chromium.org>
Commit-Queue: Jack Neus <jackneus@google.com>
Tested-by: Jack Neus <jackneus@google.com>
diff --git a/internal/git/git.go b/internal/git/git.go
index 7395ca8..095754e 100644
--- a/internal/git/git.go
+++ b/internal/git/git.go
@@ -99,11 +99,26 @@
 }
 
 // GetGitRepoRevision finds and returns the revision of a branch.
-func GetGitRepoRevision(cwd string) (string, error) {
-	output, err := RunGit(cwd, []string{"rev-parse", "HEAD"})
+func GetGitRepoRevision(cwd, branch string) (string, error) {
+	if branch == "" {
+		branch = "HEAD"
+	}
+	output, err := RunGit(cwd, []string{"rev-parse", branch})
 	return strings.TrimSpace(output.Stdout), err
 }
 
+// IsReachable determines whether one commit ref is reachable from another.
+func IsReachable(cwd, to_ref, from_ref string) (bool, error) {
+	_, err := RunGit(cwd, []string{"merge-base", "--is-ancestor", to_ref, from_ref})
+	if err != nil {
+		if strings.Contains(err.Error(), "exit status 1") {
+			return false, nil
+		}
+		return false, err
+	}
+	return true, nil
+}
+
 // StripRefsHead removes leading 'refs/heads/' from a ref name.
 func StripRefsHead(ref string) string {
 	return strings.TrimPrefix(ref, "refs/heads/")