bisect-kit: fix ChromeOS commit history analysis for branched versions

Before collecting float_specs, we tried to determine the branch that
float_specs should be by analyzing the `revision` tag from fixed
manifest.

BUG=b:147575652
TEST=python3 -m unittest bisect_kit/git_util_test.py
TEST=./bisect_cr_localbuild_internal.py init --old 81.0.3995.0 --new 81.0.3999.0
TEST=./bisect_cros_version.py init --board samus-kernelnext --old R80-12739.10.0 --new R80-12739.11.0
TEST=./bisect_cros_repo.py init --board samus-kernelnext --old R80-12739.10.0 --new R80-12739.11.0
TEST=./bisect_cros_repo.py init --board samus-kernelnext --old R80-12739.0.0 --new R80-12739.11.0
TEST=./bisect_cros_repo.py init --board samus-kernelnext --old R80-12730.0.0 --new R80-12739.0.0
TEST=./bisect_cros_repo.py init --board samus-kernelnext --old R80-12738.0.0-24800 --new R80-12739.11.0

Change-Id: I66e1ac99c5e0388acf69a63622d364ce45b4bfa3
diff --git a/bisect_kit/git_util.py b/bisect_kit/git_util.py
index eefad2f..2a2651b 100644
--- a/bisect_kit/git_util.py
+++ b/bisect_kit/git_util.py
@@ -551,7 +551,12 @@
   return result
 
 
-def get_history_recursively(git_repo, path, after, before, parser_callback):
+def get_history_recursively(git_repo,
+                            path,
+                            after,
+                            before,
+                            parser_callback,
+                            branch=None):
   """Get commit history of given path and its dependencies.
 
   In comparison to get_history(), get_history_recursively also takes
@@ -571,12 +576,13 @@
     after: limit history after given time (inclusive)
     before: limit history before given time (inclusive)
     parser_callback: callback to parse file content. See above comment.
+    branch: branch name or ref name
 
   Returns:
     list of (commit timestamp, git hash)
   """
   history = get_history(
-      git_repo, path, after=after, before=before, padding=True)
+      git_repo, path, after=after, before=before, padding=True, branch=branch)
 
   # Collect include information of each commit.
   includes = {}
@@ -609,8 +615,13 @@
   # Recursion and merge.
   result = list(history)
   for include, appeared, disappeared in dependencies:
-    result += get_history_recursively(git_repo, include, appeared, disappeared,
-                                      parser_callback)
+    result += get_history_recursively(
+        git_repo,
+        include,
+        appeared,
+        disappeared,
+        parser_callback,
+        branch=branch)
 
   # Sort and dedup.
   result2 = []
@@ -622,6 +633,29 @@
   return result2
 
 
+def get_branches(git_repo, all_branches=True, commit=None):
+  """Get branches of a repository.
+
+  Args:
+    git_repo: path of git repo
+    all_branches: return remote branches if is set to True
+    commit: return branches containing this commit if is not None
+
+  Returns:
+    list of branch names
+  """
+  cmd = ['git', 'branch', '--format=%(refname)']
+  if all_branches:
+    cmd += ['-a']
+  if commit:
+    cmd += ['--contains', commit]
+
+  result = []
+  for line in util.check_output(*cmd, cwd=git_repo).splitlines():
+    result.append(line.strip())
+  return result
+
+
 def list_commits_between_commits(git_repo, old, new):
   """Get all commits between (old, new].