##// END OF EJS Templates
remotenames: follow-up on D3639 to make revset funcs take only one arg...
Augie Fackler -
r40096:6346e21e default
parent child Browse files
Show More
@@ -1,437 +1,408 b''
1 1 # remotenames.py - extension to display remotenames
2 2 #
3 3 # Copyright 2017 Augie Fackler <raf@durin42.com>
4 4 # Copyright 2017 Sean Farley <sean@farley.io>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 """ showing remotebookmarks and remotebranches in UI (EXPERIMENTAL)
10 10
11 11 By default both remotebookmarks and remotebranches are turned on. Config knob to
12 12 control the individually are as follows.
13 13
14 14 Config options to tweak the default behaviour:
15 15
16 16 remotenames.bookmarks
17 17 Boolean value to enable or disable showing of remotebookmarks (default: True)
18 18
19 19 remotenames.branches
20 20 Boolean value to enable or disable showing of remotebranches (default: True)
21 21
22 22 remotenames.hoistedpeer
23 23 Name of the peer whose remotebookmarks should be hoisted into the top-level
24 24 namespace (default: 'default')
25 25 """
26 26
27 27 from __future__ import absolute_import
28 28
29 29 from mercurial.i18n import _
30 30
31 31 from mercurial.node import (
32 32 bin,
33 33 )
34 34 from mercurial import (
35 35 bookmarks,
36 36 extensions,
37 37 logexchange,
38 38 namespaces,
39 39 pycompat,
40 40 registrar,
41 41 revsetlang,
42 42 smartset,
43 43 templateutil,
44 44 )
45 45
46 46 from mercurial.utils import (
47 47 stringutil,
48 48 )
49 49
50 50 if pycompat.ispy3:
51 51 import collections.abc
52 52 mutablemapping = collections.abc.MutableMapping
53 53 else:
54 54 import collections
55 55 mutablemapping = collections.MutableMapping
56 56
57 57 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
58 58 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
59 59 # be specifying the version(s) of Mercurial they are tested with, or
60 60 # leave the attribute unspecified.
61 61 testedwith = 'ships-with-hg-core'
62 62
63 63 configtable = {}
64 64 configitem = registrar.configitem(configtable)
65 65 templatekeyword = registrar.templatekeyword()
66 66 revsetpredicate = registrar.revsetpredicate()
67 67
68 68 configitem('remotenames', 'bookmarks',
69 69 default=True,
70 70 )
71 71 configitem('remotenames', 'branches',
72 72 default=True,
73 73 )
74 74 configitem('remotenames', 'hoistedpeer',
75 75 default='default',
76 76 )
77 77
78 78 class lazyremotenamedict(mutablemapping):
79 79 """
80 80 Read-only dict-like Class to lazily resolve remotename entries
81 81
82 82 We are doing that because remotenames startup was slow.
83 83 We lazily read the remotenames file once to figure out the potential entries
84 84 and store them in self.potentialentries. Then when asked to resolve an
85 85 entry, if it is not in self.potentialentries, then it isn't there, if it
86 86 is in self.potentialentries we resolve it and store the result in
87 87 self.cache. We cannot be lazy is when asked all the entries (keys).
88 88 """
89 89 def __init__(self, kind, repo):
90 90 self.cache = {}
91 91 self.potentialentries = {}
92 92 self._kind = kind # bookmarks or branches
93 93 self._repo = repo
94 94 self.loaded = False
95 95
96 96 def _load(self):
97 97 """ Read the remotenames file, store entries matching selected kind """
98 98 self.loaded = True
99 99 repo = self._repo
100 100 for node, rpath, rname in logexchange.readremotenamefile(repo,
101 101 self._kind):
102 102 name = rpath + '/' + rname
103 103 self.potentialentries[name] = (node, rpath, name)
104 104
105 105 def _resolvedata(self, potentialentry):
106 106 """ Check that the node for potentialentry exists and return it """
107 107 if not potentialentry in self.potentialentries:
108 108 return None
109 109 node, remote, name = self.potentialentries[potentialentry]
110 110 repo = self._repo
111 111 binnode = bin(node)
112 112 # if the node doesn't exist, skip it
113 113 try:
114 114 repo.changelog.rev(binnode)
115 115 except LookupError:
116 116 return None
117 117 # Skip closed branches
118 118 if (self._kind == 'branches' and repo[binnode].closesbranch()):
119 119 return None
120 120 return [binnode]
121 121
122 122 def __getitem__(self, key):
123 123 if not self.loaded:
124 124 self._load()
125 125 val = self._fetchandcache(key)
126 126 if val is not None:
127 127 return val
128 128 else:
129 129 raise KeyError()
130 130
131 131 def __iter__(self):
132 132 return iter(self.potentialentries)
133 133
134 134 def __len__(self):
135 135 return len(self.potentialentries)
136 136
137 137 def __setitem__(self):
138 138 raise NotImplementedError
139 139
140 140 def __delitem__(self):
141 141 raise NotImplementedError
142 142
143 143 def _fetchandcache(self, key):
144 144 if key in self.cache:
145 145 return self.cache[key]
146 146 val = self._resolvedata(key)
147 147 if val is not None:
148 148 self.cache[key] = val
149 149 return val
150 150 else:
151 151 return None
152 152
153 153 def keys(self):
154 154 """ Get a list of bookmark or branch names """
155 155 if not self.loaded:
156 156 self._load()
157 157 return self.potentialentries.keys()
158 158
159 159 def iteritems(self):
160 160 """ Iterate over (name, node) tuples """
161 161
162 162 if not self.loaded:
163 163 self._load()
164 164
165 165 for k, vtup in self.potentialentries.iteritems():
166 166 yield (k, [bin(vtup[0])])
167 167
168 168 class remotenames(object):
169 169 """
170 170 This class encapsulates all the remotenames state. It also contains
171 171 methods to access that state in convenient ways. Remotenames are lazy
172 172 loaded. Whenever client code needs to ensure the freshest copy of
173 173 remotenames, use the `clearnames` method to force an eventual load.
174 174 """
175 175
176 176 def __init__(self, repo, *args):
177 177 self._repo = repo
178 178 self.clearnames()
179 179
180 180 def clearnames(self):
181 181 """ Clear all remote names state """
182 182 self.bookmarks = lazyremotenamedict("bookmarks", self._repo)
183 183 self.branches = lazyremotenamedict("branches", self._repo)
184 184 self._invalidatecache()
185 185
186 186 def _invalidatecache(self):
187 187 self._nodetobmarks = None
188 188 self._nodetobranch = None
189 189 self._hoisttonodes = None
190 190 self._nodetohoists = None
191 191
192 192 def bmarktonodes(self):
193 193 return self.bookmarks
194 194
195 195 def nodetobmarks(self):
196 196 if not self._nodetobmarks:
197 197 bmarktonodes = self.bmarktonodes()
198 198 self._nodetobmarks = {}
199 199 for name, node in bmarktonodes.iteritems():
200 200 self._nodetobmarks.setdefault(node[0], []).append(name)
201 201 return self._nodetobmarks
202 202
203 203 def branchtonodes(self):
204 204 return self.branches
205 205
206 206 def nodetobranch(self):
207 207 if not self._nodetobranch:
208 208 branchtonodes = self.branchtonodes()
209 209 self._nodetobranch = {}
210 210 for name, nodes in branchtonodes.iteritems():
211 211 for node in nodes:
212 212 self._nodetobranch.setdefault(node, []).append(name)
213 213 return self._nodetobranch
214 214
215 215 def hoisttonodes(self, hoist):
216 216 if not self._hoisttonodes:
217 217 marktonodes = self.bmarktonodes()
218 218 self._hoisttonodes = {}
219 219 hoist += '/'
220 220 for name, node in marktonodes.iteritems():
221 221 if name.startswith(hoist):
222 222 name = name[len(hoist):]
223 223 self._hoisttonodes[name] = node
224 224 return self._hoisttonodes
225 225
226 226 def nodetohoists(self, hoist):
227 227 if not self._nodetohoists:
228 228 marktonodes = self.bmarktonodes()
229 229 self._nodetohoists = {}
230 230 hoist += '/'
231 231 for name, node in marktonodes.iteritems():
232 232 if name.startswith(hoist):
233 233 name = name[len(hoist):]
234 234 self._nodetohoists.setdefault(node[0], []).append(name)
235 235 return self._nodetohoists
236 236
237 237 def wrapprintbookmarks(orig, ui, repo, fm, bmarks):
238 238 if 'remotebookmarks' not in repo.names:
239 239 return
240 240 ns = repo.names['remotebookmarks']
241 241
242 242 for name in ns.listnames(repo):
243 243 nodes = ns.nodes(repo, name)
244 244 if not nodes:
245 245 continue
246 246 node = nodes[0]
247 247
248 248 bmarks[name] = (node, ' ', '')
249 249
250 250 return orig(ui, repo, fm, bmarks)
251 251
252 252 def extsetup(ui):
253 253 extensions.wrapfunction(bookmarks, '_printbookmarks', wrapprintbookmarks)
254 254
255 255 def reposetup(ui, repo):
256 256
257 257 # set the config option to store remotenames
258 258 repo.ui.setconfig('experimental', 'remotenames', True, 'remotenames-ext')
259 259
260 260 if not repo.local():
261 261 return
262 262
263 263 repo._remotenames = remotenames(repo)
264 264 ns = namespaces.namespace
265 265
266 266 if ui.configbool('remotenames', 'bookmarks'):
267 267 remotebookmarkns = ns(
268 268 'remotebookmarks',
269 269 templatename='remotebookmarks',
270 270 colorname='remotebookmark',
271 271 logfmt='remote bookmark: %s\n',
272 272 listnames=lambda repo: repo._remotenames.bmarktonodes().keys(),
273 273 namemap=lambda repo, name:
274 274 repo._remotenames.bmarktonodes().get(name, []),
275 275 nodemap=lambda repo, node:
276 276 repo._remotenames.nodetobmarks().get(node, []))
277 277 repo.names.addnamespace(remotebookmarkns)
278 278
279 279 # hoisting only works if there are remote bookmarks
280 280 hoist = ui.config('remotenames', 'hoistedpeer')
281 281 if hoist:
282 282 hoistednamens = ns(
283 283 'hoistednames',
284 284 templatename='hoistednames',
285 285 colorname='hoistedname',
286 286 logfmt='hoisted name: %s\n',
287 287 listnames = lambda repo:
288 288 repo._remotenames.hoisttonodes(hoist).keys(),
289 289 namemap = lambda repo, name:
290 290 repo._remotenames.hoisttonodes(hoist).get(name, []),
291 291 nodemap = lambda repo, node:
292 292 repo._remotenames.nodetohoists(hoist).get(node, []))
293 293 repo.names.addnamespace(hoistednamens)
294 294
295 295 if ui.configbool('remotenames', 'branches'):
296 296 remotebranchns = ns(
297 297 'remotebranches',
298 298 templatename='remotebranches',
299 299 colorname='remotebranch',
300 300 logfmt='remote branch: %s\n',
301 301 listnames = lambda repo: repo._remotenames.branchtonodes().keys(),
302 302 namemap = lambda repo, name:
303 303 repo._remotenames.branchtonodes().get(name, []),
304 304 nodemap = lambda repo, node:
305 305 repo._remotenames.nodetobranch().get(node, []))
306 306 repo.names.addnamespace(remotebranchns)
307 307
308 308 @templatekeyword('remotenames', requires={'repo', 'ctx'})
309 309 def remotenameskw(context, mapping):
310 310 """List of strings. Remote names associated with the changeset."""
311 311 repo = context.resource(mapping, 'repo')
312 312 ctx = context.resource(mapping, 'ctx')
313 313
314 314 remotenames = []
315 315 if 'remotebookmarks' in repo.names:
316 316 remotenames = repo.names['remotebookmarks'].names(repo, ctx.node())
317 317
318 318 if 'remotebranches' in repo.names:
319 319 remotenames += repo.names['remotebranches'].names(repo, ctx.node())
320 320
321 321 return templateutil.compatlist(context, mapping, 'remotename', remotenames,
322 322 plural='remotenames')
323 323
324 324 @templatekeyword('remotebookmarks', requires={'repo', 'ctx'})
325 325 def remotebookmarkskw(context, mapping):
326 326 """List of strings. Remote bookmarks associated with the changeset."""
327 327 repo = context.resource(mapping, 'repo')
328 328 ctx = context.resource(mapping, 'ctx')
329 329
330 330 remotebmarks = []
331 331 if 'remotebookmarks' in repo.names:
332 332 remotebmarks = repo.names['remotebookmarks'].names(repo, ctx.node())
333 333
334 334 return templateutil.compatlist(context, mapping, 'remotebookmark',
335 335 remotebmarks, plural='remotebookmarks')
336 336
337 337 @templatekeyword('remotebranches', requires={'repo', 'ctx'})
338 338 def remotebrancheskw(context, mapping):
339 339 """List of strings. Remote branches associated with the changeset."""
340 340 repo = context.resource(mapping, 'repo')
341 341 ctx = context.resource(mapping, 'ctx')
342 342
343 343 remotebranches = []
344 344 if 'remotebranches' in repo.names:
345 345 remotebranches = repo.names['remotebranches'].names(repo, ctx.node())
346 346
347 347 return templateutil.compatlist(context, mapping, 'remotebranch',
348 348 remotebranches, plural='remotebranches')
349 349
350 def _revsetutil(repo, subset, x, rtypes, args):
350 def _revsetutil(repo, subset, x, rtypes, matcher):
351 351 """utility function to return a set of revs based on the rtypes"""
352 352
353 353 revs = set()
354 354 cl = repo.changelog
355 literals, matchers = args
356 # whether arguments were passed or not
357 argspassed = bool(literals or matchers)
358 355 for rtype in rtypes:
359 356 if rtype in repo.names:
360 357 ns = repo.names[rtype]
361 358 for name in ns.listnames(repo):
362 if argspassed:
363 if name in literals:
364 revs.update(ns.nodes(repo, name))
365 continue
366 for matcher in matchers:
367 if matcher(name):
368 revs.update(ns.nodes(repo, name))
369 break
370 else:
371 revs.update(ns.nodes(repo, name))
359 if not matcher(name):
360 continue
361 revs.update(ns.nodes(repo, name))
372 362
373 363 results = (cl.rev(n) for n in revs if cl.hasnode(n))
374 364 return subset & smartset.baseset(sorted(results))
375 365
376 366 def _parseargs(x):
377 367 """parses the argument passed in revsets
378 368
379 returns (literals, matchers) where,
380 literals is a set of literals passed by user
381 matchers is a list of matcher objects for patterns passed by user
369 Returns a matcher for the passed pattern.
382 370 """
383
384 # set of paths passed as literals
385 literals = set()
386 # list of matcher to match the patterns passed as names
387 matchers = []
388
389 if not x:
390 return literals, matchers
371 args = revsetlang.getargs(x, 0, 1, _('only one argument accepted'))
372 for arg in args:
373 kind, pattern, matcher = stringutil.stringmatcher(
374 revsetlang.getstring(arg, _('argument must be a string')))
375 return matcher
376 return lambda a: True
391 377
392 args = set()
393 lx = revsetlang.getlist(x)
394 err = _('the argument must be a string')
395 for entry in lx:
396 args.add(revsetlang.getstring(entry, err))
397 for p in args:
398 kind, pattern, matcher = stringutil.stringmatcher(p)
399 if kind == 'literal':
400 literals.add(pattern)
401 else:
402 matchers.append(matcher)
403 return literals, matchers
404
405 @revsetpredicate('remotenames([name, ...])')
378 @revsetpredicate('remotenames([name])')
406 379 def remotenamesrevset(repo, subset, x):
407 """All changesets which have a remotename on them. If paths are specified,
408 remotenames of those remote paths are only considered.
380 """All changesets which have a remotename on them. If `name` is
381 specified, only remotenames of matching remote paths are considered.
409 382
410 383 Pattern matching is supported for `name`. See :hg:`help revisions.patterns`.
411 384 """
412
413 args = _parseargs(x)
414 385 return _revsetutil(repo, subset, x, ('remotebookmarks', 'remotebranches'),
415 args)
386 _parseargs(x))
416 387
417 @revsetpredicate('remotebranches([name, ...])')
388 @revsetpredicate('remotebranches([name])')
418 389 def remotebranchesrevset(repo, subset, x):
419 """All changesets which are branch heads on remotes. If paths are specified,
420 only those remotes paths are considered.
390 """All changesets which are branch heads on remotes. If `name` is
391 specified, only remotenames of matching remote paths are considered.
421 392
422 393 Pattern matching is supported for `name`. See :hg:`help revisions.patterns`.
423 394 """
424 395
425 396 args = _parseargs(x)
426 397 return _revsetutil(repo, subset, x, ('remotebranches',), args)
427 398
428 @revsetpredicate('remotebookmarks([name, ...])')
399 @revsetpredicate('remotebookmarks([name])')
429 400 def remotebmarksrevset(repo, subset, x):
430 """All changesets which have bookmarks on remotes. If paths are specified,
431 only those remote paths are considered.
401 """All changesets which have bookmarks on remotes. If `name` is
402 specified, only remotenames of matching remote paths are considered.
432 403
433 404 Pattern matching is supported for `name`. See :hg:`help revisions.patterns`.
434 405 """
435 406
436 407 args = _parseargs(x)
437 408 return _revsetutil(repo, subset, x, ('remotebookmarks',), args)
@@ -1,580 +1,523 b''
1 1 Testing the functionality to pull remotenames
2 2 =============================================
3 3
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [ui]
6 6 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
7 7 > [alias]
8 8 > glog = log -G -T '{rev}:{node|short} {desc}'
9 9 > [extensions]
10 10 > remotenames =
11 11 > show =
12 12 > EOF
13 13
14 14 Making a server repo
15 15 --------------------
16 16
17 17 $ hg init server
18 18 $ cd server
19 19 $ for ch in a b c d e f g h; do
20 20 > echo "foo" >> $ch
21 21 > hg ci -Aqm "Added "$ch
22 22 > done
23 23 $ hg glog
24 24 @ 7:ec2426147f0e Added h
25 25 |
26 26 o 6:87d6d6676308 Added g
27 27 |
28 28 o 5:825660c69f0c Added f
29 29 |
30 30 o 4:aa98ab95a928 Added e
31 31 |
32 32 o 3:62615734edd5 Added d
33 33 |
34 34 o 2:28ad74487de9 Added c
35 35 |
36 36 o 1:29becc82797a Added b
37 37 |
38 38 o 0:18d04c59bb5d Added a
39 39
40 40 $ hg bookmark -r 3 foo
41 41 $ hg bookmark -r 6 bar
42 42 $ hg up 4
43 43 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
44 44 $ hg branch wat
45 45 marked working directory as branch wat
46 46 (branches are permanent and global, did you want a bookmark?)
47 47 $ echo foo >> bar
48 48 $ hg ci -Aqm "added bar"
49 49
50 50 Making a client repo
51 51 --------------------
52 52
53 53 $ cd ..
54 54
55 55 $ hg clone ssh://user@dummy/server client
56 56 requesting all changes
57 57 adding changesets
58 58 adding manifests
59 59 adding file changes
60 60 added 9 changesets with 9 changes to 9 files (+1 heads)
61 61 new changesets 18d04c59bb5d:3e1487808078
62 62 updating to branch default
63 63 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 64
65 65 $ cd client
66 66 $ cat .hg/logexchange/bookmarks
67 67 0
68 68
69 69 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
70 70 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
71 71
72 72 $ cat .hg/logexchange/branches
73 73 0
74 74
75 75 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
76 76 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
77 77
78 78 $ hg show work
79 79 o 3e14 (wat) (default/wat) added bar
80 80 ~
81 81 @ ec24 (default/default) Added h
82 82 ~
83 83
84 84 $ hg update "default/wat"
85 85 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
86 86 $ hg identify
87 87 3e1487808078 (wat) tip
88 88
89 89 Making a new server
90 90 -------------------
91 91
92 92 $ cd ..
93 93 $ hg init server2
94 94 $ cd server2
95 95 $ hg pull ../server/
96 96 pulling from ../server/
97 97 requesting all changes
98 98 adding changesets
99 99 adding manifests
100 100 adding file changes
101 101 added 9 changesets with 9 changes to 9 files (+1 heads)
102 102 adding remote bookmark bar
103 103 adding remote bookmark foo
104 104 new changesets 18d04c59bb5d:3e1487808078
105 105 (run 'hg heads' to see heads)
106 106
107 107 Pulling form the new server
108 108 ---------------------------
109 109 $ cd ../client/
110 110 $ hg pull ../server2/
111 111 pulling from ../server2/
112 112 searching for changes
113 113 no changes found
114 114 $ cat .hg/logexchange/bookmarks
115 115 0
116 116
117 117 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00default\x00foo (esc)
118 118 87d6d66763085b629e6d7ed56778c79827273022\x00default\x00bar (esc)
119 119 87d6d66763085b629e6d7ed56778c79827273022\x00$TESTTMP/server2\x00bar (esc)
120 120 62615734edd52f06b6fb9c2beb429e4fe30d57b8\x00$TESTTMP/server2\x00foo (esc)
121 121
122 122 $ cat .hg/logexchange/branches
123 123 0
124 124
125 125 3e1487808078543b0af6d10dadf5d46943578db0\x00default\x00wat (esc)
126 126 ec2426147f0e39dbc9cef599b066be6035ce691d\x00default\x00default (esc)
127 127 ec2426147f0e39dbc9cef599b066be6035ce691d\x00$TESTTMP/server2\x00default (esc)
128 128 3e1487808078543b0af6d10dadf5d46943578db0\x00$TESTTMP/server2\x00wat (esc)
129 129
130 130 $ hg log -G
131 131 @ changeset: 8:3e1487808078
132 132 | branch: wat
133 133 | tag: tip
134 134 | remote branch: $TESTTMP/server2/wat
135 135 | remote branch: default/wat
136 136 | parent: 4:aa98ab95a928
137 137 | user: test
138 138 | date: Thu Jan 01 00:00:00 1970 +0000
139 139 | summary: added bar
140 140 |
141 141 | o changeset: 7:ec2426147f0e
142 142 | | remote branch: $TESTTMP/server2/default
143 143 | | remote branch: default/default
144 144 | | user: test
145 145 | | date: Thu Jan 01 00:00:00 1970 +0000
146 146 | | summary: Added h
147 147 | |
148 148 | o changeset: 6:87d6d6676308
149 149 | | bookmark: bar
150 150 | | remote bookmark: $TESTTMP/server2/bar
151 151 | | remote bookmark: default/bar
152 152 | | hoisted name: bar
153 153 | | user: test
154 154 | | date: Thu Jan 01 00:00:00 1970 +0000
155 155 | | summary: Added g
156 156 | |
157 157 | o changeset: 5:825660c69f0c
158 158 |/ user: test
159 159 | date: Thu Jan 01 00:00:00 1970 +0000
160 160 | summary: Added f
161 161 |
162 162 o changeset: 4:aa98ab95a928
163 163 | user: test
164 164 | date: Thu Jan 01 00:00:00 1970 +0000
165 165 | summary: Added e
166 166 |
167 167 o changeset: 3:62615734edd5
168 168 | bookmark: foo
169 169 | remote bookmark: $TESTTMP/server2/foo
170 170 | remote bookmark: default/foo
171 171 | hoisted name: foo
172 172 | user: test
173 173 | date: Thu Jan 01 00:00:00 1970 +0000
174 174 | summary: Added d
175 175 |
176 176 o changeset: 2:28ad74487de9
177 177 | user: test
178 178 | date: Thu Jan 01 00:00:00 1970 +0000
179 179 | summary: Added c
180 180 |
181 181 o changeset: 1:29becc82797a
182 182 | user: test
183 183 | date: Thu Jan 01 00:00:00 1970 +0000
184 184 | summary: Added b
185 185 |
186 186 o changeset: 0:18d04c59bb5d
187 187 user: test
188 188 date: Thu Jan 01 00:00:00 1970 +0000
189 189 summary: Added a
190 190
191 191 Testing the templates provided by remotenames extension
192 192
193 193 `remotenames` keyword
194 194
195 195 $ hg log -G -T "{rev}:{node|short} {remotenames}\n"
196 196 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
197 197 |
198 198 | o 7:ec2426147f0e $TESTTMP/server2/default default/default
199 199 | |
200 200 | o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
201 201 | |
202 202 | o 5:825660c69f0c
203 203 |/
204 204 o 4:aa98ab95a928
205 205 |
206 206 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
207 207 |
208 208 o 2:28ad74487de9
209 209 |
210 210 o 1:29becc82797a
211 211 |
212 212 o 0:18d04c59bb5d
213 213
214 214 `remotebookmarks` and `remotebranches` keywords
215 215
216 216 $ hg log -G -T "{rev}:{node|short} [{remotebookmarks}] ({remotebranches})"
217 217 @ 8:3e1487808078 [] ($TESTTMP/server2/wat default/wat)
218 218 |
219 219 | o 7:ec2426147f0e [] ($TESTTMP/server2/default default/default)
220 220 | |
221 221 | o 6:87d6d6676308 [$TESTTMP/server2/bar default/bar] ()
222 222 | |
223 223 | o 5:825660c69f0c [] ()
224 224 |/
225 225 o 4:aa98ab95a928 [] ()
226 226 |
227 227 o 3:62615734edd5 [$TESTTMP/server2/foo default/foo] ()
228 228 |
229 229 o 2:28ad74487de9 [] ()
230 230 |
231 231 o 1:29becc82797a [] ()
232 232 |
233 233 o 0:18d04c59bb5d [] ()
234 234
235 235 The `hoistednames` template keyword
236 236
237 237 $ hg log -GT "{rev}:{node|short} ({hoistednames})"
238 238 @ 8:3e1487808078 ()
239 239 |
240 240 | o 7:ec2426147f0e ()
241 241 | |
242 242 | o 6:87d6d6676308 (bar)
243 243 | |
244 244 | o 5:825660c69f0c ()
245 245 |/
246 246 o 4:aa98ab95a928 ()
247 247 |
248 248 o 3:62615734edd5 (foo)
249 249 |
250 250 o 2:28ad74487de9 ()
251 251 |
252 252 o 1:29becc82797a ()
253 253 |
254 254 o 0:18d04c59bb5d ()
255 255
256 256
257 257 Testing the revsets provided by remotenames extension
258 258
259 259 `remotenames` revset
260 260
261 261 $ hg log -r "remotenames()" -GT "{rev}:{node|short} {remotenames}\n"
262 262 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
263 263 :
264 264 : o 7:ec2426147f0e $TESTTMP/server2/default default/default
265 265 : |
266 266 : o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
267 267 :/
268 268 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
269 269 |
270 270 ~
271 271
272 272 `remotebranches` revset
273 273
274 274 $ hg log -r "remotebranches()" -GT "{rev}:{node|short} {remotenames}\n"
275 275 @ 8:3e1487808078 $TESTTMP/server2/wat default/wat
276 276 |
277 277 ~
278 278 o 7:ec2426147f0e $TESTTMP/server2/default default/default
279 279 |
280 280 ~
281 281
282 282 `remotebookmarks` revset
283 283
284 284 $ hg log -r "remotebookmarks()" -GT "{rev}:{node|short} {remotenames}\n"
285 285 o 6:87d6d6676308 $TESTTMP/server2/bar default/bar
286 286 :
287 287 o 3:62615734edd5 $TESTTMP/server2/foo default/foo
288 288 |
289 289 ~
290 290
291 291 Updating to revision using hoisted name
292 292 ---------------------------------------
293 293
294 294 Deleting local bookmark to make sure we update to hoisted name only
295 295
296 296 $ hg bookmark -d bar
297 297
298 298 $ hg up bar
299 299 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
300 300
301 301 $ hg log -r .
302 302 changeset: 6:87d6d6676308
303 303 remote bookmark: $TESTTMP/server2/bar
304 304 remote bookmark: default/bar
305 305 hoisted name: bar
306 306 user: test
307 307 date: Thu Jan 01 00:00:00 1970 +0000
308 308 summary: Added g
309 309
310 310 When both local bookmark and hoisted name exists but on different revs
311 311
312 312 $ hg up 8
313 313 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
314 314
315 315 $ hg bookmark foo
316 316 moving bookmark 'foo' forward from 62615734edd5
317 317
318 318 Local bookmark should take precedence over hoisted name
319 319
320 320 $ hg up foo
321 321 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
322 322
323 323 $ hg log -r .
324 324 changeset: 8:3e1487808078
325 325 branch: wat
326 326 bookmark: foo
327 327 tag: tip
328 328 remote branch: $TESTTMP/server2/wat
329 329 remote branch: default/wat
330 330 parent: 4:aa98ab95a928
331 331 user: test
332 332 date: Thu Jan 01 00:00:00 1970 +0000
333 333 summary: added bar
334 334
335 335 $ hg bookmarks
336 336 $TESTTMP/server2/bar 6:87d6d6676308
337 337 $TESTTMP/server2/foo 3:62615734edd5
338 338 default/bar 6:87d6d6676308
339 339 default/foo 3:62615734edd5
340 340 * foo 8:3e1487808078
341 341
342 342 Testing the remotenames sychronization during `hg push`
343 343 -------------------------------------------------------
344 344
345 345 $ cd ../server/
346 346 $ hg bookmark foo
347 347 moving bookmark 'foo' forward from 62615734edd5
348 348
349 349 After the push, default/foo should move to rev 8
350 350 $ cd ../client/
351 351 $ hg push
352 352 pushing to ssh://user@dummy/server
353 353 searching for changes
354 354 no changes found
355 355 [1]
356 356 $ hg log -Gr 'remotenames()'
357 357 @ changeset: 8:3e1487808078
358 358 : branch: wat
359 359 : bookmark: foo
360 360 : tag: tip
361 361 : remote bookmark: default/foo
362 362 : hoisted name: foo
363 363 : remote branch: $TESTTMP/server2/wat
364 364 : remote branch: default/wat
365 365 : parent: 4:aa98ab95a928
366 366 : user: test
367 367 : date: Thu Jan 01 00:00:00 1970 +0000
368 368 : summary: added bar
369 369 :
370 370 : o changeset: 7:ec2426147f0e
371 371 : | remote branch: $TESTTMP/server2/default
372 372 : | remote branch: default/default
373 373 : | user: test
374 374 : | date: Thu Jan 01 00:00:00 1970 +0000
375 375 : | summary: Added h
376 376 : |
377 377 : o changeset: 6:87d6d6676308
378 378 :/ remote bookmark: $TESTTMP/server2/bar
379 379 : remote bookmark: default/bar
380 380 : hoisted name: bar
381 381 : user: test
382 382 : date: Thu Jan 01 00:00:00 1970 +0000
383 383 : summary: Added g
384 384 :
385 385 o changeset: 3:62615734edd5
386 386 | remote bookmark: $TESTTMP/server2/foo
387 387 ~ user: test
388 388 date: Thu Jan 01 00:00:00 1970 +0000
389 389 summary: Added d
390 390
391 391 $ hg bookmarks
392 392 $TESTTMP/server2/bar 6:87d6d6676308
393 393 $TESTTMP/server2/foo 3:62615734edd5
394 394 default/bar 6:87d6d6676308
395 395 default/foo 8:3e1487808078
396 396 * foo 8:3e1487808078
397 397
398 398 Testing the names argument to remotenames, remotebranches and remotebookmarks revsets
399 399 --------------------------------------------------------------------------------------
400 400
401 401 $ cd ..
402 402 $ hg clone ssh://user@dummy/server client2
403 403 requesting all changes
404 404 adding changesets
405 405 adding manifests
406 406 adding file changes
407 407 added 9 changesets with 9 changes to 9 files (+1 heads)
408 408 new changesets 18d04c59bb5d:3e1487808078
409 409 updating to branch default
410 410 8 files updated, 0 files merged, 0 files removed, 0 files unresolved
411 411 $ cd server2
412 412 $ hg up wat
413 413 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
414 414 $ echo foo > watwat
415 415 $ hg ci -Aqm "added watwat"
416 416 $ hg bookmark bar
417 417 abort: bookmark 'bar' already exists (use -f to force)
418 418 [255]
419 419 $ hg up ec24
420 420 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
421 421 $ echo i > i
422 422 $ hg ci -Aqm "added i"
423 423
424 424 $ cd ../client2
425 425 $ echo "[paths]" >> .hg/hgrc
426 426 $ echo "server2 = $TESTTMP/server2" >> .hg/hgrc
427 427 $ hg pull server2
428 428 pulling from $TESTTMP/server2
429 429 searching for changes
430 430 adding changesets
431 431 adding manifests
432 432 adding file changes
433 433 added 2 changesets with 2 changes to 2 files
434 434 new changesets f34adec73c21:bf433e48adea
435 435 (run 'hg update' to get a working copy)
436 436
437 437 $ hg log -Gr 'remotenames()' -T '{rev}:{node|short} {desc}\n({remotebranches}) [{remotebookmarks}]\n\n'
438 438 o 10:bf433e48adea added i
439 439 | (server2/default) []
440 440 |
441 441 | o 9:f34adec73c21 added watwat
442 442 | | (server2/wat) []
443 443 | |
444 444 | o 8:3e1487808078 added bar
445 445 | : (default/wat) [default/foo]
446 446 | :
447 447 @ : 7:ec2426147f0e Added h
448 448 | : (default/default) []
449 449 | :
450 450 o : 6:87d6d6676308 Added g
451 451 :/ () [default/bar server2/bar]
452 452 :
453 453 o 3:62615734edd5 Added d
454 454 | () [server2/foo]
455 455 ~
456 456
457 457 Testing for a single remote name which exists
458 458
459 459 $ hg log -r 'remotebranches("default/wat")' -GT "{rev}:{node|short} {remotebranches}\n"
460 460 o 8:3e1487808078 default/wat
461 461 |
462 462 ~
463 463
464 464 $ hg log -r 'remotebookmarks("server2/foo")' -GT "{rev}:{node|short} {remotebookmarks}\n"
465 465 o 3:62615734edd5 server2/foo
466 466 |
467 467 ~
468 468
469 469 $ hg log -r 'remotenames("re:default")' -GT "{rev}:{node|short} {remotenames}\n"
470 470 o 10:bf433e48adea server2/default
471 471 |
472 472 | o 8:3e1487808078 default/foo default/wat
473 473 | |
474 474 | ~
475 475 @ 7:ec2426147f0e default/default
476 476 |
477 477 o 6:87d6d6676308 default/bar server2/bar
478 478 |
479 479 ~
480 480
481 481 Testing for a single name which does not exists
482 482
483 483 $ hg log -r 'remotebranches(def)' -GT "{rev}:{node|short} {remotenames}\n"
484 484
485 485 $ hg log -r 'remotebookmarks("server3")' -GT "{rev}:{node|short} {remotenames}\n"
486 486
487 487 $ hg log -r 'remotenames("server3")' -GT "{rev}:{node|short} {remotenames}\n"
488 488
489 Testing for multiple names where all of them exists
489 Testing for multiple names, which is not supported.
490 490
491 491 $ hg log -r 'remotenames("re:default", "re:server2")' -GT "{rev}:{node|short} {remotenames}\n"
492 o 10:bf433e48adea server2/default
493 |
494 | o 9:f34adec73c21 server2/wat
495 | |
496 | o 8:3e1487808078 default/foo default/wat
497 | :
498 @ : 7:ec2426147f0e default/default
499 | :
500 o : 6:87d6d6676308 default/bar server2/bar
501 :/
502 o 3:62615734edd5 server2/foo
503 |
504 ~
492 hg: parse error: only one argument accepted
493 [255]
505 494
506 495 $ hg log -r 'remotebranches("default/wat", "server2/wat")' -GT "{rev}:{node|short} {remotebranches}\n"
507 o 9:f34adec73c21 server2/wat
508 |
509 o 8:3e1487808078 default/wat
510 |
511 ~
496 hg: parse error: only one argument accepted
497 [255]
512 498
513 499 $ hg log -r 'remotebookmarks("default/foo", "server2/foo")' -GT "{rev}:{node|short} {remotebookmarks}\n"
514 o 8:3e1487808078 default/foo
515 :
516 o 3:62615734edd5 server2/foo
517 |
518 ~
519
520 Testing for multipe names where some exists and some not
521
522 $ hg log -r 'remotenames(def, "re:server2")' -GT "{rev}:{node|short} {remotenames}\n"
523 o 10:bf433e48adea server2/default
524 :
525 : o 9:f34adec73c21 server2/wat
526 : :
527 o : 6:87d6d6676308 default/bar server2/bar
528 :/
529 o 3:62615734edd5 server2/foo
530 |
531 ~
532
533 $ hg log -r 'remotebranches("default/default", server)' -GT "{rev}:{node|short} {remotebranches}\n"
534 @ 7:ec2426147f0e default/default
535 |
536 ~
537
538 $ hg log -r 'remotebookmarks("default/foo", serv)' -GT "{rev}:{node|short} {remotebookmarks}\n"
539 o 8:3e1487808078 default/foo
540 |
541 ~
542
543 Where multiple names specified and None of them exists
544
545 $ hg log -r 'remotenames(def, serv2)' -GT "{rev}:{node|short} {remotenames}\n"
546
547 $ hg log -r 'remotebranches(defu, server)' -GT "{rev}:{node|short} {remotebranches}\n"
548
549 $ hg log -r 'remotebookmarks(delt, serv)' -GT "{rev}:{node|short} {remotebookmarks}\n"
500 hg: parse error: only one argument accepted
501 [255]
550 502
551 503 Testing pattern matching
552 504
553 505 $ hg log -r 'remotenames("re:def")' -GT "{rev}:{node|short} {remotenames}\n"
554 506 o 10:bf433e48adea server2/default
555 507 |
556 508 | o 8:3e1487808078 default/foo default/wat
557 509 | |
558 510 | ~
559 511 @ 7:ec2426147f0e default/default
560 512 |
561 513 o 6:87d6d6676308 default/bar server2/bar
562 514 |
563 515 ~
564 516
565 517 $ hg log -r 'remotebranches("re:ser.*2")' -GT "{rev}:{node|short} {remotebranches}\n"
566 518 o 10:bf433e48adea server2/default
567 519 |
568 520 ~
569 521 o 9:f34adec73c21 server2/wat
570 522 |
571 523 ~
572
573 $ hg log -r 'remotebookmarks("re:def", "re:.*2")' -GT "{rev}:{node|short} {remotebookmarks}\n"
574 o 8:3e1487808078 default/foo
575 :
576 : o 6:87d6d6676308 default/bar server2/bar
577 :/
578 o 3:62615734edd5 server2/foo
579 |
580 ~
General Comments 0
You need to be logged in to leave comments. Login now