Add git-map and git-map-branches to depot_tools.

git-map: Show your local repo's history in a pseudo-graphical format from the command line.

git-map-branches: Show the topology of all of your branches, and their upstream relationships.

git-nav-upstream: Navigate (checkout) to the upstream branch of the current branch.

git-nav-downstream: Navigate (checkout) to a downstream branch of the current branch. If there's more than one downstream branch, then present a menu to select which one you want.

R=agable@chromium.org, hinoka@chromium.org, stip@chromium.org, szager@chromium.org
BUG=

Review URL: https://codereview.chromium.org/184113002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@256384 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_common.py b/git_common.py
index 1215d9c..c1e4f0b 100644
--- a/git_common.py
+++ b/git_common.py
@@ -199,6 +199,25 @@
     del self._thread
 
 
+def branches(*args):
+  NO_BRANCH = ('* (no branch)', '* (detached from ')
+  for line in run('branch', *args).splitlines():
+    if line.startswith(NO_BRANCH):
+      continue
+    yield line.split()[-1]
+
+
+def config_list(option):
+  try:
+    return run('config', '--get-all', option).split()
+  except subprocess2.CalledProcessError:
+    return []
+
+
+def current_branch():
+  return run('rev-parse', '--abbrev-ref', 'HEAD')
+
+
 def parse_commitrefs(*commitrefs):
   """Returns binary encoded commit hashes for one or more commitrefs.
 
@@ -208,7 +227,7 @@
     * 'cool_branch~2'
   """
   try:
-    return map(binascii.unhexlify, hashes(*commitrefs))
+    return map(binascii.unhexlify, hash_multi(*commitrefs))
   except subprocess2.CalledProcessError:
     raise BadCommitRefException(commitrefs)
 
@@ -231,7 +250,11 @@
   return ret
 
 
-def hashes(*reflike):
+def hash_one(reflike):
+  return run('rev-parse', reflike)
+
+
+def hash_multi(*reflike):
   return run('rev-parse', *reflike).splitlines()
 
 
@@ -249,6 +272,10 @@
   return ret
 
 
+def tags(*args):
+  return run('tag', *args).splitlines()
+
+
 def tree(treeref, recurse=False):
   """Returns a dict representation of a git tree object.
 
@@ -286,6 +313,14 @@
   return ret
 
 
+def upstream(branch):
+  try:
+    return run('rev-parse', '--abbrev-ref', '--symbolic-full-name',
+               branch+'@{upstream}')
+  except subprocess2.CalledProcessError:
+    return None
+
+
 def mktree(treedict):
   """Makes a git tree object and returns its hash.