##// END OF EJS Templates
infinitepush: aggressively deprecated infinite push...
pierre-yves.david@ens-lyon.org -
r51597:68c4f8f3 default
parent child Browse files
Show More
@@ -1,1388 +1,1413 b''
1 1 # Infinite push
2 2 #
3 3 # Copyright 2016 Facebook, Inc.
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7 """ store some pushes in a remote blob store on the server (EXPERIMENTAL)
8 8
9 9 IMPORTANT: if you use this extension, please contact
10 10 mercurial-devel@mercurial-scm.org ASAP. This extension is believed to
11 11 be unused and barring learning of users of this functionality, we will
12 12 delete this code at the end of 2020.
13 13
14 14 [infinitepush]
15 15 # Server-side and client-side option. Pattern of the infinitepush bookmark
16 16 branchpattern = PATTERN
17 17
18 18 # Server or client
19 19 server = False
20 20
21 21 # Server-side option. Possible values: 'disk' or 'sql'. Fails if not set
22 22 indextype = disk
23 23
24 24 # Server-side option. Used only if indextype=sql.
25 25 # Format: 'IP:PORT:DB_NAME:USER:PASSWORD'
26 26 sqlhost = IP:PORT:DB_NAME:USER:PASSWORD
27 27
28 28 # Server-side option. Used only if indextype=disk.
29 29 # Filesystem path to the index store
30 30 indexpath = PATH
31 31
32 32 # Server-side option. Possible values: 'disk' or 'external'
33 33 # Fails if not set
34 34 storetype = disk
35 35
36 36 # Server-side option.
37 37 # Path to the binary that will save bundle to the bundlestore
38 38 # Formatted cmd line will be passed to it (see `put_args`)
39 39 put_binary = put
40 40
41 41 # Serser-side option. Used only if storetype=external.
42 42 # Format cmd-line string for put binary. Placeholder: {filename}
43 43 put_args = {filename}
44 44
45 45 # Server-side option.
46 46 # Path to the binary that get bundle from the bundlestore.
47 47 # Formatted cmd line will be passed to it (see `get_args`)
48 48 get_binary = get
49 49
50 50 # Serser-side option. Used only if storetype=external.
51 51 # Format cmd-line string for get binary. Placeholders: {filename} {handle}
52 52 get_args = {filename} {handle}
53 53
54 54 # Server-side option
55 55 logfile = FIlE
56 56
57 57 # Server-side option
58 58 loglevel = DEBUG
59 59
60 60 # Server-side option. Used only if indextype=sql.
61 61 # Sets mysql wait_timeout option.
62 62 waittimeout = 300
63 63
64 64 # Server-side option. Used only if indextype=sql.
65 65 # Sets mysql innodb_lock_wait_timeout option.
66 66 locktimeout = 120
67 67
68 68 # Server-side option. Used only if indextype=sql.
69 69 # Name of the repository
70 70 reponame = ''
71 71
72 72 # Client-side option. Used by --list-remote option. List of remote scratch
73 73 # patterns to list if no patterns are specified.
74 74 defaultremotepatterns = ['*']
75 75
76 76 # Instructs infinitepush to forward all received bundle2 parts to the
77 77 # bundle for storage. Defaults to False.
78 78 storeallparts = True
79 79
80 80 # routes each incoming push to the bundlestore. defaults to False
81 81 pushtobundlestore = True
82 82
83 83 [remotenames]
84 84 # Client-side option
85 85 # This option should be set only if remotenames extension is enabled.
86 86 # Whether remote bookmarks are tracked by remotenames extension.
87 87 bookmarks = True
88 88 """
89 89
90 90
91 91 import collections
92 92 import contextlib
93 93 import functools
94 94 import logging
95 95 import os
96 96 import random
97 97 import re
98 98 import socket
99 99 import subprocess
100 100 import time
101 101
102 102 from mercurial.node import (
103 103 bin,
104 104 hex,
105 105 )
106 106
107 107 from mercurial.i18n import _
108 108
109 109 from mercurial.pycompat import (
110 110 getattr,
111 111 open,
112 112 )
113 113
114 114 from mercurial.utils import (
115 115 procutil,
116 116 stringutil,
117 117 urlutil,
118 118 )
119 119
120 120 from mercurial import (
121 121 bundle2,
122 122 changegroup,
123 123 commands,
124 124 discovery,
125 125 encoding,
126 126 error,
127 127 exchange,
128 128 extensions,
129 129 hg,
130 130 localrepo,
131 131 phases,
132 132 pushkey,
133 133 pycompat,
134 134 registrar,
135 135 util,
136 136 wireprototypes,
137 137 wireprotov1peer,
138 138 wireprotov1server,
139 139 )
140 140
141 141 from . import (
142 142 bundleparts,
143 143 common,
144 144 )
145 145
146 146 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
147 147 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
148 148 # be specifying the version(s) of Mercurial they are tested with, or
149 149 # leave the attribute unspecified.
150 150 testedwith = b'ships-with-hg-core'
151 151
152 152 configtable = {}
153 153 configitem = registrar.configitem(configtable)
154 154
155 155 configitem(
156 156 b'infinitepush',
157 b'deprecation-message',
158 default=True,
159 )
160
161 configitem(
162 b'infinitepush',
163 b'deprecation-abort',
164 default=True,
165 )
166
167 configitem(
168 b'infinitepush',
157 169 b'server',
158 170 default=False,
159 171 )
160 172 configitem(
161 173 b'infinitepush',
162 174 b'storetype',
163 175 default=b'',
164 176 )
165 177 configitem(
166 178 b'infinitepush',
167 179 b'indextype',
168 180 default=b'',
169 181 )
170 182 configitem(
171 183 b'infinitepush',
172 184 b'indexpath',
173 185 default=b'',
174 186 )
175 187 configitem(
176 188 b'infinitepush',
177 189 b'storeallparts',
178 190 default=False,
179 191 )
180 192 configitem(
181 193 b'infinitepush',
182 194 b'reponame',
183 195 default=b'',
184 196 )
185 197 configitem(
186 198 b'scratchbranch',
187 199 b'storepath',
188 200 default=b'',
189 201 )
190 202 configitem(
191 203 b'infinitepush',
192 204 b'branchpattern',
193 205 default=b'',
194 206 )
195 207 configitem(
196 208 b'infinitepush',
197 209 b'pushtobundlestore',
198 210 default=False,
199 211 )
200 212 configitem(
201 213 b'experimental',
202 214 b'server-bundlestore-bookmark',
203 215 default=b'',
204 216 )
205 217 configitem(
206 218 b'experimental',
207 219 b'infinitepush-scratchpush',
208 220 default=False,
209 221 )
210 222
211 223 experimental = b'experimental'
212 224 configbookmark = b'server-bundlestore-bookmark'
213 225 configscratchpush = b'infinitepush-scratchpush'
214 226
215 227 scratchbranchparttype = bundleparts.scratchbranchparttype
216 228 revsetpredicate = registrar.revsetpredicate()
217 229 templatekeyword = registrar.templatekeyword()
218 230 _scratchbranchmatcher = lambda x: False
219 231 _maybehash = re.compile('^[a-f0-9]+$').search
220 232
221 233
222 234 def _buildexternalbundlestore(ui):
223 235 put_args = ui.configlist(b'infinitepush', b'put_args', [])
224 236 put_binary = ui.config(b'infinitepush', b'put_binary')
225 237 if not put_binary:
226 238 raise error.Abort(b'put binary is not specified')
227 239 get_args = ui.configlist(b'infinitepush', b'get_args', [])
228 240 get_binary = ui.config(b'infinitepush', b'get_binary')
229 241 if not get_binary:
230 242 raise error.Abort(b'get binary is not specified')
231 243 from . import store
232 244
233 245 return store.externalbundlestore(put_binary, put_args, get_binary, get_args)
234 246
235 247
236 248 def _buildsqlindex(ui):
237 249 sqlhost = ui.config(b'infinitepush', b'sqlhost')
238 250 if not sqlhost:
239 251 raise error.Abort(_(b'please set infinitepush.sqlhost'))
240 252 host, port, db, user, password = sqlhost.split(b':')
241 253 reponame = ui.config(b'infinitepush', b'reponame')
242 254 if not reponame:
243 255 raise error.Abort(_(b'please set infinitepush.reponame'))
244 256
245 257 logfile = ui.config(b'infinitepush', b'logfile', b'')
246 258 waittimeout = ui.configint(b'infinitepush', b'waittimeout', 300)
247 259 locktimeout = ui.configint(b'infinitepush', b'locktimeout', 120)
248 260 from . import sqlindexapi
249 261
250 262 return sqlindexapi.sqlindexapi(
251 263 reponame,
252 264 host,
253 265 port,
254 266 db,
255 267 user,
256 268 password,
257 269 logfile,
258 270 _getloglevel(ui),
259 271 waittimeout=waittimeout,
260 272 locktimeout=locktimeout,
261 273 )
262 274
263 275
264 276 def _getloglevel(ui):
265 277 loglevel = ui.config(b'infinitepush', b'loglevel', b'DEBUG')
266 278 numeric_loglevel = getattr(logging, loglevel.upper(), None)
267 279 if not isinstance(numeric_loglevel, int):
268 280 raise error.Abort(_(b'invalid log level %s') % loglevel)
269 281 return numeric_loglevel
270 282
271 283
272 284 def _tryhoist(ui, remotebookmark):
273 285 """returns a bookmarks with hoisted part removed
274 286
275 287 Remotenames extension has a 'hoist' config that allows to use remote
276 288 bookmarks without specifying remote path. For example, 'hg update master'
277 289 works as well as 'hg update remote/master'. We want to allow the same in
278 290 infinitepush.
279 291 """
280 292
281 293 if common.isremotebooksenabled(ui):
282 294 hoist = ui.config(b'remotenames', b'hoistedpeer') + b'/'
283 295 if remotebookmark.startswith(hoist):
284 296 return remotebookmark[len(hoist) :]
285 297 return remotebookmark
286 298
287 299
288 300 class bundlestore:
289 301 def __init__(self, repo):
290 302 self._repo = repo
291 303 storetype = self._repo.ui.config(b'infinitepush', b'storetype')
292 304 if storetype == b'disk':
293 305 from . import store
294 306
295 307 self.store = store.filebundlestore(self._repo.ui, self._repo)
296 308 elif storetype == b'external':
297 309 self.store = _buildexternalbundlestore(self._repo.ui)
298 310 else:
299 311 raise error.Abort(
300 312 _(b'unknown infinitepush store type specified %s') % storetype
301 313 )
302 314
303 315 indextype = self._repo.ui.config(b'infinitepush', b'indextype')
304 316 if indextype == b'disk':
305 317 from . import fileindexapi
306 318
307 319 self.index = fileindexapi.fileindexapi(self._repo)
308 320 elif indextype == b'sql':
309 321 self.index = _buildsqlindex(self._repo.ui)
310 322 else:
311 323 raise error.Abort(
312 324 _(b'unknown infinitepush index type specified %s') % indextype
313 325 )
314 326
315 327
316 328 def _isserver(ui):
317 329 return ui.configbool(b'infinitepush', b'server')
318 330
319 331
332 WARNING_MSG = b"""IMPORTANT: if you use this extension, please contact
333 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
334 unused and barring learning of users of this functionality, we drop this
335 extension in Mercurial 6.6.
336 """
337
338
320 339 def reposetup(ui, repo):
340 if ui.configbool(b'infinitepush', b'deprecation-message'):
341 ui.write_err(WARNING_MSG)
342 if ui.configbool(b'infinitepush', b'deprecation-abort'):
343 msg = b"USING EXTENSION INFINITE PUSH DESPITE PENDING DROP"
344 hint = b"contact mercurial-devel@mercurial-scm.org"
345 raise error.Abort(msg, hint=hint)
321 346 if _isserver(ui) and repo.local():
322 347 repo.bundlestore = bundlestore(repo)
323 348
324 349
325 350 def extsetup(ui):
326 351 commonsetup(ui)
327 352 if _isserver(ui):
328 353 serverextsetup(ui)
329 354 else:
330 355 clientextsetup(ui)
331 356
332 357
333 358 def uipopulate(ui):
334 359 if not ui.hasconfig(b"experimental", b"changegroup3"):
335 360 ui.setconfig(b"experimental", b"changegroup3", False, b"infinitepush")
336 361
337 362
338 363 def commonsetup(ui):
339 364 wireprotov1server.commands[b'listkeyspatterns'] = (
340 365 wireprotolistkeyspatterns,
341 366 b'namespace patterns',
342 367 )
343 368 scratchbranchpat = ui.config(b'infinitepush', b'branchpattern')
344 369 if scratchbranchpat:
345 370 global _scratchbranchmatcher
346 371 kind, pat, _scratchbranchmatcher = stringutil.stringmatcher(
347 372 scratchbranchpat
348 373 )
349 374
350 375
351 376 def serverextsetup(ui):
352 377 origpushkeyhandler = bundle2.parthandlermapping[b'pushkey']
353 378
354 379 def newpushkeyhandler(*args, **kwargs):
355 380 bundle2pushkey(origpushkeyhandler, *args, **kwargs)
356 381
357 382 newpushkeyhandler.params = origpushkeyhandler.params
358 383 bundle2.parthandlermapping[b'pushkey'] = newpushkeyhandler
359 384
360 385 orighandlephasehandler = bundle2.parthandlermapping[b'phase-heads']
361 386 newphaseheadshandler = lambda *args, **kwargs: bundle2handlephases(
362 387 orighandlephasehandler, *args, **kwargs
363 388 )
364 389 newphaseheadshandler.params = orighandlephasehandler.params
365 390 bundle2.parthandlermapping[b'phase-heads'] = newphaseheadshandler
366 391
367 392 extensions.wrapfunction(
368 393 localrepo.localrepository, b'listkeys', localrepolistkeys
369 394 )
370 395 wireprotov1server.commands[b'lookup'] = (
371 396 _lookupwrap(wireprotov1server.commands[b'lookup'][0]),
372 397 b'key',
373 398 )
374 399 extensions.wrapfunction(exchange, b'getbundlechunks', getbundlechunks)
375 400
376 401 extensions.wrapfunction(bundle2, b'processparts', processparts)
377 402
378 403
379 404 def clientextsetup(ui):
380 405 entry = extensions.wrapcommand(commands.table, b'push', _push)
381 406
382 407 entry[1].append(
383 408 (
384 409 b'',
385 410 b'bundle-store',
386 411 None,
387 412 _(b'force push to go to bundle store (EXPERIMENTAL)'),
388 413 )
389 414 )
390 415
391 416 extensions.wrapcommand(commands.table, b'pull', _pull)
392 417
393 418 extensions.wrapfunction(discovery, b'checkheads', _checkheads)
394 419
395 420 wireprotov1peer.wirepeer.listkeyspatterns = listkeyspatterns
396 421
397 422 partorder = exchange.b2partsgenorder
398 423 index = partorder.index(b'changeset')
399 424 partorder.insert(
400 425 index, partorder.pop(partorder.index(scratchbranchparttype))
401 426 )
402 427
403 428
404 429 def _checkheads(orig, pushop):
405 430 if pushop.ui.configbool(experimental, configscratchpush, False):
406 431 return
407 432 return orig(pushop)
408 433
409 434
410 435 def wireprotolistkeyspatterns(repo, proto, namespace, patterns):
411 436 patterns = wireprototypes.decodelist(patterns)
412 437 d = repo.listkeys(encoding.tolocal(namespace), patterns).items()
413 438 return pushkey.encodekeys(d)
414 439
415 440
416 441 def localrepolistkeys(orig, self, namespace, patterns=None):
417 442 if namespace == b'bookmarks' and patterns:
418 443 index = self.bundlestore.index
419 444 results = {}
420 445 bookmarks = orig(self, namespace)
421 446 for pattern in patterns:
422 447 results.update(index.getbookmarks(pattern))
423 448 if pattern.endswith(b'*'):
424 449 pattern = b're:^' + pattern[:-1] + b'.*'
425 450 kind, pat, matcher = stringutil.stringmatcher(pattern)
426 451 for bookmark, node in bookmarks.items():
427 452 if matcher(bookmark):
428 453 results[bookmark] = node
429 454 return results
430 455 else:
431 456 return orig(self, namespace)
432 457
433 458
434 459 @wireprotov1peer.batchable
435 460 def listkeyspatterns(self, namespace, patterns):
436 461 if not self.capable(b'pushkey'):
437 462 return {}, None
438 463 self.ui.debug(b'preparing listkeys for "%s"\n' % namespace)
439 464
440 465 def decode(d):
441 466 self.ui.debug(
442 467 b'received listkey for "%s": %i bytes\n' % (namespace, len(d))
443 468 )
444 469 return pushkey.decodekeys(d)
445 470
446 471 return {
447 472 b'namespace': encoding.fromlocal(namespace),
448 473 b'patterns': wireprototypes.encodelist(patterns),
449 474 }, decode
450 475
451 476
452 477 def _readbundlerevs(bundlerepo):
453 478 return list(bundlerepo.revs(b'bundle()'))
454 479
455 480
456 481 def _includefilelogstobundle(bundlecaps, bundlerepo, bundlerevs, ui):
457 482 """Tells remotefilelog to include all changed files to the changegroup
458 483
459 484 By default remotefilelog doesn't include file content to the changegroup.
460 485 But we need to include it if we are fetching from bundlestore.
461 486 """
462 487 changedfiles = set()
463 488 cl = bundlerepo.changelog
464 489 for r in bundlerevs:
465 490 # [3] means changed files
466 491 changedfiles.update(cl.read(r)[3])
467 492 if not changedfiles:
468 493 return bundlecaps
469 494
470 495 changedfiles = b'\0'.join(changedfiles)
471 496 newcaps = []
472 497 appended = False
473 498 for cap in bundlecaps or []:
474 499 if cap.startswith(b'excludepattern='):
475 500 newcaps.append(b'\0'.join((cap, changedfiles)))
476 501 appended = True
477 502 else:
478 503 newcaps.append(cap)
479 504 if not appended:
480 505 # Not found excludepattern cap. Just append it
481 506 newcaps.append(b'excludepattern=' + changedfiles)
482 507
483 508 return newcaps
484 509
485 510
486 511 def _rebundle(bundlerepo, bundleroots, unknownhead):
487 512 """
488 513 Bundle may include more revision then user requested. For example,
489 514 if user asks for revision but bundle also consists its descendants.
490 515 This function will filter out all revision that user is not requested.
491 516 """
492 517 parts = []
493 518
494 519 version = b'02'
495 520 outgoing = discovery.outgoing(
496 521 bundlerepo, commonheads=bundleroots, ancestorsof=[unknownhead]
497 522 )
498 523 cgstream = changegroup.makestream(bundlerepo, outgoing, version, b'pull')
499 524 cgstream = util.chunkbuffer(cgstream).read()
500 525 cgpart = bundle2.bundlepart(b'changegroup', data=cgstream)
501 526 cgpart.addparam(b'version', version)
502 527 parts.append(cgpart)
503 528
504 529 return parts
505 530
506 531
507 532 def _getbundleroots(oldrepo, bundlerepo, bundlerevs):
508 533 cl = bundlerepo.changelog
509 534 bundleroots = []
510 535 for rev in bundlerevs:
511 536 node = cl.node(rev)
512 537 parents = cl.parents(node)
513 538 for parent in parents:
514 539 # include all revs that exist in the main repo
515 540 # to make sure that bundle may apply client-side
516 541 if parent in oldrepo:
517 542 bundleroots.append(parent)
518 543 return bundleroots
519 544
520 545
521 546 def _needsrebundling(head, bundlerepo):
522 547 bundleheads = list(bundlerepo.revs(b'heads(bundle())'))
523 548 return not (
524 549 len(bundleheads) == 1 and bundlerepo[bundleheads[0]].node() == head
525 550 )
526 551
527 552
528 553 def _generateoutputparts(head, bundlerepo, bundleroots, bundlefile):
529 554 """generates bundle that will be send to the user
530 555
531 556 returns tuple with raw bundle string and bundle type
532 557 """
533 558 parts = []
534 559 if not _needsrebundling(head, bundlerepo):
535 560 with util.posixfile(bundlefile, b"rb") as f:
536 561 unbundler = exchange.readbundle(bundlerepo.ui, f, bundlefile)
537 562 if isinstance(unbundler, changegroup.cg1unpacker):
538 563 part = bundle2.bundlepart(
539 564 b'changegroup', data=unbundler._stream.read()
540 565 )
541 566 part.addparam(b'version', b'01')
542 567 parts.append(part)
543 568 elif isinstance(unbundler, bundle2.unbundle20):
544 569 haschangegroup = False
545 570 for part in unbundler.iterparts():
546 571 if part.type == b'changegroup':
547 572 haschangegroup = True
548 573 newpart = bundle2.bundlepart(part.type, data=part.read())
549 574 for key, value in part.params.items():
550 575 newpart.addparam(key, value)
551 576 parts.append(newpart)
552 577
553 578 if not haschangegroup:
554 579 raise error.Abort(
555 580 b'unexpected bundle without changegroup part, '
556 581 + b'head: %s' % hex(head),
557 582 hint=b'report to administrator',
558 583 )
559 584 else:
560 585 raise error.Abort(b'unknown bundle type')
561 586 else:
562 587 parts = _rebundle(bundlerepo, bundleroots, head)
563 588
564 589 return parts
565 590
566 591
567 592 def getbundlechunks(orig, repo, source, heads=None, bundlecaps=None, **kwargs):
568 593 heads = heads or []
569 594 # newheads are parents of roots of scratch bundles that were requested
570 595 newphases = {}
571 596 scratchbundles = []
572 597 newheads = []
573 598 scratchheads = []
574 599 nodestobundle = {}
575 600 allbundlestocleanup = []
576 601 try:
577 602 for head in heads:
578 603 if not repo.changelog.index.has_node(head):
579 604 if head not in nodestobundle:
580 605 newbundlefile = common.downloadbundle(repo, head)
581 606 bundlepath = b"bundle:%s+%s" % (repo.root, newbundlefile)
582 607 bundlerepo = hg.repository(repo.ui, bundlepath)
583 608
584 609 allbundlestocleanup.append((bundlerepo, newbundlefile))
585 610 bundlerevs = set(_readbundlerevs(bundlerepo))
586 611 bundlecaps = _includefilelogstobundle(
587 612 bundlecaps, bundlerepo, bundlerevs, repo.ui
588 613 )
589 614 cl = bundlerepo.changelog
590 615 bundleroots = _getbundleroots(repo, bundlerepo, bundlerevs)
591 616 for rev in bundlerevs:
592 617 node = cl.node(rev)
593 618 newphases[hex(node)] = str(phases.draft)
594 619 nodestobundle[node] = (
595 620 bundlerepo,
596 621 bundleroots,
597 622 newbundlefile,
598 623 )
599 624
600 625 scratchbundles.append(
601 626 _generateoutputparts(head, *nodestobundle[head])
602 627 )
603 628 newheads.extend(bundleroots)
604 629 scratchheads.append(head)
605 630 finally:
606 631 for bundlerepo, bundlefile in allbundlestocleanup:
607 632 bundlerepo.close()
608 633 try:
609 634 os.unlink(bundlefile)
610 635 except (IOError, OSError):
611 636 # if we can't cleanup the file then just ignore the error,
612 637 # no need to fail
613 638 pass
614 639
615 640 pullfrombundlestore = bool(scratchbundles)
616 641 wrappedchangegrouppart = False
617 642 wrappedlistkeys = False
618 643 oldchangegrouppart = exchange.getbundle2partsmapping[b'changegroup']
619 644 try:
620 645
621 646 def _changegrouppart(bundler, *args, **kwargs):
622 647 # Order is important here. First add non-scratch part
623 648 # and only then add parts with scratch bundles because
624 649 # non-scratch part contains parents of roots of scratch bundles.
625 650 result = oldchangegrouppart(bundler, *args, **kwargs)
626 651 for bundle in scratchbundles:
627 652 for part in bundle:
628 653 bundler.addpart(part)
629 654 return result
630 655
631 656 exchange.getbundle2partsmapping[b'changegroup'] = _changegrouppart
632 657 wrappedchangegrouppart = True
633 658
634 659 def _listkeys(orig, self, namespace):
635 660 origvalues = orig(self, namespace)
636 661 if namespace == b'phases' and pullfrombundlestore:
637 662 if origvalues.get(b'publishing') == b'True':
638 663 # Make repo non-publishing to preserve draft phase
639 664 del origvalues[b'publishing']
640 665 origvalues.update(newphases)
641 666 return origvalues
642 667
643 668 extensions.wrapfunction(
644 669 localrepo.localrepository, b'listkeys', _listkeys
645 670 )
646 671 wrappedlistkeys = True
647 672 heads = list((set(newheads) | set(heads)) - set(scratchheads))
648 673 result = orig(
649 674 repo, source, heads=heads, bundlecaps=bundlecaps, **kwargs
650 675 )
651 676 finally:
652 677 if wrappedchangegrouppart:
653 678 exchange.getbundle2partsmapping[b'changegroup'] = oldchangegrouppart
654 679 if wrappedlistkeys:
655 680 extensions.unwrapfunction(
656 681 localrepo.localrepository, b'listkeys', _listkeys
657 682 )
658 683 return result
659 684
660 685
661 686 def _lookupwrap(orig):
662 687 def _lookup(repo, proto, key):
663 688 localkey = encoding.tolocal(key)
664 689
665 690 if isinstance(localkey, str) and _scratchbranchmatcher(localkey):
666 691 scratchnode = repo.bundlestore.index.getnode(localkey)
667 692 if scratchnode:
668 693 return b"%d %s\n" % (1, scratchnode)
669 694 else:
670 695 return b"%d %s\n" % (
671 696 0,
672 697 b'scratch branch %s not found' % localkey,
673 698 )
674 699 else:
675 700 try:
676 701 r = hex(repo.lookup(localkey))
677 702 return b"%d %s\n" % (1, r)
678 703 except Exception as inst:
679 704 if repo.bundlestore.index.getbundle(localkey):
680 705 return b"%d %s\n" % (1, localkey)
681 706 else:
682 707 r = stringutil.forcebytestr(inst)
683 708 return b"%d %s\n" % (0, r)
684 709
685 710 return _lookup
686 711
687 712
688 713 def _pull(orig, ui, repo, source=b"default", **opts):
689 714 opts = pycompat.byteskwargs(opts)
690 715 # Copy paste from `pull` command
691 716 path = urlutil.get_unique_pull_path_obj(
692 717 b"infinite-push's pull",
693 718 ui,
694 719 source,
695 720 )
696 721
697 722 scratchbookmarks = {}
698 723 unfi = repo.unfiltered()
699 724 unknownnodes = []
700 725 for rev in opts.get(b'rev', []):
701 726 if rev not in unfi:
702 727 unknownnodes.append(rev)
703 728 if opts.get(b'bookmark'):
704 729 bookmarks = []
705 730 revs = opts.get(b'rev') or []
706 731 for bookmark in opts.get(b'bookmark'):
707 732 if _scratchbranchmatcher(bookmark):
708 733 # rev is not known yet
709 734 # it will be fetched with listkeyspatterns next
710 735 scratchbookmarks[bookmark] = b'REVTOFETCH'
711 736 else:
712 737 bookmarks.append(bookmark)
713 738
714 739 if scratchbookmarks:
715 740 other = hg.peer(repo, opts, path)
716 741 try:
717 742 fetchedbookmarks = other.listkeyspatterns(
718 743 b'bookmarks', patterns=scratchbookmarks
719 744 )
720 745 for bookmark in scratchbookmarks:
721 746 if bookmark not in fetchedbookmarks:
722 747 raise error.Abort(
723 748 b'remote bookmark %s not found!' % bookmark
724 749 )
725 750 scratchbookmarks[bookmark] = fetchedbookmarks[bookmark]
726 751 revs.append(fetchedbookmarks[bookmark])
727 752 finally:
728 753 other.close()
729 754 opts[b'bookmark'] = bookmarks
730 755 opts[b'rev'] = revs
731 756
732 757 if scratchbookmarks or unknownnodes:
733 758 # Set anyincoming to True
734 759 extensions.wrapfunction(
735 760 discovery, b'findcommonincoming', _findcommonincoming
736 761 )
737 762 try:
738 763 # Remote scratch bookmarks will be deleted because remotenames doesn't
739 764 # know about them. Let's save it before pull and restore after
740 765 remotescratchbookmarks = _readscratchremotebookmarks(ui, repo, path.loc)
741 766 result = orig(ui, repo, path.loc, **pycompat.strkwargs(opts))
742 767 # TODO(stash): race condition is possible
743 768 # if scratch bookmarks was updated right after orig.
744 769 # But that's unlikely and shouldn't be harmful.
745 770 if common.isremotebooksenabled(ui):
746 771 remotescratchbookmarks.update(scratchbookmarks)
747 772 _saveremotebookmarks(repo, remotescratchbookmarks, path.loc)
748 773 else:
749 774 _savelocalbookmarks(repo, scratchbookmarks)
750 775 return result
751 776 finally:
752 777 if scratchbookmarks:
753 778 extensions.unwrapfunction(discovery, b'findcommonincoming')
754 779
755 780
756 781 def _readscratchremotebookmarks(ui, repo, other):
757 782 if common.isremotebooksenabled(ui):
758 783 remotenamesext = extensions.find(b'remotenames')
759 784 remotepath = remotenamesext.activepath(repo.ui, other)
760 785 result = {}
761 786 # Let's refresh remotenames to make sure we have it up to date
762 787 # Seems that `repo.names['remotebookmarks']` may return stale bookmarks
763 788 # and it results in deleting scratch bookmarks. Our best guess how to
764 789 # fix it is to use `clearnames()`
765 790 repo._remotenames.clearnames()
766 791 for remotebookmark in repo.names[b'remotebookmarks'].listnames(repo):
767 792 path, bookname = remotenamesext.splitremotename(remotebookmark)
768 793 if path == remotepath and _scratchbranchmatcher(bookname):
769 794 nodes = repo.names[b'remotebookmarks'].nodes(
770 795 repo, remotebookmark
771 796 )
772 797 if nodes:
773 798 result[bookname] = hex(nodes[0])
774 799 return result
775 800 else:
776 801 return {}
777 802
778 803
779 804 def _saveremotebookmarks(repo, newbookmarks, remote):
780 805 remotenamesext = extensions.find(b'remotenames')
781 806 remotepath = remotenamesext.activepath(repo.ui, remote)
782 807 branches = collections.defaultdict(list)
783 808 bookmarks = {}
784 809 remotenames = remotenamesext.readremotenames(repo)
785 810 for hexnode, nametype, remote, rname in remotenames:
786 811 if remote != remotepath:
787 812 continue
788 813 if nametype == b'bookmarks':
789 814 if rname in newbookmarks:
790 815 # It's possible if we have a normal bookmark that matches
791 816 # scratch branch pattern. In this case just use the current
792 817 # bookmark node
793 818 del newbookmarks[rname]
794 819 bookmarks[rname] = hexnode
795 820 elif nametype == b'branches':
796 821 # saveremotenames expects 20 byte binary nodes for branches
797 822 branches[rname].append(bin(hexnode))
798 823
799 824 for bookmark, hexnode in newbookmarks.items():
800 825 bookmarks[bookmark] = hexnode
801 826 remotenamesext.saveremotenames(repo, remotepath, branches, bookmarks)
802 827
803 828
804 829 def _savelocalbookmarks(repo, bookmarks):
805 830 if not bookmarks:
806 831 return
807 832 with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
808 833 changes = []
809 834 for scratchbook, node in bookmarks.items():
810 835 changectx = repo[node]
811 836 changes.append((scratchbook, changectx.node()))
812 837 repo._bookmarks.applychanges(repo, tr, changes)
813 838
814 839
815 840 def _findcommonincoming(orig, *args, **kwargs):
816 841 common, inc, remoteheads = orig(*args, **kwargs)
817 842 return common, True, remoteheads
818 843
819 844
820 845 def _push(orig, ui, repo, *dests, **opts):
821 846 opts = pycompat.byteskwargs(opts)
822 847 bookmark = opts.get(b'bookmark')
823 848 # we only support pushing one infinitepush bookmark at once
824 849 if len(bookmark) == 1:
825 850 bookmark = bookmark[0]
826 851 else:
827 852 bookmark = b''
828 853
829 854 oldphasemove = None
830 855 overrides = {(experimental, configbookmark): bookmark}
831 856
832 857 with ui.configoverride(overrides, b'infinitepush'):
833 858 scratchpush = opts.get(b'bundle_store')
834 859 if _scratchbranchmatcher(bookmark):
835 860 scratchpush = True
836 861 # bundle2 can be sent back after push (for example, bundle2
837 862 # containing `pushkey` part to update bookmarks)
838 863 ui.setconfig(experimental, b'bundle2.pushback', True)
839 864
840 865 if scratchpush:
841 866 # this is an infinitepush, we don't want the bookmark to be applied
842 867 # rather that should be stored in the bundlestore
843 868 opts[b'bookmark'] = []
844 869 ui.setconfig(experimental, configscratchpush, True)
845 870 oldphasemove = extensions.wrapfunction(
846 871 exchange, b'_localphasemove', _phasemove
847 872 )
848 873
849 874 paths = list(urlutil.get_push_paths(repo, ui, dests))
850 875 if len(paths) > 1:
851 876 msg = _(b'cannot push to multiple path with infinitepush')
852 877 raise error.Abort(msg)
853 878
854 879 path = paths[0]
855 880 destpath = path.loc
856 881 # Remote scratch bookmarks will be deleted because remotenames doesn't
857 882 # know about them. Let's save it before push and restore after
858 883 remotescratchbookmarks = _readscratchremotebookmarks(ui, repo, destpath)
859 884 result = orig(ui, repo, *dests, **pycompat.strkwargs(opts))
860 885 if common.isremotebooksenabled(ui):
861 886 if bookmark and scratchpush:
862 887 other = hg.peer(repo, opts, path)
863 888 try:
864 889 fetchedbookmarks = other.listkeyspatterns(
865 890 b'bookmarks', patterns=[bookmark]
866 891 )
867 892 remotescratchbookmarks.update(fetchedbookmarks)
868 893 finally:
869 894 other.close()
870 895 _saveremotebookmarks(repo, remotescratchbookmarks, destpath)
871 896 if oldphasemove:
872 897 exchange._localphasemove = oldphasemove
873 898 return result
874 899
875 900
876 901 def _deleteinfinitepushbookmarks(ui, repo, path, names):
877 902 """Prune remote names by removing the bookmarks we don't want anymore,
878 903 then writing the result back to disk
879 904 """
880 905 remotenamesext = extensions.find(b'remotenames')
881 906
882 907 # remotename format is:
883 908 # (node, nametype ("branches" or "bookmarks"), remote, name)
884 909 nametype_idx = 1
885 910 remote_idx = 2
886 911 name_idx = 3
887 912 remotenames = [
888 913 remotename
889 914 for remotename in remotenamesext.readremotenames(repo)
890 915 if remotename[remote_idx] == path
891 916 ]
892 917 remote_bm_names = [
893 918 remotename[name_idx]
894 919 for remotename in remotenames
895 920 if remotename[nametype_idx] == b"bookmarks"
896 921 ]
897 922
898 923 for name in names:
899 924 if name not in remote_bm_names:
900 925 raise error.Abort(
901 926 _(
902 927 b"infinitepush bookmark '{}' does not exist "
903 928 b"in path '{}'"
904 929 ).format(name, path)
905 930 )
906 931
907 932 bookmarks = {}
908 933 branches = collections.defaultdict(list)
909 934 for node, nametype, remote, name in remotenames:
910 935 if nametype == b"bookmarks" and name not in names:
911 936 bookmarks[name] = node
912 937 elif nametype == b"branches":
913 938 # saveremotenames wants binary nodes for branches
914 939 branches[name].append(bin(node))
915 940
916 941 remotenamesext.saveremotenames(repo, path, branches, bookmarks)
917 942
918 943
919 944 def _phasemove(orig, pushop, nodes, phase=phases.public):
920 945 """prevent commits from being marked public
921 946
922 947 Since these are going to a scratch branch, they aren't really being
923 948 published."""
924 949
925 950 if phase != phases.public:
926 951 orig(pushop, nodes, phase)
927 952
928 953
929 954 @exchange.b2partsgenerator(scratchbranchparttype)
930 955 def partgen(pushop, bundler):
931 956 bookmark = pushop.ui.config(experimental, configbookmark)
932 957 scratchpush = pushop.ui.configbool(experimental, configscratchpush)
933 958 if b'changesets' in pushop.stepsdone or not scratchpush:
934 959 return
935 960
936 961 if scratchbranchparttype not in bundle2.bundle2caps(pushop.remote):
937 962 return
938 963
939 964 pushop.stepsdone.add(b'changesets')
940 965 if not pushop.outgoing.missing:
941 966 pushop.ui.status(_(b'no changes found\n'))
942 967 pushop.cgresult = 0
943 968 return
944 969
945 970 # This parameter tells the server that the following bundle is an
946 971 # infinitepush. This let's it switch the part processing to our infinitepush
947 972 # code path.
948 973 bundler.addparam(b"infinitepush", b"True")
949 974
950 975 scratchparts = bundleparts.getscratchbranchparts(
951 976 pushop.repo, pushop.remote, pushop.outgoing, pushop.ui, bookmark
952 977 )
953 978
954 979 for scratchpart in scratchparts:
955 980 bundler.addpart(scratchpart)
956 981
957 982 def handlereply(op):
958 983 # server either succeeds or aborts; no code to read
959 984 pushop.cgresult = 1
960 985
961 986 return handlereply
962 987
963 988
964 989 bundle2.capabilities[bundleparts.scratchbranchparttype] = ()
965 990
966 991
967 992 def _getrevs(bundle, oldnode, force, bookmark):
968 993 b'extracts and validates the revs to be imported'
969 994 revs = [bundle[r] for r in bundle.revs(b'sort(bundle())')]
970 995
971 996 # new bookmark
972 997 if oldnode is None:
973 998 return revs
974 999
975 1000 # Fast forward update
976 1001 if oldnode in bundle and list(bundle.set(b'bundle() & %s::', oldnode)):
977 1002 return revs
978 1003
979 1004 return revs
980 1005
981 1006
982 1007 @contextlib.contextmanager
983 1008 def logservicecall(logger, service, **kwargs):
984 1009 start = time.time()
985 1010 logger(service, eventtype=b'start', **kwargs)
986 1011 try:
987 1012 yield
988 1013 logger(
989 1014 service,
990 1015 eventtype=b'success',
991 1016 elapsedms=(time.time() - start) * 1000,
992 1017 **kwargs
993 1018 )
994 1019 except Exception as e:
995 1020 logger(
996 1021 service,
997 1022 eventtype=b'failure',
998 1023 elapsedms=(time.time() - start) * 1000,
999 1024 errormsg=stringutil.forcebytestr(e),
1000 1025 **kwargs
1001 1026 )
1002 1027 raise
1003 1028
1004 1029
1005 1030 def _getorcreateinfinitepushlogger(op):
1006 1031 logger = op.records[b'infinitepushlogger']
1007 1032 if not logger:
1008 1033 ui = op.repo.ui
1009 1034 try:
1010 1035 username = procutil.getuser()
1011 1036 except Exception:
1012 1037 username = b'unknown'
1013 1038 # Generate random request id to be able to find all logged entries
1014 1039 # for the same request. Since requestid is pseudo-generated it may
1015 1040 # not be unique, but we assume that (hostname, username, requestid)
1016 1041 # is unique.
1017 1042 random.seed()
1018 1043 requestid = random.randint(0, 2000000000)
1019 1044 hostname = socket.gethostname()
1020 1045 logger = functools.partial(
1021 1046 ui.log,
1022 1047 b'infinitepush',
1023 1048 user=username,
1024 1049 requestid=requestid,
1025 1050 hostname=hostname,
1026 1051 reponame=ui.config(b'infinitepush', b'reponame'),
1027 1052 )
1028 1053 op.records.add(b'infinitepushlogger', logger)
1029 1054 else:
1030 1055 logger = logger[0]
1031 1056 return logger
1032 1057
1033 1058
1034 1059 def storetobundlestore(orig, repo, op, unbundler):
1035 1060 """stores the incoming bundle coming from push command to the bundlestore
1036 1061 instead of applying on the revlogs"""
1037 1062
1038 1063 repo.ui.status(_(b"storing changesets on the bundlestore\n"))
1039 1064 bundler = bundle2.bundle20(repo.ui)
1040 1065
1041 1066 # processing each part and storing it in bundler
1042 1067 with bundle2.partiterator(repo, op, unbundler) as parts:
1043 1068 for part in parts:
1044 1069 bundlepart = None
1045 1070 if part.type == b'replycaps':
1046 1071 # This configures the current operation to allow reply parts.
1047 1072 bundle2._processpart(op, part)
1048 1073 else:
1049 1074 bundlepart = bundle2.bundlepart(part.type, data=part.read())
1050 1075 for key, value in part.params.items():
1051 1076 bundlepart.addparam(key, value)
1052 1077
1053 1078 # Certain parts require a response
1054 1079 if part.type in (b'pushkey', b'changegroup'):
1055 1080 if op.reply is not None:
1056 1081 rpart = op.reply.newpart(b'reply:%s' % part.type)
1057 1082 rpart.addparam(
1058 1083 b'in-reply-to', b'%d' % part.id, mandatory=False
1059 1084 )
1060 1085 rpart.addparam(b'return', b'1', mandatory=False)
1061 1086
1062 1087 op.records.add(
1063 1088 part.type,
1064 1089 {
1065 1090 b'return': 1,
1066 1091 },
1067 1092 )
1068 1093 if bundlepart:
1069 1094 bundler.addpart(bundlepart)
1070 1095
1071 1096 # storing the bundle in the bundlestore
1072 1097 buf = util.chunkbuffer(bundler.getchunks())
1073 1098 fd, bundlefile = pycompat.mkstemp()
1074 1099 try:
1075 1100 try:
1076 1101 fp = os.fdopen(fd, 'wb')
1077 1102 fp.write(buf.read())
1078 1103 finally:
1079 1104 fp.close()
1080 1105 storebundle(op, {}, bundlefile)
1081 1106 finally:
1082 1107 try:
1083 1108 os.unlink(bundlefile)
1084 1109 except Exception:
1085 1110 # we would rather see the original exception
1086 1111 pass
1087 1112
1088 1113
1089 1114 def processparts(orig, repo, op, unbundler):
1090 1115
1091 1116 # make sure we don't wrap processparts in case of `hg unbundle`
1092 1117 if op.source == b'unbundle':
1093 1118 return orig(repo, op, unbundler)
1094 1119
1095 1120 # this server routes each push to bundle store
1096 1121 if repo.ui.configbool(b'infinitepush', b'pushtobundlestore'):
1097 1122 return storetobundlestore(orig, repo, op, unbundler)
1098 1123
1099 1124 if unbundler.params.get(b'infinitepush') != b'True':
1100 1125 return orig(repo, op, unbundler)
1101 1126
1102 1127 handleallparts = repo.ui.configbool(b'infinitepush', b'storeallparts')
1103 1128
1104 1129 bundler = bundle2.bundle20(repo.ui)
1105 1130 cgparams = None
1106 1131 with bundle2.partiterator(repo, op, unbundler) as parts:
1107 1132 for part in parts:
1108 1133 bundlepart = None
1109 1134 if part.type == b'replycaps':
1110 1135 # This configures the current operation to allow reply parts.
1111 1136 bundle2._processpart(op, part)
1112 1137 elif part.type == bundleparts.scratchbranchparttype:
1113 1138 # Scratch branch parts need to be converted to normal
1114 1139 # changegroup parts, and the extra parameters stored for later
1115 1140 # when we upload to the store. Eventually those parameters will
1116 1141 # be put on the actual bundle instead of this part, then we can
1117 1142 # send a vanilla changegroup instead of the scratchbranch part.
1118 1143 cgversion = part.params.get(b'cgversion', b'01')
1119 1144 bundlepart = bundle2.bundlepart(
1120 1145 b'changegroup', data=part.read()
1121 1146 )
1122 1147 bundlepart.addparam(b'version', cgversion)
1123 1148 cgparams = part.params
1124 1149
1125 1150 # If we're not dumping all parts into the new bundle, we need to
1126 1151 # alert the future pushkey and phase-heads handler to skip
1127 1152 # the part.
1128 1153 if not handleallparts:
1129 1154 op.records.add(
1130 1155 scratchbranchparttype + b'_skippushkey', True
1131 1156 )
1132 1157 op.records.add(
1133 1158 scratchbranchparttype + b'_skipphaseheads', True
1134 1159 )
1135 1160 else:
1136 1161 if handleallparts:
1137 1162 # Ideally we would not process any parts, and instead just
1138 1163 # forward them to the bundle for storage, but since this
1139 1164 # differs from previous behavior, we need to put it behind a
1140 1165 # config flag for incremental rollout.
1141 1166 bundlepart = bundle2.bundlepart(part.type, data=part.read())
1142 1167 for key, value in part.params.items():
1143 1168 bundlepart.addparam(key, value)
1144 1169
1145 1170 # Certain parts require a response
1146 1171 if part.type == b'pushkey':
1147 1172 if op.reply is not None:
1148 1173 rpart = op.reply.newpart(b'reply:pushkey')
1149 1174 rpart.addparam(
1150 1175 b'in-reply-to', str(part.id), mandatory=False
1151 1176 )
1152 1177 rpart.addparam(b'return', b'1', mandatory=False)
1153 1178 else:
1154 1179 bundle2._processpart(op, part)
1155 1180
1156 1181 if handleallparts:
1157 1182 op.records.add(
1158 1183 part.type,
1159 1184 {
1160 1185 b'return': 1,
1161 1186 },
1162 1187 )
1163 1188 if bundlepart:
1164 1189 bundler.addpart(bundlepart)
1165 1190
1166 1191 # If commits were sent, store them
1167 1192 if cgparams:
1168 1193 buf = util.chunkbuffer(bundler.getchunks())
1169 1194 fd, bundlefile = pycompat.mkstemp()
1170 1195 try:
1171 1196 try:
1172 1197 fp = os.fdopen(fd, 'wb')
1173 1198 fp.write(buf.read())
1174 1199 finally:
1175 1200 fp.close()
1176 1201 storebundle(op, cgparams, bundlefile)
1177 1202 finally:
1178 1203 try:
1179 1204 os.unlink(bundlefile)
1180 1205 except Exception:
1181 1206 # we would rather see the original exception
1182 1207 pass
1183 1208
1184 1209
1185 1210 def storebundle(op, params, bundlefile):
1186 1211 log = _getorcreateinfinitepushlogger(op)
1187 1212 parthandlerstart = time.time()
1188 1213 log(scratchbranchparttype, eventtype=b'start')
1189 1214 index = op.repo.bundlestore.index
1190 1215 store = op.repo.bundlestore.store
1191 1216 op.records.add(scratchbranchparttype + b'_skippushkey', True)
1192 1217
1193 1218 bundle = None
1194 1219 try: # guards bundle
1195 1220 bundlepath = b"bundle:%s+%s" % (op.repo.root, bundlefile)
1196 1221 bundle = hg.repository(op.repo.ui, bundlepath)
1197 1222
1198 1223 bookmark = params.get(b'bookmark')
1199 1224 bookprevnode = params.get(b'bookprevnode', b'')
1200 1225 force = params.get(b'force')
1201 1226
1202 1227 if bookmark:
1203 1228 oldnode = index.getnode(bookmark)
1204 1229 else:
1205 1230 oldnode = None
1206 1231 bundleheads = bundle.revs(b'heads(bundle())')
1207 1232 if bookmark and len(bundleheads) > 1:
1208 1233 raise error.Abort(
1209 1234 _(b'cannot push more than one head to a scratch branch')
1210 1235 )
1211 1236
1212 1237 revs = _getrevs(bundle, oldnode, force, bookmark)
1213 1238
1214 1239 # Notify the user of what is being pushed
1215 1240 plural = b's' if len(revs) > 1 else b''
1216 1241 op.repo.ui.warn(_(b"pushing %d commit%s:\n") % (len(revs), plural))
1217 1242 maxoutput = 10
1218 1243 for i in range(0, min(len(revs), maxoutput)):
1219 1244 firstline = bundle[revs[i]].description().split(b'\n')[0][:50]
1220 1245 op.repo.ui.warn(b" %s %s\n" % (revs[i], firstline))
1221 1246
1222 1247 if len(revs) > maxoutput + 1:
1223 1248 op.repo.ui.warn(b" ...\n")
1224 1249 firstline = bundle[revs[-1]].description().split(b'\n')[0][:50]
1225 1250 op.repo.ui.warn(b" %s %s\n" % (revs[-1], firstline))
1226 1251
1227 1252 nodesctx = [bundle[rev] for rev in revs]
1228 1253 inindex = lambda rev: bool(index.getbundle(bundle[rev].hex()))
1229 1254 if bundleheads:
1230 1255 newheadscount = sum(not inindex(rev) for rev in bundleheads)
1231 1256 else:
1232 1257 newheadscount = 0
1233 1258 # If there's a bookmark specified, there should be only one head,
1234 1259 # so we choose the last node, which will be that head.
1235 1260 # If a bug or malicious client allows there to be a bookmark
1236 1261 # with multiple heads, we will place the bookmark on the last head.
1237 1262 bookmarknode = nodesctx[-1].hex() if nodesctx else None
1238 1263 key = None
1239 1264 if newheadscount:
1240 1265 with open(bundlefile, b'rb') as f:
1241 1266 bundledata = f.read()
1242 1267 with logservicecall(
1243 1268 log, b'bundlestore', bundlesize=len(bundledata)
1244 1269 ):
1245 1270 bundlesizelimit = 100 * 1024 * 1024 # 100 MB
1246 1271 if len(bundledata) > bundlesizelimit:
1247 1272 error_msg = (
1248 1273 b'bundle is too big: %d bytes. '
1249 1274 + b'max allowed size is 100 MB'
1250 1275 )
1251 1276 raise error.Abort(error_msg % (len(bundledata),))
1252 1277 key = store.write(bundledata)
1253 1278
1254 1279 with logservicecall(log, b'index', newheadscount=newheadscount), index:
1255 1280 if key:
1256 1281 index.addbundle(key, nodesctx)
1257 1282 if bookmark:
1258 1283 index.addbookmark(bookmark, bookmarknode)
1259 1284 _maybeaddpushbackpart(
1260 1285 op, bookmark, bookmarknode, bookprevnode, params
1261 1286 )
1262 1287 log(
1263 1288 scratchbranchparttype,
1264 1289 eventtype=b'success',
1265 1290 elapsedms=(time.time() - parthandlerstart) * 1000,
1266 1291 )
1267 1292
1268 1293 except Exception as e:
1269 1294 log(
1270 1295 scratchbranchparttype,
1271 1296 eventtype=b'failure',
1272 1297 elapsedms=(time.time() - parthandlerstart) * 1000,
1273 1298 errormsg=stringutil.forcebytestr(e),
1274 1299 )
1275 1300 raise
1276 1301 finally:
1277 1302 if bundle:
1278 1303 bundle.close()
1279 1304
1280 1305
1281 1306 @bundle2.parthandler(
1282 1307 scratchbranchparttype,
1283 1308 (
1284 1309 b'bookmark',
1285 1310 b'bookprevnode',
1286 1311 b'force',
1287 1312 b'pushbackbookmarks',
1288 1313 b'cgversion',
1289 1314 ),
1290 1315 )
1291 1316 def bundle2scratchbranch(op, part):
1292 1317 '''unbundle a bundle2 part containing a changegroup to store'''
1293 1318
1294 1319 bundler = bundle2.bundle20(op.repo.ui)
1295 1320 cgversion = part.params.get(b'cgversion', b'01')
1296 1321 cgpart = bundle2.bundlepart(b'changegroup', data=part.read())
1297 1322 cgpart.addparam(b'version', cgversion)
1298 1323 bundler.addpart(cgpart)
1299 1324 buf = util.chunkbuffer(bundler.getchunks())
1300 1325
1301 1326 fd, bundlefile = pycompat.mkstemp()
1302 1327 try:
1303 1328 try:
1304 1329 fp = os.fdopen(fd, 'wb')
1305 1330 fp.write(buf.read())
1306 1331 finally:
1307 1332 fp.close()
1308 1333 storebundle(op, part.params, bundlefile)
1309 1334 finally:
1310 1335 try:
1311 1336 os.unlink(bundlefile)
1312 1337 except FileNotFoundError:
1313 1338 pass
1314 1339
1315 1340 return 1
1316 1341
1317 1342
1318 1343 def _maybeaddpushbackpart(op, bookmark, newnode, oldnode, params):
1319 1344 if params.get(b'pushbackbookmarks'):
1320 1345 if op.reply and b'pushback' in op.reply.capabilities:
1321 1346 params = {
1322 1347 b'namespace': b'bookmarks',
1323 1348 b'key': bookmark,
1324 1349 b'new': newnode,
1325 1350 b'old': oldnode,
1326 1351 }
1327 1352 op.reply.newpart(b'pushkey', mandatoryparams=params.items())
1328 1353
1329 1354
1330 1355 def bundle2pushkey(orig, op, part):
1331 1356 """Wrapper of bundle2.handlepushkey()
1332 1357
1333 1358 The only goal is to skip calling the original function if flag is set.
1334 1359 It's set if infinitepush push is happening.
1335 1360 """
1336 1361 if op.records[scratchbranchparttype + b'_skippushkey']:
1337 1362 if op.reply is not None:
1338 1363 rpart = op.reply.newpart(b'reply:pushkey')
1339 1364 rpart.addparam(b'in-reply-to', str(part.id), mandatory=False)
1340 1365 rpart.addparam(b'return', b'1', mandatory=False)
1341 1366 return 1
1342 1367
1343 1368 return orig(op, part)
1344 1369
1345 1370
1346 1371 def bundle2handlephases(orig, op, part):
1347 1372 """Wrapper of bundle2.handlephases()
1348 1373
1349 1374 The only goal is to skip calling the original function if flag is set.
1350 1375 It's set if infinitepush push is happening.
1351 1376 """
1352 1377
1353 1378 if op.records[scratchbranchparttype + b'_skipphaseheads']:
1354 1379 return
1355 1380
1356 1381 return orig(op, part)
1357 1382
1358 1383
1359 1384 def _asyncsavemetadata(root, nodes):
1360 1385 """starts a separate process that fills metadata for the nodes
1361 1386
1362 1387 This function creates a separate process and doesn't wait for it's
1363 1388 completion. This was done to avoid slowing down pushes
1364 1389 """
1365 1390
1366 1391 maxnodes = 50
1367 1392 if len(nodes) > maxnodes:
1368 1393 return
1369 1394 nodesargs = []
1370 1395 for node in nodes:
1371 1396 nodesargs.append(b'--node')
1372 1397 nodesargs.append(node)
1373 1398 with open(os.devnull, b'w+b') as devnull:
1374 1399 cmdline = [
1375 1400 util.hgexecutable(),
1376 1401 b'debugfillinfinitepushmetadata',
1377 1402 b'-R',
1378 1403 root,
1379 1404 ] + nodesargs
1380 1405 # Process will run in background. We don't care about the return code
1381 1406 subprocess.Popen(
1382 1407 pycompat.rapply(procutil.tonativestr, cmdline),
1383 1408 close_fds=True,
1384 1409 shell=False,
1385 1410 stdin=devnull,
1386 1411 stdout=devnull,
1387 1412 stderr=devnull,
1388 1413 )
@@ -1,30 +1,33 b''
1 1 scratchnodes() {
2 2 for node in `find ../repo/.hg/scratchbranches/index/nodemap/* | sort`; do
3 3 echo ${node##*/} `cat $node`
4 4 done
5 5 }
6 6
7 7 scratchbookmarks() {
8 8 for bookmark in `find ../repo/.hg/scratchbranches/index/bookmarkmap/* -type f | sort`; do
9 9 echo "${bookmark##*/bookmarkmap/} `cat $bookmark`"
10 10 done
11 11 }
12 12
13 13 setupcommon() {
14 14 cat >> $HGRCPATH << EOF
15 15 [extensions]
16 16 infinitepush=
17 17 [infinitepush]
18 18 branchpattern=re:scratch/.*
19 deprecation-abort=no
20 deprecation-message=yes
21
19 22 EOF
20 23 }
21 24
22 25 setupserver() {
23 26 cat >> .hg/hgrc << EOF
24 27 [infinitepush]
25 28 server=yes
26 29 indextype=disk
27 30 storetype=disk
28 31 reponame=babar
29 32 EOF
30 33 }
@@ -1,371 +1,755 b''
1 1 #require no-reposimplestore no-chg
2 2
3 3 XXX-CHG this test hangs if `hg` is really `chg`. This was hidden by the use of
4 4 `alias hg=chg` by run-tests.py. With such alias removed, this test is revealed
5 5 buggy. This need to be resolved sooner than later.
6 6
7 7
8 8 Testing infinipush extension and the confi options provided by it
9 9
10 10 Create an ondisk bundlestore in .hg/scratchbranches
11 11 $ . "$TESTDIR/library-infinitepush.sh"
12 12 $ cp $HGRCPATH $TESTTMP/defaulthgrc
13 13 $ setupcommon
14 14 $ mkcommit() {
15 15 > echo "$1" > "$1"
16 16 > hg add "$1"
17 17 > hg ci -m "$1"
18 18 > }
19 19 $ hg init repo
20 IMPORTANT: if you use this extension, please contact
21 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
22 unused and barring learning of users of this functionality, we drop this
23 extension in Mercurial 6.6.
20 24 $ cd repo
21 25
22 26 Check that we can send a scratch on the server and it does not show there in
23 27 the history but is stored on disk
24 28 $ setupserver
25 29 $ cd ..
26 30 $ hg clone ssh://user@dummy/repo client -q
31 remote: IMPORTANT: if you use this extension, please contact
32 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
33 remote: unused and barring learning of users of this functionality, we drop this
34 remote: extension in Mercurial 6.6.
35 IMPORTANT: if you use this extension, please contact
36 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
37 unused and barring learning of users of this functionality, we drop this
38 extension in Mercurial 6.6.
39 IMPORTANT: if you use this extension, please contact
40 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
41 unused and barring learning of users of this functionality, we drop this
42 extension in Mercurial 6.6.
27 43 $ cd client
28 44 $ mkcommit initialcommit
45 IMPORTANT: if you use this extension, please contact
46 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
47 unused and barring learning of users of this functionality, we drop this
48 extension in Mercurial 6.6.
49 IMPORTANT: if you use this extension, please contact
50 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
51 unused and barring learning of users of this functionality, we drop this
52 extension in Mercurial 6.6.
29 53 $ hg push -r .
54 IMPORTANT: if you use this extension, please contact
55 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
56 unused and barring learning of users of this functionality, we drop this
57 extension in Mercurial 6.6.
30 58 pushing to ssh://user@dummy/repo
59 remote: IMPORTANT: if you use this extension, please contact
60 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
61 remote: unused and barring learning of users of this functionality, we drop this
62 remote: extension in Mercurial 6.6.
63 IMPORTANT: if you use this extension, please contact
64 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
65 unused and barring learning of users of this functionality, we drop this
66 extension in Mercurial 6.6.
31 67 searching for changes
32 68 remote: adding changesets
33 69 remote: adding manifests
34 70 remote: adding file changes
35 71 remote: added 1 changesets with 1 changes to 1 files
36 72 $ mkcommit scratchcommit
73 IMPORTANT: if you use this extension, please contact
74 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
75 unused and barring learning of users of this functionality, we drop this
76 extension in Mercurial 6.6.
77 IMPORTANT: if you use this extension, please contact
78 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
79 unused and barring learning of users of this functionality, we drop this
80 extension in Mercurial 6.6.
37 81 $ hg push -r . -B scratch/mybranch
82 IMPORTANT: if you use this extension, please contact
83 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
84 unused and barring learning of users of this functionality, we drop this
85 extension in Mercurial 6.6.
38 86 pushing to ssh://user@dummy/repo
87 remote: IMPORTANT: if you use this extension, please contact
88 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
89 remote: unused and barring learning of users of this functionality, we drop this
90 remote: extension in Mercurial 6.6.
91 IMPORTANT: if you use this extension, please contact
92 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
93 unused and barring learning of users of this functionality, we drop this
94 extension in Mercurial 6.6.
39 95 searching for changes
96 remote: IMPORTANT: if you use this extension, please contact
97 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
98 remote: unused and barring learning of users of this functionality, we drop this
99 remote: extension in Mercurial 6.6.
40 100 remote: pushing 1 commit:
41 101 remote: 20759b6926ce scratchcommit
42 102 $ hg log -G
103 IMPORTANT: if you use this extension, please contact
104 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
105 unused and barring learning of users of this functionality, we drop this
106 extension in Mercurial 6.6.
43 107 @ changeset: 1:20759b6926ce
44 108 | bookmark: scratch/mybranch
45 109 | tag: tip
46 110 | user: test
47 111 | date: Thu Jan 01 00:00:00 1970 +0000
48 112 | summary: scratchcommit
49 113 |
50 114 o changeset: 0:67145f466344
51 115 user: test
52 116 date: Thu Jan 01 00:00:00 1970 +0000
53 117 summary: initialcommit
54 118
55 119 $ hg log -G -R ../repo
120 IMPORTANT: if you use this extension, please contact
121 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
122 unused and barring learning of users of this functionality, we drop this
123 extension in Mercurial 6.6.
56 124 o changeset: 0:67145f466344
57 125 tag: tip
58 126 user: test
59 127 date: Thu Jan 01 00:00:00 1970 +0000
60 128 summary: initialcommit
61 129
62 130 $ find ../repo/.hg/scratchbranches | sort
63 131 ../repo/.hg/scratchbranches
64 132 ../repo/.hg/scratchbranches/filebundlestore
65 133 ../repo/.hg/scratchbranches/filebundlestore/b9
66 134 ../repo/.hg/scratchbranches/filebundlestore/b9/e1
67 135 ../repo/.hg/scratchbranches/filebundlestore/b9/e1/b9e1ee5f93fb6d7c42496fc176c09839639dd9cc
68 136 ../repo/.hg/scratchbranches/index
69 137 ../repo/.hg/scratchbranches/index/bookmarkmap
70 138 ../repo/.hg/scratchbranches/index/bookmarkmap/scratch
71 139 ../repo/.hg/scratchbranches/index/bookmarkmap/scratch/mybranch
72 140 ../repo/.hg/scratchbranches/index/nodemap
73 141 ../repo/.hg/scratchbranches/index/nodemap/20759b6926ce827d5a8c73eb1fa9726d6f7defb2
74 142
75 143 From another client we can get the scratchbranch if we ask for it explicitely
76 144
77 145 $ cd ..
78 146 $ hg clone ssh://user@dummy/repo client2 -q
147 remote: IMPORTANT: if you use this extension, please contact
148 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
149 remote: unused and barring learning of users of this functionality, we drop this
150 remote: extension in Mercurial 6.6.
151 IMPORTANT: if you use this extension, please contact
152 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
153 unused and barring learning of users of this functionality, we drop this
154 extension in Mercurial 6.6.
155 IMPORTANT: if you use this extension, please contact
156 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
157 unused and barring learning of users of this functionality, we drop this
158 extension in Mercurial 6.6.
79 159 $ cd client2
80 160 $ hg pull -B scratch/mybranch --traceback
161 IMPORTANT: if you use this extension, please contact
162 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
163 unused and barring learning of users of this functionality, we drop this
164 extension in Mercurial 6.6.
165 remote: IMPORTANT: if you use this extension, please contact
166 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
167 remote: unused and barring learning of users of this functionality, we drop this
168 remote: extension in Mercurial 6.6.
169 IMPORTANT: if you use this extension, please contact
170 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
171 unused and barring learning of users of this functionality, we drop this
172 extension in Mercurial 6.6.
81 173 pulling from ssh://user@dummy/repo
174 remote: IMPORTANT: if you use this extension, please contact
175 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
176 remote: unused and barring learning of users of this functionality, we drop this
177 remote: extension in Mercurial 6.6.
178 IMPORTANT: if you use this extension, please contact
179 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
180 unused and barring learning of users of this functionality, we drop this
181 extension in Mercurial 6.6.
82 182 searching for changes
183 remote: IMPORTANT: if you use this extension, please contact
184 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
185 remote: unused and barring learning of users of this functionality, we drop this
186 remote: extension in Mercurial 6.6.
83 187 adding changesets
84 188 adding manifests
85 189 adding file changes
86 190 added 1 changesets with 1 changes to 1 files
87 191 new changesets 20759b6926ce (1 drafts)
88 192 (run 'hg update' to get a working copy)
89 193 $ hg log -G
194 IMPORTANT: if you use this extension, please contact
195 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
196 unused and barring learning of users of this functionality, we drop this
197 extension in Mercurial 6.6.
90 198 o changeset: 1:20759b6926ce
91 199 | bookmark: scratch/mybranch
92 200 | tag: tip
93 201 | user: test
94 202 | date: Thu Jan 01 00:00:00 1970 +0000
95 203 | summary: scratchcommit
96 204 |
97 205 @ changeset: 0:67145f466344
98 206 user: test
99 207 date: Thu Jan 01 00:00:00 1970 +0000
100 208 summary: initialcommit
101 209
102 210 $ cd ..
103 211
104 212 Push to non-scratch bookmark
105 213
106 214 $ cd client
107 215 $ hg up 0
216 IMPORTANT: if you use this extension, please contact
217 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
218 unused and barring learning of users of this functionality, we drop this
219 extension in Mercurial 6.6.
108 220 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
109 221 $ mkcommit newcommit
222 IMPORTANT: if you use this extension, please contact
223 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
224 unused and barring learning of users of this functionality, we drop this
225 extension in Mercurial 6.6.
226 IMPORTANT: if you use this extension, please contact
227 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
228 unused and barring learning of users of this functionality, we drop this
229 extension in Mercurial 6.6.
110 230 created new head
111 231 $ hg push -r .
232 IMPORTANT: if you use this extension, please contact
233 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
234 unused and barring learning of users of this functionality, we drop this
235 extension in Mercurial 6.6.
112 236 pushing to ssh://user@dummy/repo
237 remote: IMPORTANT: if you use this extension, please contact
238 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
239 remote: unused and barring learning of users of this functionality, we drop this
240 remote: extension in Mercurial 6.6.
241 IMPORTANT: if you use this extension, please contact
242 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
243 unused and barring learning of users of this functionality, we drop this
244 extension in Mercurial 6.6.
113 245 searching for changes
114 246 remote: adding changesets
115 247 remote: adding manifests
116 248 remote: adding file changes
117 249 remote: added 1 changesets with 1 changes to 1 files
118 250 $ hg log -G -T '{desc} {phase} {bookmarks}'
251 IMPORTANT: if you use this extension, please contact
252 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
253 unused and barring learning of users of this functionality, we drop this
254 extension in Mercurial 6.6.
119 255 @ newcommit public
120 256 |
121 257 | o scratchcommit draft scratch/mybranch
122 258 |/
123 259 o initialcommit public
124 260
125 261
126 262 Push to scratch branch
127 263 $ cd ../client2
128 264 $ hg up -q scratch/mybranch
265 IMPORTANT: if you use this extension, please contact
266 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
267 unused and barring learning of users of this functionality, we drop this
268 extension in Mercurial 6.6.
129 269 $ mkcommit 'new scratch commit'
270 IMPORTANT: if you use this extension, please contact
271 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
272 unused and barring learning of users of this functionality, we drop this
273 extension in Mercurial 6.6.
274 IMPORTANT: if you use this extension, please contact
275 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
276 unused and barring learning of users of this functionality, we drop this
277 extension in Mercurial 6.6.
130 278 $ hg push -r . -B scratch/mybranch
279 IMPORTANT: if you use this extension, please contact
280 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
281 unused and barring learning of users of this functionality, we drop this
282 extension in Mercurial 6.6.
131 283 pushing to ssh://user@dummy/repo
284 remote: IMPORTANT: if you use this extension, please contact
285 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
286 remote: unused and barring learning of users of this functionality, we drop this
287 remote: extension in Mercurial 6.6.
288 IMPORTANT: if you use this extension, please contact
289 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
290 unused and barring learning of users of this functionality, we drop this
291 extension in Mercurial 6.6.
132 292 searching for changes
293 remote: IMPORTANT: if you use this extension, please contact
294 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
295 remote: unused and barring learning of users of this functionality, we drop this
296 remote: extension in Mercurial 6.6.
133 297 remote: pushing 2 commits:
134 298 remote: 20759b6926ce scratchcommit
135 299 remote: 1de1d7d92f89 new scratch commit
136 300 $ hg log -G -T '{desc} {phase} {bookmarks}'
301 IMPORTANT: if you use this extension, please contact
302 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
303 unused and barring learning of users of this functionality, we drop this
304 extension in Mercurial 6.6.
137 305 @ new scratch commit draft scratch/mybranch
138 306 |
139 307 o scratchcommit draft
140 308 |
141 309 o initialcommit public
142 310
143 311 $ scratchnodes
144 312 1de1d7d92f8965260391d0513fe8a8d5973d3042 bed63daed3beba97fff2e819a148cf415c217a85
145 313 20759b6926ce827d5a8c73eb1fa9726d6f7defb2 bed63daed3beba97fff2e819a148cf415c217a85
146 314
147 315 $ scratchbookmarks
148 316 scratch/mybranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
149 317
150 318 Push scratch bookmark with no new revs
151 319 $ hg push -r . -B scratch/anotherbranch
320 IMPORTANT: if you use this extension, please contact
321 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
322 unused and barring learning of users of this functionality, we drop this
323 extension in Mercurial 6.6.
152 324 pushing to ssh://user@dummy/repo
325 remote: IMPORTANT: if you use this extension, please contact
326 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
327 remote: unused and barring learning of users of this functionality, we drop this
328 remote: extension in Mercurial 6.6.
329 IMPORTANT: if you use this extension, please contact
330 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
331 unused and barring learning of users of this functionality, we drop this
332 extension in Mercurial 6.6.
153 333 searching for changes
334 remote: IMPORTANT: if you use this extension, please contact
335 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
336 remote: unused and barring learning of users of this functionality, we drop this
337 remote: extension in Mercurial 6.6.
154 338 remote: pushing 2 commits:
155 339 remote: 20759b6926ce scratchcommit
156 340 remote: 1de1d7d92f89 new scratch commit
157 341 $ hg log -G -T '{desc} {phase} {bookmarks}'
342 IMPORTANT: if you use this extension, please contact
343 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
344 unused and barring learning of users of this functionality, we drop this
345 extension in Mercurial 6.6.
158 346 @ new scratch commit draft scratch/anotherbranch scratch/mybranch
159 347 |
160 348 o scratchcommit draft
161 349 |
162 350 o initialcommit public
163 351
164 352 $ scratchbookmarks
165 353 scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
166 354 scratch/mybranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
167 355
168 356 Pull scratch and non-scratch bookmark at the same time
169 357
170 358 $ hg -R ../repo book newbook
359 IMPORTANT: if you use this extension, please contact
360 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
361 unused and barring learning of users of this functionality, we drop this
362 extension in Mercurial 6.6.
171 363 $ cd ../client
172 364 $ hg pull -B newbook -B scratch/mybranch --traceback
365 IMPORTANT: if you use this extension, please contact
366 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
367 unused and barring learning of users of this functionality, we drop this
368 extension in Mercurial 6.6.
369 remote: IMPORTANT: if you use this extension, please contact
370 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
371 remote: unused and barring learning of users of this functionality, we drop this
372 remote: extension in Mercurial 6.6.
373 IMPORTANT: if you use this extension, please contact
374 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
375 unused and barring learning of users of this functionality, we drop this
376 extension in Mercurial 6.6.
173 377 pulling from ssh://user@dummy/repo
378 remote: IMPORTANT: if you use this extension, please contact
379 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
380 remote: unused and barring learning of users of this functionality, we drop this
381 remote: extension in Mercurial 6.6.
382 IMPORTANT: if you use this extension, please contact
383 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
384 unused and barring learning of users of this functionality, we drop this
385 extension in Mercurial 6.6.
174 386 searching for changes
387 remote: IMPORTANT: if you use this extension, please contact
388 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
389 remote: unused and barring learning of users of this functionality, we drop this
390 remote: extension in Mercurial 6.6.
175 391 adding changesets
176 392 adding manifests
177 393 adding file changes
178 394 adding remote bookmark newbook
179 395 added 1 changesets with 1 changes to 2 files
180 396 new changesets 1de1d7d92f89 (1 drafts)
181 397 (run 'hg update' to get a working copy)
182 398 $ hg log -G -T '{desc} {phase} {bookmarks}'
399 IMPORTANT: if you use this extension, please contact
400 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
401 unused and barring learning of users of this functionality, we drop this
402 extension in Mercurial 6.6.
183 403 o new scratch commit draft scratch/mybranch
184 404 |
185 405 | @ newcommit public
186 406 | |
187 407 o | scratchcommit draft
188 408 |/
189 409 o initialcommit public
190 410
191 411
192 412 Push scratch revision without bookmark with --bundle-store
193 413
194 414 $ hg up -q tip
415 IMPORTANT: if you use this extension, please contact
416 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
417 unused and barring learning of users of this functionality, we drop this
418 extension in Mercurial 6.6.
195 419 $ mkcommit scratchcommitnobook
420 IMPORTANT: if you use this extension, please contact
421 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
422 unused and barring learning of users of this functionality, we drop this
423 extension in Mercurial 6.6.
424 IMPORTANT: if you use this extension, please contact
425 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
426 unused and barring learning of users of this functionality, we drop this
427 extension in Mercurial 6.6.
196 428 $ hg log -G -T '{desc} {phase} {bookmarks}'
429 IMPORTANT: if you use this extension, please contact
430 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
431 unused and barring learning of users of this functionality, we drop this
432 extension in Mercurial 6.6.
197 433 @ scratchcommitnobook draft
198 434 |
199 435 o new scratch commit draft scratch/mybranch
200 436 |
201 437 | o newcommit public
202 438 | |
203 439 o | scratchcommit draft
204 440 |/
205 441 o initialcommit public
206 442
207 443 $ hg push -r . --bundle-store
444 IMPORTANT: if you use this extension, please contact
445 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
446 unused and barring learning of users of this functionality, we drop this
447 extension in Mercurial 6.6.
208 448 pushing to ssh://user@dummy/repo
449 remote: IMPORTANT: if you use this extension, please contact
450 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
451 remote: unused and barring learning of users of this functionality, we drop this
452 remote: extension in Mercurial 6.6.
453 IMPORTANT: if you use this extension, please contact
454 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
455 unused and barring learning of users of this functionality, we drop this
456 extension in Mercurial 6.6.
209 457 searching for changes
458 remote: IMPORTANT: if you use this extension, please contact
459 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
460 remote: unused and barring learning of users of this functionality, we drop this
461 remote: extension in Mercurial 6.6.
210 462 remote: pushing 3 commits:
211 463 remote: 20759b6926ce scratchcommit
212 464 remote: 1de1d7d92f89 new scratch commit
213 465 remote: 2b5d271c7e0d scratchcommitnobook
214 466 $ hg -R ../repo log -G -T '{desc} {phase}'
467 IMPORTANT: if you use this extension, please contact
468 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
469 unused and barring learning of users of this functionality, we drop this
470 extension in Mercurial 6.6.
215 471 o newcommit public
216 472 |
217 473 o initialcommit public
218 474
219 475
220 476 $ scratchnodes
221 477 1de1d7d92f8965260391d0513fe8a8d5973d3042 66fa08ff107451320512817bed42b7f467a1bec3
222 478 20759b6926ce827d5a8c73eb1fa9726d6f7defb2 66fa08ff107451320512817bed42b7f467a1bec3
223 479 2b5d271c7e0d25d811359a314d413ebcc75c9524 66fa08ff107451320512817bed42b7f467a1bec3
224 480
225 481 Test with pushrebase
226 482 $ mkcommit scratchcommitwithpushrebase
483 IMPORTANT: if you use this extension, please contact
484 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
485 unused and barring learning of users of this functionality, we drop this
486 extension in Mercurial 6.6.
487 IMPORTANT: if you use this extension, please contact
488 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
489 unused and barring learning of users of this functionality, we drop this
490 extension in Mercurial 6.6.
227 491 $ hg push -r . -B scratch/mybranch
492 IMPORTANT: if you use this extension, please contact
493 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
494 unused and barring learning of users of this functionality, we drop this
495 extension in Mercurial 6.6.
228 496 pushing to ssh://user@dummy/repo
497 remote: IMPORTANT: if you use this extension, please contact
498 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
499 remote: unused and barring learning of users of this functionality, we drop this
500 remote: extension in Mercurial 6.6.
501 IMPORTANT: if you use this extension, please contact
502 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
503 unused and barring learning of users of this functionality, we drop this
504 extension in Mercurial 6.6.
229 505 searching for changes
506 remote: IMPORTANT: if you use this extension, please contact
507 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
508 remote: unused and barring learning of users of this functionality, we drop this
509 remote: extension in Mercurial 6.6.
230 510 remote: pushing 4 commits:
231 511 remote: 20759b6926ce scratchcommit
232 512 remote: 1de1d7d92f89 new scratch commit
233 513 remote: 2b5d271c7e0d scratchcommitnobook
234 514 remote: d8c4f54ab678 scratchcommitwithpushrebase
235 515 $ hg -R ../repo log -G -T '{desc} {phase}'
516 IMPORTANT: if you use this extension, please contact
517 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
518 unused and barring learning of users of this functionality, we drop this
519 extension in Mercurial 6.6.
236 520 o newcommit public
237 521 |
238 522 o initialcommit public
239 523
240 524 $ scratchnodes
241 525 1de1d7d92f8965260391d0513fe8a8d5973d3042 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
242 526 20759b6926ce827d5a8c73eb1fa9726d6f7defb2 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
243 527 2b5d271c7e0d25d811359a314d413ebcc75c9524 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
244 528 d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 e3cb2ac50f9e1e6a5ead3217fc21236c84af4397
245 529
246 530 Change the order of pushrebase and infinitepush
247 531 $ mkcommit scratchcommitwithpushrebase2
532 IMPORTANT: if you use this extension, please contact
533 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
534 unused and barring learning of users of this functionality, we drop this
535 extension in Mercurial 6.6.
536 IMPORTANT: if you use this extension, please contact
537 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
538 unused and barring learning of users of this functionality, we drop this
539 extension in Mercurial 6.6.
248 540 $ hg push -r . -B scratch/mybranch
541 IMPORTANT: if you use this extension, please contact
542 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
543 unused and barring learning of users of this functionality, we drop this
544 extension in Mercurial 6.6.
249 545 pushing to ssh://user@dummy/repo
546 remote: IMPORTANT: if you use this extension, please contact
547 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
548 remote: unused and barring learning of users of this functionality, we drop this
549 remote: extension in Mercurial 6.6.
550 IMPORTANT: if you use this extension, please contact
551 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
552 unused and barring learning of users of this functionality, we drop this
553 extension in Mercurial 6.6.
250 554 searching for changes
555 remote: IMPORTANT: if you use this extension, please contact
556 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
557 remote: unused and barring learning of users of this functionality, we drop this
558 remote: extension in Mercurial 6.6.
251 559 remote: pushing 5 commits:
252 560 remote: 20759b6926ce scratchcommit
253 561 remote: 1de1d7d92f89 new scratch commit
254 562 remote: 2b5d271c7e0d scratchcommitnobook
255 563 remote: d8c4f54ab678 scratchcommitwithpushrebase
256 564 remote: 6c10d49fe927 scratchcommitwithpushrebase2
257 565 $ hg -R ../repo log -G -T '{desc} {phase}'
566 IMPORTANT: if you use this extension, please contact
567 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
568 unused and barring learning of users of this functionality, we drop this
569 extension in Mercurial 6.6.
258 570 o newcommit public
259 571 |
260 572 o initialcommit public
261 573
262 574 $ scratchnodes
263 575 1de1d7d92f8965260391d0513fe8a8d5973d3042 cd0586065eaf8b483698518f5fc32531e36fd8e0
264 576 20759b6926ce827d5a8c73eb1fa9726d6f7defb2 cd0586065eaf8b483698518f5fc32531e36fd8e0
265 577 2b5d271c7e0d25d811359a314d413ebcc75c9524 cd0586065eaf8b483698518f5fc32531e36fd8e0
266 578 6c10d49fe92751666c40263f96721b918170d3da cd0586065eaf8b483698518f5fc32531e36fd8e0
267 579 d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 cd0586065eaf8b483698518f5fc32531e36fd8e0
268 580
269 581 Non-fastforward scratch bookmark push
270 582
271 583 $ hg log -GT "{rev}:{node} {desc}\n"
584 IMPORTANT: if you use this extension, please contact
585 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
586 unused and barring learning of users of this functionality, we drop this
587 extension in Mercurial 6.6.
272 588 @ 6:6c10d49fe92751666c40263f96721b918170d3da scratchcommitwithpushrebase2
273 589 |
274 590 o 5:d8c4f54ab678fd67cb90bb3f272a2dc6513a59a7 scratchcommitwithpushrebase
275 591 |
276 592 o 4:2b5d271c7e0d25d811359a314d413ebcc75c9524 scratchcommitnobook
277 593 |
278 594 o 3:1de1d7d92f8965260391d0513fe8a8d5973d3042 new scratch commit
279 595 |
280 596 | o 2:91894e11e8255bf41aa5434b7b98e8b2aa2786eb newcommit
281 597 | |
282 598 o | 1:20759b6926ce827d5a8c73eb1fa9726d6f7defb2 scratchcommit
283 599 |/
284 600 o 0:67145f4663446a9580364f70034fea6e21293b6f initialcommit
285 601
286 602 $ hg up 6c10d49fe927
603 IMPORTANT: if you use this extension, please contact
604 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
605 unused and barring learning of users of this functionality, we drop this
606 extension in Mercurial 6.6.
287 607 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
288 608 $ echo 1 > amend
289 609 $ hg add amend
610 IMPORTANT: if you use this extension, please contact
611 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
612 unused and barring learning of users of this functionality, we drop this
613 extension in Mercurial 6.6.
290 614 $ hg ci --amend -m 'scratch amended commit'
615 IMPORTANT: if you use this extension, please contact
616 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
617 unused and barring learning of users of this functionality, we drop this
618 extension in Mercurial 6.6.
291 619 saved backup bundle to $TESTTMP/client/.hg/strip-backup/6c10d49fe927-c99ffec5-amend.hg
292 620 $ hg log -G -T '{desc} {phase} {bookmarks}'
621 IMPORTANT: if you use this extension, please contact
622 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
623 unused and barring learning of users of this functionality, we drop this
624 extension in Mercurial 6.6.
293 625 @ scratch amended commit draft scratch/mybranch
294 626 |
295 627 o scratchcommitwithpushrebase draft
296 628 |
297 629 o scratchcommitnobook draft
298 630 |
299 631 o new scratch commit draft
300 632 |
301 633 | o newcommit public
302 634 | |
303 635 o | scratchcommit draft
304 636 |/
305 637 o initialcommit public
306 638
307 639
308 640 $ scratchbookmarks
309 641 scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
310 642 scratch/mybranch 6c10d49fe92751666c40263f96721b918170d3da
311 643 $ hg push -r . -B scratch/mybranch
644 IMPORTANT: if you use this extension, please contact
645 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
646 unused and barring learning of users of this functionality, we drop this
647 extension in Mercurial 6.6.
312 648 pushing to ssh://user@dummy/repo
649 remote: IMPORTANT: if you use this extension, please contact
650 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
651 remote: unused and barring learning of users of this functionality, we drop this
652 remote: extension in Mercurial 6.6.
653 IMPORTANT: if you use this extension, please contact
654 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
655 unused and barring learning of users of this functionality, we drop this
656 extension in Mercurial 6.6.
313 657 searching for changes
658 remote: IMPORTANT: if you use this extension, please contact
659 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
660 remote: unused and barring learning of users of this functionality, we drop this
661 remote: extension in Mercurial 6.6.
314 662 remote: pushing 5 commits:
315 663 remote: 20759b6926ce scratchcommit
316 664 remote: 1de1d7d92f89 new scratch commit
317 665 remote: 2b5d271c7e0d scratchcommitnobook
318 666 remote: d8c4f54ab678 scratchcommitwithpushrebase
319 667 remote: 8872775dd97a scratch amended commit
320 668 $ scratchbookmarks
321 669 scratch/anotherbranch 1de1d7d92f8965260391d0513fe8a8d5973d3042
322 670 scratch/mybranch 8872775dd97a750e1533dc1fbbca665644b32547
323 671 $ hg log -G -T '{desc} {phase} {bookmarks}'
672 IMPORTANT: if you use this extension, please contact
673 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
674 unused and barring learning of users of this functionality, we drop this
675 extension in Mercurial 6.6.
324 676 @ scratch amended commit draft scratch/mybranch
325 677 |
326 678 o scratchcommitwithpushrebase draft
327 679 |
328 680 o scratchcommitnobook draft
329 681 |
330 682 o new scratch commit draft
331 683 |
332 684 | o newcommit public
333 685 | |
334 686 o | scratchcommit draft
335 687 |/
336 688 o initialcommit public
337 689
338 690 Check that push path is not ignored. Add new path to the hgrc
339 691 $ cat >> .hg/hgrc << EOF
340 692 > [paths]
341 693 > peer=ssh://user@dummy/client2
342 694 > EOF
343 695
344 696 Checkout last non-scrath commit
345 697 $ hg up 91894e11e8255
698 IMPORTANT: if you use this extension, please contact
699 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
700 unused and barring learning of users of this functionality, we drop this
701 extension in Mercurial 6.6.
346 702 1 files updated, 0 files merged, 6 files removed, 0 files unresolved
347 703 $ mkcommit peercommit
704 IMPORTANT: if you use this extension, please contact
705 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
706 unused and barring learning of users of this functionality, we drop this
707 extension in Mercurial 6.6.
708 IMPORTANT: if you use this extension, please contact
709 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
710 unused and barring learning of users of this functionality, we drop this
711 extension in Mercurial 6.6.
348 712 Use --force because this push creates new head
349 713 $ hg push peer -r . -f
714 IMPORTANT: if you use this extension, please contact
715 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
716 unused and barring learning of users of this functionality, we drop this
717 extension in Mercurial 6.6.
350 718 pushing to ssh://user@dummy/client2
719 remote: IMPORTANT: if you use this extension, please contact
720 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
721 remote: unused and barring learning of users of this functionality, we drop this
722 remote: extension in Mercurial 6.6.
723 IMPORTANT: if you use this extension, please contact
724 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
725 unused and barring learning of users of this functionality, we drop this
726 extension in Mercurial 6.6.
351 727 searching for changes
352 728 remote: adding changesets
353 729 remote: adding manifests
354 730 remote: adding file changes
355 731 remote: added 2 changesets with 2 changes to 2 files (+1 heads)
356 732 $ hg -R ../repo log -G -T '{desc} {phase} {bookmarks}'
733 IMPORTANT: if you use this extension, please contact
734 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
735 unused and barring learning of users of this functionality, we drop this
736 extension in Mercurial 6.6.
357 737 o newcommit public
358 738 |
359 739 o initialcommit public
360 740
361 741 $ hg -R ../client2 log -G -T '{desc} {phase} {bookmarks}'
742 IMPORTANT: if you use this extension, please contact
743 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
744 unused and barring learning of users of this functionality, we drop this
745 extension in Mercurial 6.6.
362 746 o peercommit public
363 747 |
364 748 o newcommit public
365 749 |
366 750 | @ new scratch commit draft scratch/anotherbranch scratch/mybranch
367 751 | |
368 752 | o scratchcommit draft
369 753 |/
370 754 o initialcommit public
371 755
@@ -1,441 +1,579 b''
1 1 #require no-reposimplestore
2 2
3 3 Testing the case when there is no infinitepush extension present on the client
4 4 side and the server routes each push to bundlestore. This case is very much
5 5 similar to CI use case.
6 6
7 7 Setup
8 8 -----
9 9
10 10 $ . "$TESTDIR/library-infinitepush.sh"
11 11 $ cat >> $HGRCPATH <<EOF
12 12 > [alias]
13 13 > glog = log -GT "{rev}:{node|short} {desc}\n{phase}"
14 14 > EOF
15 15 $ cp $HGRCPATH $TESTTMP/defaulthgrc
16 16 $ hg init repo
17 17 $ cd repo
18 18 $ setupserver
19 19 $ echo "pushtobundlestore = True" >> .hg/hgrc
20 20 $ echo "[extensions]" >> .hg/hgrc
21 21 $ echo "infinitepush=" >> .hg/hgrc
22 $ echo "[infinitepush]" >> .hg/hgrc
23 $ echo "deprecation-abort=no" >> .hg/hgrc
22 24 $ echo initialcommit > initialcommit
23 25 $ hg ci -Aqm "initialcommit"
26 IMPORTANT: if you use this extension, please contact
27 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
28 unused and barring learning of users of this functionality, we drop this
29 extension in Mercurial 6.6.
30 IMPORTANT: if you use this extension, please contact (chg !)
31 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be (chg !)
32 unused and barring learning of users of this functionality, we drop this (chg !)
33 extension in Mercurial 6.6. (chg !)
24 34 $ hg phase --public .
35 IMPORTANT: if you use this extension, please contact
36 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
37 unused and barring learning of users of this functionality, we drop this
38 extension in Mercurial 6.6.
25 39
26 40 $ cd ..
27 41 $ hg clone repo client -q
42 IMPORTANT: if you use this extension, please contact
43 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
44 unused and barring learning of users of this functionality, we drop this
45 extension in Mercurial 6.6.
28 46 $ hg clone repo client2 -q
47 IMPORTANT: if you use this extension, please contact
48 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
49 unused and barring learning of users of this functionality, we drop this
50 extension in Mercurial 6.6.
29 51 $ hg clone ssh://user@dummy/repo client3 -q
52 remote: IMPORTANT: if you use this extension, please contact
53 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
54 remote: unused and barring learning of users of this functionality, we drop this
55 remote: extension in Mercurial 6.6.
30 56 $ cd client
31 57
32 58 Pushing a new commit from the client to the server
33 59 -----------------------------------------------------
34 60
35 61 $ echo foobar > a
36 62 $ hg ci -Aqm "added a"
37 63 $ hg glog
38 64 @ 1:6cb0989601f1 added a
39 65 | draft
40 66 o 0:67145f466344 initialcommit
41 67 public
42 68
43 69 $ hg push
44 70 pushing to $TESTTMP/repo
71 IMPORTANT: if you use this extension, please contact
72 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
73 unused and barring learning of users of this functionality, we drop this
74 extension in Mercurial 6.6.
45 75 searching for changes
46 76 storing changesets on the bundlestore
77 IMPORTANT: if you use this extension, please contact
78 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
79 unused and barring learning of users of this functionality, we drop this
80 extension in Mercurial 6.6.
47 81 pushing 1 commit:
48 82 6cb0989601f1 added a
49 83
50 84 $ scratchnodes
51 85 6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
52 86
53 87 Understanding how data is stored on the bundlestore in server
54 88 -------------------------------------------------------------
55 89
56 90 There are two things, filebundlestore and index
57 91 $ ls ../repo/.hg/scratchbranches
58 92 filebundlestore
59 93 index
60 94
61 95 filebundlestore stores the bundles
62 96 $ ls ../repo/.hg/scratchbranches/filebundlestore/3b/41/
63 97 3b414252ff8acab801318445d88ff48faf4a28c3
64 98
65 99 index/nodemap stores a map of node id and file in which bundle is stored in filebundlestore
66 100 $ ls ../repo/.hg/scratchbranches/index/
67 101 nodemap
68 102 $ ls ../repo/.hg/scratchbranches/index/nodemap/
69 103 6cb0989601f1fb5805238edfb16f3606713d9a0b
70 104
71 105 $ cd ../repo
72 106
73 107 Checking that the commit was not applied to revlog on the server
74 108 ------------------------------------------------------------------
75 109
76 110 $ hg glog
111 IMPORTANT: if you use this extension, please contact
112 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
113 unused and barring learning of users of this functionality, we drop this
114 extension in Mercurial 6.6.
77 115 @ 0:67145f466344 initialcommit
78 116 public
79 117
80 118 Applying the changeset from the bundlestore
81 119 --------------------------------------------
82 120
83 121 $ hg unbundle .hg/scratchbranches/filebundlestore/3b/41/3b414252ff8acab801318445d88ff48faf4a28c3
122 IMPORTANT: if you use this extension, please contact
123 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
124 unused and barring learning of users of this functionality, we drop this
125 extension in Mercurial 6.6.
84 126 adding changesets
85 127 adding manifests
86 128 adding file changes
87 129 added 1 changesets with 1 changes to 1 files
88 130 new changesets 6cb0989601f1
89 131 (run 'hg update' to get a working copy)
90 132
91 133 $ hg glog
134 IMPORTANT: if you use this extension, please contact
135 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
136 unused and barring learning of users of this functionality, we drop this
137 extension in Mercurial 6.6.
92 138 o 1:6cb0989601f1 added a
93 139 | public
94 140 @ 0:67145f466344 initialcommit
95 141 public
96 142
97 143 Pushing more changesets from the local repo
98 144 --------------------------------------------
99 145
100 146 $ cd ../client
101 147 $ echo b > b
102 148 $ hg ci -Aqm "added b"
103 149 $ echo c > c
104 150 $ hg ci -Aqm "added c"
105 151 $ hg glog
106 152 @ 3:bf8a6e3011b3 added c
107 153 | draft
108 154 o 2:eaba929e866c added b
109 155 | draft
110 156 o 1:6cb0989601f1 added a
111 157 | public
112 158 o 0:67145f466344 initialcommit
113 159 public
114 160
115 161 $ hg push
116 162 pushing to $TESTTMP/repo
163 IMPORTANT: if you use this extension, please contact
164 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
165 unused and barring learning of users of this functionality, we drop this
166 extension in Mercurial 6.6.
117 167 searching for changes
118 168 storing changesets on the bundlestore
169 IMPORTANT: if you use this extension, please contact
170 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
171 unused and barring learning of users of this functionality, we drop this
172 extension in Mercurial 6.6.
119 173 pushing 2 commits:
120 174 eaba929e866c added b
121 175 bf8a6e3011b3 added c
122 176
123 177 Checking that changesets are not applied on the server
124 178 ------------------------------------------------------
125 179
126 180 $ hg glog -R ../repo
181 IMPORTANT: if you use this extension, please contact
182 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
183 unused and barring learning of users of this functionality, we drop this
184 extension in Mercurial 6.6.
127 185 o 1:6cb0989601f1 added a
128 186 | public
129 187 @ 0:67145f466344 initialcommit
130 188 public
131 189
132 190 Both of the new changesets are stored in a single bundle-file
133 191 $ scratchnodes
134 192 6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
135 193 bf8a6e3011b345146bbbedbcb1ebd4837571492a 239585f5e61f0c09ce7106bdc1097bff731738f4
136 194 eaba929e866c59bc9a6aada5a9dd2f6990db83c0 239585f5e61f0c09ce7106bdc1097bff731738f4
137 195
138 196 Pushing more changesets to the server
139 197 -------------------------------------
140 198
141 199 $ echo d > d
142 200 $ hg ci -Aqm "added d"
143 201 $ echo e > e
144 202 $ hg ci -Aqm "added e"
145 203
146 204 XXX: we should have pushed only the parts which are not in bundlestore
147 205 $ hg push
148 206 pushing to $TESTTMP/repo
207 IMPORTANT: if you use this extension, please contact
208 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
209 unused and barring learning of users of this functionality, we drop this
210 extension in Mercurial 6.6.
149 211 searching for changes
150 212 storing changesets on the bundlestore
213 IMPORTANT: if you use this extension, please contact
214 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
215 unused and barring learning of users of this functionality, we drop this
216 extension in Mercurial 6.6.
151 217 pushing 4 commits:
152 218 eaba929e866c added b
153 219 bf8a6e3011b3 added c
154 220 1bb96358eda2 added d
155 221 b4e4bce66051 added e
156 222
157 223 Sneak peek into the bundlestore at the server
158 224 $ scratchnodes
159 225 1bb96358eda285b536c6d1c66846a7cdb2336cea 98fbae0016662521b0007da1b7bc349cd3caacd1
160 226 6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
161 227 b4e4bce660512ad3e71189e14588a70ac8e31fef 98fbae0016662521b0007da1b7bc349cd3caacd1
162 228 bf8a6e3011b345146bbbedbcb1ebd4837571492a 98fbae0016662521b0007da1b7bc349cd3caacd1
163 229 eaba929e866c59bc9a6aada5a9dd2f6990db83c0 98fbae0016662521b0007da1b7bc349cd3caacd1
164 230
165 231 Checking if `hg pull` pulls something or `hg incoming` shows something
166 232 -----------------------------------------------------------------------
167 233
168 234 $ hg incoming
235 IMPORTANT: if you use this extension, please contact
236 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
237 unused and barring learning of users of this functionality, we drop this
238 extension in Mercurial 6.6.
169 239 comparing with $TESTTMP/repo
170 240 searching for changes
171 241 no changes found
172 242 [1]
173 243
174 244 $ hg pull
175 245 pulling from $TESTTMP/repo
246 IMPORTANT: if you use this extension, please contact
247 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
248 unused and barring learning of users of this functionality, we drop this
249 extension in Mercurial 6.6.
176 250 searching for changes
177 251 no changes found
178 252
179 253 Pulling from second client which is a localpeer to test `hg pull -r <rev>`
180 254 --------------------------------------------------------------------------
181 255
182 256 Pulling the revision which is applied
183 257
184 258 $ cd ../client2
185 259 $ hg pull -r 6cb0989601f1
186 260 pulling from $TESTTMP/repo
261 IMPORTANT: if you use this extension, please contact
262 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
263 unused and barring learning of users of this functionality, we drop this
264 extension in Mercurial 6.6.
187 265 searching for changes
188 266 adding changesets
189 267 adding manifests
190 268 adding file changes
191 269 added 1 changesets with 1 changes to 1 files
192 270 new changesets 6cb0989601f1
193 271 (run 'hg update' to get a working copy)
194 272 $ hg glog
195 273 o 1:6cb0989601f1 added a
196 274 | public
197 275 @ 0:67145f466344 initialcommit
198 276 public
199 277
200 278 Pulling the revision which is in bundlestore
201 279 XXX: we should support pulling revisions from a local peers bundlestore without
202 280 client side wrapping
203 281
204 282 $ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef
205 283 pulling from $TESTTMP/repo
284 IMPORTANT: if you use this extension, please contact
285 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
286 unused and barring learning of users of this functionality, we drop this
287 extension in Mercurial 6.6.
206 288 abort: unknown revision 'b4e4bce660512ad3e71189e14588a70ac8e31fef'
207 289 [10]
208 290 $ hg glog
209 291 o 1:6cb0989601f1 added a
210 292 | public
211 293 @ 0:67145f466344 initialcommit
212 294 public
213 295
214 296 $ cd ../client
215 297
216 298 Pulling from third client which is not a localpeer
217 299 ---------------------------------------------------
218 300
219 301 Pulling the revision which is applied
220 302
221 303 $ cd ../client3
222 304 $ hg pull -r 6cb0989601f1
223 305 pulling from ssh://user@dummy/repo
306 remote: IMPORTANT: if you use this extension, please contact
307 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
308 remote: unused and barring learning of users of this functionality, we drop this
309 remote: extension in Mercurial 6.6.
224 310 searching for changes
225 311 adding changesets
226 312 adding manifests
227 313 adding file changes
228 314 added 1 changesets with 1 changes to 1 files
229 315 new changesets 6cb0989601f1
230 316 (run 'hg update' to get a working copy)
231 317 $ hg glog
232 318 o 1:6cb0989601f1 added a
233 319 | public
234 320 @ 0:67145f466344 initialcommit
235 321 public
236 322
237 323 Pulling the revision which is in bundlestore
238 324
239 325 Trying to specify short hash
240 326 XXX: we should support this
241 327 $ hg pull -r b4e4bce660512
242 328 pulling from ssh://user@dummy/repo
329 remote: IMPORTANT: if you use this extension, please contact
330 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
331 remote: unused and barring learning of users of this functionality, we drop this
332 remote: extension in Mercurial 6.6.
243 333 abort: unknown revision 'b4e4bce660512'
244 334 [255]
245 335
246 336 XXX: we should show better message when the pull is happening from bundlestore
247 337 $ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef
248 338 pulling from ssh://user@dummy/repo
339 remote: IMPORTANT: if you use this extension, please contact
340 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
341 remote: unused and barring learning of users of this functionality, we drop this
342 remote: extension in Mercurial 6.6.
249 343 searching for changes
344 remote: IMPORTANT: if you use this extension, please contact
345 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
346 remote: unused and barring learning of users of this functionality, we drop this
347 remote: extension in Mercurial 6.6.
250 348 adding changesets
251 349 adding manifests
252 350 adding file changes
253 351 added 4 changesets with 4 changes to 4 files
254 352 new changesets eaba929e866c:b4e4bce66051
255 353 (run 'hg update' to get a working copy)
256 354 $ hg glog
257 355 o 5:b4e4bce66051 added e
258 356 | public
259 357 o 4:1bb96358eda2 added d
260 358 | public
261 359 o 3:bf8a6e3011b3 added c
262 360 | public
263 361 o 2:eaba929e866c added b
264 362 | public
265 363 o 1:6cb0989601f1 added a
266 364 | public
267 365 @ 0:67145f466344 initialcommit
268 366 public
269 367
270 368 $ cd ../client
271 369
272 370 Checking storage of phase information with the bundle on bundlestore
273 371 ---------------------------------------------------------------------
274 372
275 373 creating a draft commit
276 374 $ cat >> $HGRCPATH <<EOF
277 375 > [phases]
278 376 > publish = False
279 377 > EOF
280 378 $ echo f > f
281 379 $ hg ci -Aqm "added f"
282 380 $ hg glog -r '.^::'
283 381 @ 6:9b42578d4447 added f
284 382 | draft
285 383 o 5:b4e4bce66051 added e
286 384 | public
287 385 ~
288 386
289 387 $ hg push
290 388 pushing to $TESTTMP/repo
389 IMPORTANT: if you use this extension, please contact
390 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
391 unused and barring learning of users of this functionality, we drop this
392 extension in Mercurial 6.6.
291 393 searching for changes
292 394 storing changesets on the bundlestore
395 IMPORTANT: if you use this extension, please contact
396 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
397 unused and barring learning of users of this functionality, we drop this
398 extension in Mercurial 6.6.
293 399 pushing 5 commits:
294 400 eaba929e866c added b
295 401 bf8a6e3011b3 added c
296 402 1bb96358eda2 added d
297 403 b4e4bce66051 added e
298 404 9b42578d4447 added f
299 405
300 406 XXX: the phase of 9b42578d4447 should not be changed here
301 407 $ hg glog -r .
302 408 @ 6:9b42578d4447 added f
303 409 | public
304 410 ~
305 411
306 412 applying the bundle on the server to check preservation of phase-information
307 413
308 414 $ cd ../repo
309 415 $ scratchnodes
310 416 1bb96358eda285b536c6d1c66846a7cdb2336cea 280a46a259a268f0e740c81c5a7751bdbfaec85f
311 417 6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
312 418 9b42578d44473575994109161430d65dd147d16d 280a46a259a268f0e740c81c5a7751bdbfaec85f
313 419 b4e4bce660512ad3e71189e14588a70ac8e31fef 280a46a259a268f0e740c81c5a7751bdbfaec85f
314 420 bf8a6e3011b345146bbbedbcb1ebd4837571492a 280a46a259a268f0e740c81c5a7751bdbfaec85f
315 421 eaba929e866c59bc9a6aada5a9dd2f6990db83c0 280a46a259a268f0e740c81c5a7751bdbfaec85f
316 422
317 423 $ hg unbundle .hg/scratchbranches/filebundlestore/28/0a/280a46a259a268f0e740c81c5a7751bdbfaec85f
424 IMPORTANT: if you use this extension, please contact
425 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
426 unused and barring learning of users of this functionality, we drop this
427 extension in Mercurial 6.6.
318 428 adding changesets
319 429 adding manifests
320 430 adding file changes
321 431 added 5 changesets with 5 changes to 5 files
322 432 new changesets eaba929e866c:9b42578d4447 (1 drafts)
323 433 (run 'hg update' to get a working copy)
324 434
325 435 $ hg glog
436 IMPORTANT: if you use this extension, please contact
437 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
438 unused and barring learning of users of this functionality, we drop this
439 extension in Mercurial 6.6.
326 440 o 6:9b42578d4447 added f
327 441 | draft
328 442 o 5:b4e4bce66051 added e
329 443 | public
330 444 o 4:1bb96358eda2 added d
331 445 | public
332 446 o 3:bf8a6e3011b3 added c
333 447 | public
334 448 o 2:eaba929e866c added b
335 449 | public
336 450 o 1:6cb0989601f1 added a
337 451 | public
338 452 @ 0:67145f466344 initialcommit
339 453 public
340 454
341 455 Checking storage of obsmarkers in the bundlestore
342 456 --------------------------------------------------
343 457
344 458 enabling obsmarkers and rebase extension
345 459
346 460 $ cat >> $HGRCPATH << EOF
347 461 > [experimental]
348 462 > evolution = all
349 463 > [extensions]
350 464 > rebase =
351 465 > EOF
352 466
353 467 $ cd ../client
354 468
355 469 $ hg phase -r . --draft --force
356 470 $ hg rebase -r 6 -d 3
357 471 rebasing 6:9b42578d4447 tip "added f"
358 472
359 473 $ hg glog
360 474 @ 7:99949238d9ac added f
361 475 | draft
362 476 | o 5:b4e4bce66051 added e
363 477 | | public
364 478 | o 4:1bb96358eda2 added d
365 479 |/ public
366 480 o 3:bf8a6e3011b3 added c
367 481 | public
368 482 o 2:eaba929e866c added b
369 483 | public
370 484 o 1:6cb0989601f1 added a
371 485 | public
372 486 o 0:67145f466344 initialcommit
373 487 public
374 488
375 489 $ hg push -f
376 490 pushing to $TESTTMP/repo
491 IMPORTANT: if you use this extension, please contact
492 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
493 unused and barring learning of users of this functionality, we drop this
494 extension in Mercurial 6.6.
377 495 searching for changes
378 496 storing changesets on the bundlestore
497 IMPORTANT: if you use this extension, please contact
498 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
499 unused and barring learning of users of this functionality, we drop this
500 extension in Mercurial 6.6.
379 501 pushing 1 commit:
380 502 99949238d9ac added f
381 503
382 504 XXX: the phase should not have changed here
383 505 $ hg glog -r .
384 506 @ 7:99949238d9ac added f
385 507 | public
386 508 ~
387 509
388 510 Unbundling on server to see obsmarkers being applied
389 511
390 512 $ cd ../repo
391 513
392 514 $ scratchnodes
393 515 1bb96358eda285b536c6d1c66846a7cdb2336cea 280a46a259a268f0e740c81c5a7751bdbfaec85f
394 516 6cb0989601f1fb5805238edfb16f3606713d9a0b 3b414252ff8acab801318445d88ff48faf4a28c3
395 517 99949238d9ac7f2424a33a46dface6f866afd059 090a24fe63f31d3b4bee714447f835c8c362ff57
396 518 9b42578d44473575994109161430d65dd147d16d 280a46a259a268f0e740c81c5a7751bdbfaec85f
397 519 b4e4bce660512ad3e71189e14588a70ac8e31fef 280a46a259a268f0e740c81c5a7751bdbfaec85f
398 520 bf8a6e3011b345146bbbedbcb1ebd4837571492a 280a46a259a268f0e740c81c5a7751bdbfaec85f
399 521 eaba929e866c59bc9a6aada5a9dd2f6990db83c0 280a46a259a268f0e740c81c5a7751bdbfaec85f
400 522
401 523 $ hg glog
524 IMPORTANT: if you use this extension, please contact
525 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
526 unused and barring learning of users of this functionality, we drop this
527 extension in Mercurial 6.6.
528 IMPORTANT: if you use this extension, please contact (chg !)
529 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be (chg !)
530 unused and barring learning of users of this functionality, we drop this (chg !)
531 extension in Mercurial 6.6. (chg !)
402 532 o 6:9b42578d4447 added f
403 533 | draft
404 534 o 5:b4e4bce66051 added e
405 535 | public
406 536 o 4:1bb96358eda2 added d
407 537 | public
408 538 o 3:bf8a6e3011b3 added c
409 539 | public
410 540 o 2:eaba929e866c added b
411 541 | public
412 542 o 1:6cb0989601f1 added a
413 543 | public
414 544 @ 0:67145f466344 initialcommit
415 545 public
416 546
417 547 $ hg unbundle .hg/scratchbranches/filebundlestore/09/0a/090a24fe63f31d3b4bee714447f835c8c362ff57
548 IMPORTANT: if you use this extension, please contact
549 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
550 unused and barring learning of users of this functionality, we drop this
551 extension in Mercurial 6.6.
418 552 adding changesets
419 553 adding manifests
420 554 adding file changes
421 555 added 1 changesets with 0 changes to 1 files (+1 heads)
422 556 1 new obsolescence markers
423 557 obsoleted 1 changesets
424 558 new changesets 99949238d9ac (1 drafts)
425 559 (run 'hg heads' to see heads, 'hg merge' to merge)
426 560
427 561 $ hg glog
562 IMPORTANT: if you use this extension, please contact
563 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
564 unused and barring learning of users of this functionality, we drop this
565 extension in Mercurial 6.6.
428 566 o 7:99949238d9ac added f
429 567 | draft
430 568 | o 5:b4e4bce66051 added e
431 569 | | public
432 570 | o 4:1bb96358eda2 added d
433 571 |/ public
434 572 o 3:bf8a6e3011b3 added c
435 573 | public
436 574 o 2:eaba929e866c added b
437 575 | public
438 576 o 1:6cb0989601f1 added a
439 577 | public
440 578 @ 0:67145f466344 initialcommit
441 579 public
@@ -1,172 +1,472 b''
1 1 #require no-reposimplestore no-chg
2 2
3 3 XXX-CHG this test hangs if `hg` is really `chg`. This was hidden by the use of
4 4 `alias hg=chg` by run-tests.py. With such alias removed, this test is revealed
5 5 buggy. This need to be resolved sooner than later.
6 6
7 7
8 8 Testing infinipush extension and the confi options provided by it
9 9
10 10 Setup
11 11
12 12 $ . "$TESTDIR/library-infinitepush.sh"
13 13 $ cp $HGRCPATH $TESTTMP/defaulthgrc
14 14 $ setupcommon
15 15 $ hg init repo
16 IMPORTANT: if you use this extension, please contact
17 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
18 unused and barring learning of users of this functionality, we drop this
19 extension in Mercurial 6.6.
16 20 $ cd repo
17 21 $ setupserver
18 22 $ echo initialcommit > initialcommit
19 23 $ hg ci -Aqm "initialcommit"
24 IMPORTANT: if you use this extension, please contact
25 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
26 unused and barring learning of users of this functionality, we drop this
27 extension in Mercurial 6.6.
20 28 $ hg phase --public .
29 IMPORTANT: if you use this extension, please contact
30 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
31 unused and barring learning of users of this functionality, we drop this
32 extension in Mercurial 6.6.
21 33
22 34 $ cd ..
23 35 $ hg clone ssh://user@dummy/repo client -q
36 remote: IMPORTANT: if you use this extension, please contact
37 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
38 remote: unused and barring learning of users of this functionality, we drop this
39 remote: extension in Mercurial 6.6.
40 IMPORTANT: if you use this extension, please contact
41 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
42 unused and barring learning of users of this functionality, we drop this
43 extension in Mercurial 6.6.
44 IMPORTANT: if you use this extension, please contact
45 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
46 unused and barring learning of users of this functionality, we drop this
47 extension in Mercurial 6.6.
24 48
25 49 Create two heads. Push first head alone, then two heads together. Make sure that
26 50 multihead push works.
27 51 $ cd client
28 52 $ echo multihead1 > multihead1
29 53 $ hg add multihead1
54 IMPORTANT: if you use this extension, please contact
55 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
56 unused and barring learning of users of this functionality, we drop this
57 extension in Mercurial 6.6.
30 58 $ hg ci -m "multihead1"
59 IMPORTANT: if you use this extension, please contact
60 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
61 unused and barring learning of users of this functionality, we drop this
62 extension in Mercurial 6.6.
31 63 $ hg up null
64 IMPORTANT: if you use this extension, please contact
65 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
66 unused and barring learning of users of this functionality, we drop this
67 extension in Mercurial 6.6.
32 68 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 69 $ echo multihead2 > multihead2
34 70 $ hg ci -Am "multihead2"
71 IMPORTANT: if you use this extension, please contact
72 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
73 unused and barring learning of users of this functionality, we drop this
74 extension in Mercurial 6.6.
35 75 adding multihead2
36 76 created new head
37 77 $ hg push -r . --bundle-store
78 IMPORTANT: if you use this extension, please contact
79 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
80 unused and barring learning of users of this functionality, we drop this
81 extension in Mercurial 6.6.
38 82 pushing to ssh://user@dummy/repo
83 remote: IMPORTANT: if you use this extension, please contact
84 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
85 remote: unused and barring learning of users of this functionality, we drop this
86 remote: extension in Mercurial 6.6.
87 IMPORTANT: if you use this extension, please contact
88 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
89 unused and barring learning of users of this functionality, we drop this
90 extension in Mercurial 6.6.
39 91 searching for changes
92 remote: IMPORTANT: if you use this extension, please contact
93 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
94 remote: unused and barring learning of users of this functionality, we drop this
95 remote: extension in Mercurial 6.6.
40 96 remote: pushing 1 commit:
41 97 remote: ee4802bf6864 multihead2
42 98 $ hg push -r '1:2' --bundle-store
99 IMPORTANT: if you use this extension, please contact
100 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
101 unused and barring learning of users of this functionality, we drop this
102 extension in Mercurial 6.6.
43 103 pushing to ssh://user@dummy/repo
104 remote: IMPORTANT: if you use this extension, please contact
105 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
106 remote: unused and barring learning of users of this functionality, we drop this
107 remote: extension in Mercurial 6.6.
108 IMPORTANT: if you use this extension, please contact
109 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
110 unused and barring learning of users of this functionality, we drop this
111 extension in Mercurial 6.6.
44 112 searching for changes
113 remote: IMPORTANT: if you use this extension, please contact
114 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
115 remote: unused and barring learning of users of this functionality, we drop this
116 remote: extension in Mercurial 6.6.
45 117 remote: pushing 2 commits:
46 118 remote: bc22f9a30a82 multihead1
47 119 remote: ee4802bf6864 multihead2
48 120 $ scratchnodes
49 121 bc22f9a30a821118244deacbd732e394ed0b686c de1b7d132ba98f0172cd974e3e69dfa80faa335c
50 122 ee4802bf6864326a6b3dcfff5a03abc2a0a69b8f de1b7d132ba98f0172cd974e3e69dfa80faa335c
51 123
52 124 Create two new scratch bookmarks
53 125 $ hg up 0
126 IMPORTANT: if you use this extension, please contact
127 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
128 unused and barring learning of users of this functionality, we drop this
129 extension in Mercurial 6.6.
54 130 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
55 131 $ echo scratchfirstpart > scratchfirstpart
56 132 $ hg ci -Am "scratchfirstpart"
133 IMPORTANT: if you use this extension, please contact
134 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
135 unused and barring learning of users of this functionality, we drop this
136 extension in Mercurial 6.6.
57 137 adding scratchfirstpart
58 138 created new head
59 139 $ hg push -r . -B scratch/firstpart
140 IMPORTANT: if you use this extension, please contact
141 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
142 unused and barring learning of users of this functionality, we drop this
143 extension in Mercurial 6.6.
60 144 pushing to ssh://user@dummy/repo
145 remote: IMPORTANT: if you use this extension, please contact
146 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
147 remote: unused and barring learning of users of this functionality, we drop this
148 remote: extension in Mercurial 6.6.
149 IMPORTANT: if you use this extension, please contact
150 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
151 unused and barring learning of users of this functionality, we drop this
152 extension in Mercurial 6.6.
61 153 searching for changes
154 remote: IMPORTANT: if you use this extension, please contact
155 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
156 remote: unused and barring learning of users of this functionality, we drop this
157 remote: extension in Mercurial 6.6.
62 158 remote: pushing 1 commit:
63 159 remote: 176993b87e39 scratchfirstpart
64 160 $ hg up 0
161 IMPORTANT: if you use this extension, please contact
162 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
163 unused and barring learning of users of this functionality, we drop this
164 extension in Mercurial 6.6.
65 165 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 166 $ echo scratchsecondpart > scratchsecondpart
67 167 $ hg ci -Am "scratchsecondpart"
168 IMPORTANT: if you use this extension, please contact
169 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
170 unused and barring learning of users of this functionality, we drop this
171 extension in Mercurial 6.6.
68 172 adding scratchsecondpart
69 173 created new head
70 174 $ hg push -r . -B scratch/secondpart
175 IMPORTANT: if you use this extension, please contact
176 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
177 unused and barring learning of users of this functionality, we drop this
178 extension in Mercurial 6.6.
71 179 pushing to ssh://user@dummy/repo
180 remote: IMPORTANT: if you use this extension, please contact
181 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
182 remote: unused and barring learning of users of this functionality, we drop this
183 remote: extension in Mercurial 6.6.
184 IMPORTANT: if you use this extension, please contact
185 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
186 unused and barring learning of users of this functionality, we drop this
187 extension in Mercurial 6.6.
72 188 searching for changes
189 remote: IMPORTANT: if you use this extension, please contact
190 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
191 remote: unused and barring learning of users of this functionality, we drop this
192 remote: extension in Mercurial 6.6.
73 193 remote: pushing 1 commit:
74 194 remote: 8db3891c220e scratchsecondpart
75 195
76 196 Pull two bookmarks from the second client
77 197 $ cd ..
78 198 $ hg clone ssh://user@dummy/repo client2 -q
199 remote: IMPORTANT: if you use this extension, please contact
200 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
201 remote: unused and barring learning of users of this functionality, we drop this
202 remote: extension in Mercurial 6.6.
203 IMPORTANT: if you use this extension, please contact
204 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
205 unused and barring learning of users of this functionality, we drop this
206 extension in Mercurial 6.6.
207 IMPORTANT: if you use this extension, please contact
208 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
209 unused and barring learning of users of this functionality, we drop this
210 extension in Mercurial 6.6.
79 211 $ cd client2
80 212 $ hg pull -B scratch/firstpart -B scratch/secondpart
213 IMPORTANT: if you use this extension, please contact
214 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
215 unused and barring learning of users of this functionality, we drop this
216 extension in Mercurial 6.6.
217 remote: IMPORTANT: if you use this extension, please contact
218 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
219 remote: unused and barring learning of users of this functionality, we drop this
220 remote: extension in Mercurial 6.6.
221 IMPORTANT: if you use this extension, please contact
222 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
223 unused and barring learning of users of this functionality, we drop this
224 extension in Mercurial 6.6.
81 225 pulling from ssh://user@dummy/repo
226 remote: IMPORTANT: if you use this extension, please contact
227 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
228 remote: unused and barring learning of users of this functionality, we drop this
229 remote: extension in Mercurial 6.6.
230 IMPORTANT: if you use this extension, please contact
231 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
232 unused and barring learning of users of this functionality, we drop this
233 extension in Mercurial 6.6.
82 234 searching for changes
235 remote: IMPORTANT: if you use this extension, please contact
236 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
237 remote: unused and barring learning of users of this functionality, we drop this
238 remote: extension in Mercurial 6.6.
239 remote: IMPORTANT: if you use this extension, please contact
240 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
241 remote: unused and barring learning of users of this functionality, we drop this
242 remote: extension in Mercurial 6.6.
83 243 adding changesets
84 244 adding manifests
85 245 adding file changes
86 246 adding changesets
87 247 adding manifests
88 248 adding file changes
89 249 added 2 changesets with 2 changes to 2 files (+1 heads)
90 250 new changesets * (glob)
91 251 (run 'hg heads' to see heads, 'hg merge' to merge)
92 252 $ hg log -r scratch/secondpart -T '{node}'
253 IMPORTANT: if you use this extension, please contact
254 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
255 unused and barring learning of users of this functionality, we drop this
256 extension in Mercurial 6.6.
93 257 8db3891c220e216f6da214e8254bd4371f55efca (no-eol)
94 258 $ hg log -r scratch/firstpart -T '{node}'
259 IMPORTANT: if you use this extension, please contact
260 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
261 unused and barring learning of users of this functionality, we drop this
262 extension in Mercurial 6.6.
95 263 176993b87e39bd88d66a2cccadabe33f0b346339 (no-eol)
96 264 Make two commits to the scratch branch
97 265
98 266 $ echo testpullbycommithash1 > testpullbycommithash1
99 267 $ hg ci -Am "testpullbycommithash1"
268 IMPORTANT: if you use this extension, please contact
269 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
270 unused and barring learning of users of this functionality, we drop this
271 extension in Mercurial 6.6.
100 272 adding testpullbycommithash1
101 273 created new head
102 274 $ hg log -r '.' -T '{node}\n' > ../testpullbycommithash1
275 IMPORTANT: if you use this extension, please contact
276 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
277 unused and barring learning of users of this functionality, we drop this
278 extension in Mercurial 6.6.
103 279 $ echo testpullbycommithash2 > testpullbycommithash2
104 280 $ hg ci -Aqm "testpullbycommithash2"
281 IMPORTANT: if you use this extension, please contact
282 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
283 unused and barring learning of users of this functionality, we drop this
284 extension in Mercurial 6.6.
105 285 $ hg push -r . -B scratch/mybranch -q
286 IMPORTANT: if you use this extension, please contact
287 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
288 unused and barring learning of users of this functionality, we drop this
289 extension in Mercurial 6.6.
290 remote: IMPORTANT: if you use this extension, please contact
291 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
292 remote: unused and barring learning of users of this functionality, we drop this
293 remote: extension in Mercurial 6.6.
294 IMPORTANT: if you use this extension, please contact
295 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
296 unused and barring learning of users of this functionality, we drop this
297 extension in Mercurial 6.6.
106 298
107 299 Create third client and pull by commit hash.
108 300 Make sure testpullbycommithash2 has not fetched
109 301 $ cd ..
110 302 $ hg clone ssh://user@dummy/repo client3 -q
303 remote: IMPORTANT: if you use this extension, please contact
304 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
305 remote: unused and barring learning of users of this functionality, we drop this
306 remote: extension in Mercurial 6.6.
307 IMPORTANT: if you use this extension, please contact
308 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
309 unused and barring learning of users of this functionality, we drop this
310 extension in Mercurial 6.6.
311 IMPORTANT: if you use this extension, please contact
312 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
313 unused and barring learning of users of this functionality, we drop this
314 extension in Mercurial 6.6.
111 315 $ cd client3
112 316 $ hg pull -r `cat ../testpullbycommithash1`
317 IMPORTANT: if you use this extension, please contact
318 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
319 unused and barring learning of users of this functionality, we drop this
320 extension in Mercurial 6.6.
113 321 pulling from ssh://user@dummy/repo
322 remote: IMPORTANT: if you use this extension, please contact
323 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
324 remote: unused and barring learning of users of this functionality, we drop this
325 remote: extension in Mercurial 6.6.
326 IMPORTANT: if you use this extension, please contact
327 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
328 unused and barring learning of users of this functionality, we drop this
329 extension in Mercurial 6.6.
114 330 searching for changes
331 remote: IMPORTANT: if you use this extension, please contact
332 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
333 remote: unused and barring learning of users of this functionality, we drop this
334 remote: extension in Mercurial 6.6.
115 335 adding changesets
116 336 adding manifests
117 337 adding file changes
118 338 added 1 changesets with 1 changes to 1 files
119 339 new changesets 33910bfe6ffe (1 drafts)
120 340 (run 'hg update' to get a working copy)
121 341 $ hg log -G -T '{desc} {phase} {bookmarks}'
342 IMPORTANT: if you use this extension, please contact
343 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
344 unused and barring learning of users of this functionality, we drop this
345 extension in Mercurial 6.6.
122 346 o testpullbycommithash1 draft
123 347 |
124 348 @ initialcommit public
125 349
126 350 Make public commit in the repo and pull it.
127 351 Make sure phase on the client is public.
128 352 $ cd ../repo
129 353 $ echo publiccommit > publiccommit
130 354 $ hg ci -Aqm "publiccommit"
355 IMPORTANT: if you use this extension, please contact
356 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
357 unused and barring learning of users of this functionality, we drop this
358 extension in Mercurial 6.6.
131 359 $ hg phase --public .
360 IMPORTANT: if you use this extension, please contact
361 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
362 unused and barring learning of users of this functionality, we drop this
363 extension in Mercurial 6.6.
132 364 $ cd ../client3
133 365 $ hg pull
366 IMPORTANT: if you use this extension, please contact
367 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
368 unused and barring learning of users of this functionality, we drop this
369 extension in Mercurial 6.6.
134 370 pulling from ssh://user@dummy/repo
371 remote: IMPORTANT: if you use this extension, please contact
372 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
373 remote: unused and barring learning of users of this functionality, we drop this
374 remote: extension in Mercurial 6.6.
375 IMPORTANT: if you use this extension, please contact
376 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
377 unused and barring learning of users of this functionality, we drop this
378 extension in Mercurial 6.6.
135 379 searching for changes
136 380 adding changesets
137 381 adding manifests
138 382 adding file changes
139 383 added 1 changesets with 1 changes to 1 files (+1 heads)
140 384 new changesets a79b6597f322
141 385 (run 'hg heads' to see heads, 'hg merge' to merge)
142 386 $ hg log -G -T '{desc} {phase} {bookmarks} {node|short}'
387 IMPORTANT: if you use this extension, please contact
388 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
389 unused and barring learning of users of this functionality, we drop this
390 extension in Mercurial 6.6.
143 391 o publiccommit public a79b6597f322
144 392 |
145 393 | o testpullbycommithash1 draft 33910bfe6ffe
146 394 |/
147 395 @ initialcommit public 67145f466344
148 396
149 397 $ hg up a79b6597f322
398 IMPORTANT: if you use this extension, please contact
399 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
400 unused and barring learning of users of this functionality, we drop this
401 extension in Mercurial 6.6.
150 402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 403 $ echo scratchontopofpublic > scratchontopofpublic
152 404 $ hg ci -Aqm "scratchontopofpublic"
405 IMPORTANT: if you use this extension, please contact
406 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
407 unused and barring learning of users of this functionality, we drop this
408 extension in Mercurial 6.6.
153 409 $ hg push -r . -B scratch/scratchontopofpublic
410 IMPORTANT: if you use this extension, please contact
411 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
412 unused and barring learning of users of this functionality, we drop this
413 extension in Mercurial 6.6.
154 414 pushing to ssh://user@dummy/repo
415 remote: IMPORTANT: if you use this extension, please contact
416 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
417 remote: unused and barring learning of users of this functionality, we drop this
418 remote: extension in Mercurial 6.6.
419 IMPORTANT: if you use this extension, please contact
420 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
421 unused and barring learning of users of this functionality, we drop this
422 extension in Mercurial 6.6.
155 423 searching for changes
424 remote: IMPORTANT: if you use this extension, please contact
425 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
426 remote: unused and barring learning of users of this functionality, we drop this
427 remote: extension in Mercurial 6.6.
156 428 remote: pushing 1 commit:
157 429 remote: c70aee6da07d scratchontopofpublic
158 430 $ cd ../client2
159 431 $ hg pull -B scratch/scratchontopofpublic
432 IMPORTANT: if you use this extension, please contact
433 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
434 unused and barring learning of users of this functionality, we drop this
435 extension in Mercurial 6.6.
436 remote: IMPORTANT: if you use this extension, please contact
437 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
438 remote: unused and barring learning of users of this functionality, we drop this
439 remote: extension in Mercurial 6.6.
440 IMPORTANT: if you use this extension, please contact
441 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
442 unused and barring learning of users of this functionality, we drop this
443 extension in Mercurial 6.6.
160 444 pulling from ssh://user@dummy/repo
445 remote: IMPORTANT: if you use this extension, please contact
446 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
447 remote: unused and barring learning of users of this functionality, we drop this
448 remote: extension in Mercurial 6.6.
449 IMPORTANT: if you use this extension, please contact
450 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
451 unused and barring learning of users of this functionality, we drop this
452 extension in Mercurial 6.6.
161 453 searching for changes
454 remote: IMPORTANT: if you use this extension, please contact
455 remote: mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
456 remote: unused and barring learning of users of this functionality, we drop this
457 remote: extension in Mercurial 6.6.
162 458 adding changesets
163 459 adding manifests
164 460 adding file changes
165 461 adding changesets
166 462 adding manifests
167 463 adding file changes
168 464 added 2 changesets with 2 changes to 2 files (+1 heads)
169 465 new changesets a79b6597f322:c70aee6da07d (1 drafts)
170 466 (run 'hg heads .' to see heads, 'hg merge' to merge)
171 467 $ hg log -r scratch/scratchontopofpublic -T '{phase}'
468 IMPORTANT: if you use this extension, please contact
469 mercurial-devel@mercurial-scm.org IMMEDIATELY. This extension is believed to be
470 unused and barring learning of users of this functionality, we drop this
471 extension in Mercurial 6.6.
172 472 draft (no-eol)
General Comments 0
You need to be logged in to leave comments. Login now