##// END OF EJS Templates
phases: leverage the collected information to record phase update...
marmoute -
r52303:eababb7b default
parent child Browse files
Show More
@@ -1,1065 +1,1046 b''
1 1 """ Mercurial phases support code
2 2
3 3 ---
4 4
5 5 Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
6 6 Logilab SA <contact@logilab.fr>
7 7 Augie Fackler <durin42@gmail.com>
8 8
9 9 This software may be used and distributed according to the terms
10 10 of the GNU General Public License version 2 or any later version.
11 11
12 12 ---
13 13
14 14 This module implements most phase logic in mercurial.
15 15
16 16
17 17 Basic Concept
18 18 =============
19 19
20 20 A 'changeset phase' is an indicator that tells us how a changeset is
21 21 manipulated and communicated. The details of each phase is described
22 22 below, here we describe the properties they have in common.
23 23
24 24 Like bookmarks, phases are not stored in history and thus are not
25 25 permanent and leave no audit trail.
26 26
27 27 First, no changeset can be in two phases at once. Phases are ordered,
28 28 so they can be considered from lowest to highest. The default, lowest
29 29 phase is 'public' - this is the normal phase of existing changesets. A
30 30 child changeset can not be in a lower phase than its parents.
31 31
32 32 These phases share a hierarchy of traits:
33 33
34 34 immutable shared
35 35 public: X X
36 36 draft: X
37 37 secret:
38 38
39 39 Local commits are draft by default.
40 40
41 41 Phase Movement and Exchange
42 42 ===========================
43 43
44 44 Phase data is exchanged by pushkey on pull and push. Some servers have
45 45 a publish option set, we call such a server a "publishing server".
46 46 Pushing a draft changeset to a publishing server changes the phase to
47 47 public.
48 48
49 49 A small list of fact/rules define the exchange of phase:
50 50
51 51 * old client never changes server states
52 52 * pull never changes server states
53 53 * publish and old server changesets are seen as public by client
54 54 * any secret changeset seen in another repository is lowered to at
55 55 least draft
56 56
57 57 Here is the final table summing up the 49 possible use cases of phase
58 58 exchange:
59 59
60 60 server
61 61 old publish non-publish
62 62 N X N D P N D P
63 63 old client
64 64 pull
65 65 N - X/X - X/D X/P - X/D X/P
66 66 X - X/X - X/D X/P - X/D X/P
67 67 push
68 68 X X/X X/X X/P X/P X/P X/D X/D X/P
69 69 new client
70 70 pull
71 71 N - P/X - P/D P/P - D/D P/P
72 72 D - P/X - P/D P/P - D/D P/P
73 73 P - P/X - P/D P/P - P/D P/P
74 74 push
75 75 D P/X P/X P/P P/P P/P D/D D/D P/P
76 76 P P/X P/X P/P P/P P/P P/P P/P P/P
77 77
78 78 Legend:
79 79
80 80 A/B = final state on client / state on server
81 81
82 82 * N = new/not present,
83 83 * P = public,
84 84 * D = draft,
85 85 * X = not tracked (i.e., the old client or server has no internal
86 86 way of recording the phase.)
87 87
88 88 passive = only pushes
89 89
90 90
91 91 A cell here can be read like this:
92 92
93 93 "When a new client pushes a draft changeset (D) to a publishing
94 94 server where it's not present (N), it's marked public on both
95 95 sides (P/P)."
96 96
97 97 Note: old client behave as a publishing server with draft only content
98 98 - other people see it as public
99 99 - content is pushed as draft
100 100
101 101 """
102 102
103 103
104 104 import struct
105 105 import typing
106 106 import weakref
107 107
108 108 from typing import (
109 109 Any,
110 110 Callable,
111 111 Dict,
112 112 Iterable,
113 113 List,
114 114 Optional,
115 115 Set,
116 116 Tuple,
117 117 )
118 118
119 119 from .i18n import _
120 120 from .node import (
121 121 bin,
122 122 hex,
123 123 nullrev,
124 124 short,
125 125 wdirrev,
126 126 )
127 127 from . import (
128 128 error,
129 129 pycompat,
130 130 requirements,
131 131 smartset,
132 132 txnutil,
133 133 util,
134 134 )
135 135
136 136 Phaseroots = Dict[int, Set[int]]
137 137
138 138 if typing.TYPE_CHECKING:
139 139 from . import (
140 140 localrepo,
141 141 ui as uimod,
142 142 )
143 143
144 144 # keeps pyflakes happy
145 145 assert [uimod]
146 146
147 147 Phasedefaults = List[
148 148 Callable[[localrepo.localrepository, Phaseroots], Phaseroots]
149 149 ]
150 150
151 151
152 152 _fphasesentry = struct.Struct(b'>i20s')
153 153
154 154 # record phase index
155 155 public: int = 0
156 156 draft: int = 1
157 157 secret: int = 2
158 158 archived = 32 # non-continuous for compatibility
159 159 internal = 96 # non-continuous for compatibility
160 160 allphases = (public, draft, secret, archived, internal)
161 161 trackedphases = (draft, secret, archived, internal)
162 162 not_public_phases = trackedphases
163 163 # record phase names
164 164 cmdphasenames = [b'public', b'draft', b'secret'] # known to `hg phase` command
165 165 phasenames = dict(enumerate(cmdphasenames))
166 166 phasenames[archived] = b'archived'
167 167 phasenames[internal] = b'internal'
168 168 # map phase name to phase number
169 169 phasenumber = {name: phase for phase, name in phasenames.items()}
170 170 # like phasenumber, but also include maps for the numeric and binary
171 171 # phase number to the phase number
172 172 phasenumber2 = phasenumber.copy()
173 173 phasenumber2.update({phase: phase for phase in phasenames})
174 174 phasenumber2.update({b'%i' % phase: phase for phase in phasenames})
175 175 # record phase property
176 176 mutablephases = (draft, secret, archived, internal)
177 177 relevant_mutable_phases = (draft, secret) # could be obsolete or unstable
178 178 remotehiddenphases = (secret, archived, internal)
179 179 localhiddenphases = (internal, archived)
180 180
181 181 all_internal_phases = tuple(p for p in allphases if p & internal)
182 182 # We do not want any internal content to exit the repository, ever.
183 183 no_bundle_phases = all_internal_phases
184 184
185 185
186 186 def supportinternal(repo: "localrepo.localrepository") -> bool:
187 187 """True if the internal phase can be used on a repository"""
188 188 return requirements.INTERNAL_PHASE_REQUIREMENT in repo.requirements
189 189
190 190
191 191 def supportarchived(repo: "localrepo.localrepository") -> bool:
192 192 """True if the archived phase can be used on a repository"""
193 193 return requirements.ARCHIVED_PHASE_REQUIREMENT in repo.requirements
194 194
195 195
196 196 def _readroots(
197 197 repo: "localrepo.localrepository",
198 198 phasedefaults: Optional["Phasedefaults"] = None,
199 199 ) -> Tuple[Phaseroots, bool]:
200 200 """Read phase roots from disk
201 201
202 202 phasedefaults is a list of fn(repo, roots) callable, which are
203 203 executed if the phase roots file does not exist. When phases are
204 204 being initialized on an existing repository, this could be used to
205 205 set selected changesets phase to something else than public.
206 206
207 207 Return (roots, dirty) where dirty is true if roots differ from
208 208 what is being stored.
209 209 """
210 210 repo = repo.unfiltered()
211 211 dirty = False
212 212 roots = {i: set() for i in allphases}
213 213 to_rev = repo.changelog.index.get_rev
214 214 unknown_msg = b'removing unknown node %s from %i-phase boundary\n'
215 215 try:
216 216 f, pending = txnutil.trypending(repo.root, repo.svfs, b'phaseroots')
217 217 try:
218 218 for line in f:
219 219 str_phase, hex_node = line.split()
220 220 phase = int(str_phase)
221 221 node = bin(hex_node)
222 222 rev = to_rev(node)
223 223 if rev is None:
224 224 repo.ui.debug(unknown_msg % (short(hex_node), phase))
225 225 dirty = True
226 226 else:
227 227 roots[phase].add(rev)
228 228 finally:
229 229 f.close()
230 230 except FileNotFoundError:
231 231 if phasedefaults:
232 232 for f in phasedefaults:
233 233 roots = f(repo, roots)
234 234 dirty = True
235 235 return roots, dirty
236 236
237 237
238 238 def binaryencode(phasemapping: Dict[int, List[bytes]]) -> bytes:
239 239 """encode a 'phase -> nodes' mapping into a binary stream
240 240
241 241 The revision lists are encoded as (phase, root) pairs.
242 242 """
243 243 binarydata = []
244 244 for phase, nodes in phasemapping.items():
245 245 for head in nodes:
246 246 binarydata.append(_fphasesentry.pack(phase, head))
247 247 return b''.join(binarydata)
248 248
249 249
250 250 def binarydecode(stream) -> Dict[int, List[bytes]]:
251 251 """decode a binary stream into a 'phase -> nodes' mapping
252 252
253 253 The (phase, root) pairs are turned back into a dictionary with
254 254 the phase as index and the aggregated roots of that phase as value."""
255 255 headsbyphase = {i: [] for i in allphases}
256 256 entrysize = _fphasesentry.size
257 257 while True:
258 258 entry = stream.read(entrysize)
259 259 if len(entry) < entrysize:
260 260 if entry:
261 261 raise error.Abort(_(b'bad phase-heads stream'))
262 262 break
263 263 phase, node = _fphasesentry.unpack(entry)
264 264 headsbyphase[phase].append(node)
265 265 return headsbyphase
266 266
267 267
268 268 def _sortedrange_insert(data, idx, rev, t):
269 269 merge_before = False
270 270 if idx:
271 271 r1, t1 = data[idx - 1]
272 272 merge_before = r1[-1] + 1 == rev and t1 == t
273 273 merge_after = False
274 274 if idx < len(data):
275 275 r2, t2 = data[idx]
276 276 merge_after = r2[0] == rev + 1 and t2 == t
277 277
278 278 if merge_before and merge_after:
279 279 data[idx - 1] = (range(r1[0], r2[-1] + 1), t)
280 280 data.pop(idx)
281 281 elif merge_before:
282 282 data[idx - 1] = (range(r1[0], rev + 1), t)
283 283 elif merge_after:
284 284 data[idx] = (range(rev, r2[-1] + 1), t)
285 285 else:
286 286 data.insert(idx, (range(rev, rev + 1), t))
287 287
288 288
289 289 def _sortedrange_split(data, idx, rev, t):
290 290 r1, t1 = data[idx]
291 291 if t == t1:
292 292 return
293 293 t = (t1[0], t[1])
294 294 if len(r1) == 1:
295 295 data.pop(idx)
296 296 _sortedrange_insert(data, idx, rev, t)
297 297 elif r1[0] == rev:
298 298 data[idx] = (range(rev + 1, r1[-1] + 1), t1)
299 299 _sortedrange_insert(data, idx, rev, t)
300 300 elif r1[-1] == rev:
301 301 data[idx] = (range(r1[0], rev), t1)
302 302 _sortedrange_insert(data, idx + 1, rev, t)
303 303 else:
304 304 data[idx : idx + 1] = [
305 305 (range(r1[0], rev), t1),
306 306 (range(rev, rev + 1), t),
307 307 (range(rev + 1, r1[-1] + 1), t1),
308 308 ]
309 309
310 310
311 311 def _trackphasechange(data, rev, old, new):
312 312 """add a phase move to the <data> list of ranges
313 313
314 314 If data is None, nothing happens.
315 315 """
316 316 if data is None:
317 317 return
318 318
319 319 # If data is empty, create a one-revision range and done
320 320 if not data:
321 321 data.insert(0, (range(rev, rev + 1), (old, new)))
322 322 return
323 323
324 324 low = 0
325 325 high = len(data)
326 326 t = (old, new)
327 327 while low < high:
328 328 mid = (low + high) // 2
329 329 revs = data[mid][0]
330 330 revs_low = revs[0]
331 331 revs_high = revs[-1]
332 332
333 333 if rev >= revs_low and rev <= revs_high:
334 334 _sortedrange_split(data, mid, rev, t)
335 335 return
336 336
337 337 if revs_low == rev + 1:
338 338 if mid and data[mid - 1][0][-1] == rev:
339 339 _sortedrange_split(data, mid - 1, rev, t)
340 340 else:
341 341 _sortedrange_insert(data, mid, rev, t)
342 342 return
343 343
344 344 if revs_high == rev - 1:
345 345 if mid + 1 < len(data) and data[mid + 1][0][0] == rev:
346 346 _sortedrange_split(data, mid + 1, rev, t)
347 347 else:
348 348 _sortedrange_insert(data, mid + 1, rev, t)
349 349 return
350 350
351 351 if revs_low > rev:
352 352 high = mid
353 353 else:
354 354 low = mid + 1
355 355
356 356 if low == len(data):
357 357 data.append((range(rev, rev + 1), t))
358 358 return
359 359
360 360 r1, t1 = data[low]
361 361 if r1[0] > rev:
362 362 data.insert(low, (range(rev, rev + 1), t))
363 363 else:
364 364 data.insert(low + 1, (range(rev, rev + 1), t))
365 365
366 366
367 367 class phasecache:
368 368 def __init__(
369 369 self,
370 370 repo: "localrepo.localrepository",
371 371 phasedefaults: Optional["Phasedefaults"],
372 372 _load: bool = True,
373 373 ):
374 374 if _load:
375 375 # Cheap trick to allow shallow-copy without copy module
376 376 loaded = _readroots(repo, phasedefaults)
377 377 self._phaseroots: Phaseroots = loaded[0]
378 378 self.dirty: bool = loaded[1]
379 379 self._loadedrevslen = 0
380 380 self._phasesets = None
381 381
382 382 def hasnonpublicphases(self, repo: "localrepo.localrepository") -> bool:
383 383 """detect if there are revisions with non-public phase"""
384 384 repo = repo.unfiltered()
385 385 cl = repo.changelog
386 386 if len(cl) >= self._loadedrevslen:
387 387 self.invalidate()
388 388 self.loadphaserevs(repo)
389 389 return any(
390 390 revs for phase, revs in self._phaseroots.items() if phase != public
391 391 )
392 392
393 393 def nonpublicphaseroots(
394 394 self, repo: "localrepo.localrepository"
395 395 ) -> Set[int]:
396 396 """returns the roots of all non-public phases
397 397
398 398 The roots are not minimized, so if the secret revisions are
399 399 descendants of draft revisions, their roots will still be present.
400 400 """
401 401 repo = repo.unfiltered()
402 402 cl = repo.changelog
403 403 if len(cl) >= self._loadedrevslen:
404 404 self.invalidate()
405 405 self.loadphaserevs(repo)
406 406 return set().union(
407 407 *[
408 408 revs
409 409 for phase, revs in self._phaseroots.items()
410 410 if phase != public
411 411 ]
412 412 )
413 413
414 414 def getrevset(
415 415 self,
416 416 repo: "localrepo.localrepository",
417 417 phases: Iterable[int],
418 418 subset: Optional[Any] = None,
419 419 ) -> Any:
420 420 # TODO: finish typing this
421 421 """return a smartset for the given phases"""
422 422 self.loadphaserevs(repo) # ensure phase's sets are loaded
423 423 phases = set(phases)
424 424 publicphase = public in phases
425 425
426 426 if publicphase:
427 427 # In this case, phases keeps all the *other* phases.
428 428 phases = set(allphases).difference(phases)
429 429 if not phases:
430 430 return smartset.fullreposet(repo)
431 431
432 432 # fast path: _phasesets contains the interesting sets,
433 433 # might only need a union and post-filtering.
434 434 revsneedscopy = False
435 435 if len(phases) == 1:
436 436 [p] = phases
437 437 revs = self._phasesets[p]
438 438 revsneedscopy = True # Don't modify _phasesets
439 439 else:
440 440 # revs has the revisions in all *other* phases.
441 441 revs = set.union(*[self._phasesets[p] for p in phases])
442 442
443 443 def _addwdir(wdirsubset, wdirrevs):
444 444 if wdirrev in wdirsubset and repo[None].phase() in phases:
445 445 if revsneedscopy:
446 446 wdirrevs = wdirrevs.copy()
447 447 # The working dir would never be in the # cache, but it was in
448 448 # the subset being filtered for its phase (or filtered out,
449 449 # depending on publicphase), so add it to the output to be
450 450 # included (or filtered out).
451 451 wdirrevs.add(wdirrev)
452 452 return wdirrevs
453 453
454 454 if not publicphase:
455 455 if repo.changelog.filteredrevs:
456 456 revs = revs - repo.changelog.filteredrevs
457 457
458 458 if subset is None:
459 459 return smartset.baseset(revs)
460 460 else:
461 461 revs = _addwdir(subset, revs)
462 462 return subset & smartset.baseset(revs)
463 463 else:
464 464 if subset is None:
465 465 subset = smartset.fullreposet(repo)
466 466
467 467 revs = _addwdir(subset, revs)
468 468
469 469 if not revs:
470 470 return subset
471 471 return subset.filter(lambda r: r not in revs)
472 472
473 473 def copy(self):
474 474 # Shallow copy meant to ensure isolation in
475 475 # advance/retractboundary(), nothing more.
476 476 ph = self.__class__(None, None, _load=False)
477 477 ph._phaseroots = self._phaseroots.copy()
478 478 ph.dirty = self.dirty
479 479 ph._loadedrevslen = self._loadedrevslen
480 480 ph._phasesets = self._phasesets
481 481 return ph
482 482
483 483 def replace(self, phcache):
484 484 """replace all values in 'self' with content of phcache"""
485 485 for a in (
486 486 '_phaseroots',
487 487 'dirty',
488 488 '_loadedrevslen',
489 489 '_phasesets',
490 490 ):
491 491 setattr(self, a, getattr(phcache, a))
492 492
493 493 def _getphaserevsnative(self, repo):
494 494 repo = repo.unfiltered()
495 495 return repo.changelog.computephases(self._phaseroots)
496 496
497 497 def _computephaserevspure(self, repo):
498 498 repo = repo.unfiltered()
499 499 cl = repo.changelog
500 500 self._phasesets = {phase: set() for phase in allphases}
501 501 lowerroots = set()
502 502 for phase in reversed(trackedphases):
503 503 roots = self._phaseroots[phase]
504 504 if roots:
505 505 ps = set(cl.descendants(roots))
506 506 for root in roots:
507 507 ps.add(root)
508 508 ps.difference_update(lowerroots)
509 509 lowerroots.update(ps)
510 510 self._phasesets[phase] = ps
511 511 self._loadedrevslen = len(cl)
512 512
513 513 def loadphaserevs(self, repo: "localrepo.localrepository") -> None:
514 514 """ensure phase information is loaded in the object"""
515 515 if self._phasesets is None:
516 516 try:
517 517 res = self._getphaserevsnative(repo)
518 518 self._loadedrevslen, self._phasesets = res
519 519 except AttributeError:
520 520 self._computephaserevspure(repo)
521 521
522 522 def invalidate(self):
523 523 self._loadedrevslen = 0
524 524 self._phasesets = None
525 525
526 526 def phase(self, repo: "localrepo.localrepository", rev: int) -> int:
527 527 # We need a repo argument here to be able to build _phasesets
528 528 # if necessary. The repository instance is not stored in
529 529 # phasecache to avoid reference cycles. The changelog instance
530 530 # is not stored because it is a filecache() property and can
531 531 # be replaced without us being notified.
532 532 if rev == nullrev:
533 533 return public
534 534 if rev < nullrev:
535 535 raise ValueError(_(b'cannot lookup negative revision'))
536 536 if rev >= self._loadedrevslen:
537 537 self.invalidate()
538 538 self.loadphaserevs(repo)
539 539 for phase in trackedphases:
540 540 if rev in self._phasesets[phase]:
541 541 return phase
542 542 return public
543 543
544 544 def write(self, repo):
545 545 if not self.dirty:
546 546 return
547 547 f = repo.svfs(b'phaseroots', b'w', atomictemp=True, checkambig=True)
548 548 try:
549 549 self._write(repo.unfiltered(), f)
550 550 finally:
551 551 f.close()
552 552
553 553 def _write(self, repo, fp):
554 554 assert repo.filtername is None
555 555 to_node = repo.changelog.node
556 556 for phase, roots in self._phaseroots.items():
557 557 for r in sorted(roots):
558 558 h = to_node(r)
559 559 fp.write(b'%i %s\n' % (phase, hex(h)))
560 560 self.dirty = False
561 561
562 562 def _updateroots(self, repo, phase, newroots, tr):
563 563 self._phaseroots[phase] = newroots
564 564 self.invalidate()
565 565 self.dirty = True
566 566
567 567 assert repo.filtername is None
568 568 wrepo = weakref.ref(repo)
569 569
570 570 def tr_write(fp):
571 571 repo = wrepo()
572 572 assert repo is not None
573 573 self._write(repo, fp)
574 574
575 575 tr.addfilegenerator(b'phase', (b'phaseroots',), tr_write)
576 576 tr.hookargs[b'phases_moved'] = b'1'
577 577
578 578 def registernew(self, repo, tr, targetphase, revs):
579 579 repo = repo.unfiltered()
580 580 self._retractboundary(repo, tr, targetphase, [], revs=revs)
581 581 if tr is not None and b'phases' in tr.changes:
582 582 phasetracking = tr.changes[b'phases']
583 583 phase = self.phase
584 584 for rev in sorted(revs):
585 585 revphase = phase(repo, rev)
586 586 _trackphasechange(phasetracking, rev, None, revphase)
587 587 repo.invalidatevolatilesets()
588 588
589 589 def advanceboundary(
590 590 self, repo, tr, targetphase, nodes=None, revs=None, dryrun=None
591 591 ):
592 592 """Set all 'nodes' to phase 'targetphase'
593 593
594 594 Nodes with a phase lower than 'targetphase' are not affected.
595 595
596 596 If dryrun is True, no actions will be performed
597 597
598 598 Returns a set of revs whose phase is changed or should be changed
599 599 """
600 600 if targetphase == public and not self.hasnonpublicphases(repo):
601 601 return set()
602 602 # Be careful to preserve shallow-copied values: do not update
603 603 # phaseroots values, replace them.
604 604 if revs is None:
605 605 revs = []
606 606 if not revs and not nodes:
607 607 return set()
608 608 if tr is None:
609 609 phasetracking = None
610 610 else:
611 611 phasetracking = tr.changes.get(b'phases')
612 612
613 613 repo = repo.unfiltered()
614 614 revs = [repo[n].rev() for n in nodes] + [r for r in revs]
615 615
616 616 changes = set() # set of revisions to be changed
617 617 delroots = [] # set of root deleted by this path
618 618 for phase in (phase for phase in allphases if phase > targetphase):
619 619 # filter nodes that are not in a compatible phase already
620 620 revs = [rev for rev in revs if self.phase(repo, rev) >= phase]
621 621 if not revs:
622 622 break # no roots to move anymore
623 623
624 624 olds = self._phaseroots[phase]
625 625
626 626 affected = repo.revs(b'%ld::%ld', olds, revs)
627 627 changes.update(affected)
628 628 if dryrun:
629 629 continue
630 630 for r in affected:
631 631 _trackphasechange(
632 632 phasetracking, r, self.phase(repo, r), targetphase
633 633 )
634 634
635 635 roots = set(repo.revs(b'roots((%ld::) - %ld)', olds, affected))
636 636 if olds != roots:
637 637 self._updateroots(repo, phase, roots, tr)
638 638 # some roots may need to be declared for lower phases
639 639 delroots.extend(olds - roots)
640 640 if not dryrun:
641 641 # declare deleted root in the target phase
642 642 if targetphase != 0:
643 643 self._retractboundary(repo, tr, targetphase, revs=delroots)
644 644 repo.invalidatevolatilesets()
645 645 return changes
646 646
647 647 def retractboundary(self, repo, tr, targetphase, nodes):
648 oldroots = {
649 phase: revs
650 for phase, revs in self._phaseroots.items()
651 if phase <= targetphase
652 }
653 648 if tr is None:
654 649 phasetracking = None
655 650 else:
656 651 phasetracking = tr.changes.get(b'phases')
657 652 repo = repo.unfiltered()
658 653 retracted = self._retractboundary(repo, tr, targetphase, nodes)
659 654 if retracted and phasetracking is not None:
660
661 # find the affected revisions
662 new = self._phaseroots[targetphase]
663 old = oldroots[targetphase]
664 affected = set(repo.revs(b'(%ld::) - (%ld::)', new, old))
665
666 # find the phase of the affected revision
667 for phase in range(targetphase, -1, -1):
668 if phase:
669 roots = oldroots.get(phase, [])
670 revs = set(repo.revs(b'%ld::%ld', roots, affected))
671 affected -= revs
672 else: # public phase
673 revs = affected
674 for r in sorted(revs):
675 _trackphasechange(phasetracking, r, phase, targetphase)
655 for r, old_phase in sorted(retracted.items()):
656 _trackphasechange(phasetracking, r, old_phase, targetphase)
676 657 repo.invalidatevolatilesets()
677 658
678 659 def _retractboundary(self, repo, tr, targetphase, nodes=None, revs=None):
679 660 if targetphase == public:
680 661 return {}
681 662 if (
682 663 targetphase == internal
683 664 and not supportinternal(repo)
684 665 or targetphase == archived
685 666 and not supportarchived(repo)
686 667 ):
687 668 name = phasenames[targetphase]
688 669 msg = b'this repository does not support the %s phase' % name
689 670 raise error.ProgrammingError(msg)
690 671 assert repo.filtername is None
691 672 cl = repo.changelog
692 673 torev = cl.index.rev
693 674 new_revs = set()
694 675 if revs is not None:
695 676 new_revs.update(revs)
696 677 if nodes is not None:
697 678 new_revs.update(torev(node) for node in nodes)
698 679 if not new_revs: # bail out early to avoid the loadphaserevs call
699 680 return {} # note: why do people call retractboundary with nothing ?
700 681
701 682 if nullrev in new_revs:
702 683 raise error.Abort(_(b'cannot change null revision phase'))
703 684
704 685 # Compute change in phase roots by walking the graph
705 686 #
706 687 # note: If we had a cheap parent β†’ children mapping we could do
707 688 # something even cheaper/more-bounded
708 689 #
709 690 # The idea would be to walk from item in new_revs stopping at
710 691 # descendant with phases >= target_phase.
711 692 #
712 693 # 1) This detect new_revs that are not new_roots (either already >=
713 694 # target_phase or reachable though another new_revs
714 695 # 2) This detect replaced current_roots as we reach them
715 696 # 3) This can avoid walking to the tip if we retract over a small
716 697 # branch.
717 698 #
718 699 # So instead, we do a variation of this, we walk from the smaller new
719 700 # revision to the tip to avoid missing any potential children.
720 701 #
721 702 # The following code would be a good candidate for native code… if only
722 703 # we could knew the phase of a changeset efficiently in native code.
723 704 parents = cl.parentrevs
724 705 phase = self.phase
725 706 new_roots = set() # roots added by this phases
726 707 changed_revs = {} # revision affected by this call
727 708 replaced_roots = set() # older roots replaced by this call
728 709 currentroots = self._phaseroots[targetphase]
729 710 start = min(new_revs)
730 711 end = len(cl)
731 712 rev_phases = [None] * (end - start)
732 713 for r in range(start, end):
733 714
734 715 # gather information about the current_rev
735 716 r_phase = phase(repo, r)
736 717 p_phase = None # phase inherited from parents
737 718 p1, p2 = parents(r)
738 719 if p1 >= start:
739 720 p1_phase = rev_phases[p1 - start]
740 721 if p1_phase is not None:
741 722 p_phase = p1_phase
742 723 if p2 >= start:
743 724 p2_phase = rev_phases[p2 - start]
744 725 if p2_phase is not None:
745 726 if p_phase is not None:
746 727 p_phase = max(p_phase, p2_phase)
747 728 else:
748 729 p_phase = p2_phase
749 730
750 731 # assess the situation
751 732 if r in new_revs and r_phase < targetphase:
752 733 if p_phase is None or p_phase < targetphase:
753 734 new_roots.add(r)
754 735 rev_phases[r - start] = targetphase
755 736 changed_revs[r] = r_phase
756 737 elif p_phase is None:
757 738 rev_phases[r - start] = r_phase
758 739 else:
759 740 if p_phase > r_phase:
760 741 rev_phases[r - start] = p_phase
761 742 else:
762 743 rev_phases[r - start] = r_phase
763 744 if p_phase == targetphase:
764 745 if p_phase > r_phase:
765 746 changed_revs[r] = r_phase
766 747 elif r in currentroots:
767 748 replaced_roots.add(r)
768 749
769 750 if new_roots:
770 751 assert changed_revs
771 752 final_roots = new_roots | currentroots - replaced_roots
772 753 self._updateroots(repo, targetphase, final_roots, tr)
773 754 if targetphase > 1:
774 755 retracted = set(changed_revs)
775 756 for lower_phase in range(1, targetphase):
776 757 lower_roots = self._phaseroots.get(lower_phase)
777 758 if lower_roots is None:
778 759 continue
779 760 if lower_roots & retracted:
780 761 simpler_roots = lower_roots - retracted
781 762 self._updateroots(repo, lower_phase, simpler_roots, tr)
782 763 return changed_revs
783 764 else:
784 765 assert not changed_revs
785 766 assert not replaced_roots
786 767 return {}
787 768
788 769 def register_strip(
789 770 self,
790 771 repo,
791 772 tr,
792 773 strip_rev: int,
793 774 ):
794 775 """announce a strip to the phase cache
795 776
796 777 Any roots higher than the stripped revision should be dropped.
797 778 """
798 779 for targetphase, roots in list(self._phaseroots.items()):
799 780 filtered = {r for r in roots if r >= strip_rev}
800 781 if filtered:
801 782 self._updateroots(repo, targetphase, roots - filtered, tr)
802 783 self.invalidate()
803 784
804 785
805 786 def advanceboundary(repo, tr, targetphase, nodes, revs=None, dryrun=None):
806 787 """Add nodes to a phase changing other nodes phases if necessary.
807 788
808 789 This function move boundary *forward* this means that all nodes
809 790 are set in the target phase or kept in a *lower* phase.
810 791
811 792 Simplify boundary to contains phase roots only.
812 793
813 794 If dryrun is True, no actions will be performed
814 795
815 796 Returns a set of revs whose phase is changed or should be changed
816 797 """
817 798 if revs is None:
818 799 revs = []
819 800 phcache = repo._phasecache.copy()
820 801 changes = phcache.advanceboundary(
821 802 repo, tr, targetphase, nodes, revs=revs, dryrun=dryrun
822 803 )
823 804 if not dryrun:
824 805 repo._phasecache.replace(phcache)
825 806 return changes
826 807
827 808
828 809 def retractboundary(repo, tr, targetphase, nodes):
829 810 """Set nodes back to a phase changing other nodes phases if
830 811 necessary.
831 812
832 813 This function move boundary *backward* this means that all nodes
833 814 are set in the target phase or kept in a *higher* phase.
834 815
835 816 Simplify boundary to contains phase roots only."""
836 817 phcache = repo._phasecache.copy()
837 818 phcache.retractboundary(repo, tr, targetphase, nodes)
838 819 repo._phasecache.replace(phcache)
839 820
840 821
841 822 def registernew(repo, tr, targetphase, revs):
842 823 """register a new revision and its phase
843 824
844 825 Code adding revisions to the repository should use this function to
845 826 set new changeset in their target phase (or higher).
846 827 """
847 828 phcache = repo._phasecache.copy()
848 829 phcache.registernew(repo, tr, targetphase, revs)
849 830 repo._phasecache.replace(phcache)
850 831
851 832
852 833 def listphases(repo: "localrepo.localrepository") -> Dict[bytes, bytes]:
853 834 """List phases root for serialization over pushkey"""
854 835 # Use ordered dictionary so behavior is deterministic.
855 836 keys = util.sortdict()
856 837 value = b'%i' % draft
857 838 cl = repo.unfiltered().changelog
858 839 to_node = cl.node
859 840 for root in repo._phasecache._phaseroots[draft]:
860 841 if repo._phasecache.phase(repo, root) <= draft:
861 842 keys[hex(to_node(root))] = value
862 843
863 844 if repo.publishing():
864 845 # Add an extra data to let remote know we are a publishing
865 846 # repo. Publishing repo can't just pretend they are old repo.
866 847 # When pushing to a publishing repo, the client still need to
867 848 # push phase boundary
868 849 #
869 850 # Push do not only push changeset. It also push phase data.
870 851 # New phase data may apply to common changeset which won't be
871 852 # push (as they are common). Here is a very simple example:
872 853 #
873 854 # 1) repo A push changeset X as draft to repo B
874 855 # 2) repo B make changeset X public
875 856 # 3) repo B push to repo A. X is not pushed but the data that
876 857 # X as now public should
877 858 #
878 859 # The server can't handle it on it's own as it has no idea of
879 860 # client phase data.
880 861 keys[b'publishing'] = b'True'
881 862 return keys
882 863
883 864
884 865 def pushphase(
885 866 repo: "localrepo.localrepository",
886 867 nhex: bytes,
887 868 oldphasestr: bytes,
888 869 newphasestr: bytes,
889 870 ) -> bool:
890 871 """List phases root for serialization over pushkey"""
891 872 repo = repo.unfiltered()
892 873 with repo.lock():
893 874 currentphase = repo[nhex].phase()
894 875 newphase = abs(int(newphasestr)) # let's avoid negative index surprise
895 876 oldphase = abs(int(oldphasestr)) # let's avoid negative index surprise
896 877 if currentphase == oldphase and newphase < oldphase:
897 878 with repo.transaction(b'pushkey-phase') as tr:
898 879 advanceboundary(repo, tr, newphase, [bin(nhex)])
899 880 return True
900 881 elif currentphase == newphase:
901 882 # raced, but got correct result
902 883 return True
903 884 else:
904 885 return False
905 886
906 887
907 888 def subsetphaseheads(repo, subset):
908 889 """Finds the phase heads for a subset of a history
909 890
910 891 Returns a list indexed by phase number where each item is a list of phase
911 892 head nodes.
912 893 """
913 894 cl = repo.changelog
914 895
915 896 headsbyphase = {i: [] for i in allphases}
916 897 for phase in allphases:
917 898 revset = b"heads(%%ln & _phase(%d))" % phase
918 899 headsbyphase[phase] = [cl.node(r) for r in repo.revs(revset, subset)]
919 900 return headsbyphase
920 901
921 902
922 903 def updatephases(repo, trgetter, headsbyphase):
923 904 """Updates the repo with the given phase heads"""
924 905 # Now advance phase boundaries of all phases
925 906 #
926 907 # run the update (and fetch transaction) only if there are actually things
927 908 # to update. This avoid creating empty transaction during no-op operation.
928 909
929 910 for phase in allphases:
930 911 revset = b'%ln - _phase(%s)'
931 912 heads = [c.node() for c in repo.set(revset, headsbyphase[phase], phase)]
932 913 if heads:
933 914 advanceboundary(repo, trgetter(), phase, heads)
934 915
935 916
936 917 def analyzeremotephases(repo, subset, roots):
937 918 """Compute phases heads and root in a subset of node from root dict
938 919
939 920 * subset is heads of the subset
940 921 * roots is {<nodeid> => phase} mapping. key and value are string.
941 922
942 923 Accept unknown element input
943 924 """
944 925 repo = repo.unfiltered()
945 926 # build list from dictionary
946 927 draftroots = []
947 928 has_node = repo.changelog.index.has_node # to filter unknown nodes
948 929 for nhex, phase in roots.items():
949 930 if nhex == b'publishing': # ignore data related to publish option
950 931 continue
951 932 node = bin(nhex)
952 933 phase = int(phase)
953 934 if phase == public:
954 935 if node != repo.nullid:
955 936 repo.ui.warn(
956 937 _(
957 938 b'ignoring inconsistent public root'
958 939 b' from remote: %s\n'
959 940 )
960 941 % nhex
961 942 )
962 943 elif phase == draft:
963 944 if has_node(node):
964 945 draftroots.append(node)
965 946 else:
966 947 repo.ui.warn(
967 948 _(b'ignoring unexpected root from remote: %i %s\n')
968 949 % (phase, nhex)
969 950 )
970 951 # compute heads
971 952 publicheads = newheads(repo, subset, draftroots)
972 953 return publicheads, draftroots
973 954
974 955
975 956 class remotephasessummary:
976 957 """summarize phase information on the remote side
977 958
978 959 :publishing: True is the remote is publishing
979 960 :publicheads: list of remote public phase heads (nodes)
980 961 :draftheads: list of remote draft phase heads (nodes)
981 962 :draftroots: list of remote draft phase root (nodes)
982 963 """
983 964
984 965 def __init__(self, repo, remotesubset, remoteroots):
985 966 unfi = repo.unfiltered()
986 967 self._allremoteroots = remoteroots
987 968
988 969 self.publishing = remoteroots.get(b'publishing', False)
989 970
990 971 ana = analyzeremotephases(repo, remotesubset, remoteroots)
991 972 self.publicheads, self.draftroots = ana
992 973 # Get the list of all "heads" revs draft on remote
993 974 dheads = unfi.set(b'heads(%ln::%ln)', self.draftroots, remotesubset)
994 975 self.draftheads = [c.node() for c in dheads]
995 976
996 977
997 978 def newheads(repo, heads, roots):
998 979 """compute new head of a subset minus another
999 980
1000 981 * `heads`: define the first subset
1001 982 * `roots`: define the second we subtract from the first"""
1002 983 # prevent an import cycle
1003 984 # phases > dagop > patch > copies > scmutil > obsolete > obsutil > phases
1004 985 from . import dagop
1005 986
1006 987 repo = repo.unfiltered()
1007 988 cl = repo.changelog
1008 989 rev = cl.index.get_rev
1009 990 if not roots:
1010 991 return heads
1011 992 if not heads or heads == [repo.nullid]:
1012 993 return []
1013 994 # The logic operated on revisions, convert arguments early for convenience
1014 995 new_heads = {rev(n) for n in heads if n != repo.nullid}
1015 996 roots = [rev(n) for n in roots]
1016 997 # compute the area we need to remove
1017 998 affected_zone = repo.revs(b"(%ld::%ld)", roots, new_heads)
1018 999 # heads in the area are no longer heads
1019 1000 new_heads.difference_update(affected_zone)
1020 1001 # revisions in the area have children outside of it,
1021 1002 # They might be new heads
1022 1003 candidates = repo.revs(
1023 1004 b"parents(%ld + (%ld and merge())) and not null", roots, affected_zone
1024 1005 )
1025 1006 candidates -= affected_zone
1026 1007 if new_heads or candidates:
1027 1008 # remove candidate that are ancestors of other heads
1028 1009 new_heads.update(candidates)
1029 1010 prunestart = repo.revs(b"parents(%ld) and not null", new_heads)
1030 1011 pruned = dagop.reachableroots(repo, candidates, prunestart)
1031 1012 new_heads.difference_update(pruned)
1032 1013
1033 1014 return pycompat.maplist(cl.node, sorted(new_heads))
1034 1015
1035 1016
1036 1017 def newcommitphase(ui: "uimod.ui") -> int:
1037 1018 """helper to get the target phase of new commit
1038 1019
1039 1020 Handle all possible values for the phases.new-commit options.
1040 1021
1041 1022 """
1042 1023 v = ui.config(b'phases', b'new-commit')
1043 1024 try:
1044 1025 return phasenumber2[v]
1045 1026 except KeyError:
1046 1027 raise error.ConfigError(
1047 1028 _(b"phases.new-commit: not a valid phase name ('%s')") % v
1048 1029 )
1049 1030
1050 1031
1051 1032 def hassecret(repo: "localrepo.localrepository") -> bool:
1052 1033 """utility function that check if a repo have any secret changeset."""
1053 1034 return bool(repo._phasecache._phaseroots[secret])
1054 1035
1055 1036
1056 1037 def preparehookargs(
1057 1038 node: bytes,
1058 1039 old: Optional[int],
1059 1040 new: Optional[int],
1060 1041 ) -> Dict[bytes, bytes]:
1061 1042 if old is None:
1062 1043 old = b''
1063 1044 else:
1064 1045 old = phasenames[old]
1065 1046 return {b'node': node, b'oldphase': old, b'phase': phasenames[new]}
@@ -1,1845 +1,1844 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [extensions]
3 3 > drawdag=$TESTDIR/drawdag.py
4 4 > phasereport=$TESTDIR/testlib/ext-phase-report.py
5 5 > EOF
6 6
7 7 $ hgph() { hg log -G --template "{rev} {phase} {desc} - {node|short}\n" $*; }
8 8
9 9 $ mkcommit() {
10 10 > echo "$1" > "$1"
11 11 > hg add "$1"
12 12 > message="$1"
13 13 > shift
14 14 > hg ci -m "$message" $*
15 15 > }
16 16
17 17 $ hg init alpha
18 18 $ cd alpha
19 19 $ mkcommit a-A
20 20 test-debug-phase: new rev 0: x -> 1
21 21 $ mkcommit a-B
22 22 test-debug-phase: new rev 1: x -> 1
23 23 $ mkcommit a-C
24 24 test-debug-phase: new rev 2: x -> 1
25 25 $ mkcommit a-D
26 26 test-debug-phase: new rev 3: x -> 1
27 27 $ hgph
28 28 @ 3 draft a-D - b555f63b6063
29 29 |
30 30 o 2 draft a-C - 54acac6f23ab
31 31 |
32 32 o 1 draft a-B - 548a3d25dbf0
33 33 |
34 34 o 0 draft a-A - 054250a37db4
35 35
36 36
37 37 $ hg init ../beta
38 38 $ hg push -r 1 ../beta
39 39 pushing to ../beta
40 40 searching for changes
41 41 adding changesets
42 42 adding manifests
43 43 adding file changes
44 44 added 2 changesets with 2 changes to 2 files
45 45 test-debug-phase: new rev 0: x -> 0
46 46 test-debug-phase: new rev 1: x -> 0
47 47 test-debug-phase: move rev 0: 1 -> 0
48 48 test-debug-phase: move rev 1: 1 -> 0
49 49 $ hgph
50 50 @ 3 draft a-D - b555f63b6063
51 51 |
52 52 o 2 draft a-C - 54acac6f23ab
53 53 |
54 54 o 1 public a-B - 548a3d25dbf0
55 55 |
56 56 o 0 public a-A - 054250a37db4
57 57
58 58
59 59 $ cd ../beta
60 60 $ hgph
61 61 o 1 public a-B - 548a3d25dbf0
62 62 |
63 63 o 0 public a-A - 054250a37db4
64 64
65 65 $ hg up -q
66 66 $ mkcommit b-A
67 67 test-debug-phase: new rev 2: x -> 1
68 68 $ hgph
69 69 @ 2 draft b-A - f54f1bb90ff3
70 70 |
71 71 o 1 public a-B - 548a3d25dbf0
72 72 |
73 73 o 0 public a-A - 054250a37db4
74 74
75 75 $ hg pull ../alpha
76 76 pulling from ../alpha
77 77 searching for changes
78 78 adding changesets
79 79 adding manifests
80 80 adding file changes
81 81 added 2 changesets with 2 changes to 2 files (+1 heads)
82 82 new changesets 54acac6f23ab:b555f63b6063
83 83 test-debug-phase: new rev 3: x -> 0
84 84 test-debug-phase: new rev 4: x -> 0
85 85 (run 'hg heads' to see heads, 'hg merge' to merge)
86 86 $ hgph
87 87 o 4 public a-D - b555f63b6063
88 88 |
89 89 o 3 public a-C - 54acac6f23ab
90 90 |
91 91 | @ 2 draft b-A - f54f1bb90ff3
92 92 |/
93 93 o 1 public a-B - 548a3d25dbf0
94 94 |
95 95 o 0 public a-A - 054250a37db4
96 96
97 97
98 98 pull did not updated ../alpha state.
99 99 push from alpha to beta should update phase even if nothing is transferred
100 100
101 101 $ cd ../alpha
102 102 $ hgph # not updated by remote pull
103 103 @ 3 draft a-D - b555f63b6063
104 104 |
105 105 o 2 draft a-C - 54acac6f23ab
106 106 |
107 107 o 1 public a-B - 548a3d25dbf0
108 108 |
109 109 o 0 public a-A - 054250a37db4
110 110
111 111 $ hg push -r 2 ../beta
112 112 pushing to ../beta
113 113 searching for changes
114 114 no changes found
115 115 test-debug-phase: move rev 2: 1 -> 0
116 116 [1]
117 117 $ hgph
118 118 @ 3 draft a-D - b555f63b6063
119 119 |
120 120 o 2 public a-C - 54acac6f23ab
121 121 |
122 122 o 1 public a-B - 548a3d25dbf0
123 123 |
124 124 o 0 public a-A - 054250a37db4
125 125
126 126 $ hg push ../beta
127 127 pushing to ../beta
128 128 searching for changes
129 129 no changes found
130 130 test-debug-phase: move rev 3: 1 -> 0
131 131 [1]
132 132 $ hgph
133 133 @ 3 public a-D - b555f63b6063
134 134 |
135 135 o 2 public a-C - 54acac6f23ab
136 136 |
137 137 o 1 public a-B - 548a3d25dbf0
138 138 |
139 139 o 0 public a-A - 054250a37db4
140 140
141 141
142 142 update must update phase of common changeset too
143 143
144 144 $ hg pull ../beta # getting b-A
145 145 pulling from ../beta
146 146 searching for changes
147 147 adding changesets
148 148 adding manifests
149 149 adding file changes
150 150 added 1 changesets with 1 changes to 1 files (+1 heads)
151 151 new changesets f54f1bb90ff3
152 152 test-debug-phase: new rev 4: x -> 0
153 153 (run 'hg heads' to see heads, 'hg merge' to merge)
154 154
155 155 $ cd ../beta
156 156 $ hgph # not updated by remote pull
157 157 o 4 public a-D - b555f63b6063
158 158 |
159 159 o 3 public a-C - 54acac6f23ab
160 160 |
161 161 | @ 2 draft b-A - f54f1bb90ff3
162 162 |/
163 163 o 1 public a-B - 548a3d25dbf0
164 164 |
165 165 o 0 public a-A - 054250a37db4
166 166
167 167 $ hg pull ../alpha
168 168 pulling from ../alpha
169 169 searching for changes
170 170 no changes found
171 171 1 local changesets published
172 172 test-debug-phase: move rev 2: 1 -> 0
173 173 $ hgph
174 174 o 4 public a-D - b555f63b6063
175 175 |
176 176 o 3 public a-C - 54acac6f23ab
177 177 |
178 178 | @ 2 public b-A - f54f1bb90ff3
179 179 |/
180 180 o 1 public a-B - 548a3d25dbf0
181 181 |
182 182 o 0 public a-A - 054250a37db4
183 183
184 184
185 185 Publish configuration option
186 186 ----------------------------
187 187
188 188 Pull
189 189 ````
190 190
191 191 changegroup are added without phase movement
192 192
193 193 $ hg bundle -a ../base.bundle
194 194 5 changesets found
195 195 $ cd ..
196 196 $ hg init mu
197 197 $ cd mu
198 198 $ cat > .hg/hgrc << EOF
199 199 > [phases]
200 200 > publish=0
201 201 > EOF
202 202 $ hg unbundle ../base.bundle
203 203 adding changesets
204 204 adding manifests
205 205 adding file changes
206 206 added 5 changesets with 5 changes to 5 files (+1 heads)
207 207 new changesets 054250a37db4:b555f63b6063 (5 drafts)
208 208 test-debug-phase: new rev 0: x -> 1
209 209 test-debug-phase: new rev 1: x -> 1
210 210 test-debug-phase: new rev 2: x -> 1
211 211 test-debug-phase: new rev 3: x -> 1
212 212 test-debug-phase: new rev 4: x -> 1
213 213 (run 'hg heads' to see heads, 'hg merge' to merge)
214 214 $ hgph
215 215 o 4 draft a-D - b555f63b6063
216 216 |
217 217 o 3 draft a-C - 54acac6f23ab
218 218 |
219 219 | o 2 draft b-A - f54f1bb90ff3
220 220 |/
221 221 o 1 draft a-B - 548a3d25dbf0
222 222 |
223 223 o 0 draft a-A - 054250a37db4
224 224
225 225 $ cd ..
226 226
227 227 Pulling from publish=False to publish=False does not move boundary.
228 228
229 229 $ hg init nu
230 230 $ cd nu
231 231 $ cat > .hg/hgrc << EOF
232 232 > [phases]
233 233 > publish=0
234 234 > EOF
235 235 $ hg pull ../mu -r 54acac6f23ab
236 236 pulling from ../mu
237 237 adding changesets
238 238 adding manifests
239 239 adding file changes
240 240 added 3 changesets with 3 changes to 3 files
241 241 new changesets 054250a37db4:54acac6f23ab (3 drafts)
242 242 test-debug-phase: new rev 0: x -> 1
243 243 test-debug-phase: new rev 1: x -> 1
244 244 test-debug-phase: new rev 2: x -> 1
245 245 (run 'hg update' to get a working copy)
246 246 $ hgph
247 247 o 2 draft a-C - 54acac6f23ab
248 248 |
249 249 o 1 draft a-B - 548a3d25dbf0
250 250 |
251 251 o 0 draft a-A - 054250a37db4
252 252
253 253
254 254 Even for common
255 255
256 256 $ hg pull ../mu -r f54f1bb90ff3
257 257 pulling from ../mu
258 258 searching for changes
259 259 adding changesets
260 260 adding manifests
261 261 adding file changes
262 262 added 1 changesets with 1 changes to 1 files (+1 heads)
263 263 new changesets f54f1bb90ff3 (1 drafts)
264 264 test-debug-phase: new rev 3: x -> 1
265 265 (run 'hg heads' to see heads, 'hg merge' to merge)
266 266 $ hgph
267 267 o 3 draft b-A - f54f1bb90ff3
268 268 |
269 269 | o 2 draft a-C - 54acac6f23ab
270 270 |/
271 271 o 1 draft a-B - 548a3d25dbf0
272 272 |
273 273 o 0 draft a-A - 054250a37db4
274 274
275 275
276 276
277 277 Pulling from Publish=True to Publish=False move boundary in common set.
278 278 we are in nu
279 279
280 280 $ hg pull ../alpha -r b555f63b6063
281 281 pulling from ../alpha
282 282 searching for changes
283 283 adding changesets
284 284 adding manifests
285 285 adding file changes
286 286 added 1 changesets with 1 changes to 1 files
287 287 new changesets b555f63b6063
288 288 3 local changesets published
289 289 test-debug-phase: move rev 0: 1 -> 0
290 290 test-debug-phase: move rev 1: 1 -> 0
291 291 test-debug-phase: move rev 2: 1 -> 0
292 292 test-debug-phase: new rev 4: x -> 0
293 293 (run 'hg update' to get a working copy)
294 294 $ hgph # f54f1bb90ff3 stay draft, not ancestor of -r
295 295 o 4 public a-D - b555f63b6063
296 296 |
297 297 | o 3 draft b-A - f54f1bb90ff3
298 298 | |
299 299 o | 2 public a-C - 54acac6f23ab
300 300 |/
301 301 o 1 public a-B - 548a3d25dbf0
302 302 |
303 303 o 0 public a-A - 054250a37db4
304 304
305 305
306 306 pulling from Publish=False to publish=False with some public
307 307
308 308 $ hg up -q f54f1bb90ff3
309 309 $ mkcommit n-A
310 310 test-debug-phase: new rev 5: x -> 1
311 311 $ mkcommit n-B
312 312 test-debug-phase: new rev 6: x -> 1
313 313 $ hgph
314 314 @ 6 draft n-B - 145e75495359
315 315 |
316 316 o 5 draft n-A - d6bcb4f74035
317 317 |
318 318 | o 4 public a-D - b555f63b6063
319 319 | |
320 320 o | 3 draft b-A - f54f1bb90ff3
321 321 | |
322 322 | o 2 public a-C - 54acac6f23ab
323 323 |/
324 324 o 1 public a-B - 548a3d25dbf0
325 325 |
326 326 o 0 public a-A - 054250a37db4
327 327
328 328 $ cd ../mu
329 329 $ hg pull ../nu --confirm --config ui.interactive=True<<EOF
330 330 > y
331 331 > EOF
332 332 pulling from ../nu
333 333 searching for changes
334 334 adding changesets
335 335 adding manifests
336 336 adding file changes
337 337 adding 2 changesets with 2 changes to 2 files
338 338 new changesets d6bcb4f74035:145e75495359 (2 drafts)
339 339 4 local changesets will be published
340 340 accept incoming changes (yn)? y
341 341 added 2 changesets with 2 changes to 2 files
342 342 new changesets d6bcb4f74035:145e75495359 (2 drafts)
343 343 4 local changesets published
344 344 test-debug-phase: move rev 0: 1 -> 0
345 345 test-debug-phase: move rev 1: 1 -> 0
346 346 test-debug-phase: move rev 3: 1 -> 0
347 347 test-debug-phase: move rev 4: 1 -> 0
348 348 test-debug-phase: new rev 5: x -> 1
349 349 test-debug-phase: new rev 6: x -> 1
350 350 (run 'hg update' to get a working copy)
351 351 $ hgph
352 352 o 6 draft n-B - 145e75495359
353 353 |
354 354 o 5 draft n-A - d6bcb4f74035
355 355 |
356 356 | o 4 public a-D - b555f63b6063
357 357 | |
358 358 | o 3 public a-C - 54acac6f23ab
359 359 | |
360 360 o | 2 draft b-A - f54f1bb90ff3
361 361 |/
362 362 o 1 public a-B - 548a3d25dbf0
363 363 |
364 364 o 0 public a-A - 054250a37db4
365 365
366 366 $ cd ..
367 367
368 368 pulling into publish=True
369 369
370 370 $ cd alpha
371 371 $ hgph
372 372 o 4 public b-A - f54f1bb90ff3
373 373 |
374 374 | @ 3 public a-D - b555f63b6063
375 375 | |
376 376 | o 2 public a-C - 54acac6f23ab
377 377 |/
378 378 o 1 public a-B - 548a3d25dbf0
379 379 |
380 380 o 0 public a-A - 054250a37db4
381 381
382 382 $ hg pull ../mu
383 383 pulling from ../mu
384 384 searching for changes
385 385 adding changesets
386 386 adding manifests
387 387 adding file changes
388 388 added 2 changesets with 2 changes to 2 files
389 389 new changesets d6bcb4f74035:145e75495359 (2 drafts)
390 390 test-debug-phase: new rev 5: x -> 1
391 391 test-debug-phase: new rev 6: x -> 1
392 392 (run 'hg update' to get a working copy)
393 393 $ hgph
394 394 o 6 draft n-B - 145e75495359
395 395 |
396 396 o 5 draft n-A - d6bcb4f74035
397 397 |
398 398 o 4 public b-A - f54f1bb90ff3
399 399 |
400 400 | @ 3 public a-D - b555f63b6063
401 401 | |
402 402 | o 2 public a-C - 54acac6f23ab
403 403 |/
404 404 o 1 public a-B - 548a3d25dbf0
405 405 |
406 406 o 0 public a-A - 054250a37db4
407 407
408 408 $ cd ..
409 409
410 410 pulling back into original repo
411 411
412 412 $ cd nu
413 413 $ hg pull ../alpha
414 414 pulling from ../alpha
415 415 searching for changes
416 416 no changes found
417 417 3 local changesets published
418 418 test-debug-phase: move rev 3: 1 -> 0
419 419 test-debug-phase: move rev 5: 1 -> 0
420 420 test-debug-phase: move rev 6: 1 -> 0
421 421 $ hgph
422 422 @ 6 public n-B - 145e75495359
423 423 |
424 424 o 5 public n-A - d6bcb4f74035
425 425 |
426 426 | o 4 public a-D - b555f63b6063
427 427 | |
428 428 o | 3 public b-A - f54f1bb90ff3
429 429 | |
430 430 | o 2 public a-C - 54acac6f23ab
431 431 |/
432 432 o 1 public a-B - 548a3d25dbf0
433 433 |
434 434 o 0 public a-A - 054250a37db4
435 435
436 436
437 437 Push
438 438 ````
439 439
440 440 (inserted)
441 441
442 442 Test that phase are pushed even when they are nothing to pus
443 443 (this might be tested later bu are very convenient to not alter too much test)
444 444
445 445 Push back to alpha
446 446
447 447 $ hg push ../alpha # from nu
448 448 pushing to ../alpha
449 449 searching for changes
450 450 no changes found
451 451 test-debug-phase: move rev 5: 1 -> 0
452 452 test-debug-phase: move rev 6: 1 -> 0
453 453 [1]
454 454 $ cd ..
455 455 $ cd alpha
456 456 $ hgph
457 457 o 6 public n-B - 145e75495359
458 458 |
459 459 o 5 public n-A - d6bcb4f74035
460 460 |
461 461 o 4 public b-A - f54f1bb90ff3
462 462 |
463 463 | @ 3 public a-D - b555f63b6063
464 464 | |
465 465 | o 2 public a-C - 54acac6f23ab
466 466 |/
467 467 o 1 public a-B - 548a3d25dbf0
468 468 |
469 469 o 0 public a-A - 054250a37db4
470 470
471 471
472 472 (end insertion)
473 473
474 474
475 475 initial setup
476 476
477 477 $ hg log -G # of alpha
478 478 o changeset: 6:145e75495359
479 479 | tag: tip
480 480 | user: test
481 481 | date: Thu Jan 01 00:00:00 1970 +0000
482 482 | summary: n-B
483 483 |
484 484 o changeset: 5:d6bcb4f74035
485 485 | user: test
486 486 | date: Thu Jan 01 00:00:00 1970 +0000
487 487 | summary: n-A
488 488 |
489 489 o changeset: 4:f54f1bb90ff3
490 490 | parent: 1:548a3d25dbf0
491 491 | user: test
492 492 | date: Thu Jan 01 00:00:00 1970 +0000
493 493 | summary: b-A
494 494 |
495 495 | @ changeset: 3:b555f63b6063
496 496 | | user: test
497 497 | | date: Thu Jan 01 00:00:00 1970 +0000
498 498 | | summary: a-D
499 499 | |
500 500 | o changeset: 2:54acac6f23ab
501 501 |/ user: test
502 502 | date: Thu Jan 01 00:00:00 1970 +0000
503 503 | summary: a-C
504 504 |
505 505 o changeset: 1:548a3d25dbf0
506 506 | user: test
507 507 | date: Thu Jan 01 00:00:00 1970 +0000
508 508 | summary: a-B
509 509 |
510 510 o changeset: 0:054250a37db4
511 511 user: test
512 512 date: Thu Jan 01 00:00:00 1970 +0000
513 513 summary: a-A
514 514
515 515 $ mkcommit a-E
516 516 test-debug-phase: new rev 7: x -> 1
517 517 $ mkcommit a-F
518 518 test-debug-phase: new rev 8: x -> 1
519 519 $ mkcommit a-G
520 520 test-debug-phase: new rev 9: x -> 1
521 521 $ hg up d6bcb4f74035 -q
522 522 $ mkcommit a-H
523 523 test-debug-phase: new rev 10: x -> 1
524 524 created new head
525 525 $ hgph
526 526 @ 10 draft a-H - 967b449fbc94
527 527 |
528 528 | o 9 draft a-G - 3e27b6f1eee1
529 529 | |
530 530 | o 8 draft a-F - b740e3e5c05d
531 531 | |
532 532 | o 7 draft a-E - e9f537e46dea
533 533 | |
534 534 +---o 6 public n-B - 145e75495359
535 535 | |
536 536 o | 5 public n-A - d6bcb4f74035
537 537 | |
538 538 o | 4 public b-A - f54f1bb90ff3
539 539 | |
540 540 | o 3 public a-D - b555f63b6063
541 541 | |
542 542 | o 2 public a-C - 54acac6f23ab
543 543 |/
544 544 o 1 public a-B - 548a3d25dbf0
545 545 |
546 546 o 0 public a-A - 054250a37db4
547 547
548 548
549 549 Pulling from bundle does not alter phases of changeset not present in the bundle
550 550
551 551 #if repobundlerepo
552 552 $ hg bundle --base 1 -r 6 -r 3 ../partial-bundle.hg
553 553 5 changesets found
554 554 $ hg pull ../partial-bundle.hg
555 555 pulling from ../partial-bundle.hg
556 556 searching for changes
557 557 no changes found
558 558 $ hgph
559 559 @ 10 draft a-H - 967b449fbc94
560 560 |
561 561 | o 9 draft a-G - 3e27b6f1eee1
562 562 | |
563 563 | o 8 draft a-F - b740e3e5c05d
564 564 | |
565 565 | o 7 draft a-E - e9f537e46dea
566 566 | |
567 567 +---o 6 public n-B - 145e75495359
568 568 | |
569 569 o | 5 public n-A - d6bcb4f74035
570 570 | |
571 571 o | 4 public b-A - f54f1bb90ff3
572 572 | |
573 573 | o 3 public a-D - b555f63b6063
574 574 | |
575 575 | o 2 public a-C - 54acac6f23ab
576 576 |/
577 577 o 1 public a-B - 548a3d25dbf0
578 578 |
579 579 o 0 public a-A - 054250a37db4
580 580
581 581 #endif
582 582
583 583 Pushing to Publish=False (unknown changeset)
584 584
585 585 $ hg push ../mu -r b740e3e5c05d # a-F
586 586 pushing to ../mu
587 587 searching for changes
588 588 adding changesets
589 589 adding manifests
590 590 adding file changes
591 591 added 2 changesets with 2 changes to 2 files
592 592 test-debug-phase: new rev 7: x -> 1
593 593 test-debug-phase: new rev 8: x -> 1
594 594 $ hgph
595 595 @ 10 draft a-H - 967b449fbc94
596 596 |
597 597 | o 9 draft a-G - 3e27b6f1eee1
598 598 | |
599 599 | o 8 draft a-F - b740e3e5c05d
600 600 | |
601 601 | o 7 draft a-E - e9f537e46dea
602 602 | |
603 603 +---o 6 public n-B - 145e75495359
604 604 | |
605 605 o | 5 public n-A - d6bcb4f74035
606 606 | |
607 607 o | 4 public b-A - f54f1bb90ff3
608 608 | |
609 609 | o 3 public a-D - b555f63b6063
610 610 | |
611 611 | o 2 public a-C - 54acac6f23ab
612 612 |/
613 613 o 1 public a-B - 548a3d25dbf0
614 614 |
615 615 o 0 public a-A - 054250a37db4
616 616
617 617
618 618 $ cd ../mu
619 619 $ hgph # again f54f1bb90ff3, d6bcb4f74035 and 145e75495359 stay draft,
620 620 > # not ancestor of -r
621 621 o 8 draft a-F - b740e3e5c05d
622 622 |
623 623 o 7 draft a-E - e9f537e46dea
624 624 |
625 625 | o 6 draft n-B - 145e75495359
626 626 | |
627 627 | o 5 draft n-A - d6bcb4f74035
628 628 | |
629 629 o | 4 public a-D - b555f63b6063
630 630 | |
631 631 o | 3 public a-C - 54acac6f23ab
632 632 | |
633 633 | o 2 draft b-A - f54f1bb90ff3
634 634 |/
635 635 o 1 public a-B - 548a3d25dbf0
636 636 |
637 637 o 0 public a-A - 054250a37db4
638 638
639 639
640 640 Pushing to Publish=True (unknown changeset)
641 641
642 642 $ hg push ../beta -r b740e3e5c05d
643 643 pushing to ../beta
644 644 searching for changes
645 645 adding changesets
646 646 adding manifests
647 647 adding file changes
648 648 added 2 changesets with 2 changes to 2 files
649 649 test-debug-phase: new rev 5: x -> 0
650 650 test-debug-phase: new rev 6: x -> 0
651 651 test-debug-phase: move rev 7: 1 -> 0
652 652 test-debug-phase: move rev 8: 1 -> 0
653 653 $ hgph # again f54f1bb90ff3, d6bcb4f74035 and 145e75495359 stay draft,
654 654 > # not ancestor of -r
655 655 o 8 public a-F - b740e3e5c05d
656 656 |
657 657 o 7 public a-E - e9f537e46dea
658 658 |
659 659 | o 6 draft n-B - 145e75495359
660 660 | |
661 661 | o 5 draft n-A - d6bcb4f74035
662 662 | |
663 663 o | 4 public a-D - b555f63b6063
664 664 | |
665 665 o | 3 public a-C - 54acac6f23ab
666 666 | |
667 667 | o 2 draft b-A - f54f1bb90ff3
668 668 |/
669 669 o 1 public a-B - 548a3d25dbf0
670 670 |
671 671 o 0 public a-A - 054250a37db4
672 672
673 673
674 674 Pushing to Publish=True (common changeset)
675 675
676 676 $ cd ../beta
677 677 $ hg push ../alpha
678 678 pushing to ../alpha
679 679 searching for changes
680 680 no changes found
681 681 test-debug-phase: move rev 7: 1 -> 0
682 682 test-debug-phase: move rev 8: 1 -> 0
683 683 [1]
684 684 $ hgph
685 685 o 6 public a-F - b740e3e5c05d
686 686 |
687 687 o 5 public a-E - e9f537e46dea
688 688 |
689 689 o 4 public a-D - b555f63b6063
690 690 |
691 691 o 3 public a-C - 54acac6f23ab
692 692 |
693 693 | @ 2 public b-A - f54f1bb90ff3
694 694 |/
695 695 o 1 public a-B - 548a3d25dbf0
696 696 |
697 697 o 0 public a-A - 054250a37db4
698 698
699 699 $ cd ../alpha
700 700 $ hgph
701 701 @ 10 draft a-H - 967b449fbc94
702 702 |
703 703 | o 9 draft a-G - 3e27b6f1eee1
704 704 | |
705 705 | o 8 public a-F - b740e3e5c05d
706 706 | |
707 707 | o 7 public a-E - e9f537e46dea
708 708 | |
709 709 +---o 6 public n-B - 145e75495359
710 710 | |
711 711 o | 5 public n-A - d6bcb4f74035
712 712 | |
713 713 o | 4 public b-A - f54f1bb90ff3
714 714 | |
715 715 | o 3 public a-D - b555f63b6063
716 716 | |
717 717 | o 2 public a-C - 54acac6f23ab
718 718 |/
719 719 o 1 public a-B - 548a3d25dbf0
720 720 |
721 721 o 0 public a-A - 054250a37db4
722 722
723 723
724 724 Pushing to Publish=False (common changeset that change phase + unknown one)
725 725
726 726 $ hg push ../mu -r 967b449fbc94 -f
727 727 pushing to ../mu
728 728 searching for changes
729 729 adding changesets
730 730 adding manifests
731 731 adding file changes
732 732 added 1 changesets with 1 changes to 1 files (+1 heads)
733 733 test-debug-phase: move rev 2: 1 -> 0
734 734 test-debug-phase: move rev 5: 1 -> 0
735 735 test-debug-phase: new rev 9: x -> 1
736 736 $ hgph
737 737 @ 10 draft a-H - 967b449fbc94
738 738 |
739 739 | o 9 draft a-G - 3e27b6f1eee1
740 740 | |
741 741 | o 8 public a-F - b740e3e5c05d
742 742 | |
743 743 | o 7 public a-E - e9f537e46dea
744 744 | |
745 745 +---o 6 public n-B - 145e75495359
746 746 | |
747 747 o | 5 public n-A - d6bcb4f74035
748 748 | |
749 749 o | 4 public b-A - f54f1bb90ff3
750 750 | |
751 751 | o 3 public a-D - b555f63b6063
752 752 | |
753 753 | o 2 public a-C - 54acac6f23ab
754 754 |/
755 755 o 1 public a-B - 548a3d25dbf0
756 756 |
757 757 o 0 public a-A - 054250a37db4
758 758
759 759 $ cd ../mu
760 760 $ hgph # d6bcb4f74035 should have changed phase
761 761 > # 145e75495359 is still draft. not ancestor of -r
762 762 o 9 draft a-H - 967b449fbc94
763 763 |
764 764 | o 8 public a-F - b740e3e5c05d
765 765 | |
766 766 | o 7 public a-E - e9f537e46dea
767 767 | |
768 768 +---o 6 draft n-B - 145e75495359
769 769 | |
770 770 o | 5 public n-A - d6bcb4f74035
771 771 | |
772 772 | o 4 public a-D - b555f63b6063
773 773 | |
774 774 | o 3 public a-C - 54acac6f23ab
775 775 | |
776 776 o | 2 public b-A - f54f1bb90ff3
777 777 |/
778 778 o 1 public a-B - 548a3d25dbf0
779 779 |
780 780 o 0 public a-A - 054250a37db4
781 781
782 782
783 783
784 784 Pushing to Publish=True (common changeset from publish=False)
785 785
786 786 (in mu)
787 787 $ hg push ../alpha
788 788 pushing to ../alpha
789 789 searching for changes
790 790 no changes found
791 791 test-debug-phase: move rev 10: 1 -> 0
792 792 test-debug-phase: move rev 6: 1 -> 0
793 793 test-debug-phase: move rev 9: 1 -> 0
794 794 [1]
795 795 $ hgph
796 796 o 9 public a-H - 967b449fbc94
797 797 |
798 798 | o 8 public a-F - b740e3e5c05d
799 799 | |
800 800 | o 7 public a-E - e9f537e46dea
801 801 | |
802 802 +---o 6 public n-B - 145e75495359
803 803 | |
804 804 o | 5 public n-A - d6bcb4f74035
805 805 | |
806 806 | o 4 public a-D - b555f63b6063
807 807 | |
808 808 | o 3 public a-C - 54acac6f23ab
809 809 | |
810 810 o | 2 public b-A - f54f1bb90ff3
811 811 |/
812 812 o 1 public a-B - 548a3d25dbf0
813 813 |
814 814 o 0 public a-A - 054250a37db4
815 815
816 816 $ hgph -R ../alpha # a-H should have been synced to 0
817 817 @ 10 public a-H - 967b449fbc94
818 818 |
819 819 | o 9 draft a-G - 3e27b6f1eee1
820 820 | |
821 821 | o 8 public a-F - b740e3e5c05d
822 822 | |
823 823 | o 7 public a-E - e9f537e46dea
824 824 | |
825 825 +---o 6 public n-B - 145e75495359
826 826 | |
827 827 o | 5 public n-A - d6bcb4f74035
828 828 | |
829 829 o | 4 public b-A - f54f1bb90ff3
830 830 | |
831 831 | o 3 public a-D - b555f63b6063
832 832 | |
833 833 | o 2 public a-C - 54acac6f23ab
834 834 |/
835 835 o 1 public a-B - 548a3d25dbf0
836 836 |
837 837 o 0 public a-A - 054250a37db4
838 838
839 839
840 840
841 841 Bare push with next changeset and common changeset needing sync (issue3575)
842 842
843 843 (reset some stat on remote repo to avoid confusing other tests)
844 844
845 845 $ hg -R ../alpha --config extensions.strip= strip --no-backup 967b449fbc94
846 846 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
847 847 $ hg phase --force --draft b740e3e5c05d 967b449fbc94
848 848 test-debug-phase: move rev 8: 0 -> 1
849 849 test-debug-phase: move rev 9: 0 -> 1
850 850 $ hg push -fv ../alpha
851 851 pushing to ../alpha
852 852 searching for changes
853 853 1 changesets found
854 854 uncompressed size of bundle content:
855 855 180 (changelog)
856 856 167 (manifests)
857 857 133 a-H
858 858 adding changesets
859 859 adding manifests
860 860 adding file changes
861 861 added 1 changesets with 1 changes to 1 files (+1 heads)
862 862 test-debug-phase: new rev 10: x -> 0
863 863 test-debug-phase: move rev 8: 1 -> 0
864 864 test-debug-phase: move rev 9: 1 -> 0
865 865 $ hgph
866 866 o 9 public a-H - 967b449fbc94
867 867 |
868 868 | o 8 public a-F - b740e3e5c05d
869 869 | |
870 870 | o 7 public a-E - e9f537e46dea
871 871 | |
872 872 +---o 6 public n-B - 145e75495359
873 873 | |
874 874 o | 5 public n-A - d6bcb4f74035
875 875 | |
876 876 | o 4 public a-D - b555f63b6063
877 877 | |
878 878 | o 3 public a-C - 54acac6f23ab
879 879 | |
880 880 o | 2 public b-A - f54f1bb90ff3
881 881 |/
882 882 o 1 public a-B - 548a3d25dbf0
883 883 |
884 884 o 0 public a-A - 054250a37db4
885 885
886 886
887 887 $ hg -R ../alpha update 967b449fbc94 #for latter test consistency
888 888 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
889 889 $ hgph -R ../alpha
890 890 @ 10 public a-H - 967b449fbc94
891 891 |
892 892 | o 9 draft a-G - 3e27b6f1eee1
893 893 | |
894 894 | o 8 public a-F - b740e3e5c05d
895 895 | |
896 896 | o 7 public a-E - e9f537e46dea
897 897 | |
898 898 +---o 6 public n-B - 145e75495359
899 899 | |
900 900 o | 5 public n-A - d6bcb4f74035
901 901 | |
902 902 o | 4 public b-A - f54f1bb90ff3
903 903 | |
904 904 | o 3 public a-D - b555f63b6063
905 905 | |
906 906 | o 2 public a-C - 54acac6f23ab
907 907 |/
908 908 o 1 public a-B - 548a3d25dbf0
909 909 |
910 910 o 0 public a-A - 054250a37db4
911 911
912 912
913 913 Discovery locally secret changeset on a remote repository:
914 914
915 915 - should make it non-secret
916 916
917 917 $ cd ../alpha
918 918 $ mkcommit A-secret --config phases.new-commit=2
919 919 test-debug-phase: new rev 11: x -> 2
920 920 $ hgph
921 921 @ 11 secret A-secret - 435b5d83910c
922 922 |
923 923 o 10 public a-H - 967b449fbc94
924 924 |
925 925 | o 9 draft a-G - 3e27b6f1eee1
926 926 | |
927 927 | o 8 public a-F - b740e3e5c05d
928 928 | |
929 929 | o 7 public a-E - e9f537e46dea
930 930 | |
931 931 +---o 6 public n-B - 145e75495359
932 932 | |
933 933 o | 5 public n-A - d6bcb4f74035
934 934 | |
935 935 o | 4 public b-A - f54f1bb90ff3
936 936 | |
937 937 | o 3 public a-D - b555f63b6063
938 938 | |
939 939 | o 2 public a-C - 54acac6f23ab
940 940 |/
941 941 o 1 public a-B - 548a3d25dbf0
942 942 |
943 943 o 0 public a-A - 054250a37db4
944 944
945 945 $ hg bundle --base 'parents(.)' -r . ../secret-bundle.hg
946 946 1 changesets found
947 947 $ hg -R ../mu unbundle ../secret-bundle.hg
948 948 adding changesets
949 949 adding manifests
950 950 adding file changes
951 951 added 1 changesets with 1 changes to 1 files
952 952 new changesets 435b5d83910c (1 drafts)
953 953 test-debug-phase: new rev 10: x -> 1
954 954 (run 'hg update' to get a working copy)
955 955 $ hgph -R ../mu
956 956 o 10 draft A-secret - 435b5d83910c
957 957 |
958 958 o 9 public a-H - 967b449fbc94
959 959 |
960 960 | o 8 public a-F - b740e3e5c05d
961 961 | |
962 962 | o 7 public a-E - e9f537e46dea
963 963 | |
964 964 +---o 6 public n-B - 145e75495359
965 965 | |
966 966 o | 5 public n-A - d6bcb4f74035
967 967 | |
968 968 | o 4 public a-D - b555f63b6063
969 969 | |
970 970 | o 3 public a-C - 54acac6f23ab
971 971 | |
972 972 o | 2 public b-A - f54f1bb90ff3
973 973 |/
974 974 o 1 public a-B - 548a3d25dbf0
975 975 |
976 976 o 0 public a-A - 054250a37db4
977 977
978 978 $ hg pull ../mu
979 979 pulling from ../mu
980 980 searching for changes
981 981 no changes found
982 982 test-debug-phase: move rev 11: 2 -> 1
983 983 $ hgph
984 984 @ 11 draft A-secret - 435b5d83910c
985 985 |
986 986 o 10 public a-H - 967b449fbc94
987 987 |
988 988 | o 9 draft a-G - 3e27b6f1eee1
989 989 | |
990 990 | o 8 public a-F - b740e3e5c05d
991 991 | |
992 992 | o 7 public a-E - e9f537e46dea
993 993 | |
994 994 +---o 6 public n-B - 145e75495359
995 995 | |
996 996 o | 5 public n-A - d6bcb4f74035
997 997 | |
998 998 o | 4 public b-A - f54f1bb90ff3
999 999 | |
1000 1000 | o 3 public a-D - b555f63b6063
1001 1001 | |
1002 1002 | o 2 public a-C - 54acac6f23ab
1003 1003 |/
1004 1004 o 1 public a-B - 548a3d25dbf0
1005 1005 |
1006 1006 o 0 public a-A - 054250a37db4
1007 1007
1008 1008
1009 1009 pushing a locally public and draft changesets remotely secret should make them
1010 1010 appear on the remote side.
1011 1011
1012 1012 $ hg -R ../mu phase --secret --force 967b449fbc94
1013 1013 test-debug-phase: move rev 9: 0 -> 2
1014 1014 test-debug-phase: move rev 10: 1 -> 2
1015 1015 $ hg push -r 435b5d83910c ../mu
1016 1016 pushing to ../mu
1017 1017 searching for changes
1018 1018 abort: push creates new remote head 435b5d83910c
1019 1019 (merge or see 'hg help push' for details about pushing new heads)
1020 1020 [20]
1021 1021 $ hg push -fr 435b5d83910c ../mu # because the push will create new visible head
1022 1022 pushing to ../mu
1023 1023 searching for changes
1024 1024 adding changesets
1025 1025 adding manifests
1026 1026 adding file changes
1027 1027 added 0 changesets with 0 changes to 2 files
1028 1028 test-debug-phase: move rev 9: 2 -> 0
1029 1029 test-debug-phase: move rev 10: 2 -> 1
1030 1030 $ hgph -R ../mu
1031 1031 o 10 draft A-secret - 435b5d83910c
1032 1032 |
1033 1033 o 9 public a-H - 967b449fbc94
1034 1034 |
1035 1035 | o 8 public a-F - b740e3e5c05d
1036 1036 | |
1037 1037 | o 7 public a-E - e9f537e46dea
1038 1038 | |
1039 1039 +---o 6 public n-B - 145e75495359
1040 1040 | |
1041 1041 o | 5 public n-A - d6bcb4f74035
1042 1042 | |
1043 1043 | o 4 public a-D - b555f63b6063
1044 1044 | |
1045 1045 | o 3 public a-C - 54acac6f23ab
1046 1046 | |
1047 1047 o | 2 public b-A - f54f1bb90ff3
1048 1048 |/
1049 1049 o 1 public a-B - 548a3d25dbf0
1050 1050 |
1051 1051 o 0 public a-A - 054250a37db4
1052 1052
1053 1053
1054 1054 pull new changeset with common draft locally
1055 1055
1056 1056 $ hg up -q 967b449fbc94 # create a new root for draft
1057 1057 $ mkcommit 'alpha-more'
1058 1058 test-debug-phase: new rev 12: x -> 1
1059 1059 created new head
1060 1060 $ hg push -fr . ../mu
1061 1061 pushing to ../mu
1062 1062 searching for changes
1063 1063 adding changesets
1064 1064 adding manifests
1065 1065 adding file changes
1066 1066 added 1 changesets with 1 changes to 1 files (+1 heads)
1067 1067 test-debug-phase: new rev 11: x -> 1
1068 1068 $ cd ../mu
1069 1069 $ hg phase --secret --force 1c5cfd894796
1070 1070 test-debug-phase: move rev 11: 1 -> 2
1071 1071 $ hg up -q 435b5d83910c
1072 1072 $ mkcommit 'mu-more'
1073 1073 test-debug-phase: new rev 12: x -> 1
1074 1074 $ cd ../alpha
1075 1075 $ hg pull ../mu
1076 1076 pulling from ../mu
1077 1077 searching for changes
1078 1078 adding changesets
1079 1079 adding manifests
1080 1080 adding file changes
1081 1081 added 1 changesets with 1 changes to 1 files
1082 1082 new changesets 5237fb433fc8 (1 drafts)
1083 1083 test-debug-phase: new rev 13: x -> 1
1084 1084 (run 'hg update' to get a working copy)
1085 1085 $ hgph
1086 1086 o 13 draft mu-more - 5237fb433fc8
1087 1087 |
1088 1088 | @ 12 draft alpha-more - 1c5cfd894796
1089 1089 | |
1090 1090 o | 11 draft A-secret - 435b5d83910c
1091 1091 |/
1092 1092 o 10 public a-H - 967b449fbc94
1093 1093 |
1094 1094 | o 9 draft a-G - 3e27b6f1eee1
1095 1095 | |
1096 1096 | o 8 public a-F - b740e3e5c05d
1097 1097 | |
1098 1098 | o 7 public a-E - e9f537e46dea
1099 1099 | |
1100 1100 +---o 6 public n-B - 145e75495359
1101 1101 | |
1102 1102 o | 5 public n-A - d6bcb4f74035
1103 1103 | |
1104 1104 o | 4 public b-A - f54f1bb90ff3
1105 1105 | |
1106 1106 | o 3 public a-D - b555f63b6063
1107 1107 | |
1108 1108 | o 2 public a-C - 54acac6f23ab
1109 1109 |/
1110 1110 o 1 public a-B - 548a3d25dbf0
1111 1111 |
1112 1112 o 0 public a-A - 054250a37db4
1113 1113
1114 1114
1115 1115 Test that test are properly ignored on remote event when existing locally
1116 1116
1117 1117 $ cd ..
1118 1118 $ hg clone -qU -r b555f63b6063 -r f54f1bb90ff3 beta gamma
1119 1119 test-debug-phase: new rev 0: x -> 0
1120 1120 test-debug-phase: new rev 1: x -> 0
1121 1121 test-debug-phase: new rev 2: x -> 0
1122 1122 test-debug-phase: new rev 3: x -> 0
1123 1123 test-debug-phase: new rev 4: x -> 0
1124 1124
1125 1125 # pathological case are
1126 1126 #
1127 1127 # * secret remotely
1128 1128 # * known locally
1129 1129 # * repo have uncommon changeset
1130 1130
1131 1131 $ hg -R beta phase --secret --force f54f1bb90ff3
1132 1132 test-debug-phase: move rev 2: 0 -> 2
1133 1133 $ hg -R gamma phase --draft --force f54f1bb90ff3
1134 1134 test-debug-phase: move rev 2: 0 -> 1
1135 1135
1136 1136 $ cd gamma
1137 1137 $ hg pull ../beta
1138 1138 pulling from ../beta
1139 1139 searching for changes
1140 1140 adding changesets
1141 1141 adding manifests
1142 1142 adding file changes
1143 1143 added 2 changesets with 2 changes to 2 files
1144 1144 new changesets e9f537e46dea:b740e3e5c05d
1145 1145 test-debug-phase: new rev 5: x -> 0
1146 1146 test-debug-phase: new rev 6: x -> 0
1147 1147 (run 'hg update' to get a working copy)
1148 1148 $ hg phase f54f1bb90ff3
1149 1149 2: draft
1150 1150
1151 1151 same over the wire
1152 1152
1153 1153 $ cd ../beta
1154 1154 $ hg serve -p $HGPORT -d --pid-file=../beta.pid -E ../beta-error.log
1155 1155 $ cat ../beta.pid >> $DAEMON_PIDS
1156 1156 $ cd ../gamma
1157 1157
1158 1158 $ hg pull http://localhost:$HGPORT/ # bundle2+
1159 1159 pulling from http://localhost:$HGPORT/
1160 1160 searching for changes
1161 1161 no changes found
1162 1162 $ hg phase f54f1bb90ff3
1163 1163 2: draft
1164 1164
1165 1165 enforce bundle1
1166 1166
1167 1167 $ hg pull http://localhost:$HGPORT/ --config devel.legacy.exchange=bundle1
1168 1168 pulling from http://localhost:$HGPORT/
1169 1169 searching for changes
1170 1170 no changes found
1171 1171 $ hg phase f54f1bb90ff3
1172 1172 2: draft
1173 1173
1174 1174 check that secret local on both side are not synced to public
1175 1175
1176 1176 $ hg push -r b555f63b6063 http://localhost:$HGPORT/
1177 1177 pushing to http://localhost:$HGPORT/
1178 1178 searching for changes
1179 1179 no changes found
1180 1180 [1]
1181 1181 $ hg phase f54f1bb90ff3
1182 1182 2: draft
1183 1183
1184 1184 $ killdaemons.py
1185 1185
1186 1186 put the changeset in the draft state again
1187 1187 (first test after this one expect to be able to copy)
1188 1188
1189 1189 $ cd ..
1190 1190
1191 1191
1192 1192 Test Clone behavior
1193 1193
1194 1194 A. Clone without secret changeset
1195 1195
1196 1196 1. cloning non-publishing repository
1197 1197 (Phase should be preserved)
1198 1198
1199 1199 # make sure there is no secret so we can use a copy clone
1200 1200
1201 1201 $ hg -R mu phase --draft 'secret()'
1202 1202 test-debug-phase: move rev 11: 2 -> 1
1203 1203
1204 1204 $ hg clone -U mu Tau
1205 1205 $ hgph -R Tau
1206 1206 o 12 draft mu-more - 5237fb433fc8
1207 1207 |
1208 1208 | o 11 draft alpha-more - 1c5cfd894796
1209 1209 | |
1210 1210 o | 10 draft A-secret - 435b5d83910c
1211 1211 |/
1212 1212 o 9 public a-H - 967b449fbc94
1213 1213 |
1214 1214 | o 8 public a-F - b740e3e5c05d
1215 1215 | |
1216 1216 | o 7 public a-E - e9f537e46dea
1217 1217 | |
1218 1218 +---o 6 public n-B - 145e75495359
1219 1219 | |
1220 1220 o | 5 public n-A - d6bcb4f74035
1221 1221 | |
1222 1222 | o 4 public a-D - b555f63b6063
1223 1223 | |
1224 1224 | o 3 public a-C - 54acac6f23ab
1225 1225 | |
1226 1226 o | 2 public b-A - f54f1bb90ff3
1227 1227 |/
1228 1228 o 1 public a-B - 548a3d25dbf0
1229 1229 |
1230 1230 o 0 public a-A - 054250a37db4
1231 1231
1232 1232
1233 1233 2. cloning publishing repository
1234 1234
1235 1235 (everything should be public)
1236 1236
1237 1237 $ hg clone -U alpha Upsilon
1238 1238 $ hgph -R Upsilon
1239 1239 o 13 public mu-more - 5237fb433fc8
1240 1240 |
1241 1241 | o 12 public alpha-more - 1c5cfd894796
1242 1242 | |
1243 1243 o | 11 public A-secret - 435b5d83910c
1244 1244 |/
1245 1245 o 10 public a-H - 967b449fbc94
1246 1246 |
1247 1247 | o 9 public a-G - 3e27b6f1eee1
1248 1248 | |
1249 1249 | o 8 public a-F - b740e3e5c05d
1250 1250 | |
1251 1251 | o 7 public a-E - e9f537e46dea
1252 1252 | |
1253 1253 +---o 6 public n-B - 145e75495359
1254 1254 | |
1255 1255 o | 5 public n-A - d6bcb4f74035
1256 1256 | |
1257 1257 o | 4 public b-A - f54f1bb90ff3
1258 1258 | |
1259 1259 | o 3 public a-D - b555f63b6063
1260 1260 | |
1261 1261 | o 2 public a-C - 54acac6f23ab
1262 1262 |/
1263 1263 o 1 public a-B - 548a3d25dbf0
1264 1264 |
1265 1265 o 0 public a-A - 054250a37db4
1266 1266
1267 1267 #if unix-permissions no-root
1268 1268
1269 1269 Pushing From an unlockable repo
1270 1270 --------------------------------
1271 1271 (issue3684)
1272 1272
1273 1273 Unability to lock the source repo should not prevent the push. It will prevent
1274 1274 the retrieval of remote phase during push. For example, pushing to a publishing
1275 1275 server won't turn changeset public.
1276 1276
1277 1277 1. Test that push is not prevented
1278 1278
1279 1279 $ hg init Phi
1280 1280 $ cd Upsilon
1281 1281 $ chmod -R -w .hg
1282 1282 $ hg push ../Phi
1283 1283 pushing to ../Phi
1284 1284 searching for changes
1285 1285 adding changesets
1286 1286 adding manifests
1287 1287 adding file changes
1288 1288 added 14 changesets with 14 changes to 14 files (+3 heads)
1289 1289 test-debug-phase: new rev 0: x -> 0
1290 1290 test-debug-phase: new rev 1: x -> 0
1291 1291 test-debug-phase: new rev 2: x -> 0
1292 1292 test-debug-phase: new rev 3: x -> 0
1293 1293 test-debug-phase: new rev 4: x -> 0
1294 1294 test-debug-phase: new rev 5: x -> 0
1295 1295 test-debug-phase: new rev 6: x -> 0
1296 1296 test-debug-phase: new rev 7: x -> 0
1297 1297 test-debug-phase: new rev 8: x -> 0
1298 1298 test-debug-phase: new rev 9: x -> 0
1299 1299 test-debug-phase: new rev 10: x -> 0
1300 1300 test-debug-phase: new rev 11: x -> 0
1301 1301 test-debug-phase: new rev 12: x -> 0
1302 1302 test-debug-phase: new rev 13: x -> 0
1303 1303 $ chmod -R +w .hg
1304 1304
1305 1305 2. Test that failed phases movement are reported
1306 1306
1307 1307 $ hg phase --force --draft 3
1308 1308 test-debug-phase: move rev 3: 0 -> 1
1309 1309 test-debug-phase: move rev 7: 0 -> 1
1310 1310 test-debug-phase: move rev 8: 0 -> 1
1311 1311 test-debug-phase: move rev 9: 0 -> 1
1312 1312 $ chmod -R -w .hg
1313 1313 $ hg push ../Phi
1314 1314 pushing to ../Phi
1315 1315 searching for changes
1316 1316 no changes found
1317 1317 cannot lock source repo, skipping local public phase update
1318 1318 [1]
1319 1319 $ chmod -R +w .hg
1320 1320
1321 1321 3. Test that push is prevented if lock was already acquired (not a permission
1322 1322 error, but EEXIST)
1323 1323
1324 1324 $ touch .hg/store/lock
1325 1325 $ hg push ../Phi --config ui.timeout=1 --config ui.timeout.warn=0
1326 1326 pushing to ../Phi
1327 1327 waiting for lock on repository $TESTTMP/Upsilon held by ''
1328 1328 abort: repository $TESTTMP/Upsilon: timed out waiting for lock held by ''
1329 1329 (lock might be very busy)
1330 1330 [20]
1331 1331 $ rm .hg/store/lock
1332 1332
1333 1333 $ cd ..
1334 1334
1335 1335 #endif
1336 1336
1337 1337 Test that clone behaves like pull and doesn't publish changesets as plain push
1338 1338 does. The conditional output accounts for changes in the conditional block
1339 1339 above.
1340 1340
1341 1341 #if unix-permissions no-root
1342 1342 $ hg -R Upsilon phase -q --force --draft 2
1343 1343 test-debug-phase: move rev 2: 0 -> 1
1344 1344 #else
1345 1345 $ hg -R Upsilon phase -q --force --draft 2
1346 1346 test-debug-phase: move rev 2: 0 -> 1
1347 1347 test-debug-phase: move rev 3: 0 -> 1
1348 1348 test-debug-phase: move rev 7: 0 -> 1
1349 1349 test-debug-phase: move rev 8: 0 -> 1
1350 1350 test-debug-phase: move rev 9: 0 -> 1
1351 1351 #endif
1352 1352
1353 1353 $ hg clone -q Upsilon Pi -r 7
1354 1354 test-debug-phase: new rev 0: x -> 0
1355 1355 test-debug-phase: new rev 1: x -> 0
1356 1356 test-debug-phase: new rev 2: x -> 0
1357 1357 test-debug-phase: new rev 3: x -> 0
1358 1358 test-debug-phase: new rev 4: x -> 0
1359 1359 $ hgph Upsilon -r 'min(draft())'
1360 1360 o 2 draft a-C - 54acac6f23ab
1361 1361 |
1362 1362 ~
1363 1363
1364 1364 $ hg -R Upsilon push Pi -r 7
1365 1365 pushing to Pi
1366 1366 searching for changes
1367 1367 no changes found
1368 1368 test-debug-phase: move rev 2: 1 -> 0
1369 1369 test-debug-phase: move rev 3: 1 -> 0
1370 1370 test-debug-phase: move rev 7: 1 -> 0
1371 1371 [1]
1372 1372 $ hgph Upsilon -r 'min(draft())'
1373 1373 o 8 draft a-F - b740e3e5c05d
1374 1374 |
1375 1375 ~
1376 1376
1377 1377 $ hg -R Upsilon push Pi -r 8
1378 1378 pushing to Pi
1379 1379 searching for changes
1380 1380 adding changesets
1381 1381 adding manifests
1382 1382 adding file changes
1383 1383 added 1 changesets with 1 changes to 1 files
1384 1384 test-debug-phase: new rev 5: x -> 0
1385 1385 test-debug-phase: move rev 8: 1 -> 0
1386 1386
1387 1387 $ hgph Upsilon -r 'min(draft())'
1388 1388 o 9 draft a-G - 3e27b6f1eee1
1389 1389 |
1390 1390 ~
1391 1391
1392 1392 Test phases exchange when a phaseroot is on a merge
1393 1393
1394 1394 $ hg init mergetest
1395 1395 $ cd mergetest
1396 1396 > cat > .hg/hgrc << EOF
1397 1397 > [phases]
1398 1398 > publish = false
1399 1399 > EOF
1400 1400
1401 1401 $ hg debugdrawdag << EOF
1402 1402 > E Z
1403 1403 > |\|
1404 1404 > D Y
1405 1405 > | |
1406 1406 > C X
1407 1407 > |/
1408 1408 > B
1409 1409 > |
1410 1410 > A
1411 1411 > EOF
1412 1412 test-debug-phase: new rev 0: x -> 1
1413 1413 test-debug-phase: new rev 1: x -> 1
1414 1414 test-debug-phase: new rev 2: x -> 1
1415 1415 test-debug-phase: new rev 3: x -> 1
1416 1416 test-debug-phase: new rev 4: x -> 1
1417 1417 test-debug-phase: new rev 5: x -> 1
1418 1418 test-debug-phase: new rev 6: x -> 1
1419 1419 test-debug-phase: new rev 7: x -> 1
1420 1420
1421 1421 $ hg phase --public -r D
1422 1422 test-debug-phase: move rev 0: 1 -> 0
1423 1423 test-debug-phase: move rev 1: 1 -> 0
1424 1424 test-debug-phase: move rev 2: 1 -> 0
1425 1425 test-debug-phase: move rev 4: 1 -> 0
1426 1426
1427 1427 $ hg log -G -T '{shortest(node, 5)} {phase}'
1428 1428 o bb947 draft
1429 1429 |
1430 1430 | o 5ac28 draft
1431 1431 |/|
1432 1432 o | 13b7b draft
1433 1433 | |
1434 1434 | o f5853 public
1435 1435 | |
1436 1436 o | c67c4 draft
1437 1437 | |
1438 1438 | o 26805 public
1439 1439 |/
1440 1440 o 11247 public
1441 1441 |
1442 1442 o 426ba public
1443 1443
1444 1444 $ cd ..
1445 1445
1446 1446 Works with default settings
1447 1447
1448 1448 $ hg -R mergetest serve -p $HGPORT -d --pid-file=hg.pid
1449 1449 $ cat hg.pid >> $DAEMON_PIDS
1450 1450
1451 1451 $ hg clone -U http://localhost:$HGPORT mergetest-normal
1452 1452 requesting all changes
1453 1453 adding changesets
1454 1454 adding manifests
1455 1455 adding file changes
1456 1456 added 8 changesets with 7 changes to 7 files (+1 heads)
1457 1457 new changesets 426bada5c675:bb94757e651a (4 drafts)
1458 1458 test-debug-phase: new rev 0: x -> 0
1459 1459 test-debug-phase: new rev 1: x -> 0
1460 1460 test-debug-phase: new rev 2: x -> 0
1461 1461 test-debug-phase: new rev 3: x -> 1
1462 1462 test-debug-phase: new rev 4: x -> 0
1463 1463 test-debug-phase: new rev 5: x -> 1
1464 1464 test-debug-phase: new rev 6: x -> 1
1465 1465 test-debug-phase: new rev 7: x -> 1
1466 1466
1467 1467 $ hg -R mergetest-normal log -G -T '{shortest(node, 5)} {phase}'
1468 1468 o bb947 draft
1469 1469 |
1470 1470 | o 5ac28 draft
1471 1471 |/|
1472 1472 o | 13b7b draft
1473 1473 | |
1474 1474 | o f5853 public
1475 1475 | |
1476 1476 o | c67c4 draft
1477 1477 | |
1478 1478 | o 26805 public
1479 1479 |/
1480 1480 o 11247 public
1481 1481 |
1482 1482 o 426ba public
1483 1483
1484 1484 $ killdaemons.py
1485 1485
1486 1486 With legacy listkeys over bundle2
1487 1487 (issue 5939: public phase was lost on 26805 and f5853 before, due to a bug
1488 1488 of phase heads computation)
1489 1489
1490 1490 $ hg -R mergetest --config devel.legacy.exchange=phases serve -p $HGPORT -d --pid-file=hg.pid
1491 1491 $ cat hg.pid >> $DAEMON_PIDS
1492 1492
1493 1493 $ hg clone -U http://localhost:$HGPORT mergetest-nobinarypart
1494 1494 requesting all changes
1495 1495 adding changesets
1496 1496 adding manifests
1497 1497 adding file changes
1498 1498 added 8 changesets with 7 changes to 7 files (+1 heads)
1499 1499 new changesets 426bada5c675:bb94757e651a (4 drafts)
1500 1500 test-debug-phase: new rev 0: x -> 0
1501 1501 test-debug-phase: new rev 1: x -> 0
1502 1502 test-debug-phase: new rev 2: x -> 0
1503 1503 test-debug-phase: new rev 3: x -> 1
1504 1504 test-debug-phase: new rev 4: x -> 0
1505 1505 test-debug-phase: new rev 5: x -> 1
1506 1506 test-debug-phase: new rev 6: x -> 1
1507 1507 test-debug-phase: new rev 7: x -> 1
1508 1508
1509 1509 $ hg -R mergetest-nobinarypart log -G -T '{shortest(node, 5)} {phase}'
1510 1510 o bb947 draft
1511 1511 |
1512 1512 | o 5ac28 draft
1513 1513 |/|
1514 1514 o | 13b7b draft
1515 1515 | |
1516 1516 | o f5853 public
1517 1517 | |
1518 1518 o | c67c4 draft
1519 1519 | |
1520 1520 | o 26805 public
1521 1521 |/
1522 1522 o 11247 public
1523 1523 |
1524 1524 o 426ba public
1525 1525
1526 1526 $ killdaemons.py
1527 1527
1528 1528 Without bundle2
1529 1529 (issue 5939: public phase was lost on 26805 and f5853 before, due to a bug
1530 1530 of phase heads computation)
1531 1531
1532 1532 $ hg -R mergetest serve -p $HGPORT -d --pid-file=hg.pid
1533 1533 $ cat hg.pid >> $DAEMON_PIDS
1534 1534
1535 1535 $ hg --config devel.legacy.exchange=bundle1 clone -U http://localhost:$HGPORT mergetest-bundle1
1536 1536 requesting all changes
1537 1537 adding changesets
1538 1538 adding manifests
1539 1539 adding file changes
1540 1540 added 8 changesets with 7 changes to 7 files (+1 heads)
1541 1541 new changesets 426bada5c675:bb94757e651a (4 drafts)
1542 1542 test-debug-phase: new rev 0: x -> 0
1543 1543 test-debug-phase: new rev 1: x -> 0
1544 1544 test-debug-phase: new rev 2: x -> 0
1545 1545 test-debug-phase: new rev 3: x -> 1
1546 1546 test-debug-phase: new rev 4: x -> 0
1547 1547 test-debug-phase: new rev 5: x -> 1
1548 1548 test-debug-phase: new rev 6: x -> 1
1549 1549 test-debug-phase: new rev 7: x -> 1
1550 1550
1551 1551 $ hg -R mergetest-bundle1 log -G -T '{shortest(node, 5)} {phase}'
1552 1552 o bb947 draft
1553 1553 |
1554 1554 | o 5ac28 draft
1555 1555 |/|
1556 1556 o | 13b7b draft
1557 1557 | |
1558 1558 | o f5853 public
1559 1559 | |
1560 1560 o | c67c4 draft
1561 1561 | |
1562 1562 | o 26805 public
1563 1563 |/
1564 1564 o 11247 public
1565 1565 |
1566 1566 o 426ba public
1567 1567
1568 1568 $ killdaemons.py
1569 1569
1570 1570
1571 1571 auto-publish config
1572 1572 -------------------
1573 1573
1574 1574 $ hg init auto-publish-orig
1575 1575 $ hg clone -q auto-publish-orig auto-publish-clone
1576 1576 $ cd auto-publish-clone
1577 1577 $ mkcommit a-p-A
1578 1578 test-debug-phase: new rev 0: x -> 1
1579 1579 $ mkcommit a-p-B
1580 1580 test-debug-phase: new rev 1: x -> 1
1581 1581
1582 1582 abort behavior
1583 1583
1584 1584 $ hg push --config experimental.auto-publish=abort
1585 1585 pushing to $TESTTMP/auto-publish-orig
1586 1586 abort: push would publish 2 changesets
1587 1587 (use --publish or adjust 'experimental.auto-publish' config)
1588 1588 [255]
1589 1589 $ hg push -r '.^' --config experimental.auto-publish=abort
1590 1590 pushing to $TESTTMP/auto-publish-orig
1591 1591 abort: push would publish 1 changesets
1592 1592 (use --publish or adjust 'experimental.auto-publish' config)
1593 1593 [255]
1594 1594
1595 1595 trying to push a secret changeset doesn't confuse auto-publish
1596 1596
1597 1597 $ hg phase --secret --force
1598 test-debug-phase: move rev 0: 1 -> 2
1599 1598 test-debug-phase: move rev 1: 1 -> 2
1600 1599
1601 1600 $ hg push --config experimental.auto-publish=abort
1602 1601 pushing to $TESTTMP/auto-publish-orig
1603 1602 abort: push would publish 1 changesets
1604 1603 (use --publish or adjust 'experimental.auto-publish' config)
1605 1604 [255]
1606 1605 $ hg push -r . --config experimental.auto-publish=abort
1607 1606 pushing to $TESTTMP/auto-publish-orig
1608 1607 abort: push would publish 1 changesets
1609 1608 (use --publish or adjust 'experimental.auto-publish' config)
1610 1609 [255]
1611 1610
1612 1611 $ hg phase --draft
1613 1612 test-debug-phase: move rev 1: 2 -> 1
1614 1613
1615 1614 --publish flag makes push succeed
1616 1615
1617 1616 $ hg push -r '.^' --publish --config experimental.auto-publish=abort
1618 1617 pushing to $TESTTMP/auto-publish-orig
1619 1618 searching for changes
1620 1619 adding changesets
1621 1620 adding manifests
1622 1621 adding file changes
1623 1622 added 1 changesets with 1 changes to 1 files
1624 1623 test-debug-phase: new rev 0: x -> 0
1625 1624 test-debug-phase: move rev 0: 1 -> 0
1626 1625
1627 1626 warn behavior
1628 1627
1629 1628 $ hg push --config experimental.auto-publish=warn
1630 1629 pushing to $TESTTMP/auto-publish-orig
1631 1630 1 changesets about to be published
1632 1631 searching for changes
1633 1632 adding changesets
1634 1633 adding manifests
1635 1634 adding file changes
1636 1635 added 1 changesets with 1 changes to 1 files
1637 1636 test-debug-phase: new rev 1: x -> 0
1638 1637 test-debug-phase: move rev 1: 1 -> 0
1639 1638
1640 1639 confirm behavior
1641 1640
1642 1641 $ mkcommit a-p-C
1643 1642 test-debug-phase: new rev 2: x -> 1
1644 1643 $ hg push --config experimental.auto-publish=confirm
1645 1644 pushing to $TESTTMP/auto-publish-orig
1646 1645 push and publish 1 changesets (yn)? y
1647 1646 searching for changes
1648 1647 adding changesets
1649 1648 adding manifests
1650 1649 adding file changes
1651 1650 added 1 changesets with 1 changes to 1 files
1652 1651 test-debug-phase: new rev 2: x -> 0
1653 1652 test-debug-phase: move rev 2: 1 -> 0
1654 1653
1655 1654 $ cd ..
1656 1655
1657 1656
1658 1657 --publish flag
1659 1658 --------------
1660 1659
1661 1660 $ hg init doesnt-publish
1662 1661 $ cd doesnt-publish
1663 1662 $ cat > .hg/hgrc << EOF
1664 1663 > [phases]
1665 1664 > publish=0
1666 1665 > EOF
1667 1666 $ mkcommit orig-root
1668 1667 test-debug-phase: new rev 0: x -> 1
1669 1668 $ hg phase --public -r 'all()'
1670 1669 test-debug-phase: move rev 0: 1 -> 0
1671 1670 $ cd ..
1672 1671
1673 1672 $ hg clone -q doesnt-publish client
1674 1673 $ cd client
1675 1674
1676 1675 pushing nothing
1677 1676
1678 1677 $ mkcommit new-A
1679 1678 test-debug-phase: new rev 1: x -> 1
1680 1679 $ mkcommit new-B
1681 1680 test-debug-phase: new rev 2: x -> 1
1682 1681 $ hg push --publish -r null
1683 1682 pushing to $TESTTMP/doesnt-publish
1684 1683 searching for changes
1685 1684 no changes found
1686 1685 [1]
1687 1686 $ hgph
1688 1687 @ 2 draft new-B - 89512e87d697
1689 1688 |
1690 1689 o 1 draft new-A - 4826e44e690e
1691 1690 |
1692 1691 o 0 public orig-root - c48edaf99a10
1693 1692
1694 1693
1695 1694 pushing a new changeset (selective)
1696 1695
1697 1696 $ hg push --publish -r 'desc("new-A")'
1698 1697 pushing to $TESTTMP/doesnt-publish
1699 1698 searching for changes
1700 1699 adding changesets
1701 1700 adding manifests
1702 1701 adding file changes
1703 1702 added 1 changesets with 1 changes to 1 files
1704 1703 test-debug-phase: new rev 1: x -> 0
1705 1704 test-debug-phase: move rev 1: 1 -> 0
1706 1705 $ hgph
1707 1706 @ 2 draft new-B - 89512e87d697
1708 1707 |
1709 1708 o 1 public new-A - 4826e44e690e
1710 1709 |
1711 1710 o 0 public orig-root - c48edaf99a10
1712 1711
1713 1712
1714 1713 pushing a new changeset (linear)
1715 1714
1716 1715 $ hg push --publish
1717 1716 pushing to $TESTTMP/doesnt-publish
1718 1717 searching for changes
1719 1718 adding changesets
1720 1719 adding manifests
1721 1720 adding file changes
1722 1721 added 1 changesets with 1 changes to 1 files
1723 1722 test-debug-phase: new rev 2: x -> 0
1724 1723 test-debug-phase: move rev 2: 1 -> 0
1725 1724 $ hgph
1726 1725 @ 2 public new-B - 89512e87d697
1727 1726 |
1728 1727 o 1 public new-A - 4826e44e690e
1729 1728 |
1730 1729 o 0 public orig-root - c48edaf99a10
1731 1730
1732 1731
1733 1732 pushing new changesets (different branches)
1734 1733
1735 1734 $ mkcommit new-C
1736 1735 test-debug-phase: new rev 3: x -> 1
1737 1736 $ hg update -q '.^'
1738 1737 $ hg branch -q another
1739 1738 $ mkcommit new-D
1740 1739 test-debug-phase: new rev 4: x -> 1
1741 1740 $ hg push --new-branch --publish
1742 1741 pushing to $TESTTMP/doesnt-publish
1743 1742 searching for changes
1744 1743 adding changesets
1745 1744 adding manifests
1746 1745 adding file changes
1747 1746 added 2 changesets with 2 changes to 2 files (+1 heads)
1748 1747 test-debug-phase: new rev 3: x -> 0
1749 1748 test-debug-phase: new rev 4: x -> 0
1750 1749 test-debug-phase: move rev 3: 1 -> 0
1751 1750 test-debug-phase: move rev 4: 1 -> 0
1752 1751 $ hgph
1753 1752 @ 4 public new-D - 5e53dcafd13c
1754 1753 |
1755 1754 | o 3 public new-C - 1665482cc06d
1756 1755 |/
1757 1756 o 2 public new-B - 89512e87d697
1758 1757 |
1759 1758 o 1 public new-A - 4826e44e690e
1760 1759 |
1761 1760 o 0 public orig-root - c48edaf99a10
1762 1761
1763 1762
1764 1763 pushing a shared changeset
1765 1764
1766 1765 $ mkcommit new-E
1767 1766 test-debug-phase: new rev 5: x -> 1
1768 1767 $ hg push
1769 1768 pushing to $TESTTMP/doesnt-publish
1770 1769 searching for changes
1771 1770 adding changesets
1772 1771 adding manifests
1773 1772 adding file changes
1774 1773 added 1 changesets with 1 changes to 1 files
1775 1774 test-debug-phase: new rev 5: x -> 1
1776 1775 $ hg push --publish
1777 1776 pushing to $TESTTMP/doesnt-publish
1778 1777 searching for changes
1779 1778 no changes found
1780 1779 test-debug-phase: move rev 5: 1 -> 0
1781 1780 test-debug-phase: move rev 5: 1 -> 0
1782 1781 [1]
1783 1782 $ hgph
1784 1783 @ 5 public new-E - 48931ee3529c
1785 1784 |
1786 1785 o 4 public new-D - 5e53dcafd13c
1787 1786 |
1788 1787 | o 3 public new-C - 1665482cc06d
1789 1788 |/
1790 1789 o 2 public new-B - 89512e87d697
1791 1790 |
1792 1791 o 1 public new-A - 4826e44e690e
1793 1792 |
1794 1793 o 0 public orig-root - c48edaf99a10
1795 1794
1796 1795 $ cd ..
1797 1796
1798 1797 --publish with subrepos (doesn't propagate to subrepos currently)
1799 1798
1800 1799 $ hg init with-subrepo
1801 1800 $ cd with-subrepo
1802 1801 $ cat > .hg/hgrc << EOF
1803 1802 > [phases]
1804 1803 > publish=0
1805 1804 > EOF
1806 1805 $ hg init subrepo
1807 1806 $ cd subrepo
1808 1807 $ cat > .hg/hgrc << EOF
1809 1808 > [phases]
1810 1809 > publish=0
1811 1810 > EOF
1812 1811 $ echo foo > foo
1813 1812 $ hg ci -qAm0
1814 1813 test-debug-phase: new rev 0: x -> 1
1815 1814 $ cd ..
1816 1815 $ echo 'subrepo = subrepo' > .hgsub
1817 1816 $ hg add .hgsub
1818 1817 $ hg ci -m 'Adding subrepo'
1819 1818 test-debug-phase: new rev 0: x -> 1
1820 1819 $ hgph
1821 1820 @ 0 draft Adding subrepo - 74d5b62379c0
1822 1821
1823 1822 $ hgph -R subrepo
1824 1823 @ 0 draft 0 - 4b3f578e3344
1825 1824
1826 1825 $ cd ..
1827 1826 $ hg clone with-subrepo client-with-subrepo
1828 1827 updating to branch default
1829 1828 cloning subrepo subrepo from $TESTTMP/with-subrepo/subrepo
1830 1829 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1831 1830 $ cd client-with-subrepo
1832 1831 $ hg push --publish
1833 1832 pushing to $TESTTMP/with-subrepo
1834 1833 no changes made to subrepo subrepo since last push to $TESTTMP/with-subrepo/subrepo
1835 1834 searching for changes
1836 1835 no changes found
1837 1836 test-debug-phase: move rev 0: 1 -> 0
1838 1837 test-debug-phase: move rev 0: 1 -> 0
1839 1838 [1]
1840 1839 $ hgph
1841 1840 @ 0 public Adding subrepo - 74d5b62379c0
1842 1841
1843 1842 $ hgph -R subrepo
1844 1843 @ 0 draft 0 - 4b3f578e3344
1845 1844
@@ -1,1148 +1,1146 b''
1 1 $ cat > $TESTTMP/hook.sh << 'EOF'
2 2 > echo "test-hook-close-phase: $HG_NODE: $HG_OLDPHASE -> $HG_PHASE"
3 3 > EOF
4 4
5 5 $ cat >> $HGRCPATH << EOF
6 6 > [extensions]
7 7 > phasereport=$TESTDIR/testlib/ext-phase-report.py
8 8 > [hooks]
9 9 > txnclose-phase.test = sh $TESTTMP/hook.sh
10 10 > EOF
11 11
12 12 $ hglog() { hg log -G --template "{rev} {phaseidx} {desc}\n" $*; }
13 13 $ mkcommit() {
14 14 > echo "$1" > "$1"
15 15 > hg add "$1"
16 16 > message="$1"
17 17 > shift
18 18 > hg ci -m "$message" $*
19 19 > }
20 20
21 21 $ hg init initialrepo
22 22 $ cd initialrepo
23 23
24 24 Cannot change null revision phase
25 25
26 26 $ hg phase --force --secret null
27 27 abort: cannot change null revision phase
28 28 [255]
29 29 $ hg phase null
30 30 -1: public
31 31
32 32 $ mkcommit A
33 33 test-debug-phase: new rev 0: x -> 1
34 34 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
35 35
36 36 New commit are draft by default
37 37
38 38 $ hglog
39 39 @ 0 1 A
40 40
41 41
42 42 Following commit are draft too
43 43
44 44 $ mkcommit B
45 45 test-debug-phase: new rev 1: x -> 1
46 46 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> draft
47 47
48 48 $ hglog
49 49 @ 1 1 B
50 50 |
51 51 o 0 1 A
52 52
53 53
54 54 Working directory phase is secret when its parent is secret.
55 55
56 56 $ hg phase --force --secret .
57 test-debug-phase: move rev 0: 1 -> 2
58 57 test-debug-phase: move rev 1: 1 -> 2
59 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> secret
60 58 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> secret
61 59 $ hg log -r 'wdir()' -T '{phase}\n'
62 60 secret
63 61 $ hg log -r 'wdir() and public()' -T '{phase}\n'
64 62 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
65 63 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
66 64 secret
67 65
68 66 Working directory phase is draft when its parent is draft.
69 67
70 68 $ hg phase --draft .
71 69 test-debug-phase: move rev 1: 2 -> 1
72 70 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: secret -> draft
73 71 $ hg log -r 'wdir()' -T '{phase}\n'
74 72 draft
75 73 $ hg log -r 'wdir() and public()' -T '{phase}\n'
76 74 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
77 75 draft
78 76 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
79 77
80 78 Working directory phase is secret when a new commit will be created as secret,
81 79 even if the parent is draft.
82 80
83 81 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
84 82 > --config phases.new-commit='secret'
85 83 secret
86 84
87 85 Working directory phase is draft when its parent is public.
88 86
89 87 $ hg phase --public .
90 88 test-debug-phase: move rev 0: 1 -> 0
91 89 test-debug-phase: move rev 1: 1 -> 0
92 90 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: draft -> public
93 91 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
94 92 $ hg log -r 'wdir()' -T '{phase}\n'
95 93 draft
96 94 $ hg log -r 'wdir() and public()' -T '{phase}\n'
97 95 $ hg log -r 'wdir() and draft()' -T '{phase}\n'
98 96 draft
99 97 $ hg log -r 'wdir() and secret()' -T '{phase}\n'
100 98 $ hg log -r 'wdir() and secret()' -T '{phase}\n' \
101 99 > --config phases.new-commit='secret'
102 100 secret
103 101
104 102 Draft commit are properly created over public one:
105 103
106 104 $ hg phase
107 105 1: public
108 106 $ hglog
109 107 @ 1 0 B
110 108 |
111 109 o 0 0 A
112 110
113 111
114 112 $ mkcommit C
115 113 test-debug-phase: new rev 2: x -> 1
116 114 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
117 115 $ mkcommit D
118 116 test-debug-phase: new rev 3: x -> 1
119 117 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
120 118
121 119 $ hglog
122 120 @ 3 1 D
123 121 |
124 122 o 2 1 C
125 123 |
126 124 o 1 0 B
127 125 |
128 126 o 0 0 A
129 127
130 128
131 129 Test creating changeset as secret
132 130
133 131 $ mkcommit E --config phases.new-commit='secret'
134 132 test-debug-phase: new rev 4: x -> 2
135 133 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> secret
136 134 $ hglog
137 135 @ 4 2 E
138 136 |
139 137 o 3 1 D
140 138 |
141 139 o 2 1 C
142 140 |
143 141 o 1 0 B
144 142 |
145 143 o 0 0 A
146 144
147 145
148 146 Test the secret property is inherited
149 147
150 148 $ mkcommit H
151 149 test-debug-phase: new rev 5: x -> 2
152 150 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
153 151 $ hglog
154 152 @ 5 2 H
155 153 |
156 154 o 4 2 E
157 155 |
158 156 o 3 1 D
159 157 |
160 158 o 2 1 C
161 159 |
162 160 o 1 0 B
163 161 |
164 162 o 0 0 A
165 163
166 164
167 165 Even on merge
168 166
169 167 $ hg up -q 1
170 168 $ mkcommit "B'"
171 169 test-debug-phase: new rev 6: x -> 1
172 170 created new head
173 171 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
174 172 $ hglog
175 173 @ 6 1 B'
176 174 |
177 175 | o 5 2 H
178 176 | |
179 177 | o 4 2 E
180 178 | |
181 179 | o 3 1 D
182 180 | |
183 181 | o 2 1 C
184 182 |/
185 183 o 1 0 B
186 184 |
187 185 o 0 0 A
188 186
189 187 $ hg merge 4 # E
190 188 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
191 189 (branch merge, don't forget to commit)
192 190 $ hg phase
193 191 6: draft
194 192 4: secret
195 193 $ hg ci -m "merge B' and E"
196 194 test-debug-phase: new rev 7: x -> 2
197 195 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> secret
198 196
199 197 $ hglog
200 198 @ 7 2 merge B' and E
201 199 |\
202 200 | o 6 1 B'
203 201 | |
204 202 +---o 5 2 H
205 203 | |
206 204 o | 4 2 E
207 205 | |
208 206 o | 3 1 D
209 207 | |
210 208 o | 2 1 C
211 209 |/
212 210 o 1 0 B
213 211 |
214 212 o 0 0 A
215 213
216 214
217 215 Test secret changeset are not pushed
218 216
219 217 $ hg init ../push-dest
220 218 $ cat > ../push-dest/.hg/hgrc << EOF
221 219 > [phases]
222 220 > publish=False
223 221 > EOF
224 222 $ hg outgoing ../push-dest --template='{rev} {phase} {desc|firstline}\n'
225 223 comparing with ../push-dest
226 224 searching for changes
227 225 0 public A
228 226 1 public B
229 227 2 draft C
230 228 3 draft D
231 229 6 draft B'
232 230 $ hg outgoing -r 'branch(default)' ../push-dest --template='{rev} {phase} {desc|firstline}\n'
233 231 comparing with ../push-dest
234 232 searching for changes
235 233 0 public A
236 234 1 public B
237 235 2 draft C
238 236 3 draft D
239 237 6 draft B'
240 238
241 239 $ hg push ../push-dest -f # force because we push multiple heads
242 240 pushing to ../push-dest
243 241 searching for changes
244 242 adding changesets
245 243 adding manifests
246 244 adding file changes
247 245 added 5 changesets with 5 changes to 5 files (+1 heads)
248 246 test-debug-phase: new rev 0: x -> 0
249 247 test-debug-phase: new rev 1: x -> 0
250 248 test-debug-phase: new rev 2: x -> 1
251 249 test-debug-phase: new rev 3: x -> 1
252 250 test-debug-phase: new rev 4: x -> 1
253 251 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
254 252 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
255 253 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> draft
256 254 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> draft
257 255 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> draft
258 256 $ hglog
259 257 @ 7 2 merge B' and E
260 258 |\
261 259 | o 6 1 B'
262 260 | |
263 261 +---o 5 2 H
264 262 | |
265 263 o | 4 2 E
266 264 | |
267 265 o | 3 1 D
268 266 | |
269 267 o | 2 1 C
270 268 |/
271 269 o 1 0 B
272 270 |
273 271 o 0 0 A
274 272
275 273 $ cd ../push-dest
276 274 $ hglog
277 275 o 4 1 B'
278 276 |
279 277 | o 3 1 D
280 278 | |
281 279 | o 2 1 C
282 280 |/
283 281 o 1 0 B
284 282 |
285 283 o 0 0 A
286 284
287 285
288 286 (Issue3303)
289 287 Check that remote secret changeset are ignore when checking creation of remote heads
290 288
291 289 We add a secret head into the push destination. This secret head shadows a
292 290 visible shared between the initial repo and the push destination.
293 291
294 292 $ hg up -q 4 # B'
295 293 $ mkcommit Z --config phases.new-commit=secret
296 294 test-debug-phase: new rev 5: x -> 2
297 295 test-hook-close-phase: 2713879da13d6eea1ff22b442a5a87cb31a7ce6a: -> secret
298 296 $ hg phase .
299 297 5: secret
300 298
301 299 We now try to push a new public changeset that descend from the common public
302 300 head shadowed by the remote secret head.
303 301
304 302 $ cd ../initialrepo
305 303 $ hg up -q 6 #B'
306 304 $ mkcommit I
307 305 test-debug-phase: new rev 8: x -> 1
308 306 created new head
309 307 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
310 308 $ hg push ../push-dest
311 309 pushing to ../push-dest
312 310 searching for changes
313 311 adding changesets
314 312 adding manifests
315 313 adding file changes
316 314 added 1 changesets with 1 changes to 1 files (+1 heads)
317 315 test-debug-phase: new rev 6: x -> 1
318 316 test-hook-close-phase: 6d6770faffce199f1fddd1cf87f6f026138cf061: -> draft
319 317
320 318 :note: The "(+1 heads)" is wrong as we do not had any visible head
321 319
322 320 check that branch cache with "served" filter are properly computed and stored
323 321
324 322 $ ls ../push-dest/.hg/cache/branch2*
325 323 ../push-dest/.hg/cache/branch2-base
326 324 ../push-dest/.hg/cache/branch2-served
327 325 $ cat ../push-dest/.hg/cache/branch2-served
328 326 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
329 327 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
330 328 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
331 329 $ hg heads -R ../push-dest --template '{rev}:{node} {phase}\n' #update visible cache too
332 330 6:6d6770faffce199f1fddd1cf87f6f026138cf061 draft
333 331 5:2713879da13d6eea1ff22b442a5a87cb31a7ce6a secret
334 332 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e draft
335 333 $ ls ../push-dest/.hg/cache/branch2*
336 334 ../push-dest/.hg/cache/branch2-base
337 335 ../push-dest/.hg/cache/branch2-served
338 336 ../push-dest/.hg/cache/branch2-visible
339 337 $ cat ../push-dest/.hg/cache/branch2-served
340 338 6d6770faffce199f1fddd1cf87f6f026138cf061 6 465891ffab3c47a3c23792f7dc84156e19a90722
341 339 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
342 340 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
343 341 $ cat ../push-dest/.hg/cache/branch2-visible
344 342 6d6770faffce199f1fddd1cf87f6f026138cf061 6
345 343 b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e o default
346 344 2713879da13d6eea1ff22b442a5a87cb31a7ce6a o default
347 345 6d6770faffce199f1fddd1cf87f6f026138cf061 o default
348 346
349 347
350 348 Restore condition prior extra insertion.
351 349 $ hg -q --config extensions.mq= strip .
352 350 $ hg up -q 7
353 351 $ cd ..
354 352
355 353 Test secret changeset are not pull
356 354
357 355 $ hg init pull-dest
358 356 $ cd pull-dest
359 357 $ hg pull ../initialrepo
360 358 pulling from ../initialrepo
361 359 requesting all changes
362 360 adding changesets
363 361 adding manifests
364 362 adding file changes
365 363 added 5 changesets with 5 changes to 5 files (+1 heads)
366 364 new changesets 4a2df7238c3b:cf9fe039dfd6
367 365 test-debug-phase: new rev 0: x -> 0
368 366 test-debug-phase: new rev 1: x -> 0
369 367 test-debug-phase: new rev 2: x -> 0
370 368 test-debug-phase: new rev 3: x -> 0
371 369 test-debug-phase: new rev 4: x -> 0
372 370 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
373 371 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
374 372 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
375 373 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
376 374 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
377 375 (run 'hg heads' to see heads, 'hg merge' to merge)
378 376 $ hglog
379 377 o 4 0 B'
380 378 |
381 379 | o 3 0 D
382 380 | |
383 381 | o 2 0 C
384 382 |/
385 383 o 1 0 B
386 384 |
387 385 o 0 0 A
388 386
389 387 $ cd ..
390 388
391 389 But secret can still be bundled explicitly
392 390
393 391 $ cd initialrepo
394 392 $ hg bundle --base '4^' -r 'children(4)' ../secret-bundle.hg
395 393 4 changesets found
396 394 $ cd ..
397 395
398 396 Test secret changeset are not cloned
399 397 (during local clone)
400 398
401 399 $ hg clone -qU initialrepo clone-dest
402 400 test-debug-phase: new rev 0: x -> 0
403 401 test-debug-phase: new rev 1: x -> 0
404 402 test-debug-phase: new rev 2: x -> 0
405 403 test-debug-phase: new rev 3: x -> 0
406 404 test-debug-phase: new rev 4: x -> 0
407 405 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
408 406 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
409 407 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
410 408 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
411 409 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
412 410 $ hglog -R clone-dest
413 411 o 4 0 B'
414 412 |
415 413 | o 3 0 D
416 414 | |
417 415 | o 2 0 C
418 416 |/
419 417 o 1 0 B
420 418 |
421 419 o 0 0 A
422 420
423 421
424 422 Test summary
425 423
426 424 $ hg summary -R clone-dest --verbose
427 425 parent: -1:000000000000 (no revision checked out)
428 426 branch: default
429 427 commit: (clean)
430 428 update: 5 new changesets (update)
431 429 $ hg summary -R initialrepo
432 430 parent: 7:17a481b3bccb tip
433 431 merge B' and E
434 432 branch: default
435 433 commit: (clean) (secret)
436 434 update: 1 new changesets, 2 branch heads (merge)
437 435 phases: 3 draft, 3 secret
438 436 $ hg summary -R initialrepo --quiet
439 437 parent: 7:17a481b3bccb tip
440 438 update: 1 new changesets, 2 branch heads (merge)
441 439
442 440 Test revset
443 441
444 442 $ cd initialrepo
445 443 $ hglog -r 'public()'
446 444 o 1 0 B
447 445 |
448 446 o 0 0 A
449 447
450 448 $ hglog -r 'draft()'
451 449 o 6 1 B'
452 450 |
453 451 ~
454 452 o 3 1 D
455 453 |
456 454 o 2 1 C
457 455 |
458 456 ~
459 457 $ hglog -r 'secret()'
460 458 @ 7 2 merge B' and E
461 459 |\
462 460 | ~
463 461 | o 5 2 H
464 462 |/
465 463 o 4 2 E
466 464 |
467 465 ~
468 466
469 467 test that phase are displayed in log at debug level
470 468
471 469 $ hg log --debug
472 470 changeset: 7:17a481b3bccb796c0521ae97903d81c52bfee4af
473 471 tag: tip
474 472 phase: secret
475 473 parent: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
476 474 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
477 475 manifest: 7:5e724ffacba267b2ab726c91fc8b650710deaaa8
478 476 user: test
479 477 date: Thu Jan 01 00:00:00 1970 +0000
480 478 extra: branch=default
481 479 description:
482 480 merge B' and E
483 481
484 482
485 483 changeset: 6:cf9fe039dfd67e829edf6522a45de057b5c86519
486 484 phase: draft
487 485 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
488 486 parent: -1:0000000000000000000000000000000000000000
489 487 manifest: 6:ab8bfef2392903058bf4ebb9e7746e8d7026b27a
490 488 user: test
491 489 date: Thu Jan 01 00:00:00 1970 +0000
492 490 files+: B'
493 491 extra: branch=default
494 492 description:
495 493 B'
496 494
497 495
498 496 changeset: 5:a030c6be5127abc010fcbff1851536552e6951a8
499 497 phase: secret
500 498 parent: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
501 499 parent: -1:0000000000000000000000000000000000000000
502 500 manifest: 5:5c710aa854874fe3d5fa7192e77bdb314cc08b5a
503 501 user: test
504 502 date: Thu Jan 01 00:00:00 1970 +0000
505 503 files+: H
506 504 extra: branch=default
507 505 description:
508 506 H
509 507
510 508
511 509 changeset: 4:a603bfb5a83e312131cebcd05353c217d4d21dde
512 510 phase: secret
513 511 parent: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
514 512 parent: -1:0000000000000000000000000000000000000000
515 513 manifest: 4:7173fd1c27119750b959e3a0f47ed78abe75d6dc
516 514 user: test
517 515 date: Thu Jan 01 00:00:00 1970 +0000
518 516 files+: E
519 517 extra: branch=default
520 518 description:
521 519 E
522 520
523 521
524 522 changeset: 3:b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e
525 523 phase: draft
526 524 parent: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
527 525 parent: -1:0000000000000000000000000000000000000000
528 526 manifest: 3:6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c
529 527 user: test
530 528 date: Thu Jan 01 00:00:00 1970 +0000
531 529 files+: D
532 530 extra: branch=default
533 531 description:
534 532 D
535 533
536 534
537 535 changeset: 2:f838bfaca5c7226600ebcfd84f3c3c13a28d3757
538 536 phase: draft
539 537 parent: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
540 538 parent: -1:0000000000000000000000000000000000000000
541 539 manifest: 2:66a5a01817fdf5239c273802b5b7618d051c89e4
542 540 user: test
543 541 date: Thu Jan 01 00:00:00 1970 +0000
544 542 files+: C
545 543 extra: branch=default
546 544 description:
547 545 C
548 546
549 547
550 548 changeset: 1:27547f69f25460a52fff66ad004e58da7ad3fb56
551 549 phase: public
552 550 parent: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
553 551 parent: -1:0000000000000000000000000000000000000000
554 552 manifest: 1:cb5cbbc1bfbf24cc34b9e8c16914e9caa2d2a7fd
555 553 user: test
556 554 date: Thu Jan 01 00:00:00 1970 +0000
557 555 files+: B
558 556 extra: branch=default
559 557 description:
560 558 B
561 559
562 560
563 561 changeset: 0:4a2df7238c3b48766b5e22fafbb8a2f506ec8256
564 562 phase: public
565 563 parent: -1:0000000000000000000000000000000000000000
566 564 parent: -1:0000000000000000000000000000000000000000
567 565 manifest: 0:007d8c9d88841325f5c6b06371b35b4e8a2b1a83
568 566 user: test
569 567 date: Thu Jan 01 00:00:00 1970 +0000
570 568 files+: A
571 569 extra: branch=default
572 570 description:
573 571 A
574 572
575 573
576 574
577 575
578 576 (Issue3707)
579 577 test invalid phase name
580 578
581 579 $ mkcommit I --config phases.new-commit='babar'
582 580 transaction abort!
583 581 rollback completed
584 582 config error: phases.new-commit: not a valid phase name ('babar')
585 583 [30]
586 584 Test phase command
587 585 ===================
588 586
589 587 initial picture
590 588
591 589 $ hg log -G --template "{rev} {phase} {desc}\n"
592 590 @ 7 secret merge B' and E
593 591 |\
594 592 | o 6 draft B'
595 593 | |
596 594 +---o 5 secret H
597 595 | |
598 596 o | 4 secret E
599 597 | |
600 598 o | 3 draft D
601 599 | |
602 600 o | 2 draft C
603 601 |/
604 602 o 1 public B
605 603 |
606 604 o 0 public A
607 605
608 606
609 607 display changesets phase
610 608
611 609 (mixing -r and plain rev specification)
612 610
613 611 $ hg phase 1::4 -r 7
614 612 1: public
615 613 2: draft
616 614 3: draft
617 615 4: secret
618 616 7: secret
619 617
620 618
621 619 move changeset forward
622 620
623 621 (with -r option)
624 622
625 623 $ hg phase --public -r 2
626 624 test-debug-phase: move rev 2: 1 -> 0
627 625 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
628 626 $ hg log -G --template "{rev} {phase} {desc}\n"
629 627 @ 7 secret merge B' and E
630 628 |\
631 629 | o 6 draft B'
632 630 | |
633 631 +---o 5 secret H
634 632 | |
635 633 o | 4 secret E
636 634 | |
637 635 o | 3 draft D
638 636 | |
639 637 o | 2 public C
640 638 |/
641 639 o 1 public B
642 640 |
643 641 o 0 public A
644 642
645 643
646 644 move changeset backward
647 645
648 646 (without -r option)
649 647
650 648 $ hg phase --draft --force 2
651 649 test-debug-phase: move rev 2: 0 -> 1
652 650 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: public -> draft
653 651 $ hg log -G --template "{rev} {phase} {desc}\n"
654 652 @ 7 secret merge B' and E
655 653 |\
656 654 | o 6 draft B'
657 655 | |
658 656 +---o 5 secret H
659 657 | |
660 658 o | 4 secret E
661 659 | |
662 660 o | 3 draft D
663 661 | |
664 662 o | 2 draft C
665 663 |/
666 664 o 1 public B
667 665 |
668 666 o 0 public A
669 667
670 668
671 669 move changeset forward and backward
672 670
673 671 $ hg phase --draft --force 1::4
674 672 test-debug-phase: move rev 1: 0 -> 1
675 673 test-debug-phase: move rev 4: 2 -> 1
676 674 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: public -> draft
677 675 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
678 676 $ hg log -G --template "{rev} {phase} {desc}\n"
679 677 @ 7 secret merge B' and E
680 678 |\
681 679 | o 6 draft B'
682 680 | |
683 681 +---o 5 secret H
684 682 | |
685 683 o | 4 draft E
686 684 | |
687 685 o | 3 draft D
688 686 | |
689 687 o | 2 draft C
690 688 |/
691 689 o 1 draft B
692 690 |
693 691 o 0 public A
694 692
695 693 test partial failure
696 694
697 695 $ hg phase --public 7
698 696 test-debug-phase: move rev 1: 1 -> 0
699 697 test-debug-phase: move rev 2: 1 -> 0
700 698 test-debug-phase: move rev 3: 1 -> 0
701 699 test-debug-phase: move rev 4: 1 -> 0
702 700 test-debug-phase: move rev 6: 1 -> 0
703 701 test-debug-phase: move rev 7: 2 -> 0
704 702 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: draft -> public
705 703 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: draft -> public
706 704 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: draft -> public
707 705 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: draft -> public
708 706 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: draft -> public
709 707 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> public
710 708 $ hg phase --draft '5 or 7'
711 709 test-debug-phase: move rev 5: 2 -> 1
712 710 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: secret -> draft
713 711 cannot move 1 changesets to a higher phase, use --force
714 712 phase changed for 1 changesets
715 713 [1]
716 714 $ hg log -G --template "{rev} {phase} {desc}\n"
717 715 @ 7 public merge B' and E
718 716 |\
719 717 | o 6 public B'
720 718 | |
721 719 +---o 5 draft H
722 720 | |
723 721 o | 4 public E
724 722 | |
725 723 o | 3 public D
726 724 | |
727 725 o | 2 public C
728 726 |/
729 727 o 1 public B
730 728 |
731 729 o 0 public A
732 730
733 731
734 732 test complete failure
735 733
736 734 $ hg phase --draft 7
737 735 cannot move 1 changesets to a higher phase, use --force
738 736 no phases changed
739 737 [1]
740 738
741 739 $ cd ..
742 740
743 741 test hidden changeset are not cloned as public (issue3935)
744 742
745 743 $ cd initialrepo
746 744
747 745 (enabling evolution)
748 746 $ cat >> $HGRCPATH << EOF
749 747 > [experimental]
750 748 > evolution.createmarkers=True
751 749 > EOF
752 750
753 751 (making a changeset hidden; H in that case)
754 752 $ hg debugobsolete `hg id --debug -r 5`
755 753 1 new obsolescence markers
756 754 obsoleted 1 changesets
757 755
758 756 $ cd ..
759 757 $ hg clone initialrepo clonewithobs
760 758 requesting all changes
761 759 adding changesets
762 760 adding manifests
763 761 adding file changes
764 762 added 7 changesets with 6 changes to 6 files
765 763 new changesets 4a2df7238c3b:17a481b3bccb
766 764 test-debug-phase: new rev 0: x -> 0
767 765 test-debug-phase: new rev 1: x -> 0
768 766 test-debug-phase: new rev 2: x -> 0
769 767 test-debug-phase: new rev 3: x -> 0
770 768 test-debug-phase: new rev 4: x -> 0
771 769 test-debug-phase: new rev 5: x -> 0
772 770 test-debug-phase: new rev 6: x -> 0
773 771 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> public
774 772 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> public
775 773 test-hook-close-phase: f838bfaca5c7226600ebcfd84f3c3c13a28d3757: -> public
776 774 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: -> public
777 775 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: -> public
778 776 test-hook-close-phase: cf9fe039dfd67e829edf6522a45de057b5c86519: -> public
779 777 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: -> public
780 778 updating to branch default
781 779 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
782 780 $ cd clonewithobs
783 781 $ hg log -G --template "{rev} {phase} {desc}\n"
784 782 @ 6 public merge B' and E
785 783 |\
786 784 | o 5 public B'
787 785 | |
788 786 o | 4 public E
789 787 | |
790 788 o | 3 public D
791 789 | |
792 790 o | 2 public C
793 791 |/
794 792 o 1 public B
795 793 |
796 794 o 0 public A
797 795
798 796
799 797 test verify repo containing hidden changesets, which should not abort just
800 798 because repo.cancopy() is False
801 799
802 800 $ cd ../initialrepo
803 801 $ hg verify -q
804 802
805 803 $ cd ..
806 804
807 805 check whether HG_PENDING makes pending changes only in related
808 806 repositories visible to an external hook.
809 807
810 808 (emulate a transaction running concurrently by copied
811 809 .hg/phaseroots.pending in subsequent test)
812 810
813 811 $ cat > $TESTTMP/savepending.sh <<EOF
814 812 > cp .hg/store/phaseroots.pending .hg/store/phaseroots.pending.saved
815 813 > exit 1 # to avoid changing phase for subsequent tests
816 814 > EOF
817 815 $ cd push-dest
818 816 $ hg phase 6
819 817 6: draft
820 818 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" phase -f -s 6
821 819 abort: pretxnclose hook exited with status 1
822 820 [40]
823 821 $ cp .hg/store/phaseroots.pending.saved .hg/store/phaseroots.pending
824 822
825 823 (check (in)visibility of phaseroot while transaction running in repo)
826 824
827 825 $ cat > $TESTTMP/checkpending.sh <<EOF
828 826 > echo '@initialrepo'
829 827 > hg -R "$TESTTMP/initialrepo" phase 7
830 828 > echo '@push-dest'
831 829 > hg -R "$TESTTMP/push-dest" phase 6
832 830 > exit 1 # to avoid changing phase for subsequent tests
833 831 > EOF
834 832 $ cd ../initialrepo
835 833 $ hg phase 7
836 834 7: public
837 835 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" phase -f -s 7
838 836 @initialrepo
839 837 7: secret
840 838 @push-dest
841 839 6: draft
842 840 abort: pretxnclose hook exited with status 1
843 841 [40]
844 842
845 843 Check that pretxnclose-phase hook can control phase movement
846 844
847 845 $ hg phase --force b3325c91a4d9 --secret
848 846 test-debug-phase: move rev 3: 0 -> 2
849 847 test-debug-phase: move rev 4: 0 -> 2
850 848 test-debug-phase: move rev 5: 1 -> 2
851 849 test-debug-phase: move rev 7: 0 -> 2
852 850 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: public -> secret
853 851 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: public -> secret
854 852 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: draft -> secret
855 853 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: public -> secret
856 854 $ hg log -G -T phases
857 855 @ changeset: 7:17a481b3bccb
858 856 |\ tag: tip
859 857 | | phase: secret
860 858 | | parent: 6:cf9fe039dfd6
861 859 | | parent: 4:a603bfb5a83e
862 860 | | user: test
863 861 | | date: Thu Jan 01 00:00:00 1970 +0000
864 862 | | summary: merge B' and E
865 863 | |
866 864 | o changeset: 6:cf9fe039dfd6
867 865 | | phase: public
868 866 | | parent: 1:27547f69f254
869 867 | | user: test
870 868 | | date: Thu Jan 01 00:00:00 1970 +0000
871 869 | | summary: B'
872 870 | |
873 871 o | changeset: 4:a603bfb5a83e
874 872 | | phase: secret
875 873 | | user: test
876 874 | | date: Thu Jan 01 00:00:00 1970 +0000
877 875 | | summary: E
878 876 | |
879 877 o | changeset: 3:b3325c91a4d9
880 878 | | phase: secret
881 879 | | user: test
882 880 | | date: Thu Jan 01 00:00:00 1970 +0000
883 881 | | summary: D
884 882 | |
885 883 o | changeset: 2:f838bfaca5c7
886 884 |/ phase: public
887 885 | user: test
888 886 | date: Thu Jan 01 00:00:00 1970 +0000
889 887 | summary: C
890 888 |
891 889 o changeset: 1:27547f69f254
892 890 | phase: public
893 891 | user: test
894 892 | date: Thu Jan 01 00:00:00 1970 +0000
895 893 | summary: B
896 894 |
897 895 o changeset: 0:4a2df7238c3b
898 896 phase: public
899 897 user: test
900 898 date: Thu Jan 01 00:00:00 1970 +0000
901 899 summary: A
902 900
903 901
904 902 Install a hook that prevent b3325c91a4d9 to become public
905 903
906 904 $ cat >> .hg/hgrc << EOF
907 905 > [hooks]
908 906 > pretxnclose-phase.nopublish_D = sh -c "(echo \$HG_NODE| grep -v b3325c91a4d9>/dev/null) || [ 'public' != \$HG_PHASE ]"
909 907 > EOF
910 908
911 909 Try various actions. only the draft move should succeed
912 910
913 911 $ hg phase --public b3325c91a4d9
914 912 abort: pretxnclose-phase.nopublish_D hook exited with status 1
915 913 [40]
916 914 $ hg phase --public a603bfb5a83e
917 915 abort: pretxnclose-phase.nopublish_D hook exited with status 1
918 916 [40]
919 917 $ hg phase --draft 17a481b3bccb
920 918 test-debug-phase: move rev 3: 2 -> 1
921 919 test-debug-phase: move rev 4: 2 -> 1
922 920 test-debug-phase: move rev 7: 2 -> 1
923 921 test-hook-close-phase: b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e: secret -> draft
924 922 test-hook-close-phase: a603bfb5a83e312131cebcd05353c217d4d21dde: secret -> draft
925 923 test-hook-close-phase: 17a481b3bccb796c0521ae97903d81c52bfee4af: secret -> draft
926 924 $ hg phase --public 17a481b3bccb
927 925 abort: pretxnclose-phase.nopublish_D hook exited with status 1
928 926 [40]
929 927
930 928 $ cd ..
931 929
932 930 Test for the "internal" phase
933 931 =============================
934 932
935 933 Check we deny its usage on older repository
936 934
937 935 $ hg init no-internal-phase --config format.use-internal-phase=no
938 936 $ cd no-internal-phase
939 937 $ hg debugrequires | grep internal-phase
940 938 [1]
941 939 $ echo X > X
942 940 $ hg add X
943 941 $ hg status
944 942 A X
945 943 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit" 2>&1 | grep ProgrammingError
946 944 ** ProgrammingError: this repository does not support the internal phase
947 945 raise error.ProgrammingError(msg) (no-pyoxidizer !)
948 946 *ProgrammingError: this repository does not support the internal phase (glob)
949 947 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit" 2>&1 | grep ProgrammingError
950 948 ** ProgrammingError: this repository does not support the archived phase
951 949 raise error.ProgrammingError(msg) (no-pyoxidizer !)
952 950 *ProgrammingError: this repository does not support the archived phase (glob)
953 951
954 952 $ cd ..
955 953
956 954 Check it works fine with repository that supports it.
957 955
958 956 $ hg init internal-phase --config format.use-internal-phase=yes
959 957 $ cd internal-phase
960 958 $ hg debugrequires | grep internal-phase
961 959 internal-phase-2
962 960 $ mkcommit A
963 961 test-debug-phase: new rev 0: x -> 1
964 962 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
965 963
966 964 Commit an internal changesets
967 965
968 966 $ echo B > B
969 967 $ hg add B
970 968 $ hg status
971 969 A B
972 970 $ hg --config "phases.new-commit=internal" commit -m "my test internal commit"
973 971 test-debug-phase: new rev 1: x -> 96
974 972 test-hook-close-phase: c01c42dffc7f81223397e99652a0703f83e1c5ea: -> internal
975 973
976 974 The changeset is a working parent descendant.
977 975 Per the usual visibility rules, it is made visible.
978 976
979 977 $ hg log -G -l 3
980 978 @ changeset: 1:c01c42dffc7f
981 979 | tag: tip
982 980 | user: test
983 981 | date: Thu Jan 01 00:00:00 1970 +0000
984 982 | summary: my test internal commit
985 983 |
986 984 o changeset: 0:4a2df7238c3b
987 985 user: test
988 986 date: Thu Jan 01 00:00:00 1970 +0000
989 987 summary: A
990 988
991 989
992 990 Commit is hidden as expected
993 991
994 992 $ hg up 0
995 993 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
996 994 $ hg log -G
997 995 @ changeset: 0:4a2df7238c3b
998 996 tag: tip
999 997 user: test
1000 998 date: Thu Jan 01 00:00:00 1970 +0000
1001 999 summary: A
1002 1000
1003 1001 The hidden commit is an orphan but doesn't show up without --hidden
1004 1002 And internal changesets are not considered for unstability.
1005 1003
1006 1004 $ hg debugobsolete `hg id --debug -ir 0`
1007 1005 1 new obsolescence markers
1008 1006 obsoleted 1 changesets
1009 1007 $ hg --hidden log -G -r '(0::) - 0'
1010 1008 o changeset: 1:c01c42dffc7f
1011 1009 | tag: tip
1012 1010 ~ user: test
1013 1011 date: Thu Jan 01 00:00:00 1970 +0000
1014 1012 summary: my test internal commit
1015 1013
1016 1014 $ hg --hidden log -G -r 'unstable()'
1017 1015
1018 1016 $ hg log -G -r 'unstable()'
1019 1017
1020 1018
1021 1019 Test for archived phase
1022 1020 -----------------------
1023 1021
1024 1022 Commit an archived changesets
1025 1023
1026 1024 $ cd ..
1027 1025 $ hg clone --quiet --pull internal-phase archived-phase \
1028 1026 > --config format.exp-archived-phase=yes \
1029 1027 > --config extensions.phasereport='!' \
1030 1028 > --config hooks.txnclose-phase.test=
1031 1029
1032 1030 $ cd archived-phase
1033 1031
1034 1032 $ echo B > B
1035 1033 $ hg add B
1036 1034 $ hg status
1037 1035 A B
1038 1036 $ hg --config "phases.new-commit=archived" commit -m "my test archived commit"
1039 1037 test-debug-phase: new rev 1: x -> 32
1040 1038 test-hook-close-phase: 8df5997c3361518f733d1ae67cd3adb9b0eaf125: -> archived
1041 1039
1042 1040 The changeset is a working parent descendant.
1043 1041 Per the usual visibility rules, it is made visible.
1044 1042
1045 1043 $ hg log -G -l 3
1046 1044 @ changeset: 1:8df5997c3361
1047 1045 | tag: tip
1048 1046 | user: test
1049 1047 | date: Thu Jan 01 00:00:00 1970 +0000
1050 1048 | summary: my test archived commit
1051 1049 |
1052 1050 o changeset: 0:4a2df7238c3b
1053 1051 user: test
1054 1052 date: Thu Jan 01 00:00:00 1970 +0000
1055 1053 summary: A
1056 1054
1057 1055
1058 1056 Commit is hidden as expected
1059 1057
1060 1058 $ hg up 0
1061 1059 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1062 1060 $ hg log -G
1063 1061 @ changeset: 0:4a2df7238c3b
1064 1062 tag: tip
1065 1063 user: test
1066 1064 date: Thu Jan 01 00:00:00 1970 +0000
1067 1065 summary: A
1068 1066
1069 1067 $ cd ..
1070 1068
1071 1069 Recommitting an exact match of a public commit shouldn't change it to
1072 1070 draft:
1073 1071
1074 1072 $ cd initialrepo
1075 1073 $ hg phase -r 2
1076 1074 2: public
1077 1075 $ hg up -C 1
1078 1076 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
1079 1077 $ mkcommit C
1080 1078 warning: commit already existed in the repository!
1081 1079 $ hg phase -r 2
1082 1080 2: public
1083 1081
1084 1082 Same, but for secret:
1085 1083
1086 1084 $ hg up 7
1087 1085 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1088 1086 $ mkcommit F -s
1089 1087 test-debug-phase: new rev 8: x -> 2
1090 1088 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1091 1089 $ hg up 7
1092 1090 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1093 1091 $ hg phase
1094 1092 7: draft
1095 1093 $ mkcommit F
1096 1094 test-debug-phase: new rev 8: x -> 2
1097 1095 warning: commit already existed in the repository!
1098 1096 test-hook-close-phase: de414268ec5ce2330c590b942fbb5ff0b0ca1a0a: -> secret
1099 1097 $ hg phase -r tip
1100 1098 8: secret
1101 1099
1102 1100 But what about obsoleted changesets?
1103 1101
1104 1102 $ hg up 4
1105 1103 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1106 1104 $ mkcommit H
1107 1105 test-debug-phase: new rev 5: x -> 2
1108 1106 warning: commit already existed in the repository!
1109 1107 test-hook-close-phase: a030c6be5127abc010fcbff1851536552e6951a8: -> secret
1110 1108 $ hg phase -r 5
1111 1109 5: secret
1112 1110 $ hg par
1113 1111 changeset: 5:a030c6be5127
1114 1112 user: test
1115 1113 date: Thu Jan 01 00:00:00 1970 +0000
1116 1114 obsolete: pruned
1117 1115 summary: H
1118 1116
1119 1117 $ hg up tip
1120 1118 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1121 1119 $ cd ..
1122 1120
1123 1121 Testing that command line flags override configuration
1124 1122
1125 1123 $ hg init commit-overrides
1126 1124 $ cd commit-overrides
1127 1125
1128 1126 `hg commit --draft` overrides new-commit=secret
1129 1127
1130 1128 $ mkcommit A --config phases.new-commit='secret' --draft
1131 1129 test-debug-phase: new rev 0: x -> 1
1132 1130 test-hook-close-phase: 4a2df7238c3b48766b5e22fafbb8a2f506ec8256: -> draft
1133 1131 $ hglog
1134 1132 @ 0 1 A
1135 1133
1136 1134
1137 1135 `hg commit --secret` overrides new-commit=draft
1138 1136
1139 1137 $ mkcommit B --config phases.new-commit='draft' --secret
1140 1138 test-debug-phase: new rev 1: x -> 2
1141 1139 test-hook-close-phase: 27547f69f25460a52fff66ad004e58da7ad3fb56: -> secret
1142 1140 $ hglog
1143 1141 @ 1 2 B
1144 1142 |
1145 1143 o 0 1 A
1146 1144
1147 1145
1148 1146 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now