Add script to compare performance of two versions of pdfium.

Run from the pdfium root:

$ testing/tools/safetynet_compare.py testing
This compares the current branch with and without local changes.

$ testing/tools/safetynet_compare.py testing/corpus --branch-before x
This compares the current branch + local changes against branch x.
It runs only the corpus tests.

$ testing/tools/safetynet_compare.py testing --branch-before x
    --branch-after y --build-dir=~/output_compare
This compares branch x and branch y. x and y can be revision hashes.
The callgrind.out files of cases with significant changes will be
created in ~/output_compare.

$ testing/tools/safetynet_compare.py -h
Print all options.

Change-Id: I43aaf5fe890745db611fb3bc00a656ef799fdfef
Reviewed-on: https://pdfium-review.googlesource.com/7390
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
diff --git a/testing/tools/githelper.py b/testing/tools/githelper.py
new file mode 100644
index 0000000..42cc57d
--- /dev/null
+++ b/testing/tools/githelper.py
@@ -0,0 +1,50 @@
+# Copyright 2017 The PDFium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Classes for dealing with git."""
+
+import subprocess
+
+
+class GitHelper(object):
+  """Issues git commands. Stateful."""
+
+  def __init__(self):
+    self.stashed = 0
+
+  def Checkout(self, branch):
+    """Checks out a branch."""
+    subprocess.check_output(['git', 'checkout', branch])
+
+  def StashPush(self):
+    """Stashes uncommitted changes."""
+    output = subprocess.check_output(['git', 'stash', '--include-untracked'])
+    if 'No local changes to save' in output:
+      return False
+
+    self.stashed += 1
+    return True
+
+  def StashPopAll(self):
+    """Pops as many changes as this instance stashed."""
+    while self.stashed > 0:
+      subprocess.check_output(['git', 'stash', 'pop'])
+      self.stashed -= 1
+
+  def GetCurrentBranchName(self):
+    """Returns a string with the current branch name."""
+    return subprocess.check_output(
+        ['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
+
+  def BranchExists(self, branch_name):
+    """Return whether a branch with the given name exists."""
+    try:
+      subprocess.check_output(['git', 'rev-parse', '--verify',
+                               branch_name])
+      return True
+    except subprocess.CalledProcessError:
+      return False
+
+  def CloneLocal(self, source_repo, new_repo):
+    subprocess.check_call(['git', 'clone', source_repo, new_repo])