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) | ||