infra/go: misc TODOs

Updated git.PushRef to take a force parameter. Also wrote a small unit test for something.

BUG=None
TEST=run_tests.sh

Change-Id: I8dbd8d79b47380ecc15be5d5de1a1b345db8ba78
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/infra/go/+/1758856
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 9793f00..6b10dfb 100644
--- a/internal/git/git.go
+++ b/internal/git/git.go
@@ -30,6 +30,11 @@
 	Ref    string
 }
 
+type GitOpts struct {
+	DryRun bool
+	Force  bool
+}
+
 // RunGit the specified git command in the specified repo. It returns
 // stdout and stderr.
 func RunGit(gitRepo string, cmd []string) (CommandOutput, error) {
@@ -221,18 +226,21 @@
 	}
 	output, err := RunGit(gitRepo, []string{"rev-parse", "HEAD"})
 	if err != nil {
-		return "", nil
+		return "", err
 	}
 	return strings.TrimSpace(output.Stdout), nil
 }
 
 // PushRef pushes the specified local ref to the specified remote ref.
-func PushRef(gitRepo, localRef string, dryRun bool, pushTo RemoteRef) error {
+func PushRef(gitRepo, localRef string, pushTo RemoteRef, opts GitOpts) error {
 	ref := fmt.Sprintf("%s:%s", localRef, pushTo.Ref)
 	cmd := []string{"push", pushTo.Remote, ref}
-	if dryRun {
+	if opts.DryRun {
 		cmd = append(cmd, "--dry-run")
 	}
+	if opts.Force {
+		cmd = append(cmd, "--force")
+	}
 	_, err := RunGit(gitRepo, cmd)
 	return err
 }