branch_util: make tool fast (and correct)!

A few improvements here. Some for performance, some for correctness:
- Perform shallower checkouts (usually either a single branch, --depth=1, or both). This
is more important for larger repos (like chromite).
- Added retries on certain git operations. Actual runs of the tool were failing due
to http flakes.
- Fixed some logic with repairing manifests caused by corner cases in actual manifests
that weren't represented in tests.
- Created worker pools for branch validation and branch creation. This sped things up a lot.

BUG=chromium:980346,chromium:986454
TEST=run_tests.sh and manual dry runs

Change-Id: I1032cb4a45d883da188d026f015a1da58308cea0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/go/+/1754909
Tested-by: Jack Neus <jackneus@google.com>
Reviewed-by: Benjamin Gordon <bmgordon@chromium.org>
Reviewed-by: Evan Hernandez <evanhernandez@chromium.org>
Commit-Queue: Jack Neus <jackneus@google.com>
diff --git a/internal/git/git.go b/internal/git/git.go
index 4a80848..044fab1 100644
--- a/internal/git/git.go
+++ b/internal/git/git.go
@@ -107,6 +107,12 @@
 	return matchedBranches, nil
 }
 
+// IsSHA checks whether or not the given ref is a SHA.
+func IsSHA(ref string) bool {
+	shaRegexp := regexp.MustCompile("^[0-9a-f]{40}$")
+	return shaRegexp.MatchString(ref)
+}
+
 // GetGitRepoRevision finds and returns the revision of a branch.
 func GetGitRepoRevision(cwd, branch string) (string, error) {
 	if branch == "" {
@@ -311,7 +317,7 @@
 		if strings.Contains(output.Stderr, "not appear to be a git repository") {
 			return []string{}, fmt.Errorf("%s is not a valid remote", remote)
 		}
-		return []string{}, err
+		return []string{}, fmt.Errorf(output.Stderr)
 	}
 	remotes := []string{}
 	for _, line := range strings.Split(strings.TrimSpace(output.Stdout), "\n") {
@@ -325,17 +331,14 @@
 
 // RemoteHasBranch checks whether or not a branch exists on a remote.
 func RemoteHasBranch(gitRepo, remote, branch string) (bool, error) {
-	branches, err := RemoteBranches(gitRepo, remote)
+	output, err := RunGit(gitRepo, []string{"ls-remote", remote, branch})
 	if err != nil {
-		return false, err
-	}
-	branch = StripRefs(branch)
-	for _, remoteBranch := range branches {
-		if branch == remoteBranch {
-			return true, nil
+		if strings.Contains(output.Stderr, "not appear to be a git repository") {
+			return false, fmt.Errorf("%s is not a valid remote", remote)
 		}
+		return false, fmt.Errorf(output.Stderr)
 	}
-	return false, nil
+	return output.Stdout != "", nil
 }
 
 // AssertGitBranches asserts that the git repo has the given branches (it may have others, too).