##// END OF EJS Templates
logexchange: use command executor for wire protocol commands...
Gregory Szorc -
r37657:0e50dda7 default
parent child Browse files
Show More
@@ -1,143 +1,152 b''
1 # logexchange.py
1 # logexchange.py
2 #
2 #
3 # Copyright 2017 Augie Fackler <raf@durin42.com>
3 # Copyright 2017 Augie Fackler <raf@durin42.com>
4 # Copyright 2017 Sean Farley <sean@farley.io>
4 # Copyright 2017 Sean Farley <sean@farley.io>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 from __future__ import absolute_import
9 from __future__ import absolute_import
10
10
11 from .node import hex
11 from .node import hex
12
12
13 from . import (
13 from . import (
14 util,
14 util,
15 vfs as vfsmod,
15 vfs as vfsmod,
16 )
16 )
17
17
18 # directory name in .hg/ in which remotenames files will be present
18 # directory name in .hg/ in which remotenames files will be present
19 remotenamedir = 'logexchange'
19 remotenamedir = 'logexchange'
20
20
21 def readremotenamefile(repo, filename):
21 def readremotenamefile(repo, filename):
22 """
22 """
23 reads a file from .hg/logexchange/ directory and yields it's content
23 reads a file from .hg/logexchange/ directory and yields it's content
24 filename: the file to be read
24 filename: the file to be read
25 yield a tuple (node, remotepath, name)
25 yield a tuple (node, remotepath, name)
26 """
26 """
27
27
28 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
28 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
29 if not vfs.exists(filename):
29 if not vfs.exists(filename):
30 return
30 return
31 f = vfs(filename)
31 f = vfs(filename)
32 lineno = 0
32 lineno = 0
33 for line in f:
33 for line in f:
34 line = line.strip()
34 line = line.strip()
35 if not line:
35 if not line:
36 continue
36 continue
37 # contains the version number
37 # contains the version number
38 if lineno == 0:
38 if lineno == 0:
39 lineno += 1
39 lineno += 1
40 try:
40 try:
41 node, remote, rname = line.split('\0')
41 node, remote, rname = line.split('\0')
42 yield node, remote, rname
42 yield node, remote, rname
43 except ValueError:
43 except ValueError:
44 pass
44 pass
45
45
46 f.close()
46 f.close()
47
47
48 def readremotenames(repo):
48 def readremotenames(repo):
49 """
49 """
50 read the details about the remotenames stored in .hg/logexchange/ and
50 read the details about the remotenames stored in .hg/logexchange/ and
51 yields a tuple (node, remotepath, name). It does not yields information
51 yields a tuple (node, remotepath, name). It does not yields information
52 about whether an entry yielded is branch or bookmark. To get that
52 about whether an entry yielded is branch or bookmark. To get that
53 information, call the respective functions.
53 information, call the respective functions.
54 """
54 """
55
55
56 for bmentry in readremotenamefile(repo, 'bookmarks'):
56 for bmentry in readremotenamefile(repo, 'bookmarks'):
57 yield bmentry
57 yield bmentry
58 for branchentry in readremotenamefile(repo, 'branches'):
58 for branchentry in readremotenamefile(repo, 'branches'):
59 yield branchentry
59 yield branchentry
60
60
61 def writeremotenamefile(repo, remotepath, names, nametype):
61 def writeremotenamefile(repo, remotepath, names, nametype):
62 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
62 vfs = vfsmod.vfs(repo.vfs.join(remotenamedir))
63 f = vfs(nametype, 'w', atomictemp=True)
63 f = vfs(nametype, 'w', atomictemp=True)
64 # write the storage version info on top of file
64 # write the storage version info on top of file
65 # version '0' represents the very initial version of the storage format
65 # version '0' represents the very initial version of the storage format
66 f.write('0\n\n')
66 f.write('0\n\n')
67
67
68 olddata = set(readremotenamefile(repo, nametype))
68 olddata = set(readremotenamefile(repo, nametype))
69 # re-save the data from a different remote than this one.
69 # re-save the data from a different remote than this one.
70 for node, oldpath, rname in sorted(olddata):
70 for node, oldpath, rname in sorted(olddata):
71 if oldpath != remotepath:
71 if oldpath != remotepath:
72 f.write('%s\0%s\0%s\n' % (node, oldpath, rname))
72 f.write('%s\0%s\0%s\n' % (node, oldpath, rname))
73
73
74 for name, node in sorted(names.iteritems()):
74 for name, node in sorted(names.iteritems()):
75 if nametype == "branches":
75 if nametype == "branches":
76 for n in node:
76 for n in node:
77 f.write('%s\0%s\0%s\n' % (n, remotepath, name))
77 f.write('%s\0%s\0%s\n' % (n, remotepath, name))
78 elif nametype == "bookmarks":
78 elif nametype == "bookmarks":
79 if node:
79 if node:
80 f.write('%s\0%s\0%s\n' % (node, remotepath, name))
80 f.write('%s\0%s\0%s\n' % (node, remotepath, name))
81
81
82 f.close()
82 f.close()
83
83
84 def saveremotenames(repo, remotepath, branches=None, bookmarks=None):
84 def saveremotenames(repo, remotepath, branches=None, bookmarks=None):
85 """
85 """
86 save remotenames i.e. remotebookmarks and remotebranches in their
86 save remotenames i.e. remotebookmarks and remotebranches in their
87 respective files under ".hg/logexchange/" directory.
87 respective files under ".hg/logexchange/" directory.
88 """
88 """
89 wlock = repo.wlock()
89 wlock = repo.wlock()
90 try:
90 try:
91 if bookmarks:
91 if bookmarks:
92 writeremotenamefile(repo, remotepath, bookmarks, 'bookmarks')
92 writeremotenamefile(repo, remotepath, bookmarks, 'bookmarks')
93 if branches:
93 if branches:
94 writeremotenamefile(repo, remotepath, branches, 'branches')
94 writeremotenamefile(repo, remotepath, branches, 'branches')
95 finally:
95 finally:
96 wlock.release()
96 wlock.release()
97
97
98 def activepath(repo, remote):
98 def activepath(repo, remote):
99 """returns remote path"""
99 """returns remote path"""
100 local = None
100 local = None
101 # is the remote a local peer
101 # is the remote a local peer
102 local = remote.local()
102 local = remote.local()
103
103
104 # determine the remote path from the repo, if possible; else just
104 # determine the remote path from the repo, if possible; else just
105 # use the string given to us
105 # use the string given to us
106 rpath = remote
106 rpath = remote
107 if local:
107 if local:
108 rpath = remote._repo.root
108 rpath = remote._repo.root
109 elif not isinstance(remote, bytes):
109 elif not isinstance(remote, bytes):
110 rpath = remote._url
110 rpath = remote._url
111
111
112 # represent the remotepath with user defined path name if exists
112 # represent the remotepath with user defined path name if exists
113 for path, url in repo.ui.configitems('paths'):
113 for path, url in repo.ui.configitems('paths'):
114 # remove auth info from user defined url
114 # remove auth info from user defined url
115 url = util.removeauth(url)
115 url = util.removeauth(url)
116 if url == rpath:
116 if url == rpath:
117 rpath = path
117 rpath = path
118 break
118 break
119
119
120 return rpath
120 return rpath
121
121
122 def pullremotenames(localrepo, remoterepo):
122 def pullremotenames(localrepo, remoterepo):
123 """
123 """
124 pulls bookmarks and branches information of the remote repo during a
124 pulls bookmarks and branches information of the remote repo during a
125 pull or clone operation.
125 pull or clone operation.
126 localrepo is our local repository
126 localrepo is our local repository
127 remoterepo is the peer instance
127 remoterepo is the peer instance
128 """
128 """
129 remotepath = activepath(localrepo, remoterepo)
129 remotepath = activepath(localrepo, remoterepo)
130 bookmarks = remoterepo.listkeys('bookmarks')
130
131 with remoterepo.commandexecutor() as e:
132 bookmarks = e.callcommand('listkeys', {
133 'namespace': 'bookmarks',
134 }).result()
135
131 # on a push, we don't want to keep obsolete heads since
136 # on a push, we don't want to keep obsolete heads since
132 # they won't show up as heads on the next pull, so we
137 # they won't show up as heads on the next pull, so we
133 # remove them here otherwise we would require the user
138 # remove them here otherwise we would require the user
134 # to issue a pull to refresh the storage
139 # to issue a pull to refresh the storage
135 bmap = {}
140 bmap = {}
136 repo = localrepo.unfiltered()
141 repo = localrepo.unfiltered()
137 for branch, nodes in remoterepo.branchmap().iteritems():
142
143 with remoterepo.commandexecutor() as e:
144 branchmap = e.callcommand('branchmap', {}).result()
145
146 for branch, nodes in branchmap.iteritems():
138 bmap[branch] = []
147 bmap[branch] = []
139 for node in nodes:
148 for node in nodes:
140 if node in repo and not repo[node].obsolete():
149 if node in repo and not repo[node].obsolete():
141 bmap[branch].append(hex(node))
150 bmap[branch].append(hex(node))
142
151
143 saveremotenames(localrepo, remotepath, bmap, bookmarks)
152 saveremotenames(localrepo, remotepath, bmap, bookmarks)
General Comments 0
You need to be logged in to leave comments. Login now