comparison mercurial/copies.py @ 40057:25b2868206e2

copies: add a devel debug mode to trace what copy tracing does Mercurial can spend a lot of time finding renames between two commits. Having more information about that process help to understand what makes it slow in an individual instance. (eg: many files vs 1 file, etc...)
author Boris Feld <boris.feld@octobus.net>
date Fri, 07 Sep 2018 11:16:06 -0400
parents 707c3804e607
children cf01616f8d96
comparison
equal deleted inserted replaced
40056:324b4b10351e 40057:25b2868206e2
161 161
162 def _committedforwardcopies(a, b, match): 162 def _committedforwardcopies(a, b, match):
163 """Like _forwardcopies(), but b.rev() cannot be None (working copy)""" 163 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
164 # files might have to be traced back to the fctx parent of the last 164 # files might have to be traced back to the fctx parent of the last
165 # one-side-only changeset, but not further back than that 165 # one-side-only changeset, but not further back than that
166 limit = _findlimit(a._repo, a.rev(), b.rev()) 166 repo = a._repo
167 debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
168 dbg = repo.ui.debug
169 if debug:
170 dbg('debug.copies: looking into rename from %s to %s\n'
171 % (a, b))
172 limit = _findlimit(repo, a.rev(), b.rev())
167 if limit is None: 173 if limit is None:
168 limit = -1 174 limit = -1
175 if debug:
176 dbg('debug.copies: search limit: %d\n' % limit)
169 am = a.manifest() 177 am = a.manifest()
170 178
171 # find where new files came from 179 # find where new files came from
172 # we currently don't try to find where old files went, too expensive 180 # we currently don't try to find where old files went, too expensive
173 # this means we can miss a case like 'hg rm b; hg cp a b' 181 # this means we can miss a case like 'hg rm b; hg cp a b'
184 filesmatcher = scmutil.matchfiles(a._repo, b.files()) 192 filesmatcher = scmutil.matchfiles(a._repo, b.files())
185 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher) 193 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
186 missing = _computeforwardmissing(a, b, match=forwardmissingmatch) 194 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
187 195
188 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True) 196 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
197
198 if debug:
199 dbg('debug.copies: missing file to search: %d\n' % len(missing))
200
189 for f in missing: 201 for f in missing:
202 if debug:
203 dbg('debug.copies: tracing file: %s\n' % f)
190 fctx = b[f] 204 fctx = b[f]
191 fctx._ancestrycontext = ancestrycontext 205 fctx._ancestrycontext = ancestrycontext
206
192 ofctx = _tracefile(fctx, am, limit) 207 ofctx = _tracefile(fctx, am, limit)
193 if ofctx: 208 if ofctx:
209 if debug:
210 dbg('debug.copies: rename of: %s\n' % ofctx._path)
194 cm[f] = ofctx.path() 211 cm[f] = ofctx.path()
195 return cm 212 return cm
196 213
197 def _forwardcopies(a, b, match=None): 214 def _forwardcopies(a, b, match=None):
198 """find {dst@b: src@a} copy mapping where a is an ancestor of b""" 215 """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
224 r[v] = k 241 r[v] = k
225 return r 242 return r
226 243
227 def pathcopies(x, y, match=None): 244 def pathcopies(x, y, match=None):
228 """find {dst@y: src@x} copy mapping for directed compare""" 245 """find {dst@y: src@x} copy mapping for directed compare"""
246 repo = x._repo
247 debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies')
248 if debug:
249 repo.ui.debug('debug.copies: searching copies from %s to %s\n'
250 % (x, y))
229 if x == y or not x or not y: 251 if x == y or not x or not y:
230 return {} 252 return {}
231 a = y.ancestor(x) 253 a = y.ancestor(x)
232 if a == x: 254 if a == x:
255 if debug:
256 repo.ui.debug('debug.copies: search mode: forward\n')
233 return _forwardcopies(x, y, match=match) 257 return _forwardcopies(x, y, match=match)
234 if a == y: 258 if a == y:
259 if debug:
260 repo.ui.debug('debug.copies: search mode: backward\n')
235 return _backwardrenames(x, y) 261 return _backwardrenames(x, y)
262 if debug:
263 repo.ui.debug('debug.copies: search mode: combined\n')
236 return _chain(x, y, _backwardrenames(x, a), 264 return _chain(x, y, _backwardrenames(x, a),
237 _forwardcopies(a, y, match=match)) 265 _forwardcopies(a, y, match=match))
238 266
239 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, baselabel=''): 267 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, baselabel=''):
240 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1 268 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1