Show More
@@ -0,0 +1,64 b'' | |||||
|
1 | # streamclone.py - producing and consuming streaming repository data | |||
|
2 | # | |||
|
3 | # Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms of the | |||
|
6 | # GNU General Public License version 2 or any later version. | |||
|
7 | ||||
|
8 | from __future__ import absolute_import | |||
|
9 | ||||
|
10 | from . import ( | |||
|
11 | branchmap, | |||
|
12 | exchange, | |||
|
13 | ) | |||
|
14 | ||||
|
15 | def applyremotedata(repo, remotereqs, remotebranchmap, fp): | |||
|
16 | """Apply stream clone data to a repository. | |||
|
17 | ||||
|
18 | "remotereqs" is a set of requirements to handle the incoming data. | |||
|
19 | "remotebranchmap" is the result of a branchmap lookup on the remote. It | |||
|
20 | can be None. | |||
|
21 | "fp" is a file object containing the raw stream data, suitable for | |||
|
22 | feeding into exchange.consumestreamclone. | |||
|
23 | """ | |||
|
24 | lock = repo.lock() | |||
|
25 | try: | |||
|
26 | exchange.consumestreamclone(repo, fp) | |||
|
27 | ||||
|
28 | # new requirements = old non-format requirements + | |||
|
29 | # new format-related remote requirements | |||
|
30 | # requirements from the streamed-in repository | |||
|
31 | repo.requirements = remotereqs | ( | |||
|
32 | repo.requirements - repo.supportedformats) | |||
|
33 | repo._applyopenerreqs() | |||
|
34 | repo._writerequirements() | |||
|
35 | ||||
|
36 | if remotebranchmap: | |||
|
37 | rbheads = [] | |||
|
38 | closed = [] | |||
|
39 | for bheads in remotebranchmap.itervalues(): | |||
|
40 | rbheads.extend(bheads) | |||
|
41 | for h in bheads: | |||
|
42 | r = repo.changelog.rev(h) | |||
|
43 | b, c = repo.changelog.branchinfo(r) | |||
|
44 | if c: | |||
|
45 | closed.append(h) | |||
|
46 | ||||
|
47 | if rbheads: | |||
|
48 | rtiprev = max((int(repo.changelog.rev(node)) | |||
|
49 | for node in rbheads)) | |||
|
50 | cache = branchmap.branchcache(remotebranchmap, | |||
|
51 | repo[rtiprev].node(), | |||
|
52 | rtiprev, | |||
|
53 | closednodes=closed) | |||
|
54 | # Try to stick it as low as possible | |||
|
55 | # filter above served are unlikely to be fetch from a clone | |||
|
56 | for candidate in ('base', 'immutable', 'served'): | |||
|
57 | rview = repo.filtered(candidate) | |||
|
58 | if cache.validfor(rview): | |||
|
59 | repo._branchcaches[candidate] = cache | |||
|
60 | cache.write(rview) | |||
|
61 | break | |||
|
62 | repo.invalidate() | |||
|
63 | finally: | |||
|
64 | lock.release() |
@@ -19,6 +19,7 b' from lock import release' | |||||
19 | import weakref, errno, os, time, inspect, random |
|
19 | import weakref, errno, os, time, inspect, random | |
20 | import branchmap, pathutil |
|
20 | import branchmap, pathutil | |
21 | import namespaces |
|
21 | import namespaces | |
|
22 | import streamclone | |||
22 | propertycache = util.propertycache |
|
23 | propertycache = util.propertycache | |
23 | filecache = scmutil.filecache |
|
24 | filecache = scmutil.filecache | |
24 |
|
25 | |||
@@ -1808,60 +1809,9 b' class localrepository(object):' | |||||
1808 | elif resp != 0: |
|
1809 | elif resp != 0: | |
1809 | raise util.Abort(_('the server sent an unknown error code')) |
|
1810 | raise util.Abort(_('the server sent an unknown error code')) | |
1810 |
|
1811 | |||
1811 |
self |
|
1812 | streamclone.applyremotedata(self, remotereqs, rbranchmap, fp) | |
1812 | return len(self.heads()) + 1 |
|
1813 | return len(self.heads()) + 1 | |
1813 |
|
1814 | |||
1814 | def applystreamclone(self, remotereqs, remotebranchmap, fp): |
|
|||
1815 | """Apply stream clone data to this repository. |
|
|||
1816 |
|
||||
1817 | "remotereqs" is a set of requirements to handle the incoming data. |
|
|||
1818 | "remotebranchmap" is the result of a branchmap lookup on the remote. It |
|
|||
1819 | can be None. |
|
|||
1820 | "fp" is a file object containing the raw stream data, suitable for |
|
|||
1821 | feeding into exchange.consumestreamclone. |
|
|||
1822 | """ |
|
|||
1823 | lock = self.lock() |
|
|||
1824 | try: |
|
|||
1825 | exchange.consumestreamclone(self, fp) |
|
|||
1826 |
|
||||
1827 | # new requirements = old non-format requirements + |
|
|||
1828 | # new format-related remote requirements |
|
|||
1829 | # requirements from the streamed-in repository |
|
|||
1830 | self.requirements = remotereqs | ( |
|
|||
1831 | self.requirements - self.supportedformats) |
|
|||
1832 | self._applyopenerreqs() |
|
|||
1833 | self._writerequirements() |
|
|||
1834 |
|
||||
1835 | if remotebranchmap: |
|
|||
1836 | rbheads = [] |
|
|||
1837 | closed = [] |
|
|||
1838 | for bheads in remotebranchmap.itervalues(): |
|
|||
1839 | rbheads.extend(bheads) |
|
|||
1840 | for h in bheads: |
|
|||
1841 | r = self.changelog.rev(h) |
|
|||
1842 | b, c = self.changelog.branchinfo(r) |
|
|||
1843 | if c: |
|
|||
1844 | closed.append(h) |
|
|||
1845 |
|
||||
1846 | if rbheads: |
|
|||
1847 | rtiprev = max((int(self.changelog.rev(node)) |
|
|||
1848 | for node in rbheads)) |
|
|||
1849 | cache = branchmap.branchcache(remotebranchmap, |
|
|||
1850 | self[rtiprev].node(), |
|
|||
1851 | rtiprev, |
|
|||
1852 | closednodes=closed) |
|
|||
1853 | # Try to stick it as low as possible |
|
|||
1854 | # filter above served are unlikely to be fetch from a clone |
|
|||
1855 | for candidate in ('base', 'immutable', 'served'): |
|
|||
1856 | rview = self.filtered(candidate) |
|
|||
1857 | if cache.validfor(rview): |
|
|||
1858 | self._branchcaches[candidate] = cache |
|
|||
1859 | cache.write(rview) |
|
|||
1860 | break |
|
|||
1861 | self.invalidate() |
|
|||
1862 | finally: |
|
|||
1863 | lock.release() |
|
|||
1864 |
|
||||
1865 | def clone(self, remote, heads=[], stream=None): |
|
1815 | def clone(self, remote, heads=[], stream=None): | |
1866 | '''clone remote repository. |
|
1816 | '''clone remote repository. | |
1867 |
|
1817 |
General Comments 0
You need to be logged in to leave comments.
Login now