info.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. # Copyright (C) 2012 The Android Open Source Project
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from command import PagedCommand
  15. from color import Coloring
  16. from git_refs import R_M, R_HEADS
  17. class _Coloring(Coloring):
  18. def __init__(self, config):
  19. Coloring.__init__(self, config, "status")
  20. class Info(PagedCommand):
  21. common = True
  22. helpSummary = "Get info on the manifest branch, current branch or unmerged branches"
  23. helpUsage = "%prog [-dl] [-o [-b]] [<project>...]"
  24. def _Options(self, p):
  25. p.add_option('-d', '--diff',
  26. dest='all', action='store_true',
  27. help="show full info and commit diff including remote branches")
  28. p.add_option('-o', '--overview',
  29. dest='overview', action='store_true',
  30. help='show overview of all local commits')
  31. p.add_option('-b', '--current-branch',
  32. dest="current_branch", action="store_true",
  33. help="consider only checked out branches")
  34. p.add_option('-l', '--local-only',
  35. dest="local", action="store_true",
  36. help="Disable all remote operations")
  37. def Execute(self, opt, args):
  38. self.out = _Coloring(self.client.globalConfig)
  39. self.heading = self.out.printer('heading', attr='bold')
  40. self.headtext = self.out.nofmt_printer('headtext', fg='yellow')
  41. self.redtext = self.out.printer('redtext', fg='red')
  42. self.sha = self.out.printer("sha", fg='yellow')
  43. self.text = self.out.nofmt_printer('text')
  44. self.dimtext = self.out.printer('dimtext', attr='dim')
  45. self.opt = opt
  46. manifestConfig = self.manifest.manifestProject.config
  47. mergeBranch = manifestConfig.GetBranch("default").merge
  48. manifestGroups = (manifestConfig.GetString('manifest.groups')
  49. or 'all,-notdefault')
  50. self.heading("Manifest branch: ")
  51. if self.manifest.default.revisionExpr:
  52. self.headtext(self.manifest.default.revisionExpr)
  53. self.out.nl()
  54. self.heading("Manifest merge branch: ")
  55. self.headtext(mergeBranch)
  56. self.out.nl()
  57. self.heading("Manifest groups: ")
  58. self.headtext(manifestGroups)
  59. self.out.nl()
  60. self.printSeparator()
  61. if not opt.overview:
  62. self.printDiffInfo(args)
  63. else:
  64. self.printCommitOverview(args)
  65. def printSeparator(self):
  66. self.text("----------------------------")
  67. self.out.nl()
  68. def printDiffInfo(self, args):
  69. # We let exceptions bubble up to main as they'll be well structured.
  70. projs = self.GetProjects(args)
  71. for p in projs:
  72. self.heading("Project: ")
  73. self.headtext(p.name)
  74. self.out.nl()
  75. self.heading("Mount path: ")
  76. self.headtext(p.worktree)
  77. self.out.nl()
  78. self.heading("Current revision: ")
  79. self.headtext(p.GetRevisionId())
  80. self.out.nl()
  81. currentBranch = p.CurrentBranch
  82. if currentBranch:
  83. self.heading('Current branch: ')
  84. self.headtext(currentBranch)
  85. self.out.nl()
  86. self.heading("Manifest revision: ")
  87. self.headtext(p.revisionExpr)
  88. self.out.nl()
  89. localBranches = list(p.GetBranches().keys())
  90. self.heading("Local Branches: ")
  91. self.redtext(str(len(localBranches)))
  92. if localBranches:
  93. self.text(" [")
  94. self.text(", ".join(localBranches))
  95. self.text("]")
  96. self.out.nl()
  97. if self.opt.all:
  98. self.findRemoteLocalDiff(p)
  99. self.printSeparator()
  100. def findRemoteLocalDiff(self, project):
  101. # Fetch all the latest commits.
  102. if not self.opt.local:
  103. project.Sync_NetworkHalf(quiet=True, current_branch_only=True)
  104. branch = self.manifest.manifestProject.config.GetBranch('default').merge
  105. if branch.startswith(R_HEADS):
  106. branch = branch[len(R_HEADS):]
  107. logTarget = R_M + branch
  108. bareTmp = project.bare_git._bare
  109. project.bare_git._bare = False
  110. localCommits = project.bare_git.rev_list(
  111. '--abbrev=8',
  112. '--abbrev-commit',
  113. '--pretty=oneline',
  114. logTarget + "..",
  115. '--')
  116. originCommits = project.bare_git.rev_list(
  117. '--abbrev=8',
  118. '--abbrev-commit',
  119. '--pretty=oneline',
  120. ".." + logTarget,
  121. '--')
  122. project.bare_git._bare = bareTmp
  123. self.heading("Local Commits: ")
  124. self.redtext(str(len(localCommits)))
  125. self.dimtext(" (on current branch)")
  126. self.out.nl()
  127. for c in localCommits:
  128. split = c.split()
  129. self.sha(split[0] + " ")
  130. self.text(" ".join(split[1:]))
  131. self.out.nl()
  132. self.printSeparator()
  133. self.heading("Remote Commits: ")
  134. self.redtext(str(len(originCommits)))
  135. self.out.nl()
  136. for c in originCommits:
  137. split = c.split()
  138. self.sha(split[0] + " ")
  139. self.text(" ".join(split[1:]))
  140. self.out.nl()
  141. def printCommitOverview(self, args):
  142. all_branches = []
  143. for project in self.GetProjects(args):
  144. br = [project.GetUploadableBranch(x)
  145. for x in project.GetBranches()]
  146. br = [x for x in br if x]
  147. if self.opt.current_branch:
  148. br = [x for x in br if x.name == project.CurrentBranch]
  149. all_branches.extend(br)
  150. if not all_branches:
  151. return
  152. self.out.nl()
  153. self.heading('Projects Overview')
  154. project = None
  155. for branch in all_branches:
  156. if project != branch.project:
  157. project = branch.project
  158. self.out.nl()
  159. self.headtext(project.relpath)
  160. self.out.nl()
  161. commits = branch.commits
  162. date = branch.date
  163. self.text('%s %-33s (%2d commit%s, %s)' % (
  164. branch.name == project.CurrentBranch and '*' or ' ',
  165. branch.name,
  166. len(commits),
  167. len(commits) != 1 and 's' or '',
  168. date))
  169. self.out.nl()
  170. for commit in commits:
  171. split = commit.split()
  172. self.text('{0:38}{1} '.format('', '-'))
  173. self.sha(split[0] + " ")
  174. self.text(" ".join(split[1:]))
  175. self.out.nl()