##// END OF EJS Templates
remotenames: show remote bookmarks in `hg bookmarks`...
Pulkit Goyal -
r37108:a61fff49 default
parent child Browse files
Show More
@@ -1,352 +1,372 b''
1 # remotenames.py - extension to display remotenames
1 # remotenames.py - extension to display remotenames
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 """ showing remotebookmarks and remotebranches in UI
9 """ showing remotebookmarks and remotebranches in UI
10
10
11 By default both remotebookmarks and remotebranches are turned on. Config knob to
11 By default both remotebookmarks and remotebranches are turned on. Config knob to
12 control the individually are as follows.
12 control the individually are as follows.
13
13
14 Config options to tweak the default behaviour:
14 Config options to tweak the default behaviour:
15
15
16 remotenames.bookmarks
16 remotenames.bookmarks
17 Boolean value to enable or disable showing of remotebookmarks (default: True)
17 Boolean value to enable or disable showing of remotebookmarks (default: True)
18
18
19 remotenames.branches
19 remotenames.branches
20 Boolean value to enable or disable showing of remotebranches (default: True)
20 Boolean value to enable or disable showing of remotebranches (default: True)
21
21
22 remotenames.hoistedpeer
22 remotenames.hoistedpeer
23 Name of the peer whose remotebookmarks should be hoisted into the top-level
23 Name of the peer whose remotebookmarks should be hoisted into the top-level
24 namespace (default: 'default')
24 namespace (default: 'default')
25 """
25 """
26
26
27 from __future__ import absolute_import
27 from __future__ import absolute_import
28
28
29 from mercurial.i18n import _
29 from mercurial.i18n import _
30
30
31 from mercurial.node import (
31 from mercurial.node import (
32 bin,
32 bin,
33 )
33 )
34 from mercurial import (
34 from mercurial import (
35 bookmarks,
36 extensions,
35 logexchange,
37 logexchange,
36 namespaces,
38 namespaces,
37 pycompat,
39 pycompat,
38 registrar,
40 registrar,
39 revsetlang,
41 revsetlang,
40 smartset,
42 smartset,
41 templateutil,
43 templateutil,
42 )
44 )
43
45
44 if pycompat.ispy3:
46 if pycompat.ispy3:
45 import collections.abc
47 import collections.abc
46 mutablemapping = collections.abc.MutableMapping
48 mutablemapping = collections.abc.MutableMapping
47 else:
49 else:
48 import collections
50 import collections
49 mutablemapping = collections.MutableMapping
51 mutablemapping = collections.MutableMapping
50
52
51 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
53 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
52 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
54 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
53 # be specifying the version(s) of Mercurial they are tested with, or
55 # be specifying the version(s) of Mercurial they are tested with, or
54 # leave the attribute unspecified.
56 # leave the attribute unspecified.
55 testedwith = 'ships-with-hg-core'
57 testedwith = 'ships-with-hg-core'
56
58
57 configtable = {}
59 configtable = {}
58 configitem = registrar.configitem(configtable)
60 configitem = registrar.configitem(configtable)
59 templatekeyword = registrar.templatekeyword()
61 templatekeyword = registrar.templatekeyword()
60 revsetpredicate = registrar.revsetpredicate()
62 revsetpredicate = registrar.revsetpredicate()
61
63
62 configitem('remotenames', 'bookmarks',
64 configitem('remotenames', 'bookmarks',
63 default=True,
65 default=True,
64 )
66 )
65 configitem('remotenames', 'branches',
67 configitem('remotenames', 'branches',
66 default=True,
68 default=True,
67 )
69 )
68 configitem('remotenames', 'hoistedpeer',
70 configitem('remotenames', 'hoistedpeer',
69 default='default',
71 default='default',
70 )
72 )
71
73
72 class lazyremotenamedict(mutablemapping):
74 class lazyremotenamedict(mutablemapping):
73 """
75 """
74 Read-only dict-like Class to lazily resolve remotename entries
76 Read-only dict-like Class to lazily resolve remotename entries
75
77
76 We are doing that because remotenames startup was slow.
78 We are doing that because remotenames startup was slow.
77 We lazily read the remotenames file once to figure out the potential entries
79 We lazily read the remotenames file once to figure out the potential entries
78 and store them in self.potentialentries. Then when asked to resolve an
80 and store them in self.potentialentries. Then when asked to resolve an
79 entry, if it is not in self.potentialentries, then it isn't there, if it
81 entry, if it is not in self.potentialentries, then it isn't there, if it
80 is in self.potentialentries we resolve it and store the result in
82 is in self.potentialentries we resolve it and store the result in
81 self.cache. We cannot be lazy is when asked all the entries (keys).
83 self.cache. We cannot be lazy is when asked all the entries (keys).
82 """
84 """
83 def __init__(self, kind, repo):
85 def __init__(self, kind, repo):
84 self.cache = {}
86 self.cache = {}
85 self.potentialentries = {}
87 self.potentialentries = {}
86 self._kind = kind # bookmarks or branches
88 self._kind = kind # bookmarks or branches
87 self._repo = repo
89 self._repo = repo
88 self.loaded = False
90 self.loaded = False
89
91
90 def _load(self):
92 def _load(self):
91 """ Read the remotenames file, store entries matching selected kind """
93 """ Read the remotenames file, store entries matching selected kind """
92 self.loaded = True
94 self.loaded = True
93 repo = self._repo
95 repo = self._repo
94 for node, rpath, rname in logexchange.readremotenamefile(repo,
96 for node, rpath, rname in logexchange.readremotenamefile(repo,
95 self._kind):
97 self._kind):
96 name = rpath + '/' + rname
98 name = rpath + '/' + rname
97 self.potentialentries[name] = (node, rpath, name)
99 self.potentialentries[name] = (node, rpath, name)
98
100
99 def _resolvedata(self, potentialentry):
101 def _resolvedata(self, potentialentry):
100 """ Check that the node for potentialentry exists and return it """
102 """ Check that the node for potentialentry exists and return it """
101 if not potentialentry in self.potentialentries:
103 if not potentialentry in self.potentialentries:
102 return None
104 return None
103 node, remote, name = self.potentialentries[potentialentry]
105 node, remote, name = self.potentialentries[potentialentry]
104 repo = self._repo
106 repo = self._repo
105 binnode = bin(node)
107 binnode = bin(node)
106 # if the node doesn't exist, skip it
108 # if the node doesn't exist, skip it
107 try:
109 try:
108 repo.changelog.rev(binnode)
110 repo.changelog.rev(binnode)
109 except LookupError:
111 except LookupError:
110 return None
112 return None
111 # Skip closed branches
113 # Skip closed branches
112 if (self._kind == 'branches' and repo[binnode].closesbranch()):
114 if (self._kind == 'branches' and repo[binnode].closesbranch()):
113 return None
115 return None
114 return [binnode]
116 return [binnode]
115
117
116 def __getitem__(self, key):
118 def __getitem__(self, key):
117 if not self.loaded:
119 if not self.loaded:
118 self._load()
120 self._load()
119 val = self._fetchandcache(key)
121 val = self._fetchandcache(key)
120 if val is not None:
122 if val is not None:
121 return val
123 return val
122 else:
124 else:
123 raise KeyError()
125 raise KeyError()
124
126
125 def __iter__(self):
127 def __iter__(self):
126 return iter(self.potentialentries)
128 return iter(self.potentialentries)
127
129
128 def __len__(self):
130 def __len__(self):
129 return len(self.potentialentries)
131 return len(self.potentialentries)
130
132
131 def __setitem__(self):
133 def __setitem__(self):
132 raise NotImplementedError
134 raise NotImplementedError
133
135
134 def __delitem__(self):
136 def __delitem__(self):
135 raise NotImplementedError
137 raise NotImplementedError
136
138
137 def _fetchandcache(self, key):
139 def _fetchandcache(self, key):
138 if key in self.cache:
140 if key in self.cache:
139 return self.cache[key]
141 return self.cache[key]
140 val = self._resolvedata(key)
142 val = self._resolvedata(key)
141 if val is not None:
143 if val is not None:
142 self.cache[key] = val
144 self.cache[key] = val
143 return val
145 return val
144 else:
146 else:
145 return None
147 return None
146
148
147 def keys(self):
149 def keys(self):
148 """ Get a list of bookmark or branch names """
150 """ Get a list of bookmark or branch names """
149 if not self.loaded:
151 if not self.loaded:
150 self._load()
152 self._load()
151 return self.potentialentries.keys()
153 return self.potentialentries.keys()
152
154
153 def iteritems(self):
155 def iteritems(self):
154 """ Iterate over (name, node) tuples """
156 """ Iterate over (name, node) tuples """
155
157
156 if not self.loaded:
158 if not self.loaded:
157 self._load()
159 self._load()
158
160
159 for k, vtup in self.potentialentries.iteritems():
161 for k, vtup in self.potentialentries.iteritems():
160 yield (k, [bin(vtup[0])])
162 yield (k, [bin(vtup[0])])
161
163
162 class remotenames(object):
164 class remotenames(object):
163 """
165 """
164 This class encapsulates all the remotenames state. It also contains
166 This class encapsulates all the remotenames state. It also contains
165 methods to access that state in convenient ways. Remotenames are lazy
167 methods to access that state in convenient ways. Remotenames are lazy
166 loaded. Whenever client code needs to ensure the freshest copy of
168 loaded. Whenever client code needs to ensure the freshest copy of
167 remotenames, use the `clearnames` method to force an eventual load.
169 remotenames, use the `clearnames` method to force an eventual load.
168 """
170 """
169
171
170 def __init__(self, repo, *args):
172 def __init__(self, repo, *args):
171 self._repo = repo
173 self._repo = repo
172 self.clearnames()
174 self.clearnames()
173
175
174 def clearnames(self):
176 def clearnames(self):
175 """ Clear all remote names state """
177 """ Clear all remote names state """
176 self.bookmarks = lazyremotenamedict("bookmarks", self._repo)
178 self.bookmarks = lazyremotenamedict("bookmarks", self._repo)
177 self.branches = lazyremotenamedict("branches", self._repo)
179 self.branches = lazyremotenamedict("branches", self._repo)
178 self._invalidatecache()
180 self._invalidatecache()
179
181
180 def _invalidatecache(self):
182 def _invalidatecache(self):
181 self._nodetobmarks = None
183 self._nodetobmarks = None
182 self._nodetobranch = None
184 self._nodetobranch = None
183 self._hoisttonodes = None
185 self._hoisttonodes = None
184 self._nodetohoists = None
186 self._nodetohoists = None
185
187
186 def bmarktonodes(self):
188 def bmarktonodes(self):
187 return self.bookmarks
189 return self.bookmarks
188
190
189 def nodetobmarks(self):
191 def nodetobmarks(self):
190 if not self._nodetobmarks:
192 if not self._nodetobmarks:
191 bmarktonodes = self.bmarktonodes()
193 bmarktonodes = self.bmarktonodes()
192 self._nodetobmarks = {}
194 self._nodetobmarks = {}
193 for name, node in bmarktonodes.iteritems():
195 for name, node in bmarktonodes.iteritems():
194 self._nodetobmarks.setdefault(node[0], []).append(name)
196 self._nodetobmarks.setdefault(node[0], []).append(name)
195 return self._nodetobmarks
197 return self._nodetobmarks
196
198
197 def branchtonodes(self):
199 def branchtonodes(self):
198 return self.branches
200 return self.branches
199
201
200 def nodetobranch(self):
202 def nodetobranch(self):
201 if not self._nodetobranch:
203 if not self._nodetobranch:
202 branchtonodes = self.branchtonodes()
204 branchtonodes = self.branchtonodes()
203 self._nodetobranch = {}
205 self._nodetobranch = {}
204 for name, nodes in branchtonodes.iteritems():
206 for name, nodes in branchtonodes.iteritems():
205 for node in nodes:
207 for node in nodes:
206 self._nodetobranch.setdefault(node, []).append(name)
208 self._nodetobranch.setdefault(node, []).append(name)
207 return self._nodetobranch
209 return self._nodetobranch
208
210
209 def hoisttonodes(self, hoist):
211 def hoisttonodes(self, hoist):
210 if not self._hoisttonodes:
212 if not self._hoisttonodes:
211 marktonodes = self.bmarktonodes()
213 marktonodes = self.bmarktonodes()
212 self._hoisttonodes = {}
214 self._hoisttonodes = {}
213 hoist += '/'
215 hoist += '/'
214 for name, node in marktonodes.iteritems():
216 for name, node in marktonodes.iteritems():
215 if name.startswith(hoist):
217 if name.startswith(hoist):
216 name = name[len(hoist):]
218 name = name[len(hoist):]
217 self._hoisttonodes[name] = node
219 self._hoisttonodes[name] = node
218 return self._hoisttonodes
220 return self._hoisttonodes
219
221
220 def nodetohoists(self, hoist):
222 def nodetohoists(self, hoist):
221 if not self._nodetohoists:
223 if not self._nodetohoists:
222 marktonodes = self.bmarktonodes()
224 marktonodes = self.bmarktonodes()
223 self._nodetohoists = {}
225 self._nodetohoists = {}
224 hoist += '/'
226 hoist += '/'
225 for name, node in marktonodes.iteritems():
227 for name, node in marktonodes.iteritems():
226 if name.startswith(hoist):
228 if name.startswith(hoist):
227 name = name[len(hoist):]
229 name = name[len(hoist):]
228 self._nodetohoists.setdefault(node[0], []).append(name)
230 self._nodetohoists.setdefault(node[0], []).append(name)
229 return self._nodetohoists
231 return self._nodetohoists
230
232
233 def wrapprintbookmarks(orig, ui, repo, bmarks, **opts):
234 if 'remotebookmarks' not in repo.names:
235 return
236 ns = repo.names['remotebookmarks']
237
238 for name in ns.listnames(repo):
239 nodes = ns.nodes(repo, name)
240 if not nodes:
241 continue
242 node = nodes[0]
243
244 bmarks[name] = (node, ' ', '')
245
246 return orig(ui, repo, bmarks, **opts)
247
248 def extsetup(ui):
249 extensions.wrapfunction(bookmarks, '_printbookmarks', wrapprintbookmarks)
250
231 def reposetup(ui, repo):
251 def reposetup(ui, repo):
232 if not repo.local():
252 if not repo.local():
233 return
253 return
234
254
235 repo._remotenames = remotenames(repo)
255 repo._remotenames = remotenames(repo)
236 ns = namespaces.namespace
256 ns = namespaces.namespace
237
257
238 if ui.configbool('remotenames', 'bookmarks'):
258 if ui.configbool('remotenames', 'bookmarks'):
239 remotebookmarkns = ns(
259 remotebookmarkns = ns(
240 'remotebookmarks',
260 'remotebookmarks',
241 templatename='remotebookmarks',
261 templatename='remotebookmarks',
242 colorname='remotebookmark',
262 colorname='remotebookmark',
243 logfmt='remote bookmark: %s\n',
263 logfmt='remote bookmark: %s\n',
244 listnames=lambda repo: repo._remotenames.bmarktonodes().keys(),
264 listnames=lambda repo: repo._remotenames.bmarktonodes().keys(),
245 namemap=lambda repo, name:
265 namemap=lambda repo, name:
246 repo._remotenames.bmarktonodes().get(name, []),
266 repo._remotenames.bmarktonodes().get(name, []),
247 nodemap=lambda repo, node:
267 nodemap=lambda repo, node:
248 repo._remotenames.nodetobmarks().get(node, []))
268 repo._remotenames.nodetobmarks().get(node, []))
249 repo.names.addnamespace(remotebookmarkns)
269 repo.names.addnamespace(remotebookmarkns)
250
270
251 # hoisting only works if there are remote bookmarks
271 # hoisting only works if there are remote bookmarks
252 hoist = ui.config('remotenames', 'hoistedpeer')
272 hoist = ui.config('remotenames', 'hoistedpeer')
253 if hoist:
273 if hoist:
254 hoistednamens = ns(
274 hoistednamens = ns(
255 'hoistednames',
275 'hoistednames',
256 templatename='hoistednames',
276 templatename='hoistednames',
257 colorname='hoistedname',
277 colorname='hoistedname',
258 logfmt='hoisted name: %s\n',
278 logfmt='hoisted name: %s\n',
259 listnames = lambda repo:
279 listnames = lambda repo:
260 repo._remotenames.hoisttonodes(hoist).keys(),
280 repo._remotenames.hoisttonodes(hoist).keys(),
261 namemap = lambda repo, name:
281 namemap = lambda repo, name:
262 repo._remotenames.hoisttonodes(hoist).get(name, []),
282 repo._remotenames.hoisttonodes(hoist).get(name, []),
263 nodemap = lambda repo, node:
283 nodemap = lambda repo, node:
264 repo._remotenames.nodetohoists(hoist).get(node, []))
284 repo._remotenames.nodetohoists(hoist).get(node, []))
265 repo.names.addnamespace(hoistednamens)
285 repo.names.addnamespace(hoistednamens)
266
286
267 if ui.configbool('remotenames', 'branches'):
287 if ui.configbool('remotenames', 'branches'):
268 remotebranchns = ns(
288 remotebranchns = ns(
269 'remotebranches',
289 'remotebranches',
270 templatename='remotebranches',
290 templatename='remotebranches',
271 colorname='remotebranch',
291 colorname='remotebranch',
272 logfmt='remote branch: %s\n',
292 logfmt='remote branch: %s\n',
273 listnames = lambda repo: repo._remotenames.branchtonodes().keys(),
293 listnames = lambda repo: repo._remotenames.branchtonodes().keys(),
274 namemap = lambda repo, name:
294 namemap = lambda repo, name:
275 repo._remotenames.branchtonodes().get(name, []),
295 repo._remotenames.branchtonodes().get(name, []),
276 nodemap = lambda repo, node:
296 nodemap = lambda repo, node:
277 repo._remotenames.nodetobranch().get(node, []))
297 repo._remotenames.nodetobranch().get(node, []))
278 repo.names.addnamespace(remotebranchns)
298 repo.names.addnamespace(remotebranchns)
279
299
280 @templatekeyword('remotenames', requires={'repo', 'ctx'})
300 @templatekeyword('remotenames', requires={'repo', 'ctx'})
281 def remotenameskw(context, mapping):
301 def remotenameskw(context, mapping):
282 """List of strings. Remote names associated with the changeset."""
302 """List of strings. Remote names associated with the changeset."""
283 repo = context.resource(mapping, 'repo')
303 repo = context.resource(mapping, 'repo')
284 ctx = context.resource(mapping, 'ctx')
304 ctx = context.resource(mapping, 'ctx')
285
305
286 remotenames = []
306 remotenames = []
287 if 'remotebookmarks' in repo.names:
307 if 'remotebookmarks' in repo.names:
288 remotenames = repo.names['remotebookmarks'].names(repo, ctx.node())
308 remotenames = repo.names['remotebookmarks'].names(repo, ctx.node())
289
309
290 if 'remotebranches' in repo.names:
310 if 'remotebranches' in repo.names:
291 remotenames += repo.names['remotebranches'].names(repo, ctx.node())
311 remotenames += repo.names['remotebranches'].names(repo, ctx.node())
292
312
293 return templateutil.compatlist(context, mapping, 'remotename', remotenames,
313 return templateutil.compatlist(context, mapping, 'remotename', remotenames,
294 plural='remotenames')
314 plural='remotenames')
295
315
296 @templatekeyword('remotebookmarks', requires={'repo', 'ctx'})
316 @templatekeyword('remotebookmarks', requires={'repo', 'ctx'})
297 def remotebookmarkskw(context, mapping):
317 def remotebookmarkskw(context, mapping):
298 """List of strings. Remote bookmarks associated with the changeset."""
318 """List of strings. Remote bookmarks associated with the changeset."""
299 repo = context.resource(mapping, 'repo')
319 repo = context.resource(mapping, 'repo')
300 ctx = context.resource(mapping, 'ctx')
320 ctx = context.resource(mapping, 'ctx')
301
321
302 remotebmarks = []
322 remotebmarks = []
303 if 'remotebookmarks' in repo.names:
323 if 'remotebookmarks' in repo.names:
304 remotebmarks = repo.names['remotebookmarks'].names(repo, ctx.node())
324 remotebmarks = repo.names['remotebookmarks'].names(repo, ctx.node())
305
325
306 return templateutil.compatlist(context, mapping, 'remotebookmark',
326 return templateutil.compatlist(context, mapping, 'remotebookmark',
307 remotebmarks, plural='remotebookmarks')
327 remotebmarks, plural='remotebookmarks')
308
328
309 @templatekeyword('remotebranches', requires={'repo', 'ctx'})
329 @templatekeyword('remotebranches', requires={'repo', 'ctx'})
310 def remotebrancheskw(context, mapping):
330 def remotebrancheskw(context, mapping):
311 """List of strings. Remote branches associated with the changeset."""
331 """List of strings. Remote branches associated with the changeset."""
312 repo = context.resource(mapping, 'repo')
332 repo = context.resource(mapping, 'repo')
313 ctx = context.resource(mapping, 'ctx')
333 ctx = context.resource(mapping, 'ctx')
314
334
315 remotebranches = []
335 remotebranches = []
316 if 'remotebranches' in repo.names:
336 if 'remotebranches' in repo.names:
317 remotebranches = repo.names['remotebranches'].names(repo, ctx.node())
337 remotebranches = repo.names['remotebranches'].names(repo, ctx.node())
318
338
319 return templateutil.compatlist(context, mapping, 'remotebranch',
339 return templateutil.compatlist(context, mapping, 'remotebranch',
320 remotebranches, plural='remotebranches')
340 remotebranches, plural='remotebranches')
321
341
322 def _revsetutil(repo, subset, x, rtypes):
342 def _revsetutil(repo, subset, x, rtypes):
323 """utility function to return a set of revs based on the rtypes"""
343 """utility function to return a set of revs based on the rtypes"""
324
344
325 revs = set()
345 revs = set()
326 cl = repo.changelog
346 cl = repo.changelog
327 for rtype in rtypes:
347 for rtype in rtypes:
328 if rtype in repo.names:
348 if rtype in repo.names:
329 ns = repo.names[rtype]
349 ns = repo.names[rtype]
330 for name in ns.listnames(repo):
350 for name in ns.listnames(repo):
331 revs.update(ns.nodes(repo, name))
351 revs.update(ns.nodes(repo, name))
332
352
333 results = (cl.rev(n) for n in revs if cl.hasnode(n))
353 results = (cl.rev(n) for n in revs if cl.hasnode(n))
334 return subset & smartset.baseset(sorted(results))
354 return subset & smartset.baseset(sorted(results))
335
355
336 @revsetpredicate('remotenames()')
356 @revsetpredicate('remotenames()')
337 def remotenamesrevset(repo, subset, x):
357 def remotenamesrevset(repo, subset, x):
338 """All changesets which have a remotename on them."""
358 """All changesets which have a remotename on them."""
339 revsetlang.getargs(x, 0, 0, _("remotenames takes no arguments"))
359 revsetlang.getargs(x, 0, 0, _("remotenames takes no arguments"))
340 return _revsetutil(repo, subset, x, ('remotebookmarks', 'remotebranches'))
360 return _revsetutil(repo, subset, x, ('remotebookmarks', 'remotebranches'))
341
361
342 @revsetpredicate('remotebranches()')
362 @revsetpredicate('remotebranches()')
343 def remotebranchesrevset(repo, subset, x):
363 def remotebranchesrevset(repo, subset, x):
344 """All changesets which are branch heads on remotes."""
364 """All changesets which are branch heads on remotes."""
345 revsetlang.getargs(x, 0, 0, _("remotebranches takes no arguments"))
365 revsetlang.getargs(x, 0, 0, _("remotebranches takes no arguments"))
346 return _revsetutil(repo, subset, x, ('remotebranches',))
366 return _revsetutil(repo, subset, x, ('remotebranches',))
347
367
348 @revsetpredicate('remotebookmarks()')
368 @revsetpredicate('remotebookmarks()')
349 def remotebmarksrevset(repo, subset, x):
369 def remotebmarksrevset(repo, subset, x):
350 """All changesets which have bookmarks on remotes."""
370 """All changesets which have bookmarks on remotes."""
351 revsetlang.getargs(x, 0, 0, _("remotebookmarks takes no arguments"))
371 revsetlang.getargs(x, 0, 0, _("remotebookmarks takes no arguments"))
352 return _revsetutil(repo, subset, x, ('remotebookmarks',))
372 return _revsetutil(repo, subset, x, ('remotebookmarks',))
@@ -1,329 +1,335 b''
1 Testing the functionality to pull remotenames
1 Testing the functionality to pull remotenames
2 =============================================
2 =============================================
3
3
4 $ cat >> $HGRCPATH << EOF
4 $ cat >> $HGRCPATH << EOF
5 > [alias]
5 > [alias]
6 > glog = log -G -T '{rev}:{node|short} {desc}'
6 > glog = log -G -T '{rev}:{node|short} {desc}'
7 > [experimental]
7 > [experimental]
8 > remotenames = True
8 > remotenames = True
9 > [extensions]
9 > [extensions]
10 > remotenames =
10 > remotenames =
11 > show =
11 > show =
12 > EOF
12 > EOF
13
13
14 Making a server repo
14 Making a server repo
15 --------------------
15 --------------------
16
16
17 $ hg init server
17 $ hg init server
18 $ cd server
18 $ cd server
19 $ for ch in a b c d e f g h; do
19 $ for ch in a b c d e f g h; do
20 > echo "foo" >> $ch
20 > echo "foo" >> $ch
21 > hg ci -Aqm "Added "$ch
21 > hg ci -Aqm "Added "$ch
22 > done
22 > done
23 $ hg glog
23 $ hg glog
24 @ 7:ec2426147f0e Added h
24 @ 7:ec2426147f0e Added h
25 |
25 |
26 o 6:87d6d6676308 Added g
26 o 6:87d6d6676308 Added g
27 |
27 |
28 o 5:825660c69f0c Added f
28 o 5:825660c69f0c Added f
29 |
29 |
30 o 4:aa98ab95a928 Added e
30 o 4:aa98ab95a928 Added e
31 |
31 |
32 o 3:62615734edd5 Added d
32 o 3:62615734edd5 Added d
33 |
33 |
34 o 2:28ad74487de9 Added c
34 o 2:28ad74487de9 Added c
35 |
35 |
36 o 1:29becc82797a Added b
36 o 1:29becc82797a Added b
37 |
37 |
38 o 0:18d04c59bb5d Added a
38 o 0:18d04c59bb5d Added a
39
39
40 $ hg bookmark -r 3 foo
40 $ hg bookmark -r 3 foo
41 $ hg bookmark -r 6 bar
41 $ hg bookmark -r 6 bar
42 $ hg up 4
42 $ hg up 4
43 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
43 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
44 $ hg branch wat
44 $ hg branch wat
45 marked working directory as branch wat
45 marked working directory as branch wat
46 (branches are permanent and global, did you want a bookmark?)
46 (branches are permanent and global, did you want a bookmark?)
47 $ echo foo >> bar
47 $ echo foo >> bar
48 $ hg ci -Aqm "added bar"
48 $ hg ci -Aqm "added bar"
49
49
50 Making a client repo
50 Making a client repo
51 --------------------
51 --------------------
52
52
53 $ cd ..
53 $ cd ..
54
54
55 $ hg clone server client
55 $ hg clone server client
56 updating to branch default
56 updating to branch default
57 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
57 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
58
58
59 $ cd client
59 $ cd client
60 $ cat .hg/logexchange/bookmarks
60 $ cat .hg/logexchange/bookmarks
61 0
61 0
62
62
63 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
63 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
64 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
64 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
65
65
66 $ cat .hg/logexchange/branches
66 $ cat .hg/logexchange/branches
67 0
67 0
68
68
69 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
69 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
70 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
70 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
71
71
72 $ hg show work
72 $ hg show work
73 o 3e14 (wat) (default/wat) added bar
73 o 3e14 (wat) (default/wat) added bar
74 |
74 |
75 ~
75 ~
76 @ ec24 (default/default) Added h
76 @ ec24 (default/default) Added h
77 |
77 |
78 ~
78 ~
79
79
80 $ hg update "default/wat"
80 $ hg update "default/wat"
81 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
81 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
82 $ hg identify
82 $ hg identify
83 3e1487808078 (wat) tip
83 3e1487808078 (wat) tip
84
84
85 Making a new server
85 Making a new server
86 -------------------
86 -------------------
87
87
88 $ cd ..
88 $ cd ..
89 $ hg init server2
89 $ hg init server2
90 $ cd server2
90 $ cd server2
91 $ hg pull ../server/
91 $ hg pull ../server/
92 pulling from ../server/
92 pulling from ../server/
93 requesting all changes
93 requesting all changes
94 adding changesets
94 adding changesets
95 adding manifests
95 adding manifests
96 adding file changes
96 adding file changes
97 added 9 changesets with 9 changes to 9 files (+1 heads)
97 added 9 changesets with 9 changes to 9 files (+1 heads)
98 adding remote bookmark bar
98 adding remote bookmark bar
99 adding remote bookmark foo
99 adding remote bookmark foo
100 new changesets 18d04c59bb5d:3e1487808078
100 new changesets 18d04c59bb5d:3e1487808078
101 (run 'hg heads' to see heads)
101 (run 'hg heads' to see heads)
102
102
103 Pulling form the new server
103 Pulling form the new server
104 ---------------------------
104 ---------------------------
105 $ cd ../client/
105 $ cd ../client/
106 $ hg pull ../server2/
106 $ hg pull ../server2/
107 pulling from ../server2/
107 pulling from ../server2/
108 searching for changes
108 searching for changes
109 no changes found
109 no changes found
110 $ cat .hg/logexchange/bookmarks
110 $ cat .hg/logexchange/bookmarks
111 0
111 0
112
112
113 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
113 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
114 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
114 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
115 87d6d66763085b629e6d7ed56778c79827273022\x00$TESTTMP/server2\x00bar (esc)
115 87d6d66763085b629e6d7ed56778c79827273022\x00$TESTTMP/server2\x00bar (esc)
116 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00$TESTTMP/server2\x00foo (esc)
116 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00$TESTTMP/server2\x00foo (esc)
117
117
118 $ cat .hg/logexchange/branches
118 $ cat .hg/logexchange/branches
119 0
119 0
120
120
121 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
121 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
122 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
122 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
123 ec2426147f0e39dbc9cef599b066be6035ce691d\x00$TESTTMP/server2\x00default (esc)
123 ec2426147f0e39dbc9cef599b066be6035ce691d\x00$TESTTMP/server2\x00default (esc)
124 3e1487808078543b0af6d10dadf5d46943578db0\x00$TESTTMP/server2\x00wat (esc)
124 3e1487808078543b0af6d10dadf5d46943578db0\x00$TESTTMP/server2\x00wat (esc)
125
125
126 $ hg log -G
126 $ hg log -G
127 @ changeset: 8:3e1487808078
127 @ changeset: 8:3e1487808078
128 | branch: wat
128 | branch: wat
129 | tag: tip
129 | tag: tip
130 | remote branch: $TESTTMP/server2/wat
130 | remote branch: $TESTTMP/server2/wat
131 | remote branch: default/wat
131 | remote branch: default/wat
132 | parent: 4:aa98ab95a928
132 | parent: 4:aa98ab95a928
133 | user: test
133 | user: test
134 | date: Thu Jan 01 00:00:00 1970 +0000
134 | date: Thu Jan 01 00:00:00 1970 +0000
135 | summary: added bar
135 | summary: added bar
136 |
136 |
137 | o changeset: 7:ec2426147f0e
137 | o changeset: 7:ec2426147f0e
138 | | remote branch: $TESTTMP/server2/default
138 | | remote branch: $TESTTMP/server2/default
139 | | remote branch: default/default
139 | | remote branch: default/default
140 | | user: test
140 | | user: test
141 | | date: Thu Jan 01 00:00:00 1970 +0000
141 | | date: Thu Jan 01 00:00:00 1970 +0000
142 | | summary: Added h
142 | | summary: Added h
143 | |
143 | |
144 | o changeset: 6:87d6d6676308
144 | o changeset: 6:87d6d6676308
145 | | bookmark: bar
145 | | bookmark: bar
146 | | remote bookmark: $TESTTMP/server2/bar
146 | | remote bookmark: $TESTTMP/server2/bar
147 | | remote bookmark: default/bar
147 | | remote bookmark: default/bar
148 | | hoisted name: bar
148 | | hoisted name: bar
149 | | user: test
149 | | user: test
150 | | date: Thu Jan 01 00:00:00 1970 +0000
150 | | date: Thu Jan 01 00:00:00 1970 +0000
151 | | summary: Added g
151 | | summary: Added g
152 | |
152 | |
153 | o changeset: 5:825660c69f0c
153 | o changeset: 5:825660c69f0c
154 |/ user: test
154 |/ user: test
155 | date: Thu Jan 01 00:00:00 1970 +0000
155 | date: Thu Jan 01 00:00:00 1970 +0000
156 | summary: Added f
156 | summary: Added f
157 |
157 |
158 o changeset: 4:aa98ab95a928
158 o changeset: 4:aa98ab95a928
159 | user: test
159 | user: test
160 | date: Thu Jan 01 00:00:00 1970 +0000
160 | date: Thu Jan 01 00:00:00 1970 +0000
161 | summary: Added e
161 | summary: Added e
162 |
162 |
163 o changeset: 3:62615734edd5
163 o changeset: 3:62615734edd5
164 | bookmark: foo
164 | bookmark: foo
165 | remote bookmark: $TESTTMP/server2/foo
165 | remote bookmark: $TESTTMP/server2/foo
166 | remote bookmark: default/foo
166 | remote bookmark: default/foo
167 | hoisted name: foo
167 | hoisted name: foo
168 | user: test
168 | user: test
169 | date: Thu Jan 01 00:00:00 1970 +0000
169 | date: Thu Jan 01 00:00:00 1970 +0000
170 | summary: Added d
170 | summary: Added d
171 |
171 |
172 o changeset: 2:28ad74487de9
172 o changeset: 2:28ad74487de9
173 | user: test
173 | user: test
174 | date: Thu Jan 01 00:00:00 1970 +0000
174 | date: Thu Jan 01 00:00:00 1970 +0000
175 | summary: Added c
175 | summary: Added c
176 |
176 |
177 o changeset: 1:29becc82797a
177 o changeset: 1:29becc82797a
178 | user: test
178 | user: test
179 | date: Thu Jan 01 00:00:00 1970 +0000
179 | date: Thu Jan 01 00:00:00 1970 +0000
180 | summary: Added b
180 | summary: Added b
181 |
181 |
182 o changeset: 0:18d04c59bb5d
182 o changeset: 0:18d04c59bb5d
183 user: test
183 user: test
184 date: Thu Jan 01 00:00:00 1970 +0000
184 date: Thu Jan 01 00:00:00 1970 +0000
185 summary: Added a
185 summary: Added a
186
186
187 Testing the templates provided by remotenames extension
187 Testing the templates provided by remotenames extension
188
188
189 `remotenames` keyword
189 `remotenames` keyword
190
190
191 $ hg log -G -T "{rev}:{node|short} {remotenames}\n"
191 $ hg log -G -T "{rev}:{node|short} {remotenames}\n"
192 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
192 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
193 |
193 |
194 | o 7:ec2426147f0e $TESTTMP/server2/default default/default
194 | o 7:ec2426147f0e $TESTTMP/server2/default default/default
195 | |
195 | |
196 | o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
196 | o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
197 | |
197 | |
198 | o 5:825660c69f0c
198 | o 5:825660c69f0c
199 |/
199 |/
200 o 4:aa98ab95a928
200 o 4:aa98ab95a928
201 |
201 |
202 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
202 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
203 |
203 |
204 o 2:28ad74487de9
204 o 2:28ad74487de9
205 |
205 |
206 o 1:29becc82797a
206 o 1:29becc82797a
207 |
207 |
208 o 0:18d04c59bb5d
208 o 0:18d04c59bb5d
209
209
210 `remotebookmarks` and `remotebranches` keywords
210 `remotebookmarks` and `remotebranches` keywords
211
211
212 $ hg log -G -T "{rev}:{node|short} [{remotebookmarks}] ({remotebranches})"
212 $ hg log -G -T "{rev}:{node|short} [{remotebookmarks}] ({remotebranches})"
213 @ 8:3e1487808078 [] ($TESTTMP/server2/wat default/wat)
213 @ 8:3e1487808078 [] ($TESTTMP/server2/wat default/wat)
214 |
214 |
215 | o 7:ec2426147f0e [] ($TESTTMP/server2/default default/default)
215 | o 7:ec2426147f0e [] ($TESTTMP/server2/default default/default)
216 | |
216 | |
217 | o 6:87d6d6676308 [$TESTTMP/server2/bar default/bar] ()
217 | o 6:87d6d6676308 [$TESTTMP/server2/bar default/bar] ()
218 | |
218 | |
219 | o 5:825660c69f0c [] ()
219 | o 5:825660c69f0c [] ()
220 |/
220 |/
221 o 4:aa98ab95a928 [] ()
221 o 4:aa98ab95a928 [] ()
222 |
222 |
223 o 3:62615734edd5 [$TESTTMP/server2/foo default/foo] ()
223 o 3:62615734edd5 [$TESTTMP/server2/foo default/foo] ()
224 |
224 |
225 o 2:28ad74487de9 [] ()
225 o 2:28ad74487de9 [] ()
226 |
226 |
227 o 1:29becc82797a [] ()
227 o 1:29becc82797a [] ()
228 |
228 |
229 o 0:18d04c59bb5d [] ()
229 o 0:18d04c59bb5d [] ()
230
230
231 The `hoistednames` template keyword
231 The `hoistednames` template keyword
232
232
233 $ hg log -GT "{rev}:{node|short} ({hoistednames})"
233 $ hg log -GT "{rev}:{node|short} ({hoistednames})"
234 @ 8:3e1487808078 ()
234 @ 8:3e1487808078 ()
235 |
235 |
236 | o 7:ec2426147f0e ()
236 | o 7:ec2426147f0e ()
237 | |
237 | |
238 | o 6:87d6d6676308 (bar)
238 | o 6:87d6d6676308 (bar)
239 | |
239 | |
240 | o 5:825660c69f0c ()
240 | o 5:825660c69f0c ()
241 |/
241 |/
242 o 4:aa98ab95a928 ()
242 o 4:aa98ab95a928 ()
243 |
243 |
244 o 3:62615734edd5 (foo)
244 o 3:62615734edd5 (foo)
245 |
245 |
246 o 2:28ad74487de9 ()
246 o 2:28ad74487de9 ()
247 |
247 |
248 o 1:29becc82797a ()
248 o 1:29becc82797a ()
249 |
249 |
250 o 0:18d04c59bb5d ()
250 o 0:18d04c59bb5d ()
251
251
252
252
253 Testing the revsets provided by remotenames extension
253 Testing the revsets provided by remotenames extension
254
254
255 `remotenames` revset
255 `remotenames` revset
256
256
257 $ hg log -r "remotenames()" -GT "{rev}:{node|short} {remotenames}\n"
257 $ hg log -r "remotenames()" -GT "{rev}:{node|short} {remotenames}\n"
258 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
258 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
259 :
259 :
260 : o 7:ec2426147f0e $TESTTMP/server2/default default/default
260 : o 7:ec2426147f0e $TESTTMP/server2/default default/default
261 : |
261 : |
262 : o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
262 : o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
263 :/
263 :/
264 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
264 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
265 |
265 |
266 ~
266 ~
267
267
268 `remotebranches` revset
268 `remotebranches` revset
269
269
270 $ hg log -r "remotebranches()" -GT "{rev}:{node|short} {remotenames}\n"
270 $ hg log -r "remotebranches()" -GT "{rev}:{node|short} {remotenames}\n"
271 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
271 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
272 |
272 |
273 ~
273 ~
274 o 7:ec2426147f0e $TESTTMP/server2/default default/default
274 o 7:ec2426147f0e $TESTTMP/server2/default default/default
275 |
275 |
276 ~
276 ~
277
277
278 `remotebookmarks` revset
278 `remotebookmarks` revset
279
279
280 $ hg log -r "remotebookmarks()" -GT "{rev}:{node|short} {remotenames}\n"
280 $ hg log -r "remotebookmarks()" -GT "{rev}:{node|short} {remotenames}\n"
281 o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
281 o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
282 :
282 :
283 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
283 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
284 |
284 |
285 ~
285 ~
286
286
287 Updating to revision using hoisted name
287 Updating to revision using hoisted name
288
288
289 Deleting local bookmark to make sure we update to hoisted name only
289 Deleting local bookmark to make sure we update to hoisted name only
290
290
291 $ hg bookmark -d bar
291 $ hg bookmark -d bar
292
292
293 $ hg up bar
293 $ hg up bar
294 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
294 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
295
295
296 $ hg log -r .
296 $ hg log -r .
297 changeset: 6:87d6d6676308
297 changeset: 6:87d6d6676308
298 remote bookmark: $TESTTMP/server2/bar
298 remote bookmark: $TESTTMP/server2/bar
299 remote bookmark: default/bar
299 remote bookmark: default/bar
300 hoisted name: bar
300 hoisted name: bar
301 user: test
301 user: test
302 date: Thu Jan 01 00:00:00 1970 +0000
302 date: Thu Jan 01 00:00:00 1970 +0000
303 summary: Added g
303 summary: Added g
304
304
305 When both local bookmark and hoisted name exists but on different revs
305 When both local bookmark and hoisted name exists but on different revs
306
306
307 $ hg up 8
307 $ hg up 8
308 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
308 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
309
309
310 $ hg bookmark foo
310 $ hg bookmark foo
311 moving bookmark 'foo' forward from 62615734edd5
311 moving bookmark 'foo' forward from 62615734edd5
312
312
313 Local bookmark should take precedence over hoisted name
313 Local bookmark should take precedence over hoisted name
314
314
315 $ hg up foo
315 $ hg up foo
316 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
316 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
317
317
318 $ hg log -r .
318 $ hg log -r .
319 changeset: 8:3e1487808078
319 changeset: 8:3e1487808078
320 branch: wat
320 branch: wat
321 bookmark: foo
321 bookmark: foo
322 tag: tip
322 tag: tip
323 remote branch: $TESTTMP/server2/wat
323 remote branch: $TESTTMP/server2/wat
324 remote branch: default/wat
324 remote branch: default/wat
325 parent: 4:aa98ab95a928
325 parent: 4:aa98ab95a928
326 user: test
326 user: test
327 date: Thu Jan 01 00:00:00 1970 +0000
327 date: Thu Jan 01 00:00:00 1970 +0000
328 summary: added bar
328 summary: added bar
329
329
330 $ hg bookmarks
331 $TESTTMP/server2/bar 6:87d6d6676308
332 $TESTTMP/server2/foo 3:62615734edd5
333 default/bar 6:87d6d6676308
334 default/foo 3:62615734edd5
335 * foo 8:3e1487808078
General Comments 0
You need to be logged in to leave comments. Login now