diff options
| author | Will Richey <wmrichey@gmail.com> | 2012-06-21 09:49:59 -0400 |
|---|---|---|
| committer | David Pursehouse <david.pursehouse@sonymobile.com> | 2013-01-29 10:01:53 +0900 |
| commit | 63d356ffce72f76936a17902fe2f4abcb43078bb (patch) | |
| tree | 44288b45acaf5bd883135d762403e7bf7970c5e7 /subcmds | |
| parent | 35765966bf77d3afc8f9f98d6e24ccaf302ce95d (diff) | |
| download | git-repo-63d356ffce72f76936a17902fe2f4abcb43078bb.tar.gz | |
'repo status --orphans' shows non-repo files
'repo status --orphans' searches for non-repo objects
(not within a project), which is particularly helpful
before removing a working tree.
Change-Id: I2239c12e6bc0447b0ad71129551cb50fa671961c
Diffstat (limited to 'subcmds')
| -rw-r--r-- | subcmds/status.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/subcmds/status.py b/subcmds/status.py index 40562274..cce00c81 100644 --- a/subcmds/status.py +++ b/subcmds/status.py | |||
| @@ -20,10 +20,14 @@ try: | |||
| 20 | except ImportError: | 20 | except ImportError: |
| 21 | import dummy_threading as _threading | 21 | import dummy_threading as _threading |
| 22 | 22 | ||
| 23 | import glob | ||
| 23 | import itertools | 24 | import itertools |
| 25 | import os | ||
| 24 | import sys | 26 | import sys |
| 25 | import StringIO | 27 | import StringIO |
| 26 | 28 | ||
| 29 | from color import Coloring | ||
| 30 | |||
| 27 | class Status(PagedCommand): | 31 | class Status(PagedCommand): |
| 28 | common = True | 32 | common = True |
| 29 | helpSummary = "Show the working tree status" | 33 | helpSummary = "Show the working tree status" |
| @@ -39,6 +43,13 @@ is a difference between these three states. | |||
| 39 | The -j/--jobs option can be used to run multiple status queries | 43 | The -j/--jobs option can be used to run multiple status queries |
| 40 | in parallel. | 44 | in parallel. |
| 41 | 45 | ||
| 46 | The -o/--orphans option can be used to show objects that are in | ||
| 47 | the working directory, but not associated with a repo project. | ||
| 48 | This includes unmanaged top-level files and directories, but also | ||
| 49 | includes deeper items. For example, if dir/subdir/proj1 and | ||
| 50 | dir/subdir/proj2 are repo projects, dir/subdir/proj3 will be shown | ||
| 51 | if it is not known to repo. | ||
| 52 | |||
| 42 | Status Display | 53 | Status Display |
| 43 | -------------- | 54 | -------------- |
| 44 | 55 | ||
| @@ -76,6 +87,9 @@ the following meanings: | |||
| 76 | p.add_option('-j', '--jobs', | 87 | p.add_option('-j', '--jobs', |
| 77 | dest='jobs', action='store', type='int', default=2, | 88 | dest='jobs', action='store', type='int', default=2, |
| 78 | help="number of projects to check simultaneously") | 89 | help="number of projects to check simultaneously") |
| 90 | p.add_option('-o', '--orphans', | ||
| 91 | dest='orphans', action='store_true', | ||
| 92 | help="include objects in working directory outside of repo projects") | ||
| 79 | 93 | ||
| 80 | def _StatusHelper(self, project, clean_counter, sem, output): | 94 | def _StatusHelper(self, project, clean_counter, sem, output): |
| 81 | """Obtains the status for a specific project. | 95 | """Obtains the status for a specific project. |
| @@ -97,6 +111,22 @@ the following meanings: | |||
| 97 | finally: | 111 | finally: |
| 98 | sem.release() | 112 | sem.release() |
| 99 | 113 | ||
| 114 | def _FindOrphans(self, dirs, proj_dirs, proj_dirs_parents, outstring): | ||
| 115 | """find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'""" | ||
| 116 | status_header = ' --\t' | ||
| 117 | for item in dirs: | ||
| 118 | if not os.path.isdir(item): | ||
| 119 | outstring.write(''.join([status_header, item])) | ||
| 120 | continue | ||
| 121 | if item in proj_dirs: | ||
| 122 | continue | ||
| 123 | if item in proj_dirs_parents: | ||
| 124 | self._FindOrphans(glob.glob('%s/.*' % item) + \ | ||
| 125 | glob.glob('%s/*' % item), \ | ||
| 126 | proj_dirs, proj_dirs_parents, outstring) | ||
| 127 | continue | ||
| 128 | outstring.write(''.join([status_header, item, '/'])) | ||
| 129 | |||
| 100 | def Execute(self, opt, args): | 130 | def Execute(self, opt, args): |
| 101 | all_projects = self.GetProjects(args) | 131 | all_projects = self.GetProjects(args) |
| 102 | counter = itertools.count() | 132 | counter = itertools.count() |
| @@ -130,3 +160,45 @@ the following meanings: | |||
| 130 | output.close() | 160 | output.close() |
| 131 | if len(all_projects) == counter.next(): | 161 | if len(all_projects) == counter.next(): |
| 132 | print('nothing to commit (working directory clean)') | 162 | print('nothing to commit (working directory clean)') |
| 163 | |||
| 164 | if opt.orphans: | ||
| 165 | proj_dirs = set() | ||
| 166 | proj_dirs_parents = set() | ||
| 167 | for project in self.GetProjects(None, missing_ok=True): | ||
| 168 | proj_dirs.add(project.relpath) | ||
| 169 | (head, _tail) = os.path.split(project.relpath) | ||
| 170 | while head != "": | ||
| 171 | proj_dirs_parents.add(head) | ||
| 172 | (head, _tail) = os.path.split(head) | ||
| 173 | proj_dirs.add('.repo') | ||
| 174 | |||
| 175 | class StatusColoring(Coloring): | ||
| 176 | def __init__(self, config): | ||
| 177 | Coloring.__init__(self, config, 'status') | ||
| 178 | self.project = self.printer('header', attr = 'bold') | ||
| 179 | self.untracked = self.printer('untracked', fg = 'red') | ||
| 180 | |||
| 181 | orig_path = os.getcwd() | ||
| 182 | try: | ||
| 183 | os.chdir(self.manifest.topdir) | ||
| 184 | |||
| 185 | outstring = StringIO.StringIO() | ||
| 186 | self._FindOrphans(glob.glob('.*') + \ | ||
| 187 | glob.glob('*'), \ | ||
| 188 | proj_dirs, proj_dirs_parents, outstring) | ||
| 189 | |||
| 190 | if outstring.buflist: | ||
| 191 | output = StatusColoring(self.manifest.globalConfig) | ||
| 192 | output.project('Objects not within a project (orphans)') | ||
| 193 | output.nl() | ||
| 194 | for entry in outstring.buflist: | ||
| 195 | output.untracked(entry) | ||
| 196 | output.nl() | ||
| 197 | else: | ||
| 198 | print('No orphan files or directories') | ||
| 199 | |||
| 200 | outstring.close() | ||
| 201 | |||
| 202 | finally: | ||
| 203 | # Restore CWD. | ||
| 204 | os.chdir(orig_path) | ||
