# HG changeset patch # User Tomasz Kleczek # Date 1349295593 25200 # Node ID e6067bec18da78a75952425206a6cb9e8583f837 # Parent 5b08e8b7ab00ccac86da4384d918481865266ff4 branchcache: fetch source branchcache during clone (issue3378) Recomputing branch cache on clone may be expensive, therefore if possible we fetch it along with the data. - If the clone is performed by copying, we just copy branchcache file. - If we localrepo.clone and streaming then we follow the procedure: 1. Fetch branchmap from the remote 2. Fetch the actual data. 3. Find the latest rev within branch heads (tip at the time of branchmap fetch) 4. Update the cache for the revs in [remotetip+1, tip] This way we ensure that the branchcache is correct even in case of races with commits. diff -r 5b08e8b7ab00 -r e6067bec18da mercurial/hg.py --- a/mercurial/hg.py Wed Oct 10 01:30:45 2012 +0200 +++ b/mercurial/hg.py Wed Oct 03 13:19:53 2012 -0700 @@ -336,6 +336,16 @@ destlock = copystore(ui, srcrepo, destpath) + # Recomputing branch cache might be slow on big repos, + # so just copy it + dstcachedir = os.path.join(destpath, 'cache') + srcbranchcache = srcrepo.sjoin('cache/branchheads') + dstbranchcache = os.path.join(dstcachedir, 'branchheads') + if os.path.exists(srcbranchcache): + if not os.path.exists(dstcachedir): + os.mkdir(dstcachedir) + util.copyfile(srcbranchcache, dstbranchcache) + # we need to re-init the repo after manually copying the data # into it destpeer = peer(ui, peeropts, dest) diff -r 5b08e8b7ab00 -r e6067bec18da mercurial/localrepo.py --- a/mercurial/localrepo.py Wed Oct 10 01:30:45 2012 +0200 +++ b/mercurial/localrepo.py Wed Oct 03 13:19:53 2012 -0700 @@ -2472,6 +2472,12 @@ def stream_in(self, remote, requirements): lock = self.lock() try: + # Save remote branchmap. We will use it later + # to speed up branchcache creation + rbranchmap = None + if remote.capable("branchmap"): + rbranchmap = remote.branchmap() + fp = remote.stream_out() l = fp.readline() try: @@ -2532,6 +2538,17 @@ self._applyrequirements(requirements) self._writerequirements() + if rbranchmap: + rbheads = [] + for bheads in rbranchmap.itervalues(): + rbheads.extend(bheads) + + self.branchcache = rbranchmap + if rbheads: + rtiprev = max((int(self.changelog.rev(node)) + for node in rbheads)) + self._writebranchcache(self.branchcache, + self[rtiprev].node(), rtiprev) self.invalidate() return len(self.heads()) + 1 finally: diff -r 5b08e8b7ab00 -r e6067bec18da tests/test-http-proxy.t --- a/tests/test-http-proxy.t Wed Oct 10 01:30:45 2012 +0200 +++ b/tests/test-http-proxy.t Wed Oct 03 13:19:53 2012 -0700 @@ -99,6 +99,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat proxy.log * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob) + * - - [*] "GET http://localhost:$HGPORT/?cmd=branchmap HTTP/1.1" - - (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=stream_out HTTP/1.1" - - (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob) * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)