about summary refs log tree commit diff
path: root/third_party/go/git-appraise/repository
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@google.com>2019-09-02T19·00+0100
committerVincent Ambo <tazjin@google.com>2019-09-02T19·01+0100
commitf2e0f3ee27ae59e45b92351d0956432920722b7e (patch)
tree6ae59ed4b6a931f4be79af4de6f3e6dc75cad2cf /third_party/go/git-appraise/repository
parent2f239426aa4b9783c301a0ecbb4a9a4fd8b8e6dd (diff)
chore(third_party): Remove git-appraise r/74
Not actually in use here ...
Diffstat (limited to 'third_party/go/git-appraise/repository')
-rw-r--r--third_party/go/git-appraise/repository/git.go987
-rw-r--r--third_party/go/git-appraise/repository/git_test.go94
-rw-r--r--third_party/go/git-appraise/repository/mock_repo.go613
-rw-r--r--third_party/go/git-appraise/repository/repo.go221
4 files changed, 0 insertions, 1915 deletions
diff --git a/third_party/go/git-appraise/repository/git.go b/third_party/go/git-appraise/repository/git.go
deleted file mode 100644
index 31d27ea6d2ec..000000000000
--- a/third_party/go/git-appraise/repository/git.go
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
-Copyright 2015 Google Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package repository contains helper methods for working with the Git repo.
-package repository
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/sha1"
-	"encoding/json"
-	"fmt"
-	"io"
-	"os"
-	"os/exec"
-	"strconv"
-	"strings"
-)
-
-const branchRefPrefix = "refs/heads/"
-
-// GitRepo represents an instance of a (local) git repository.
-type GitRepo struct {
-	Path string
-}
-
-// Run the given git command with the given I/O reader/writers, returning an error if it fails.
-func (repo *GitRepo) runGitCommandWithIO(stdin io.Reader, stdout, stderr io.Writer, args ...string) error {
-	cmd := exec.Command("git", args...)
-	cmd.Dir = repo.Path
-	cmd.Stdin = stdin
-	cmd.Stdout = stdout
-	cmd.Stderr = stderr
-	return cmd.Run()
-}
-
-// Run the given git command and return its stdout, or an error if the command fails.
-func (repo *GitRepo) runGitCommandRaw(args ...string) (string, string, error) {
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
-	err := repo.runGitCommandWithIO(nil, &stdout, &stderr, args...)
-	return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err
-}
-
-// Run the given git command and return its stdout, or an error if the command fails.
-func (repo *GitRepo) runGitCommand(args ...string) (string, error) {
-	stdout, stderr, err := repo.runGitCommandRaw(args...)
-	if err != nil {
-		if stderr == "" {
-			stderr = "Error running git command: " + strings.Join(args, " ")
-		}
-		err = fmt.Errorf(stderr)
-	}
-	return stdout, err
-}
-
-// Run the given git command using the same stdin, stdout, and stderr as the review tool.
-func (repo *GitRepo) runGitCommandInline(args ...string) error {
-	return repo.runGitCommandWithIO(os.Stdin, os.Stdout, os.Stderr, args...)
-}
-
-// NewGitRepo determines if the given working directory is inside of a git repository,
-// and returns the corresponding GitRepo instance if it is.
-func NewGitRepo(path string) (*GitRepo, error) {
-	repo := &GitRepo{Path: path}
-	_, _, err := repo.runGitCommandRaw("rev-parse")
-	if err == nil {
-		return repo, nil
-	}
-	if _, ok := err.(*exec.ExitError); ok {
-		return nil, err
-	}
-	return nil, err
-}
-
-// GetPath returns the path to the repo.
-func (repo *GitRepo) GetPath() string {
-	return repo.Path
-}
-
-// GetRepoStateHash returns a hash which embodies the entire current state of a repository.
-func (repo *GitRepo) GetRepoStateHash() (string, error) {
-	stateSummary, error := repo.runGitCommand("show-ref")
-	return fmt.Sprintf("%x", sha1.Sum([]byte(stateSummary))), error
-}
-
-// GetUserEmail returns the email address that the user has used to configure git.
-func (repo *GitRepo) GetUserEmail() (string, error) {
-	return repo.runGitCommand("config", "user.email")
-}
-
-// GetUserSigningKey returns the key id the user has configured for
-// sigining git artifacts.
-func (repo *GitRepo) GetUserSigningKey() (string, error) {
-	return repo.runGitCommand("config", "user.signingKey")
-}
-
-// GetCoreEditor returns the name of the editor that the user has used to configure git.
-func (repo *GitRepo) GetCoreEditor() (string, error) {
-	return repo.runGitCommand("var", "GIT_EDITOR")
-}
-
-// GetSubmitStrategy returns the way in which a review is submitted
-func (repo *GitRepo) GetSubmitStrategy() (string, error) {
-	submitStrategy, _ := repo.runGitCommand("config", "appraise.submit")
-	return submitStrategy, nil
-}
-
-// HasUncommittedChanges returns true if there are local, uncommitted changes.
-func (repo *GitRepo) HasUncommittedChanges() (bool, error) {
-	out, err := repo.runGitCommand("status", "--porcelain")
-	if err != nil {
-		return false, err
-	}
-	if len(out) > 0 {
-		return true, nil
-	}
-	return false, nil
-}
-
-// VerifyCommit verifies that the supplied hash points to a known commit.
-func (repo *GitRepo) VerifyCommit(hash string) error {
-	out, err := repo.runGitCommand("cat-file", "-t", hash)
-	if err != nil {
-		return err
-	}
-	objectType := strings.TrimSpace(string(out))
-	if objectType != "commit" {
-		return fmt.Errorf("Hash %q points to a non-commit object of type %q", hash, objectType)
-	}
-	return nil
-}
-
-// VerifyGitRef verifies that the supplied ref points to a known commit.
-func (repo *GitRepo) VerifyGitRef(ref string) error {
-	_, err := repo.runGitCommand("show-ref", "--verify", ref)
-	return err
-}
-
-// GetHeadRef returns the ref that is the current HEAD.
-func (repo *GitRepo) GetHeadRef() (string, error) {
-	return repo.runGitCommand("symbolic-ref", "HEAD")
-}
-
-// GetCommitHash returns the hash of the commit pointed to by the given ref.
-func (repo *GitRepo) GetCommitHash(ref string) (string, error) {
-	return repo.runGitCommand("show", "-s", "--format=%H", ref)
-}
-
-// ResolveRefCommit returns the commit pointed to by the given ref, which may be a remote ref.
-//
-// This differs from GetCommitHash which only works on exact matches, in that it will try to
-// intelligently handle the scenario of a ref not existing locally, but being known to exist
-// in a remote repo.
-//
-// This method should be used when a command may be performed by either the reviewer or the
-// reviewee, while GetCommitHash should be used when the encompassing command should only be
-// performed by the reviewee.
-func (repo *GitRepo) ResolveRefCommit(ref string) (string, error) {
-	if err := repo.VerifyGitRef(ref); err == nil {
-		return repo.GetCommitHash(ref)
-	}
-	if strings.HasPrefix(ref, "refs/heads/") {
-		// The ref is a branch. Check if it exists in exactly one remote
-		pattern := strings.Replace(ref, "refs/heads", "**", 1)
-		matchingOutput, err := repo.runGitCommand("for-each-ref", "--format=%(refname)", pattern)
-		if err != nil {
-			return "", err
-		}
-		matchingRefs := strings.Split(matchingOutput, "\n")
-		if len(matchingRefs) == 1 && matchingRefs[0] != "" {
-			// There is exactly one match
-			return repo.GetCommitHash(matchingRefs[0])
-		}
-		return "", fmt.Errorf("Unable to find a git ref matching the pattern %q", pattern)
-	}
-	return "", fmt.Errorf("Unknown git ref %q", ref)
-}
-
-// GetCommitMessage returns the message stored in the commit pointed to by the given ref.
-func (repo *GitRepo) GetCommitMessage(ref string) (string, error) {
-	return repo.runGitCommand("show", "-s", "--format=%B", ref)
-}
-
-// GetCommitTime returns the commit time of the commit pointed to by the given ref.
-func (repo *GitRepo) GetCommitTime(ref string) (string, error) {
-	return repo.runGitCommand("show", "-s", "--format=%ct", ref)
-}
-
-// GetLastParent returns the last parent of the given commit (as ordered by git).
-func (repo *GitRepo) GetLastParent(ref string) (string, error) {
-	return repo.runGitCommand("rev-list", "--skip", "1", "-n", "1", ref)
-}
-
-// GetCommitDetails returns the details of a commit's metadata.
-func (repo GitRepo) GetCommitDetails(ref string) (*CommitDetails, error) {
-	var err error
-	show := func(formatString string) (result string) {
-		if err != nil {
-			return ""
-		}
-		result, err = repo.runGitCommand("show", "-s", ref, fmt.Sprintf("--format=tformat:%s", formatString))
-		return result
-	}
-
-	jsonFormatString := "{\"tree\":\"%T\", \"time\": \"%at\"}"
-	detailsJSON := show(jsonFormatString)
-	if err != nil {
-		return nil, err
-	}
-	var details CommitDetails
-	err = json.Unmarshal([]byte(detailsJSON), &details)
-	if err != nil {
-		return nil, err
-	}
-	details.Author = show("%an")
-	details.AuthorEmail = show("%ae")
-	details.Summary = show("%s")
-	parentsString := show("%P")
-	details.Parents = strings.Split(parentsString, " ")
-	if err != nil {
-		return nil, err
-	}
-	return &details, nil
-}
-
-// MergeBase determines if the first commit that is an ancestor of the two arguments.
-func (repo *GitRepo) MergeBase(a, b string) (string, error) {
-	return repo.runGitCommand("merge-base", a, b)
-}
-
-// IsAncestor determines if the first argument points to a commit that is an ancestor of the second.
-func (repo *GitRepo) IsAncestor(ancestor, descendant string) (bool, error) {
-	_, _, err := repo.runGitCommandRaw("merge-base", "--is-ancestor", ancestor, descendant)
-	if err == nil {
-		return true, nil
-	}
-	if _, ok := err.(*exec.ExitError); ok {
-		return false, nil
-	}
-	return false, fmt.Errorf("Error while trying to determine commit ancestry: %v", err)
-}
-
-// Diff computes the diff between two given commits.
-func (repo *GitRepo) Diff(left, right string, diffArgs ...string) (string, error) {
-	args := []string{"diff"}
-	args = append(args, diffArgs...)
-	args = append(args, fmt.Sprintf("%s..%s", left, right))
-	return repo.runGitCommand(args...)
-}
-
-// Show returns the contents of the given file at the given commit.
-func (repo *GitRepo) Show(commit, path string) (string, error) {
-	return repo.runGitCommand("show", fmt.Sprintf("%s:%s", commit, path))
-}
-
-// SwitchToRef changes the currently-checked-out ref.
-func (repo *GitRepo) SwitchToRef(ref string) error {
-	// If the ref starts with "refs/heads/", then we have to trim that prefix,
-	// or else we will wind up in a detached HEAD state.
-	if strings.HasPrefix(ref, branchRefPrefix) {
-		ref = ref[len(branchRefPrefix):]
-	}
-	_, err := repo.runGitCommand("checkout", ref)
-	return err
-}
-
-// mergeArchives merges two archive refs.
-func (repo *GitRepo) mergeArchives(archive, remoteArchive string) error {
-	remoteHash, err := repo.GetCommitHash(remoteArchive)
-	if err != nil {
-		return err
-	}
-	if remoteHash == "" {
-		// The remote archive does not exist, so we have nothing to do
-		return nil
-	}
-
-	archiveHash, err := repo.GetCommitHash(archive)
-	if err != nil {
-		return err
-	}
-	if archiveHash == "" {
-		// The local archive does not exist, so we merely need to set it
-		_, err := repo.runGitCommand("update-ref", archive, remoteHash)
-		return err
-	}
-
-	isAncestor, err := repo.IsAncestor(archiveHash, remoteHash)
-	if err != nil {
-		return err
-	}
-	if isAncestor {
-		// The archive can simply be fast-forwarded
-		_, err := repo.runGitCommand("update-ref", archive, remoteHash, archiveHash)
-		return err
-	}
-
-	// Create a merge commit of the two archives
-	refDetails, err := repo.GetCommitDetails(remoteArchive)
-	if err != nil {
-		return err
-	}
-	newArchiveHash, err := repo.runGitCommand("commit-tree", "-p", remoteHash, "-p", archiveHash, "-m", "Merge local and remote archives", refDetails.Tree)
-	if err != nil {
-		return err
-	}
-	newArchiveHash = strings.TrimSpace(newArchiveHash)
-	_, err = repo.runGitCommand("update-ref", archive, newArchiveHash, archiveHash)
-	return err
-}
-
-// ArchiveRef adds the current commit pointed to by the 'ref' argument
-// under the ref specified in the 'archive' argument.
-//
-// Both the 'ref' and 'archive' arguments are expected to be the fully
-// qualified names of git refs (e.g. 'refs/heads/my-change' or
-// 'refs/devtools/archives/reviews').
-//
-// If the ref pointed to by the 'archive' argument does not exist
-// yet, then it will be created.
-func (repo *GitRepo) ArchiveRef(ref, archive string) error {
-	refHash, err := repo.GetCommitHash(ref)
-	if err != nil {
-		return err
-	}
-	refDetails, err := repo.GetCommitDetails(ref)
-	if err != nil {
-		return err
-	}
-
-	commitTreeArgs := []string{"commit-tree"}
-	archiveHash, err := repo.GetCommitHash(archive)
-	if err != nil {
-		archiveHash = ""
-	} else {
-		commitTreeArgs = append(commitTreeArgs, "-p", archiveHash)
-	}
-	commitTreeArgs = append(commitTreeArgs, "-p", refHash, "-m", fmt.Sprintf("Archive %s", refHash), refDetails.Tree)
-	newArchiveHash, err := repo.runGitCommand(commitTreeArgs...)
-	if err != nil {
-		return err
-	}
-	newArchiveHash = strings.TrimSpace(newArchiveHash)
-	updateRefArgs := []string{"update-ref", archive, newArchiveHash}
-	if archiveHash != "" {
-		updateRefArgs = append(updateRefArgs, archiveHash)
-	}
-	_, err = repo.runGitCommand(updateRefArgs...)
-	return err
-}
-
-// MergeRef merges the given ref into the current one.
-//
-// The ref argument is the ref to merge, and fastForward indicates that the
-// current ref should only move forward, as opposed to creating a bubble merge.
-// The messages argument(s) provide text that should be included in the default
-// merge commit message (separated by blank lines).
-func (repo *GitRepo) MergeRef(ref string, fastForward bool, messages ...string) error {
-	args := []string{"merge"}
-	if fastForward {
-		args = append(args, "--ff", "--ff-only")
-	} else {
-		args = append(args, "--no-ff")
-	}
-	if len(messages) > 0 {
-		commitMessage := strings.Join(messages, "\n\n")
-		args = append(args, "-e", "-m", commitMessage)
-	}
-	args = append(args, ref)
-	return repo.runGitCommandInline(args...)
-}
-
-// MergeAndSignRef merges the given ref into the current one and signs the
-// merge.
-//
-// The ref argument is the ref to merge, and fastForward indicates that the
-// current ref should only move forward, as opposed to creating a bubble merge.
-// The messages argument(s) provide text that should be included in the default
-// merge commit message (separated by blank lines).
-func (repo *GitRepo) MergeAndSignRef(ref string, fastForward bool,
-	messages ...string) error {
-
-	args := []string{"merge"}
-	if fastForward {
-		args = append(args, "--ff", "--ff-only", "-S")
-	} else {
-		args = append(args, "--no-ff", "-S")
-	}
-	if len(messages) > 0 {
-		commitMessage := strings.Join(messages, "\n\n")
-		args = append(args, "-e", "-m", commitMessage)
-	}
-	args = append(args, ref)
-	return repo.runGitCommandInline(args...)
-}
-
-// RebaseRef rebases the current ref onto the given one.
-func (repo *GitRepo) RebaseRef(ref string) error {
-	return repo.runGitCommandInline("rebase", "-i", ref)
-}
-
-// RebaseAndSignRef rebases the current ref onto the given one and signs the
-// result.
-func (repo *GitRepo) RebaseAndSignRef(ref string) error {
-	return repo.runGitCommandInline("rebase", "-S", "-i", ref)
-}
-
-// ListCommits returns the list of commits reachable from the given ref.
-//
-// The generated list is in chronological order (with the oldest commit first).
-//
-// If the specified ref does not exist, then this method returns an empty result.
-func (repo *GitRepo) ListCommits(ref string) []string {
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
-	if err := repo.runGitCommandWithIO(nil, &stdout, &stderr, "rev-list", "--reverse", ref); err != nil {
-		return nil
-	}
-
-	byteLines := bytes.Split(stdout.Bytes(), []byte("\n"))
-	var commits []string
-	for _, byteLine := range byteLines {
-		commits = append(commits, string(byteLine))
-	}
-	return commits
-}
-
-// ListCommitsBetween returns the list of commits between the two given revisions.
-//
-// The "from" parameter is the starting point (exclusive), and the "to"
-// parameter is the ending point (inclusive).
-//
-// The "from" commit does not need to be an ancestor of the "to" commit. If it
-// is not, then the merge base of the two is used as the starting point.
-// Admittedly, this makes calling these the "between" commits is a bit of a
-// misnomer, but it also makes the method easier to use when you want to
-// generate the list of changes in a feature branch, as it eliminates the need
-// to explicitly calculate the merge base. This also makes the semantics of the
-// method compatible with git's built-in "rev-list" command.
-//
-// The generated list is in chronological order (with the oldest commit first).
-func (repo *GitRepo) ListCommitsBetween(from, to string) ([]string, error) {
-	out, err := repo.runGitCommand("rev-list", "--reverse", from+".."+to)
-	if err != nil {
-		return nil, err
-	}
-	if out == "" {
-		return nil, nil
-	}
-	return strings.Split(out, "\n"), nil
-}
-
-// GetNotes uses the "git" command-line tool to read the notes from the given ref for a given revision.
-func (repo *GitRepo) GetNotes(notesRef, revision string) []Note {
-	var notes []Note
-	rawNotes, err := repo.runGitCommand("notes", "--ref", notesRef, "show", revision)
-	if err != nil {
-		// We just assume that this means there are no notes
-		return nil
-	}
-	for _, line := range strings.Split(rawNotes, "\n") {
-		notes = append(notes, Note([]byte(line)))
-	}
-	return notes
-}
-
-func stringsReader(s []*string) io.Reader {
-	var subReaders []io.Reader
-	for _, strPtr := range s {
-		subReader := strings.NewReader(*strPtr)
-		subReaders = append(subReaders, subReader, strings.NewReader("\n"))
-	}
-	return io.MultiReader(subReaders...)
-}
-
-// splitBatchCheckOutput parses the output of a 'git cat-file --batch-check=...' command.
-//
-// The output is expected to be formatted as a series of entries, with each
-// entry consisting of:
-// 1. The SHA1 hash of the git object being output, followed by a space.
-// 2. The git "type" of the object (commit, blob, tree, missing, etc), followed by a newline.
-//
-// To generate this format, make sure that the 'git cat-file' command includes
-// the argument '--batch-check=%(objectname) %(objecttype)'.
-//
-// The return value is a map from object hash to a boolean indicating if that object is a commit.
-func splitBatchCheckOutput(out *bytes.Buffer) (map[string]bool, error) {
-	isCommit := make(map[string]bool)
-	reader := bufio.NewReader(out)
-	for {
-		nameLine, err := reader.ReadString(byte(' '))
-		if err == io.EOF {
-			return isCommit, nil
-		}
-		if err != nil {
-			return nil, fmt.Errorf("Failure while reading the next object name: %v", err)
-		}
-		nameLine = strings.TrimSuffix(nameLine, " ")
-		typeLine, err := reader.ReadString(byte('\n'))
-		if err != nil && err != io.EOF {
-			return nil, fmt.Errorf("Failure while reading the next object type: %q - %v", nameLine, err)
-		}
-		typeLine = strings.TrimSuffix(typeLine, "\n")
-		if typeLine == "commit" {
-			isCommit[nameLine] = true
-		}
-	}
-}
-
-// splitBatchCatFileOutput parses the output of a 'git cat-file --batch=...' command.
-//
-// The output is expected to be formatted as a series of entries, with each
-// entry consisting of:
-// 1. The SHA1 hash of the git object being output, followed by a newline.
-// 2. The size of the object's contents in bytes, followed by a newline.
-// 3. The objects contents.
-//
-// To generate this format, make sure that the 'git cat-file' command includes
-// the argument '--batch=%(objectname)\n%(objectsize)'.
-func splitBatchCatFileOutput(out *bytes.Buffer) (map[string][]byte, error) {
-	contentsMap := make(map[string][]byte)
-	reader := bufio.NewReader(out)
-	for {
-		nameLine, err := reader.ReadString(byte('\n'))
-		if strings.HasSuffix(nameLine, "\n") {
-			nameLine = strings.TrimSuffix(nameLine, "\n")
-		}
-		if err == io.EOF {
-			return contentsMap, nil
-		}
-		if err != nil {
-			return nil, fmt.Errorf("Failure while reading the next object name: %v", err)
-		}
-		sizeLine, err := reader.ReadString(byte('\n'))
-		if strings.HasSuffix(sizeLine, "\n") {
-			sizeLine = strings.TrimSuffix(sizeLine, "\n")
-		}
-		if err != nil {
-			return nil, fmt.Errorf("Failure while reading the next object size: %q - %v", nameLine, err)
-		}
-		size, err := strconv.Atoi(sizeLine)
-		if err != nil {
-			return nil, fmt.Errorf("Failure while parsing the next object size: %q - %v", nameLine, err)
-		}
-		contentBytes := make([]byte, size, size)
-		readDest := contentBytes
-		len := 0
-		err = nil
-		for err == nil && len < size {
-			nextLen := 0
-			nextLen, err = reader.Read(readDest)
-			len += nextLen
-			readDest = contentBytes[len:]
-		}
-		contentsMap[nameLine] = contentBytes
-		if err == io.EOF {
-			return contentsMap, nil
-		}
-		if err != nil {
-			return nil, err
-		}
-		for bs, err := reader.Peek(1); err == nil && bs[0] == byte('\n'); bs, err = reader.Peek(1) {
-			reader.ReadByte()
-		}
-	}
-}
-
-// notesMapping represents the association between a git object and the notes for that object.
-type notesMapping struct {
-	ObjectHash *string
-	NotesHash  *string
-}
-
-// notesOverview represents a high-level overview of all the notes under a single notes ref.
-type notesOverview struct {
-	NotesMappings      []*notesMapping
-	ObjectHashesReader io.Reader
-	NotesHashesReader  io.Reader
-}
-
-// notesOverview returns an overview of the git notes stored under the given ref.
-func (repo *GitRepo) notesOverview(notesRef string) (*notesOverview, error) {
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
-	if err := repo.runGitCommandWithIO(nil, &stdout, &stderr, "notes", "--ref", notesRef, "list"); err != nil {
-		return nil, err
-	}
-
-	var notesMappings []*notesMapping
-	var objHashes []*string
-	var notesHashes []*string
-	outScanner := bufio.NewScanner(&stdout)
-	for outScanner.Scan() {
-		line := outScanner.Text()
-		lineParts := strings.Split(line, " ")
-		if len(lineParts) != 2 {
-			return nil, fmt.Errorf("Malformed output line from 'git-notes list': %q", line)
-		}
-		objHash := &lineParts[1]
-		notesHash := &lineParts[0]
-		notesMappings = append(notesMappings, &notesMapping{
-			ObjectHash: objHash,
-			NotesHash:  notesHash,
-		})
-		objHashes = append(objHashes, objHash)
-		notesHashes = append(notesHashes, notesHash)
-	}
-	err := outScanner.Err()
-	if err != nil && err != io.EOF {
-		return nil, fmt.Errorf("Failure parsing the output of 'git-notes list': %v", err)
-	}
-	return &notesOverview{
-		NotesMappings:      notesMappings,
-		ObjectHashesReader: stringsReader(objHashes),
-		NotesHashesReader:  stringsReader(notesHashes),
-	}, nil
-}
-
-// getIsCommitMap returns a mapping of all the annotated objects that are commits.
-func (overview *notesOverview) getIsCommitMap(repo *GitRepo) (map[string]bool, error) {
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
-	if err := repo.runGitCommandWithIO(overview.ObjectHashesReader, &stdout, &stderr, "cat-file", "--batch-check=%(objectname) %(objecttype)"); err != nil {
-		return nil, fmt.Errorf("Failure performing a batch file check: %v", err)
-	}
-	isCommit, err := splitBatchCheckOutput(&stdout)
-	if err != nil {
-		return nil, fmt.Errorf("Failure parsing the output of a batch file check: %v", err)
-	}
-	return isCommit, nil
-}
-
-// getNoteContentsMap returns a mapping from all the notes hashes to their contents.
-func (overview *notesOverview) getNoteContentsMap(repo *GitRepo) (map[string][]byte, error) {
-	var stdout bytes.Buffer
-	var stderr bytes.Buffer
-	if err := repo.runGitCommandWithIO(overview.NotesHashesReader, &stdout, &stderr, "cat-file", "--batch=%(objectname)\n%(objectsize)"); err != nil {
-		return nil, fmt.Errorf("Failure performing a batch file read: %v", err)
-	}
-	noteContentsMap, err := splitBatchCatFileOutput(&stdout)
-	if err != nil {
-		return nil, fmt.Errorf("Failure parsing the output of a batch file read: %v", err)
-	}
-	return noteContentsMap, nil
-}
-
-// GetAllNotes reads the contents of the notes under the given ref for every commit.
-//
-// The returned value is a mapping from commit hash to the list of notes for that commit.
-//
-// This is the batch version of the corresponding GetNotes(...) method.
-func (repo *GitRepo) GetAllNotes(notesRef string) (map[string][]Note, error) {
-	// This code is unfortunately quite complicated, but it needs to be so.
-	//
-	// Conceptually, this is equivalent to:
-	//   result := make(map[string][]Note)
-	//   for _, commit := range repo.ListNotedRevisions(notesRef) {
-	//     result[commit] = repo.GetNotes(notesRef, commit)
-	//   }
-	//   return result, nil
-	//
-	// However, that logic would require separate executions of the 'git'
-	// command for every annotated commit. For a repo with 10s of thousands
-	// of reviews, that would mean calling Cmd.Run(...) 10s of thousands of
-	// times. That, in turn, would take so long that the tool would be unusable.
-	//
-	// This method avoids that by taking advantage of the 'git cat-file --batch="..."'
-	// command. That allows us to use a single invocation of Cmd.Run(...) to
-	// inspect multiple git objects at once.
-	//
-	// As such, regardless of the number of reviews in a repo, we can get all
-	// of the notes using a total of three invocations of Cmd.Run(...):
-	//  1. One to list all the annotated objects (and their notes hash)
-	//  2. A second one to filter out all of the annotated objects that are not commits.
-	//  3. A final one to get the contents of all of the notes blobs.
-	overview, err := repo.notesOverview(notesRef)
-	if err != nil {
-		return nil, err
-	}
-	isCommit, err := overview.getIsCommitMap(repo)
-	if err != nil {
-		return nil, fmt.Errorf("Failure building the set of commit objects: %v", err)
-	}
-	noteContentsMap, err := overview.getNoteContentsMap(repo)
-	if err != nil {
-		return nil, fmt.Errorf("Failure building the mapping from notes hash to contents: %v", err)
-	}
-	commitNotesMap := make(map[string][]Note)
-	for _, notesMapping := range overview.NotesMappings {
-		if !isCommit[*notesMapping.ObjectHash] {
-			continue
-		}
-		noteBytes := noteContentsMap[*notesMapping.NotesHash]
-		byteSlices := bytes.Split(noteBytes, []byte("\n"))
-		var notes []Note
-		for _, slice := range byteSlices {
-			notes = append(notes, Note(slice))
-		}
-		commitNotesMap[*notesMapping.ObjectHash] = notes
-	}
-
-	return commitNotesMap, nil
-}
-
-// AppendNote appends a note to a revision under the given ref.
-func (repo *GitRepo) AppendNote(notesRef, revision string, note Note) error {
-	_, err := repo.runGitCommand("notes", "--ref", notesRef, "append", "-m", string(note), revision)
-	return err
-}
-
-// ListNotedRevisions returns the collection of revisions that are annotated by notes in the given ref.
-func (repo *GitRepo) ListNotedRevisions(notesRef string) []string {
-	var revisions []string
-	notesListOut, err := repo.runGitCommand("notes", "--ref", notesRef, "list")
-	if err != nil {
-		return nil
-	}
-	notesList := strings.Split(notesListOut, "\n")
-	for _, notePair := range notesList {
-		noteParts := strings.SplitN(notePair, " ", 2)
-		if len(noteParts) == 2 {
-			objHash := noteParts[1]
-			objType, err := repo.runGitCommand("cat-file", "-t", objHash)
-			// If a note points to an object that we do not know about (yet), then err will not
-			// be nil. We can safely just ignore those notes.
-			if err == nil && objType == "commit" {
-				revisions = append(revisions, objHash)
-			}
-		}
-	}
-	return revisions
-}
-
-// PushNotes pushes git notes to a remote repo.
-func (repo *GitRepo) PushNotes(remote, notesRefPattern string) error {
-	refspec := fmt.Sprintf("%s:%s", notesRefPattern, notesRefPattern)
-
-	// The push is liable to fail if the user forgot to do a pull first, so
-	// we treat errors as user errors rather than fatal errors.
-	err := repo.runGitCommandInline("push", remote, refspec)
-	if err != nil {
-		return fmt.Errorf("Failed to push to the remote '%s': %v", remote, err)
-	}
-	return nil
-}
-
-// PushNotesAndArchive pushes the given notes and archive refs to a remote repo.
-func (repo *GitRepo) PushNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error {
-	notesRefspec := fmt.Sprintf("%s:%s", notesRefPattern, notesRefPattern)
-	archiveRefspec := fmt.Sprintf("%s:%s", archiveRefPattern, archiveRefPattern)
-	err := repo.runGitCommandInline("push", remote, notesRefspec, archiveRefspec)
-	if err != nil {
-		return fmt.Errorf("Failed to push the local archive to the remote '%s': %v", remote, err)
-	}
-	return nil
-}
-
-func getRemoteNotesRef(remote, localNotesRef string) string {
-	relativeNotesRef := strings.TrimPrefix(localNotesRef, "refs/notes/")
-	return "refs/notes/" + remote + "/" + relativeNotesRef
-}
-
-// MergeNotes merges in the remote's state of the notes reference into the
-// local repository's.
-func (repo *GitRepo) MergeNotes(remote, notesRefPattern string) error {
-	remoteRefs, err := repo.runGitCommand("ls-remote", remote, notesRefPattern)
-	if err != nil {
-		return err
-	}
-	for _, line := range strings.Split(remoteRefs, "\n") {
-		lineParts := strings.Split(line, "\t")
-		if len(lineParts) == 2 {
-			ref := lineParts[1]
-			remoteRef := getRemoteNotesRef(remote, ref)
-			_, err := repo.runGitCommand("notes", "--ref", ref, "merge", remoteRef, "-s", "cat_sort_uniq")
-			if err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-// PullNotes fetches the contents of the given notes ref from a remote repo,
-// and then merges them with the corresponding local notes using the
-// "cat_sort_uniq" strategy.
-func (repo *GitRepo) PullNotes(remote, notesRefPattern string) error {
-	remoteNotesRefPattern := getRemoteNotesRef(remote, notesRefPattern)
-	fetchRefSpec := fmt.Sprintf("+%s:%s", notesRefPattern, remoteNotesRefPattern)
-	err := repo.runGitCommandInline("fetch", remote, fetchRefSpec)
-	if err != nil {
-		return err
-	}
-
-	return repo.MergeNotes(remote, notesRefPattern)
-}
-
-func getRemoteArchiveRef(remote, archiveRefPattern string) string {
-	relativeArchiveRef := strings.TrimPrefix(archiveRefPattern, "refs/devtools/archives/")
-	return "refs/devtools/remoteArchives/" + remote + "/" + relativeArchiveRef
-}
-
-// MergeArchives merges in the remote's state of the archives reference into
-// the local repository's.
-func (repo *GitRepo) MergeArchives(remote, archiveRefPattern string) error {
-	remoteRefs, err := repo.runGitCommand("ls-remote", remote, archiveRefPattern)
-	if err != nil {
-		return err
-	}
-	for _, line := range strings.Split(remoteRefs, "\n") {
-		lineParts := strings.Split(line, "\t")
-		if len(lineParts) == 2 {
-			ref := lineParts[1]
-			remoteRef := getRemoteArchiveRef(remote, ref)
-			if err := repo.mergeArchives(ref, remoteRef); err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-func (repo *GitRepo) fetchNotes(remote, notesRefPattern,
-	archiveRefPattern string) error {
-
-	remoteArchiveRef := getRemoteArchiveRef(remote, archiveRefPattern)
-	archiveFetchRefSpec := fmt.Sprintf("+%s:%s", archiveRefPattern, remoteArchiveRef)
-
-	remoteNotesRefPattern := getRemoteNotesRef(remote, notesRefPattern)
-	notesFetchRefSpec := fmt.Sprintf("+%s:%s", notesRefPattern, remoteNotesRefPattern)
-
-	return repo.runGitCommandInline("fetch", remote, notesFetchRefSpec, archiveFetchRefSpec)
-}
-
-// PullNotesAndArchive fetches the contents of the notes and archives refs from
-// a remote repo, and merges them with the corresponding local refs.
-//
-// For notes refs, we assume that every note can be automatically merged using
-// the 'cat_sort_uniq' strategy (the git-appraise schemas fit that requirement),
-// so we automatically merge the remote notes into the local notes.
-//
-// For "archive" refs, they are expected to be used solely for maintaining
-// reachability of commits that are part of the history of any reviews,
-// so we do not maintain any consistency with their tree objects. Instead,
-// we merely ensure that their history graph includes every commit that we
-// intend to keep.
-func (repo *GitRepo) PullNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error {
-	err := repo.fetchNotes(remote, notesRefPattern, archiveRefPattern)
-	if err != nil {
-		return err
-	}
-
-	err = repo.MergeNotes(remote, notesRefPattern)
-	if err != nil {
-		return err
-	}
-	return repo.MergeArchives(remote, archiveRefPattern)
-}
-
-// FetchAndReturnNewReviewHashes fetches the notes "branches" and then susses
-// out the IDs (the revision the review points to) of any new reviews, then
-// returns that list of IDs.
-//
-// This is accomplished by determining which files in the notes tree have
-// changed because the _names_ of these files correspond to the revisions they
-// point to.
-func (repo *GitRepo) FetchAndReturnNewReviewHashes(remote, notesRefPattern,
-	archiveRefPattern string) ([]string, error) {
-
-	// Record the current state of the reviews and comments refs.
-	var (
-		getAllRevs, getAllComs    bool
-		reviewsList, commentsList []string
-	)
-	reviewBeforeHash, err := repo.GetCommitHash(
-		"notes/" + remote + "/devtools/reviews")
-	getAllRevs = err != nil
-
-	commentBeforeHash, err := repo.GetCommitHash(
-		"notes/" + remote + "/devtools/discuss")
-	getAllComs = err != nil
-
-	// Update them from the remote.
-	err = repo.fetchNotes(remote, notesRefPattern, archiveRefPattern)
-	if err != nil {
-		return nil, err
-	}
-
-	// Now, if either of these are new refs, we just use the whole tree at that
-	// new ref. Otherwise we see which reviews or comments changed and collect
-	// them into a list.
-	if getAllRevs {
-		hash, err := repo.GetCommitHash(
-			"notes/" + remote + "/devtools/reviews")
-		// It is possible that even after we've pulled that this ref still
-		// isn't present (because there are no reviews yet).
-		if err == nil {
-			rvws, err := repo.runGitCommand("ls-tree", "-r", "--name-only",
-				hash)
-			if err != nil {
-				return nil, err
-			}
-			reviewsList = strings.Split(strings.Replace(rvws, "/", "", -1),
-				"\n")
-		}
-	} else {
-		reviewAfterHash, err := repo.GetCommitHash(
-			"notes/" + remote + "/devtools/reviews")
-		if err != nil {
-			return nil, err
-		}
-
-		// Only run through this if the fetch fetched new revisions.
-		// Otherwise leave reviewsList as its default value, an empty slice
-		// of strings.
-		if reviewBeforeHash != reviewAfterHash {
-			newReviewsRaw, err := repo.runGitCommand("diff", "--name-only",
-				reviewBeforeHash, reviewAfterHash)
-			if err != nil {
-				return nil, err
-			}
-			reviewsList = strings.Split(strings.Replace(newReviewsRaw,
-				"/", "", -1), "\n")
-		}
-	}
-
-	if getAllComs {
-		hash, err := repo.GetCommitHash(
-			"notes/" + remote + "/devtools/discuss")
-		// It is possible that even after we've pulled that this ref still
-		// isn't present (because there are no comments yet).
-		if err == nil {
-			rvws, err := repo.runGitCommand("ls-tree", "-r", "--name-only",
-				hash)
-			if err != nil {
-				return nil, err
-			}
-			commentsList = strings.Split(strings.Replace(rvws, "/", "", -1),
-				"\n")
-		}
-	} else {
-		commentAfterHash, err := repo.GetCommitHash(
-			"notes/" + remote + "/devtools/discuss")
-		if err != nil {
-			return nil, err
-		}
-
-		// Only run through this if the fetch fetched new revisions.
-		// Otherwise leave commentsList as its default value, an empty slice
-		// of strings.
-		if commentBeforeHash != commentAfterHash {
-			newCommentsRaw, err := repo.runGitCommand("diff", "--name-only",
-				commentBeforeHash, commentAfterHash)
-			if err != nil {
-				return nil, err
-			}
-			commentsList = strings.Split(strings.Replace(newCommentsRaw,
-				"/", "", -1), "\n")
-		}
-	}
-
-	// Now that we have our two lists, we need to merge them.
-	updatedReviewSet := make(map[string]struct{})
-	for _, hash := range append(reviewsList, commentsList...) {
-		updatedReviewSet[hash] = struct{}{}
-	}
-
-	updatedReviews := make([]string, 0, len(updatedReviewSet))
-	for key, _ := range updatedReviewSet {
-		updatedReviews = append(updatedReviews, key)
-	}
-	return updatedReviews, nil
-}
diff --git a/third_party/go/git-appraise/repository/git_test.go b/third_party/go/git-appraise/repository/git_test.go
deleted file mode 100644
index e1a9e2b2eace..000000000000
--- a/third_party/go/git-appraise/repository/git_test.go
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-Copyright 2016 Google Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package repository
-
-import (
-	"bytes"
-	"testing"
-)
-
-const (
-	simpleBatchCheckOutput = `ddbdcb9d5aa71d35de481789bacece9a2f8138d0 commit
-de9ebcdf2a1e93365eefc2739f73f2c68a280c11 commit
-def9abf52f9a17d4f168e05bc420557a87a55961 commit
-df324616ea2bc9bf6fc7025fc80a373ecec687b6 missing
-dfdd159c9c11c08d84c8c050d2a1a4db29147916 commit
-e4e48e2b4d76ac305cf76fee1d1c8c0283127d71 commit
-e6ae4ed08704fe3c258ab486b07a36e28c3c238a commit
-e807a993d1807b154294b9875b9d926b6f246d0c commit
-e90f75882526e9bc5a71af64d60ea50092ed0b1d commit`
-	simpleBatchCatFileOutput = `c1f5a5f135b171cc963b822d338000d185f1ae4f
-342
-{"timestamp":"1450315153","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/105/"}
-
-{"timestamp":"1450315161","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/105/","status":"success"}
-
-31ea4952450bbe5db0d6a7a7903e451925106c0f
-141
-{"timestamp":"1440202534","url":"https://travis-ci.org/google/git-appraise/builds/76722074","agent":"continuous-integration/travis-ci/push"}
-
-bde25250a9f6dc9c56f16befa5a2d73c8558b472
-342
-{"timestamp":"1450434854","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/112/"}
-
-{"timestamp":"1450434860","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/112/","status":"success"}
-
-3128dc6881bf7647aea90fef1f4fbf883df6a8fe
-342
-{"timestamp":"1457445850","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/191/"}
-
-{"timestamp":"1457445856","v":0,"agent":"Jenkins(1.627) GitNotesJobLogger","url":"https://jenkins-dot-developer-tools-bundle.appspot.com/job/git-appraise/191/","status":"success"}
-
-`
-)
-
-func TestSplitBatchCheckOutput(t *testing.T) {
-	buf := bytes.NewBuffer([]byte(simpleBatchCheckOutput))
-	commitsMap, err := splitBatchCheckOutput(buf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !commitsMap["ddbdcb9d5aa71d35de481789bacece9a2f8138d0"] {
-		t.Fatal("Failed to recognize the first commit as valid")
-	}
-	if !commitsMap["de9ebcdf2a1e93365eefc2739f73f2c68a280c11"] {
-		t.Fatal("Failed to recognize the second commit as valid")
-	}
-	if !commitsMap["e90f75882526e9bc5a71af64d60ea50092ed0b1d"] {
-		t.Fatal("Failed to recognize the last commit as valid")
-	}
-	if commitsMap["df324616ea2bc9bf6fc7025fc80a373ecec687b6"] {
-		t.Fatal("Failed to filter out a missing object")
-	}
-}
-
-func TestSplitBatchCatFileOutput(t *testing.T) {
-	buf := bytes.NewBuffer([]byte(simpleBatchCatFileOutput))
-	notesMap, err := splitBatchCatFileOutput(buf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(notesMap["c1f5a5f135b171cc963b822d338000d185f1ae4f"]) != 342 {
-		t.Fatal("Failed to parse the contents of the first cat'ed file")
-	}
-	if len(notesMap["31ea4952450bbe5db0d6a7a7903e451925106c0f"]) != 141 {
-		t.Fatal("Failed to parse the contents of the second cat'ed file")
-	}
-	if len(notesMap["3128dc6881bf7647aea90fef1f4fbf883df6a8fe"]) != 342 {
-		t.Fatal("Failed to parse the contents of the last cat'ed file")
-	}
-}
diff --git a/third_party/go/git-appraise/repository/mock_repo.go b/third_party/go/git-appraise/repository/mock_repo.go
deleted file mode 100644
index 2d8debe48387..000000000000
--- a/third_party/go/git-appraise/repository/mock_repo.go
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
-Copyright 2015 Google Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package repository
-
-import (
-	"crypto/sha1"
-	"encoding/json"
-	"fmt"
-	"strings"
-)
-
-// Constants used for testing.
-// We initialize our mock repo with two branches (one of which holds a pending review),
-// and commit history that looks like this:
-//
-//  Master Branch:    A--B--D--E--F--J
-//                     \   /    \  \
-//                       C       \  \
-//                                \  \
-//  Review Branch:                 G--H--I
-//
-// Where commits "B" and "D" represent reviews that have been submitted, and "G"
-// is a pending review.
-const (
-	TestTargetRef          = "refs/heads/master"
-	TestReviewRef          = "refs/heads/ojarjur/mychange"
-	TestAlternateReviewRef = "refs/review/mychange"
-	TestRequestsRef        = "refs/notes/devtools/reviews"
-	TestCommentsRef        = "refs/notes/devtools/discuss"
-
-	TestCommitA = "A"
-	TestCommitB = "B"
-	TestCommitC = "C"
-	TestCommitD = "D"
-	TestCommitE = "E"
-	TestCommitF = "F"
-	TestCommitG = "G"
-	TestCommitH = "H"
-	TestCommitI = "I"
-	TestCommitJ = "J"
-
-	TestRequestB = `{"timestamp": "0000000001", "reviewRef": "refs/heads/ojarjur/mychange", "targetRef": "refs/heads/master", "requester": "ojarjur", "reviewers": ["ojarjur"], "description": "B"}`
-	TestRequestD = `{"timestamp": "0000000002", "reviewRef": "refs/heads/ojarjur/mychange", "targetRef": "refs/heads/master", "requester": "ojarjur", "reviewers": ["ojarjur"], "description": "D"}`
-	TestRequestG = `{"timestamp": "0000000004", "reviewRef": "refs/heads/ojarjur/mychange", "targetRef": "refs/heads/master", "requester": "ojarjur", "reviewers": ["ojarjur"], "description": "G"}
-
-{"timestamp": "0000000005", "reviewRef": "refs/heads/ojarjur/mychange", "targetRef": "refs/heads/master", "requester": "ojarjur", "reviewers": ["ojarjur"], "description": "Updated description of G"}
-
-{"timestamp": "0000000005", "reviewRef": "refs/heads/ojarjur/mychange", "targetRef": "refs/heads/master", "requester": "ojarjur", "reviewers": ["ojarjur"], "description": "Final description of G"}`
-
-	TestDiscussB = `{"timestamp": "0000000001", "author": "ojarjur", "location": {"commit": "B"}, "resolved": true}`
-	TestDiscussD = `{"timestamp": "0000000003", "author": "ojarjur", "location": {"commit": "E"}, "resolved": true}`
-)
-
-type mockCommit struct {
-	Message string   `json:"message,omitempty"`
-	Time    string   `json:"time,omitempty"`
-	Parents []string `json:"parents,omitempty"`
-}
-
-// mockRepoForTest defines an instance of Repo that can be used for testing.
-type mockRepoForTest struct {
-	Head    string
-	Refs    map[string]string            `json:"refs,omitempty"`
-	Commits map[string]mockCommit        `json:"commits,omitempty"`
-	Notes   map[string]map[string]string `json:"notes,omitempty"`
-}
-
-func (r *mockRepoForTest) createCommit(message string, time string, parents []string) (string, error) {
-	newCommit := mockCommit{
-		Message: message,
-		Time:    time,
-		Parents: parents,
-	}
-	newCommitJSON, err := json.Marshal(newCommit)
-	if err != nil {
-		return "", err
-	}
-	newCommitHash := fmt.Sprintf("%x", sha1.Sum([]byte(newCommitJSON)))
-	r.Commits[newCommitHash] = newCommit
-	return newCommitHash, nil
-}
-
-// NewMockRepoForTest returns a mocked-out instance of the Repo interface that has been pre-populated with test data.
-func NewMockRepoForTest() Repo {
-	commitA := mockCommit{
-		Message: "First commit",
-		Time:    "0",
-		Parents: nil,
-	}
-	commitB := mockCommit{
-		Message: "Second commit",
-		Time:    "1",
-		Parents: []string{TestCommitA},
-	}
-	commitC := mockCommit{
-		Message: "No, I'm the second commit",
-		Time:    "1",
-		Parents: []string{TestCommitA},
-	}
-	commitD := mockCommit{
-		Message: "Fourth commit",
-		Time:    "2",
-		Parents: []string{TestCommitB, TestCommitC},
-	}
-	commitE := mockCommit{
-		Message: "Fifth commit",
-		Time:    "3",
-		Parents: []string{TestCommitD},
-	}
-	commitF := mockCommit{
-		Message: "Sixth commit",
-		Time:    "4",
-		Parents: []string{TestCommitE},
-	}
-	commitG := mockCommit{
-		Message: "No, I'm the sixth commit",
-		Time:    "4",
-		Parents: []string{TestCommitE},
-	}
-	commitH := mockCommit{
-		Message: "Seventh commit",
-		Time:    "5",
-		Parents: []string{TestCommitG, TestCommitF},
-	}
-	commitI := mockCommit{
-		Message: "Eighth commit",
-		Time:    "6",
-		Parents: []string{TestCommitH},
-	}
-	commitJ := mockCommit{
-		Message: "No, I'm the eighth commit",
-		Time:    "6",
-		Parents: []string{TestCommitF},
-	}
-	return &mockRepoForTest{
-		Head: TestTargetRef,
-		Refs: map[string]string{
-			TestTargetRef:          TestCommitJ,
-			TestReviewRef:          TestCommitI,
-			TestAlternateReviewRef: TestCommitI,
-		},
-		Commits: map[string]mockCommit{
-			TestCommitA: commitA,
-			TestCommitB: commitB,
-			TestCommitC: commitC,
-			TestCommitD: commitD,
-			TestCommitE: commitE,
-			TestCommitF: commitF,
-			TestCommitG: commitG,
-			TestCommitH: commitH,
-			TestCommitI: commitI,
-			TestCommitJ: commitJ,
-		},
-		Notes: map[string]map[string]string{
-			TestRequestsRef: map[string]string{
-				TestCommitB: TestRequestB,
-				TestCommitD: TestRequestD,
-				TestCommitG: TestRequestG,
-			},
-			TestCommentsRef: map[string]string{
-				TestCommitB: TestDiscussB,
-				TestCommitD: TestDiscussD,
-			},
-		},
-	}
-}
-
-// GetPath returns the path to the repo.
-func (r *mockRepoForTest) GetPath() string { return "~/mockRepo/" }
-
-// GetRepoStateHash returns a hash which embodies the entire current state of a repository.
-func (r *mockRepoForTest) GetRepoStateHash() (string, error) {
-	repoJSON, err := json.Marshal(r)
-	if err != nil {
-		return "", err
-	}
-	return fmt.Sprintf("%x", sha1.Sum([]byte(repoJSON))), nil
-}
-
-// GetUserEmail returns the email address that the user has used to configure git.
-func (r *mockRepoForTest) GetUserEmail() (string, error) { return "user@example.com", nil }
-
-// GetUserSigningKey returns the key id the user has configured for
-// sigining git artifacts.
-func (r *mockRepoForTest) GetUserSigningKey() (string, error) {
-	return "gpgsig", nil
-}
-
-// GetCoreEditor returns the name of the editor that the user has used to configure git.
-func (r *mockRepoForTest) GetCoreEditor() (string, error) { return "vi", nil }
-
-// GetSubmitStrategy returns the way in which a review is submitted
-func (r *mockRepoForTest) GetSubmitStrategy() (string, error) { return "merge", nil }
-
-// HasUncommittedChanges returns true if there are local, uncommitted changes.
-func (r *mockRepoForTest) HasUncommittedChanges() (bool, error) { return false, nil }
-
-func (r *mockRepoForTest) resolveLocalRef(ref string) (string, error) {
-	if ref == "HEAD" {
-		ref = r.Head
-	}
-	if commit, ok := r.Refs[ref]; ok {
-		return commit, nil
-	}
-	if _, ok := r.Commits[ref]; ok {
-		return ref, nil
-	}
-	return "", fmt.Errorf("The ref %q does not exist", ref)
-}
-
-// VerifyCommit verifies that the supplied hash points to a known commit.
-func (r *mockRepoForTest) VerifyCommit(hash string) error {
-	if _, ok := r.Commits[hash]; !ok {
-		return fmt.Errorf("The given hash %q is not a known commit", hash)
-	}
-	return nil
-}
-
-// VerifyGitRef verifies that the supplied ref points to a known commit.
-func (r *mockRepoForTest) VerifyGitRef(ref string) error {
-	_, err := r.resolveLocalRef(ref)
-	return err
-}
-
-// GetHeadRef returns the ref that is the current HEAD.
-func (r *mockRepoForTest) GetHeadRef() (string, error) { return r.Head, nil }
-
-// GetCommitHash returns the hash of the commit pointed to by the given ref.
-func (r *mockRepoForTest) GetCommitHash(ref string) (string, error) {
-	err := r.VerifyGitRef(ref)
-	if err != nil {
-		return "", err
-	}
-	return r.resolveLocalRef(ref)
-}
-
-// ResolveRefCommit returns the commit pointed to by the given ref, which may be a remote ref.
-//
-// This differs from GetCommitHash which only works on exact matches, in that it will try to
-// intelligently handle the scenario of a ref not existing locally, but being known to exist
-// in a remote repo.
-//
-// This method should be used when a command may be performed by either the reviewer or the
-// reviewee, while GetCommitHash should be used when the encompassing command should only be
-// performed by the reviewee.
-func (r *mockRepoForTest) ResolveRefCommit(ref string) (string, error) {
-	if commit, err := r.resolveLocalRef(ref); err == nil {
-		return commit, err
-	}
-	return r.resolveLocalRef(strings.Replace(ref, "refs/heads/", "refs/remotes/origin/", 1))
-}
-
-func (r *mockRepoForTest) getCommit(ref string) (mockCommit, error) {
-	commit, err := r.resolveLocalRef(ref)
-	return r.Commits[commit], err
-}
-
-// GetCommitMessage returns the message stored in the commit pointed to by the given ref.
-func (r *mockRepoForTest) GetCommitMessage(ref string) (string, error) {
-	commit, err := r.getCommit(ref)
-	if err != nil {
-		return "", err
-	}
-	return commit.Message, nil
-}
-
-// GetCommitTime returns the commit time of the commit pointed to by the given ref.
-func (r *mockRepoForTest) GetCommitTime(ref string) (string, error) {
-	commit, err := r.getCommit(ref)
-	if err != nil {
-		return "", err
-	}
-	return commit.Time, nil
-}
-
-// GetLastParent returns the last parent of the given commit (as ordered by git).
-func (r *mockRepoForTest) GetLastParent(ref string) (string, error) {
-	commit, err := r.getCommit(ref)
-	if len(commit.Parents) > 0 {
-		return commit.Parents[len(commit.Parents)-1], err
-	}
-	return "", err
-}
-
-// GetCommitDetails returns the details of a commit's metadata.
-func (r *mockRepoForTest) GetCommitDetails(ref string) (*CommitDetails, error) {
-	commit, err := r.getCommit(ref)
-	if err != nil {
-		return nil, err
-	}
-	var details CommitDetails
-	details.Author = "Test Author"
-	details.AuthorEmail = "author@example.com"
-	details.Summary = commit.Message
-	details.Time = commit.Time
-	details.Parents = commit.Parents
-	return &details, nil
-}
-
-// ancestors returns the breadth-first traversal of a commit's ancestors
-func (r *mockRepoForTest) ancestors(commit string) ([]string, error) {
-	queue := []string{commit}
-	var ancestors []string
-	for queue != nil {
-		var nextQueue []string
-		for _, c := range queue {
-			commit, err := r.getCommit(c)
-			if err != nil {
-				return nil, err
-			}
-			parents := commit.Parents
-			nextQueue = append(nextQueue, parents...)
-			ancestors = append(ancestors, parents...)
-		}
-		queue = nextQueue
-	}
-	return ancestors, nil
-}
-
-// IsAncestor determines if the first argument points to a commit that is an ancestor of the second.
-func (r *mockRepoForTest) IsAncestor(ancestor, descendant string) (bool, error) {
-	var err error
-	ancestor, err = r.resolveLocalRef(ancestor)
-	if err != nil {
-		return false, err
-	}
-	descendant, err = r.resolveLocalRef(descendant)
-	if err != nil {
-		return false, err
-	}
-	if ancestor == descendant {
-		return true, nil
-	}
-	descendantCommit, err := r.getCommit(descendant)
-	if err != nil {
-		return false, err
-	}
-	for _, parent := range descendantCommit.Parents {
-		if t, e := r.IsAncestor(ancestor, parent); e == nil && t {
-			return true, nil
-		}
-	}
-	return false, nil
-}
-
-// MergeBase determines if the first commit that is an ancestor of the two arguments.
-func (r *mockRepoForTest) MergeBase(a, b string) (string, error) {
-	ancestors, err := r.ancestors(a)
-	if err != nil {
-		return "", err
-	}
-	for _, ancestor := range ancestors {
-		if t, e := r.IsAncestor(ancestor, b); e == nil && t {
-			return ancestor, nil
-		}
-	}
-	return "", nil
-}
-
-// Diff computes the diff between two given commits.
-func (r *mockRepoForTest) Diff(left, right string, diffArgs ...string) (string, error) {
-	return fmt.Sprintf("Diff between %q and %q", left, right), nil
-}
-
-// Show returns the contents of the given file at the given commit.
-func (r *mockRepoForTest) Show(commit, path string) (string, error) {
-	return fmt.Sprintf("%s:%s", commit, path), nil
-}
-
-// SwitchToRef changes the currently-checked-out ref.
-func (r *mockRepoForTest) SwitchToRef(ref string) error {
-	r.Head = ref
-	return nil
-}
-
-// ArchiveRef adds the current commit pointed to by the 'ref' argument
-// under the ref specified in the 'archive' argument.
-//
-// Both the 'ref' and 'archive' arguments are expected to be the fully
-// qualified names of git refs (e.g. 'refs/heads/my-change' or
-// 'refs/archive/devtools').
-//
-// If the ref pointed to by the 'archive' argument does not exist
-// yet, then it will be created.
-func (r *mockRepoForTest) ArchiveRef(ref, archive string) error {
-	commitToArchive, err := r.resolveLocalRef(ref)
-	if err != nil {
-		return err
-	}
-	var archiveParents []string
-	if archiveCommit, err := r.resolveLocalRef(archive); err == nil {
-		archiveParents = []string{archiveCommit, commitToArchive}
-	} else {
-		archiveParents = []string{commitToArchive}
-	}
-	archiveCommit, err := r.createCommit("Archiving", "Nowish", archiveParents)
-	if err != nil {
-		return err
-	}
-	r.Refs[archive] = archiveCommit
-	return nil
-}
-
-// MergeRef merges the given ref into the current one.
-//
-// The ref argument is the ref to merge, and fastForward indicates that the
-// current ref should only move forward, as opposed to creating a bubble merge.
-func (r *mockRepoForTest) MergeRef(ref string, fastForward bool, messages ...string) error {
-	newCommitHash, err := r.resolveLocalRef(ref)
-	if err != nil {
-		return err
-	}
-	if !fastForward {
-		origCommit, err := r.resolveLocalRef(r.Head)
-		if err != nil {
-			return err
-		}
-		newCommit, err := r.getCommit(ref)
-		if err != nil {
-			return err
-		}
-		message := strings.Join(messages, "\n\n")
-		time := newCommit.Time
-		parents := []string{origCommit, newCommitHash}
-		newCommitHash, err = r.createCommit(message, time, parents)
-		if err != nil {
-			return err
-		}
-	}
-	r.Refs[r.Head] = newCommitHash
-	return nil
-}
-
-// MergeAndSignRef merges the given ref into the current one and signs the
-// merge.
-//
-// The ref argument is the ref to merge, and fastForward indicates that the
-// current ref should only move forward, as opposed to creating a bubble merge.
-func (r *mockRepoForTest) MergeAndSignRef(ref string, fastForward bool,
-	messages ...string) error {
-	return nil
-}
-
-// RebaseRef rebases the current ref onto the given one.
-func (r *mockRepoForTest) RebaseRef(ref string) error {
-	parentHash := r.Refs[ref]
-	origCommit, err := r.getCommit(r.Head)
-	if err != nil {
-		return err
-	}
-	newCommitHash, err := r.createCommit(origCommit.Message, origCommit.Time, []string{parentHash})
-	if err != nil {
-		return err
-	}
-	if strings.HasPrefix(r.Head, "refs/heads/") {
-		r.Refs[r.Head] = newCommitHash
-	} else {
-		// The current head is not a branch, so updating
-		// it should leave us in a detached-head state.
-		r.Head = newCommitHash
-	}
-	return nil
-}
-
-// RebaseAndSignRef rebases the current ref onto the given one and signs the
-// result.
-func (r *mockRepoForTest) RebaseAndSignRef(ref string) error { return nil }
-
-// ListCommits returns the list of commits reachable from the given ref.
-//
-// The generated list is in chronological order (with the oldest commit first).
-//
-// If the specified ref does not exist, then this method returns an empty result.
-func (r *mockRepoForTest) ListCommits(ref string) []string { return nil }
-
-// ListCommitsBetween returns the list of commits between the two given revisions.
-//
-// The "from" parameter is the starting point (exclusive), and the "to"
-// parameter is the ending point (inclusive).
-//
-// The "from" commit does not need to be an ancestor of the "to" commit. If it
-// is not, then the merge base of the two is used as the starting point.
-// Admittedly, this makes calling these the "between" commits is a bit of a
-// misnomer, but it also makes the method easier to use when you want to
-// generate the list of changes in a feature branch, as it eliminates the need
-// to explicitly calculate the merge base. This also makes the semantics of the
-// method compatible with git's built-in "rev-list" command.
-//
-// The generated list is in chronological order (with the oldest commit first).
-func (r *mockRepoForTest) ListCommitsBetween(from, to string) ([]string, error) {
-	commits := []string{to}
-	potentialCommits, _ := r.ancestors(to)
-	for _, commit := range potentialCommits {
-		blocked, err := r.IsAncestor(commit, from)
-		if err != nil {
-			return nil, err
-		}
-		if !blocked {
-			commits = append(commits, commit)
-		}
-	}
-	return commits, nil
-}
-
-// GetNotes reads the notes from the given ref that annotate the given revision.
-func (r *mockRepoForTest) GetNotes(notesRef, revision string) []Note {
-	notesText := r.Notes[notesRef][revision]
-	var notes []Note
-	for _, line := range strings.Split(notesText, "\n") {
-		notes = append(notes, Note(line))
-	}
-	return notes
-}
-
-// GetAllNotes reads the contents of the notes under the given ref for every commit.
-//
-// The returned value is a mapping from commit hash to the list of notes for that commit.
-//
-// This is the batch version of the corresponding GetNotes(...) method.
-func (r *mockRepoForTest) GetAllNotes(notesRef string) (map[string][]Note, error) {
-	notesMap := make(map[string][]Note)
-	for _, commit := range r.ListNotedRevisions(notesRef) {
-		notesMap[commit] = r.GetNotes(notesRef, commit)
-	}
-	return notesMap, nil
-}
-
-// AppendNote appends a note to a revision under the given ref.
-func (r *mockRepoForTest) AppendNote(ref, revision string, note Note) error {
-	existingNotes := r.Notes[ref][revision]
-	newNotes := existingNotes + "\n" + string(note)
-	r.Notes[ref][revision] = newNotes
-	return nil
-}
-
-// ListNotedRevisions returns the collection of revisions that are annotated by notes in the given ref.
-func (r *mockRepoForTest) ListNotedRevisions(notesRef string) []string {
-	var revisions []string
-	for revision := range r.Notes[notesRef] {
-		if _, ok := r.Commits[revision]; ok {
-			revisions = append(revisions, revision)
-		}
-	}
-	return revisions
-}
-
-// PushNotes pushes git notes to a remote repo.
-func (r *mockRepoForTest) PushNotes(remote, notesRefPattern string) error { return nil }
-
-// PullNotes fetches the contents of the given notes ref from a remote repo,
-// and then merges them with the corresponding local notes using the
-// "cat_sort_uniq" strategy.
-func (r *mockRepoForTest) PullNotes(remote, notesRefPattern string) error { return nil }
-
-// PushNotesAndArchive pushes the given notes and archive refs to a remote repo.
-func (r *mockRepoForTest) PushNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error {
-	return nil
-}
-
-// PullNotesAndArchive fetches the contents of the notes and archives refs from
-// a remote repo, and merges them with the corresponding local refs.
-//
-// For notes refs, we assume that every note can be automatically merged using
-// the 'cat_sort_uniq' strategy (the git-appraise schemas fit that requirement),
-// so we automatically merge the remote notes into the local notes.
-//
-// For "archive" refs, they are expected to be used solely for maintaining
-// reachability of commits that are part of the history of any reviews,
-// so we do not maintain any consistency with their tree objects. Instead,
-// we merely ensure that their history graph includes every commit that we
-// intend to keep.
-func (r *mockRepoForTest) PullNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error {
-	return nil
-}
-
-// MergeNotes merges in the remote's state of the archives reference into
-// the local repository's.
-func (repo *mockRepoForTest) MergeNotes(remote, notesRefPattern string) error {
-	return nil
-}
-
-// MergeArchives merges in the remote's state of the archives reference into
-// the local repository's.
-func (repo *mockRepoForTest) MergeArchives(remote,
-	archiveRefPattern string) error {
-	return nil
-}
-
-// FetchAndReturnNewReviewHashes fetches the notes "branches" and then susses
-// out the IDs (the revision the review points to) of any new reviews, then
-// returns that list of IDs.
-//
-// This is accomplished by determining which files in the notes tree have
-// changed because the _names_ of these files correspond to the revisions they
-// point to.
-func (repo *mockRepoForTest) FetchAndReturnNewReviewHashes(remote, notesRefPattern,
-	archiveRefPattern string) ([]string, error) {
-	return nil, nil
-}
diff --git a/third_party/go/git-appraise/repository/repo.go b/third_party/go/git-appraise/repository/repo.go
deleted file mode 100644
index 91acd177edf0..000000000000
--- a/third_party/go/git-appraise/repository/repo.go
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
-Copyright 2015 Google Inc. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-// Package repository contains helper methods for working with a Git repo.
-package repository
-
-// Note represents the contents of a git-note
-type Note []byte
-
-// CommitDetails represents the contents of a commit.
-type CommitDetails struct {
-	Author      string   `json:"author,omitempty"`
-	AuthorEmail string   `json:"authorEmail,omitempty"`
-	Tree        string   `json:"tree,omitempty"`
-	Time        string   `json:"time,omitempty"`
-	Parents     []string `json:"parents,omitempty"`
-	Summary     string   `json:"summary,omitempty"`
-}
-
-// Repo represents a source code repository.
-type Repo interface {
-	// GetPath returns the path to the repo.
-	GetPath() string
-
-	// GetRepoStateHash returns a hash which embodies the entire current state of a repository.
-	GetRepoStateHash() (string, error)
-
-	// GetUserEmail returns the email address that the user has used to configure git.
-	GetUserEmail() (string, error)
-
-	// GetUserSigningKey returns the key id the user has configured for
-	// sigining git artifacts.
-	GetUserSigningKey() (string, error)
-
-	// GetCoreEditor returns the name of the editor that the user has used to configure git.
-	GetCoreEditor() (string, error)
-
-	// GetSubmitStrategy returns the way in which a review is submitted
-	GetSubmitStrategy() (string, error)
-
-	// HasUncommittedChanges returns true if there are local, uncommitted changes.
-	HasUncommittedChanges() (bool, error)
-
-	// VerifyCommit verifies that the supplied hash points to a known commit.
-	VerifyCommit(hash string) error
-
-	// VerifyGitRef verifies that the supplied ref points to a known commit.
-	VerifyGitRef(ref string) error
-
-	// GetHeadRef returns the ref that is the current HEAD.
-	GetHeadRef() (string, error)
-
-	// GetCommitHash returns the hash of the commit pointed to by the given ref.
-	GetCommitHash(ref string) (string, error)
-
-	// ResolveRefCommit returns the commit pointed to by the given ref, which may be a remote ref.
-	//
-	// This differs from GetCommitHash which only works on exact matches, in that it will try to
-	// intelligently handle the scenario of a ref not existing locally, but being known to exist
-	// in a remote repo.
-	//
-	// This method should be used when a command may be performed by either the reviewer or the
-	// reviewee, while GetCommitHash should be used when the encompassing command should only be
-	// performed by the reviewee.
-	ResolveRefCommit(ref string) (string, error)
-
-	// GetCommitMessage returns the message stored in the commit pointed to by the given ref.
-	GetCommitMessage(ref string) (string, error)
-
-	// GetCommitTime returns the commit time of the commit pointed to by the given ref.
-	GetCommitTime(ref string) (string, error)
-
-	// GetLastParent returns the last parent of the given commit (as ordered by git).
-	GetLastParent(ref string) (string, error)
-
-	// GetCommitDetails returns the details of a commit's metadata.
-	GetCommitDetails(ref string) (*CommitDetails, error)
-
-	// MergeBase determines if the first commit that is an ancestor of the two arguments.
-	MergeBase(a, b string) (string, error)
-
-	// IsAncestor determines if the first argument points to a commit that is an ancestor of the second.
-	IsAncestor(ancestor, descendant string) (bool, error)
-
-	// Diff computes the diff between two given commits.
-	Diff(left, right string, diffArgs ...string) (string, error)
-
-	// Show returns the contents of the given file at the given commit.
-	Show(commit, path string) (string, error)
-
-	// SwitchToRef changes the currently-checked-out ref.
-	SwitchToRef(ref string) error
-
-	// ArchiveRef adds the current commit pointed to by the 'ref' argument
-	// under the ref specified in the 'archive' argument.
-	//
-	// Both the 'ref' and 'archive' arguments are expected to be the fully
-	// qualified names of git refs (e.g. 'refs/heads/my-change' or
-	// 'refs/archive/devtools').
-	//
-	// If the ref pointed to by the 'archive' argument does not exist
-	// yet, then it will be created.
-	ArchiveRef(ref, archive string) error
-
-	// MergeRef merges the given ref into the current one.
-	//
-	// The ref argument is the ref to merge, and fastForward indicates that the
-	// current ref should only move forward, as opposed to creating a bubble merge.
-	// The messages argument(s) provide text that should be included in the default
-	// merge commit message (separated by blank lines).
-	MergeRef(ref string, fastForward bool, messages ...string) error
-
-	// MergeAndSignRef merges the given ref into the current one and signs the
-	// merge.
-	//
-	// The ref argument is the ref to merge, and fastForward indicates that the
-	// current ref should only move forward, as opposed to creating a bubble merge.
-	// The messages argument(s) provide text that should be included in the default
-	// merge commit message (separated by blank lines).
-	MergeAndSignRef(ref string, fastForward bool, messages ...string) error
-
-	// RebaseRef rebases the current ref onto the given one.
-	RebaseRef(ref string) error
-
-	// RebaseAndSignRef rebases the current ref onto the given one and signs
-	// the result.
-	RebaseAndSignRef(ref string) error
-
-	// ListCommits returns the list of commits reachable from the given ref.
-	//
-	// The generated list is in chronological order (with the oldest commit first).
-	//
-	// If the specified ref does not exist, then this method returns an empty result.
-	ListCommits(ref string) []string
-
-	// ListCommitsBetween returns the list of commits between the two given revisions.
-	//
-	// The "from" parameter is the starting point (exclusive), and the "to"
-	// parameter is the ending point (inclusive).
-	//
-	// The "from" commit does not need to be an ancestor of the "to" commit. If it
-	// is not, then the merge base of the two is used as the starting point.
-	// Admittedly, this makes calling these the "between" commits is a bit of a
-	// misnomer, but it also makes the method easier to use when you want to
-	// generate the list of changes in a feature branch, as it eliminates the need
-	// to explicitly calculate the merge base. This also makes the semantics of the
-	// method compatible with git's built-in "rev-list" command.
-	//
-	// The generated list is in chronological order (with the oldest commit first).
-	ListCommitsBetween(from, to string) ([]string, error)
-
-	// GetNotes reads the notes from the given ref that annotate the given revision.
-	GetNotes(notesRef, revision string) []Note
-
-	// GetAllNotes reads the contents of the notes under the given ref for every commit.
-	//
-	// The returned value is a mapping from commit hash to the list of notes for that commit.
-	//
-	// This is the batch version of the corresponding GetNotes(...) method.
-	GetAllNotes(notesRef string) (map[string][]Note, error)
-
-	// AppendNote appends a note to a revision under the given ref.
-	AppendNote(ref, revision string, note Note) error
-
-	// ListNotedRevisions returns the collection of revisions that are annotated by notes in the given ref.
-	ListNotedRevisions(notesRef string) []string
-
-	// PushNotes pushes git notes to a remote repo.
-	PushNotes(remote, notesRefPattern string) error
-
-	// PullNotes fetches the contents of the given notes ref from a remote repo,
-	// and then merges them with the corresponding local notes using the
-	// "cat_sort_uniq" strategy.
-	PullNotes(remote, notesRefPattern string) error
-
-	// PushNotesAndArchive pushes the given notes and archive refs to a remote repo.
-	PushNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error
-
-	// PullNotesAndArchive fetches the contents of the notes and archives refs from
-	// a remote repo, and merges them with the corresponding local refs.
-	//
-	// For notes refs, we assume that every note can be automatically merged using
-	// the 'cat_sort_uniq' strategy (the git-appraise schemas fit that requirement),
-	// so we automatically merge the remote notes into the local notes.
-	//
-	// For "archive" refs, they are expected to be used solely for maintaining
-	// reachability of commits that are part of the history of any reviews,
-	// so we do not maintain any consistency with their tree objects. Instead,
-	// we merely ensure that their history graph includes every commit that we
-	// intend to keep.
-	PullNotesAndArchive(remote, notesRefPattern, archiveRefPattern string) error
-
-	// MergeNotes merges in the remote's state of the archives reference into
-	// the local repository's.
-	MergeNotes(remote, notesRefPattern string) error
-	// MergeArchives merges in the remote's state of the archives reference
-	// into the local repository's.
-	MergeArchives(remote, archiveRefPattern string) error
-
-	// FetchAndReturnNewReviewHashes fetches the notes "branches" and then
-	// susses out the IDs (the revision the review points to) of any new
-	// reviews, then returns that list of IDs.
-	//
-	// This is accomplished by determining which files in the notes tree have
-	// changed because the _names_ of these files correspond to the revisions
-	// they point to.
-	FetchAndReturnNewReviewHashes(remote, notesRefPattern, archiveRefPattern string) ([]string, error)
-}