Mercurial > hg
comparison hgext/largefiles/reposetup.py @ 15617:74e691b141c4
largefiles: optimize performance of status on largefiles repos (issue3136)
author | Na'Tosha Bard <natosha@unity3d.com> |
---|---|
date | Wed, 07 Dec 2011 12:56:44 +0100 |
parents | 4439ec496378 |
children | 931dc4af0d95 |
comparison
equal
deleted
inserted
replaced
15614:260a6449d83a | 15617:74e691b141c4 |
---|---|
125 def tostandin(file): | 125 def tostandin(file): |
126 if inctx(lfutil.standin(file), ctx2): | 126 if inctx(lfutil.standin(file), ctx2): |
127 return lfutil.standin(file) | 127 return lfutil.standin(file) |
128 return file | 128 return file |
129 | 129 |
130 # Create a function that we can use to override what is | |
131 # normally the ignore matcher. We've already checked | |
132 # for ignored files on the first dirstate walk, and | |
133 # unecessarily re-checking here causes a huge performance | |
134 # hit because lfdirstate only knows about largefiles | |
135 def _ignoreoverride(self): | |
136 return False | |
137 | |
130 m = copy.copy(match) | 138 m = copy.copy(match) |
131 m._files = [tostandin(f) for f in m._files] | 139 m._files = [tostandin(f) for f in m._files] |
132 | 140 |
133 # get ignored, clean, and unknown but remove them | 141 # Get ignored files here even if we weren't asked for them; we |
134 # later if they were not asked for | 142 # must use the result here for filtering later |
135 try: | 143 try: |
136 result = super(lfiles_repo, self).status(node1, node2, m, | 144 result = super(lfiles_repo, self).status(node1, node2, m, |
137 True, True, True, listsubrepos) | 145 True, clean, unknown, listsubrepos) |
138 except TypeError: | 146 except TypeError: |
139 result = super(lfiles_repo, self).status(node1, node2, m, | 147 result = super(lfiles_repo, self).status(node1, node2, m, |
140 True, True, True) | 148 True, clean, unknown) |
141 if working: | 149 if working: |
142 # hold the wlock while we read largefiles and | 150 # hold the wlock while we read largefiles and |
143 # update the lfdirstate | 151 # update the lfdirstate |
144 wlock = repo.wlock() | 152 wlock = repo.wlock() |
145 try: | 153 try: |
146 # Any non-largefiles that were explicitly listed must be | 154 # Any non-largefiles that were explicitly listed must be |
147 # taken out or lfdirstate.status will report an error. | 155 # taken out or lfdirstate.status will report an error. |
148 # The status of these files was already computed using | 156 # The status of these files was already computed using |
149 # super's status. | 157 # super's status. |
150 lfdirstate = lfutil.openlfdirstate(ui, self) | 158 lfdirstate = lfutil.openlfdirstate(ui, self) |
159 # Override lfdirstate's ignore matcher to not do | |
160 # anything | |
161 orig_ignore = lfdirstate._ignore | |
162 lfdirstate._ignore = _ignoreoverride | |
163 | |
151 match._files = [f for f in match._files if f in | 164 match._files = [f for f in match._files if f in |
152 lfdirstate] | 165 lfdirstate] |
153 s = lfdirstate.status(match, [], listignored, | 166 # Don't waste time getting the ignored and unknown |
154 listclean, listunknown) | 167 # files again; we already have them |
168 s = lfdirstate.status(match, [], False, | |
169 listclean, False) | |
155 (unsure, modified, added, removed, missing, unknown, | 170 (unsure, modified, added, removed, missing, unknown, |
156 ignored, clean) = s | 171 ignored, clean) = s |
172 # Replace the list of ignored and unknown files with | |
173 # the previously caclulated lists, and strip out the | |
174 # largefiles | |
175 lfiles = set(lfdirstate._map) | |
176 ignored = set(result[5]).difference(lfiles) | |
177 unknown = set(result[4]).difference(lfiles) | |
157 if parentworking: | 178 if parentworking: |
158 for lfile in unsure: | 179 for lfile in unsure: |
159 if ctx1[lfutil.standin(lfile)].data().strip() \ | 180 if ctx1[lfutil.standin(lfile)].data().strip() \ |
160 != lfutil.hashfile(self.wjoin(lfile)): | 181 != lfutil.hashfile(self.wjoin(lfile)): |
161 modified.append(lfile) | 182 modified.append(lfile) |
175 modified.append(lfile) | 196 modified.append(lfile) |
176 else: | 197 else: |
177 clean.append(lfile) | 198 clean.append(lfile) |
178 else: | 199 else: |
179 added.append(lfile) | 200 added.append(lfile) |
201 # Replace the original ignore function | |
202 lfdirstate._ignore = orig_ignore | |
180 finally: | 203 finally: |
181 wlock.release() | 204 wlock.release() |
182 | 205 |
183 for standin in ctx1.manifest(): | 206 for standin in ctx1.manifest(): |
184 if not lfutil.isstandin(standin): | 207 if not lfutil.isstandin(standin): |
190 removed.append(lfile) | 213 removed.append(lfile) |
191 # Handle unknown and ignored differently | 214 # Handle unknown and ignored differently |
192 lfiles = (modified, added, removed, missing, [], [], clean) | 215 lfiles = (modified, added, removed, missing, [], [], clean) |
193 result = list(result) | 216 result = list(result) |
194 # Unknown files | 217 # Unknown files |
218 unknown = set(unknown).difference(ignored) | |
195 result[4] = [f for f in unknown | 219 result[4] = [f for f in unknown |
196 if (repo.dirstate[f] == '?' and | 220 if (repo.dirstate[f] == '?' and |
197 not lfutil.isstandin(f))] | 221 not lfutil.isstandin(f))] |
198 # Ignored files must be ignored by both the dirstate and | 222 # Ignored files were calculated earlier by the dirstate, |
199 # lfdirstate | 223 # and we already stripped out the largefiles from the list |
200 result[5] = set(ignored).intersection(set(result[5])) | 224 result[5] = ignored |
201 # combine normal files and largefiles | 225 # combine normal files and largefiles |
202 normals = [[fn for fn in filelist | 226 normals = [[fn for fn in filelist |
203 if not lfutil.isstandin(fn)] | 227 if not lfutil.isstandin(fn)] |
204 for filelist in result] | 228 for filelist in result] |
205 result = [sorted(list1 + list2) | 229 result = [sorted(list1 + list2) |