comparison hgsubversion/wrappers.py @ 1293:9e85feb93984

wrappers: improve push performance by reusing the existing metadata Push operation for n commits regenerated SVNMeta class 2*n+1 times (one time at beginning, n times in push() loop, 1 time per each of n pulls). This operation is very costly when the revision map is big. This commit reuses this metadata every time when there is no rebase made between svn commits which leads to 1 metadata rebuild in optimistic case and n+1 metadata rebuilds in pessimistic case (rebase after every commit). To achieve this I added extra parameter to pull command to pass metadata to it. All unit tests are passing for this change.
author Mateusz Kwapich <mitrandir@fb.com>
date Fri, 12 Dec 2014 16:17:11 -0800
parents 8cec74df235a
children fc48e1065926
comparison
equal deleted inserted replaced
1292:7bbe120be193 1293:9e85feb93984
259 finally: 259 finally:
260 util.swap_out_encoding() 260 util.swap_out_encoding()
261 261
262 # Don't trust the pre-rebase repo and context. 262 # Don't trust the pre-rebase repo and context.
263 repo = getlocalpeer(ui, {}, meta.path) 263 repo = getlocalpeer(ui, {}, meta.path)
264 meta = repo.svnmeta(svn.uuid, svn.subdir)
265 hashes = meta.revmap.hashes()
264 tip_ctx = repo[tip_ctx.node()] 266 tip_ctx = repo[tip_ctx.node()]
265 for c in tip_ctx.descendants(): 267 for c in tip_ctx.descendants():
266 rebasesrc = c.extra().get('rebase_source') 268 rebasesrc = c.extra().get('rebase_source')
267 if rebasesrc and node.bin(rebasesrc) == current_ctx.node(): 269 if rebasesrc and node.bin(rebasesrc) == current_ctx.node():
268 current_ctx = c 270 current_ctx = c
287 # push a revision and pull it back. 289 # push a revision and pull it back.
288 repo.hook('debug-hgsubversion-between-push-and-pull-for-tests') 290 repo.hook('debug-hgsubversion-between-push-and-pull-for-tests')
289 291
290 # 5. Pull the latest changesets from subversion, which will 292 # 5. Pull the latest changesets from subversion, which will
291 # include the one we just committed (and possibly others). 293 # include the one we just committed (and possibly others).
292 r = pull(repo, dest, force=force) 294 r = pull(repo, dest, force=force, meta=meta)
293 assert not r or r == 0 295 assert not r or r == 0
294 meta = repo.svnmeta(svn.uuid, svn.subdir)
295 hashes = meta.revmap.hashes()
296 296
297 # 6. Move our tip to the latest pulled tip 297 # 6. Move our tip to the latest pulled tip
298 for c in tip_ctx.descendants(): 298 for c in tip_ctx.descendants():
299 if c.node() in hashes and c.branch() == svnbranch: 299 if c.node() in hashes and c.branch() == svnbranch:
300 if meta.get_source_rev(ctx=c)[0] == pushedrev.revnum: 300 if meta.get_source_rev(ctx=c)[0] == pushedrev.revnum:
377 pushop.cgresult = push(repo, remote, force, revs) 377 pushop.cgresult = push(repo, remote, force, revs)
378 return pushop 378 return pushop
379 else: 379 else:
380 return orig(repo, remote, force, revs, newbranch, bookmarks=bookmarks) 380 return orig(repo, remote, force, revs, newbranch, bookmarks=bookmarks)
381 381
382 def pull(repo, source, heads=[], force=False): 382 def pull(repo, source, heads=[], force=False, meta=None):
383 """pull new revisions from Subversion""" 383 """pull new revisions from Subversion"""
384 assert source.capable('subversion') 384 assert source.capable('subversion')
385 svn_url = source.svnurl 385 svn_url = source.svnurl
386 386
387 # Split off #rev 387 # Split off #rev
392 have_replay = not repo.ui.configbool('hgsubversion', 'stupid') 392 have_replay = not repo.ui.configbool('hgsubversion', 'stupid')
393 if not have_replay: 393 if not have_replay:
394 repo.ui.note('fetching stupidly...\n') 394 repo.ui.note('fetching stupidly...\n')
395 395
396 svn = source.svn 396 svn = source.svn
397 meta = repo.svnmeta(svn.uuid, svn.subdir) 397 if meta is None:
398 meta = repo.svnmeta(svn.uuid, svn.subdir)
398 399
399 stopat_rev = util.parse_revnum(svn, checkout) 400 stopat_rev = util.parse_revnum(svn, checkout)
400 401
401 layout = layouts.detect.layout_from_config(meta, allow_auto=True) 402 layout = layouts.detect.layout_from_config(meta, allow_auto=True)
402 if layout == 'auto': 403 if layout == 'auto':