mercurial/phases.py
author Patrick Mezard <patrick@mezard.eu>
Sat, 12 May 2012 00:24:07 +0200
changeset 16659 58edd786e96f
parent 16658 6b3d31d04a69
child 16724 00535da82faf
permissions -rw-r--r--
phase: make if abort on nullid for the good reason The good reason being you cannot call retractboundary() on nullid, not revset.set() cannot resolve '-1'.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15659
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     1
""" Mercurial phases support code
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     2
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     3
    ---
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     4
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     5
    Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     6
                   Logilab SA        <contact@logilab.fr>
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     7
                   Augie Fackler     <durin42@gmail.com>
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     8
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
     9
    This software may be used and distributed according to the terms of the
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    10
    GNU General Public License version 2 or any later version.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    11
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    12
    ---
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    13
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    14
This module implements most phase logic in mercurial.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    15
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    16
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    17
Basic Concept
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    18
=============
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    19
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    20
A 'changeset phases' is an indicator that tells us how a changeset is
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    21
manipulated and communicated. The details of each phase is described below,
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    22
here we describe the properties they have in common.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    23
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    24
Like bookmarks, phases are not stored in history and thus are not permanent and
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    25
leave no audit trail.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    26
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    27
First, no changeset can be in two phases at once. Phases are ordered, so they
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    28
can be considered from lowest to highest. The default, lowest phase is 'public'
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    29
- this is the normal phase of existing changesets. A child changeset can not be
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    30
in a lower phase than its parents.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    31
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    32
These phases share a hierarchy of traits:
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    33
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    34
            immutable shared
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    35
    public:     X        X
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    36
    draft:               X
15705
e34f4d1f0dbb phases: update doc to mention secret phase
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15697
diff changeset
    37
    secret:
15659
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    38
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    39
local commits are draft by default
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    40
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    41
Phase movement and exchange
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    42
============================
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    43
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    44
Phase data are exchanged by pushkey on pull and push. Some server have a
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    45
publish option set, we call them publishing server. Pushing to such server make
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    46
draft changeset publish.
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    47
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    48
A small list of fact/rules define the exchange of phase:
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    49
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    50
* old client never changes server states
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    51
* pull never changes server states
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    52
* publish and old server csets are seen as public by client
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    53
15705
e34f4d1f0dbb phases: update doc to mention secret phase
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15697
diff changeset
    54
* Any secret changeset seens in another repository is lowered to at least draft
e34f4d1f0dbb phases: update doc to mention secret phase
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15697
diff changeset
    55
15659
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    56
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    57
Here is the final table summing up the 49 possible usecase of phase exchange:
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    58
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    59
                           server
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    60
                  old     publish      non-publish
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    61
                 N   X    N   D   P    N   D   P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    62
    old client
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    63
    pull
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    64
     N           -   X/X  -   X/D X/P  -   X/D X/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    65
     X           -   X/X  -   X/D X/P  -   X/D X/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    66
    push
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    67
     X           X/X X/X  X/P X/P X/P  X/D X/D X/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    68
    new client
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    69
    pull
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    70
     N           -   P/X  -   P/D P/P  -   D/D P/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    71
     D           -   P/X  -   P/D P/P  -   D/D P/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    72
     P           -   P/X  -   P/D P/P  -   P/D P/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    73
    push
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    74
     D           P/X P/X  P/P P/P P/P  D/D D/D P/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    75
     P           P/X P/X  P/P P/P P/P  P/P P/P P/P
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    76
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    77
Legend:
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    78
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    79
    A/B = final state on client / state on server
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    80
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    81
    * N = new/not present,
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    82
    * P = public,
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    83
    * D = draft,
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    84
    * X = not tracked (ie: the old client or server has no internal way of
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    85
          recording the phase.)
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    86
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    87
    passive = only pushes
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    88
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    89
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    90
    A cell here can be read like this:
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    91
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    92
    "When a new client pushes a draft changeset (D) to a publishing server
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    93
    where it's not present (N), it's marked public on both sides (P/P)."
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    94
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    95
Note: old client behave as publish server with Draft only content
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    96
- other people see it as public
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    97
- content is pushed as draft
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    98
7fba5a245acc phases: change publish behavior to only alter behavior when server.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15649
diff changeset
    99
"""
15417
5261140d9322 phases: Minimal first add.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   100
15419
ccb7de21625a phases: handle errors other than ENOENT appropriately
Matt Mackall <mpm@selenic.com>
parents: 15418
diff changeset
   101
import errno
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   102
from node import nullid, nullrev, bin, hex, short
15456
abcaaf51d568 phases: handle unknown nodes in boundary
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15454
diff changeset
   103
from i18n import _
16659
58edd786e96f phase: make if abort on nullid for the good reason
Patrick Mezard <patrick@mezard.eu>
parents: 16658
diff changeset
   104
import util
15418
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   105
15818
57241845a4bb phases: store phase values in constant instead of using raw integer
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15705
diff changeset
   106
allphases = public, draft, secret = range(3)
15417
5261140d9322 phases: Minimal first add.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
   107
trackedphases = allphases[1:]
15821
e3ee8bf5d0cc phases: add list of string to access phase name
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15818
diff changeset
   108
phasenames = ['public', 'draft', 'secret']
15418
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   109
16624
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   110
def _filterunknown(ui, changelog, phaseroots):
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   111
    """remove unknown nodes from the phase boundary
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   112
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   113
    Nothing is lost as unknown nodes only hold data for their descendants
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   114
    """
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   115
    updated = False
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   116
    nodemap = changelog.nodemap # to filter unknown nodes
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   117
    for phase, nodes in enumerate(phaseroots):
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   118
        missing = [node for node in nodes if node not in nodemap]
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   119
        if missing:
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   120
            for mnode in missing:
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   121
                ui.debug(
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   122
                    'removing unknown node %s from %i-phase boundary\n'
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   123
                    % (short(mnode), phase))
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   124
            nodes.symmetric_difference_update(missing)
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   125
            updated = True
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   126
    return updated
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   127
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   128
def _readroots(repo, phasedefaults=None):
16625
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   129
    """Read phase roots from disk
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   130
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   131
    phasedefaults is a list of fn(repo, roots) callable, which are
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   132
    executed if the phase roots file does not exist. When phases are
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   133
    being initialized on an existing repository, this could be used to
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   134
    set selected changesets phase to something else than public.
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   135
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   136
    Return (roots, dirty) where dirty is true if roots differ from
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   137
    what is being stored.
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   138
    """
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   139
    dirty = False
15418
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   140
    roots = [set() for i in allphases]
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   141
    try:
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   142
        f = repo.sopener('phaseroots')
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   143
        try:
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   144
            for line in f:
16588
72319bfd7966 phases: line.strip().split() == line.split()
Martin Geisler <mg@aragost.com>
parents: 16535
diff changeset
   145
                phase, nh = line.split()
15418
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   146
                roots[int(phase)].add(bin(nh))
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   147
        finally:
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   148
            f.close()
15419
ccb7de21625a phases: handle errors other than ENOENT appropriately
Matt Mackall <mpm@selenic.com>
parents: 15418
diff changeset
   149
    except IOError, inst:
ccb7de21625a phases: handle errors other than ENOENT appropriately
Matt Mackall <mpm@selenic.com>
parents: 15418
diff changeset
   150
        if inst.errno != errno.ENOENT:
ccb7de21625a phases: handle errors other than ENOENT appropriately
Matt Mackall <mpm@selenic.com>
parents: 15418
diff changeset
   151
            raise
16625
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   152
        if phasedefaults:
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   153
            for f in phasedefaults:
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   154
                roots = f(repo, roots)
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   155
        dirty = True
16624
3f85cef66dcc phases: call filterunknown() in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16588
diff changeset
   156
    if _filterunknown(repo.ui, repo.changelog, roots):
16625
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   157
        dirty = True
df9df747070d phases: stop modifying localrepo in readroots()
Patrick Mezard <patrick@mezard.eu>
parents: 16624
diff changeset
   158
    return roots, dirty
15418
cf729af26963 phases: basic I/O logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15417
diff changeset
   159
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   160
class phasecache(object):
16658
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   161
    def __init__(self, repo, phasedefaults, _load=True):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   162
        if _load:
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   163
            # Cheap trick to allow shallow-copy without copy module
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   164
            self.phaseroots, self.dirty = _readroots(repo, phasedefaults)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   165
            self.opener = repo.sopener
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   166
            self._phaserevs = None
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   167
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   168
    def copy(self):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   169
        # Shallow copy meant to ensure isolation in
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   170
        # advance/retractboundary(), nothing more.
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   171
        ph = phasecache(None, None, _load=False)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   172
        ph.phaseroots = self.phaseroots[:]
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   173
        ph.dirty = self.dirty
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   174
        ph.opener = self.opener
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   175
        ph._phaserevs = self._phaserevs
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   176
        return ph
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   177
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   178
    def replace(self, phcache):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   179
        for a in 'phaseroots dirty opener _phaserevs'.split():
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   180
            setattr(self, a, getattr(phcache, a))
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   181
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   182
    def getphaserevs(self, repo, rebuild=False):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   183
        if rebuild or self._phaserevs is None:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   184
            revs = [public] * len(repo.changelog)
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   185
            for phase in trackedphases:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   186
                roots = map(repo.changelog.rev, self.phaseroots[phase])
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   187
                if roots:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   188
                    for rev in roots:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   189
                        revs[rev] = phase
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   190
                    for rev in repo.changelog.descendants(*roots):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   191
                        revs[rev] = phase
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   192
            self._phaserevs = revs
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   193
        return self._phaserevs
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   194
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   195
    def phase(self, repo, rev):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   196
        # We need a repo argument here to be able to build _phaserev
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   197
        # if necessary. The repository instance is not stored in
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   198
        # phasecache to avoid reference cycles. The changelog instance
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   199
        # is not stored because it is a filecache() property and can
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   200
        # be replaced without us being notified.
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   201
        if rev == nullrev:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   202
            return public
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   203
        if self._phaserevs is None or rev >= len(self._phaserevs):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   204
            self._phaserevs = self.getphaserevs(repo, rebuild=True)
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   205
        return self._phaserevs[rev]
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   206
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   207
    def write(self):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   208
        if not self.dirty:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   209
            return
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   210
        f = self.opener('phaseroots', 'w', atomictemp=True)
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   211
        try:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   212
            for phase, roots in enumerate(self.phaseroots):
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   213
                for h in roots:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   214
                    f.write('%i %s\n' % (phase, hex(h)))
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   215
        finally:
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   216
            f.close()
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   217
        self.dirty = False
15454
5a7dde5adec8 phases: add a moveboundary function to move phases boundaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15419
diff changeset
   218
16658
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   219
    def _updateroots(self, phase, newroots):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   220
        self.phaseroots[phase] = newroots
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   221
        self._phaserevs = None
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   222
        self.dirty = True
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   223
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   224
    def advanceboundary(self, repo, targetphase, nodes):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   225
        # Be careful to preserve shallow-copied values: do not update
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   226
        # phaseroots values, replace them.
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   227
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   228
        delroots = [] # set of root deleted by this path
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   229
        for phase in xrange(targetphase + 1, len(allphases)):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   230
            # filter nodes that are not in a compatible phase already
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   231
            nodes = [n for n in nodes
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   232
                     if self.phase(repo, repo[n].rev()) >= phase]
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   233
            if not nodes:
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   234
                break # no roots to move anymore
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   235
            olds = self.phaseroots[phase]
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   236
            roots = set(ctx.node() for ctx in repo.set(
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   237
                    'roots((%ln::) - (%ln::%ln))', olds, olds, nodes))
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   238
            if olds != roots:
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   239
                self._updateroots(phase, roots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   240
                # some roots may need to be declared for lower phases
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   241
                delroots.extend(olds - roots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   242
            # declare deleted root in the target phase
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   243
            if targetphase != 0:
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   244
                self.retractboundary(repo, targetphase, delroots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   245
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   246
    def retractboundary(self, repo, targetphase, nodes):
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   247
        # Be careful to preserve shallow-copied values: do not update
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   248
        # phaseroots values, replace them.
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   249
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   250
        currentroots = self.phaseroots[targetphase]
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   251
        newroots = [n for n in nodes
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   252
                    if self.phase(repo, repo[n].rev()) < targetphase]
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   253
        if newroots:
16659
58edd786e96f phase: make if abort on nullid for the good reason
Patrick Mezard <patrick@mezard.eu>
parents: 16658
diff changeset
   254
            if nullid in newroots:
58edd786e96f phase: make if abort on nullid for the good reason
Patrick Mezard <patrick@mezard.eu>
parents: 16658
diff changeset
   255
                raise util.Abort(_('cannot change null revision phase'))
16658
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   256
            currentroots = currentroots.copy()
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   257
            currentroots.update(newroots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   258
            ctxs = repo.set('roots(%ln::)', currentroots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   259
            currentroots.intersection_update(ctx.node() for ctx in ctxs)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   260
            self._updateroots(targetphase, currentroots)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   261
15481
0b7ce2f739fb phases: rename moveboundary into advance boundary
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15480
diff changeset
   262
def advanceboundary(repo, targetphase, nodes):
15454
5a7dde5adec8 phases: add a moveboundary function to move phases boundaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15419
diff changeset
   263
    """Add nodes to a phase changing other nodes phases if necessary.
5a7dde5adec8 phases: add a moveboundary function to move phases boundaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15419
diff changeset
   264
15482
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   265
    This function move boundary *forward* this means that all nodes are set
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   266
    in the target phase or kept in a *lower* phase.
15454
5a7dde5adec8 phases: add a moveboundary function to move phases boundaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15419
diff changeset
   267
15482
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   268
    Simplify boundary to contains phase roots only."""
16658
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   269
    phcache = repo._phasecache.copy()
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   270
    phcache.advanceboundary(repo, targetphase, nodes)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   271
    repo._phasecache.replace(phcache)
15482
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   272
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   273
def retractboundary(repo, targetphase, nodes):
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   274
    """Set nodes back to a phase changing other nodes phases if necessary.
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   275
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   276
    This function move boundary *backward* this means that all nodes are set
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   277
    in the target phase or kept in a *higher* phase.
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   278
a667c89e49b3 phases: add retractboundary function to move boundary backward
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15481
diff changeset
   279
    Simplify boundary to contains phase roots only."""
16658
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   280
    phcache = repo._phasecache.copy()
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   281
    phcache.retractboundary(repo, targetphase, nodes)
6b3d31d04a69 phases: make advance/retractboundary() atomic
Patrick Mezard <patrick@mezard.eu>
parents: 16657
diff changeset
   282
    repo._phasecache.replace(phcache)
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   283
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   284
def listphases(repo):
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   285
    """List phases root for serialisation over pushkey"""
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   286
    keys = {}
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   287
    value = '%i' % draft
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   288
    for root in repo._phasecache.phaseroots[draft]:
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   289
        keys[hex(root)] = value
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   290
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   291
    if repo.ui.configbool('phases', 'publish', True):
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   292
        # Add an extra data to let remote know we are a publishing repo.
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   293
        # Publishing repo can't just pretend they are old repo. When pushing to
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   294
        # a publishing repo, the client still need to push phase boundary
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   295
        #
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   296
        # Push do not only push changeset. It also push phase data. New
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   297
        # phase data may apply to common changeset which won't be push (as they
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   298
        # are common).  Here is a very simple example:
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   299
        #
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   300
        # 1) repo A push changeset X as draft to repo B
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   301
        # 2) repo B make changeset X public
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   302
        # 3) repo B push to repo A. X is not pushed but the data that X as now
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   303
        #    public should
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   304
        #
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   305
        # The server can't handle it on it's own as it has no idea of client
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   306
        # phase data.
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   307
        keys['publishing'] = 'True'
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   308
    return keys
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   309
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   310
def pushphase(repo, nhex, oldphasestr, newphasestr):
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   311
    """List phases root for serialisation over pushkey"""
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   312
    lock = repo.lock()
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   313
    try:
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   314
        currentphase = repo[nhex].phase()
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   315
        newphase = abs(int(newphasestr)) # let's avoid negative index surprise
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   316
        oldphase = abs(int(oldphasestr)) # let's avoid negative index surprise
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   317
        if currentphase == oldphase and newphase < oldphase:
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   318
            advanceboundary(repo, newphase, [bin(nhex)])
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   319
            return 1
16051
2aa5b51f310f phases: don't complain if cset is already public on pushkey (issue3230)
Matt Mackall <mpm@selenic.com>
parents: 16030
diff changeset
   320
        elif currentphase == newphase:
2aa5b51f310f phases: don't complain if cset is already public on pushkey (issue3230)
Matt Mackall <mpm@selenic.com>
parents: 16030
diff changeset
   321
            # raced, but got correct result
2aa5b51f310f phases: don't complain if cset is already public on pushkey (issue3230)
Matt Mackall <mpm@selenic.com>
parents: 16030
diff changeset
   322
            return 1
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   323
        else:
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   324
            return 0
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   325
    finally:
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15482
diff changeset
   326
        lock.release()
15649
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   327
15697
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   328
def visibleheads(repo):
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   329
    """return the set of visible head of this repo"""
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   330
    # XXX we want a cache on this
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   331
    sroots = repo._phasecache.phaseroots[secret]
15697
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   332
    if sroots:
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   333
        # XXX very slow revset. storing heads or secret "boundary" would help.
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   334
        revset = repo.set('heads(not (%ln::))', sroots)
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   335
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   336
        vheads = [ctx.node() for ctx in revset]
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   337
        if not vheads:
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   338
            vheads.append(nullid)
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   339
    else:
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   340
        vheads = repo.heads()
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   341
    return vheads
21eb048edc19 phases: add a function to compute visible heads
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15696
diff changeset
   342
16535
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   343
def visiblebranchmap(repo):
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   344
    """return a branchmap for the visible set"""
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   345
    # XXX Recomputing this data on the fly is very slow.  We should build a
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   346
    # XXX cached version while computin the standard branchmap version.
16657
b6081c2c4647 phases: introduce phasecache
Patrick Mezard <patrick@mezard.eu>
parents: 16626
diff changeset
   347
    sroots = repo._phasecache.phaseroots[secret]
16535
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   348
    if sroots:
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   349
        vbranchmap = {}
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   350
        for branch, nodes in  repo.branchmap().iteritems():
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   351
            # search for secret heads.
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   352
            for n in nodes:
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   353
                if repo[n].phase() >= secret:
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   354
                    nodes = None
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   355
                    break
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   356
            # if secreat heads where found we must compute them again
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   357
            if nodes is None:
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   358
                s = repo.set('heads(branch(%s) - secret())', branch)
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   359
                nodes = [c.node() for c in s]
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   360
            vbranchmap[branch] = nodes
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   361
    else:
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   362
        vbranchmap = repo.branchmap()
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   363
    return vbranchmap
39d1f83eb05d branchmap: server should not advertise secret changeset in branchmap (Issue3303)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16293
diff changeset
   364
15649
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   365
def analyzeremotephases(repo, subset, roots):
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   366
    """Compute phases heads and root in a subset of node from root dict
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   367
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   368
    * subset is heads of the subset
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   369
    * roots is {<nodeid> => phase} mapping. key and value are string.
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   370
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   371
    Accept unknown element input
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   372
    """
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   373
    # build list from dictionary
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   374
    draftroots = []
15902
4252d9f08d7e phases: use nodemap to check for missing nodes
Sune Foldager <cryo@cyanite.org>
parents: 15892
diff changeset
   375
    nodemap = repo.changelog.nodemap # to filter unknown nodes
15649
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   376
    for nhex, phase in roots.iteritems():
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   377
        if nhex == 'publishing': # ignore data related to publish option
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   378
            continue
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   379
        node = bin(nhex)
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   380
        phase = int(phase)
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   381
        if phase == 0:
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   382
            if node != nullid:
15953
52dc2b33d0be phase: fix warning text from invalid remote phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15948
diff changeset
   383
                repo.ui.warn(_('ignoring inconsistent public root'
52dc2b33d0be phase: fix warning text from invalid remote phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15948
diff changeset
   384
                               ' from remote: %s\n') % nhex)
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   385
        elif phase == 1:
15902
4252d9f08d7e phases: use nodemap to check for missing nodes
Sune Foldager <cryo@cyanite.org>
parents: 15892
diff changeset
   386
            if node in nodemap:
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   387
                draftroots.append(node)
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   388
        else:
15953
52dc2b33d0be phase: fix warning text from invalid remote phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15948
diff changeset
   389
            repo.ui.warn(_('ignoring unexpected root from remote: %i %s\n')
52dc2b33d0be phase: fix warning text from invalid remote phase
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15948
diff changeset
   390
                         % (phase, nhex))
15649
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   391
    # compute heads
15954
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   392
    publicheads = newheads(repo, subset, draftroots)
15892
592b3d1742a1 phases: simplify phase exchange and movement over pushkey
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15821
diff changeset
   393
    return publicheads, draftroots
15649
ca7c4254a21a phases: add a function to compute heads from root
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15648
diff changeset
   394
15954
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   395
def newheads(repo, heads, roots):
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   396
    """compute new head of a subset minus another
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   397
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   398
    * `heads`: define the first subset
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   399
    * `rroots`: define the second we substract to the first"""
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   400
    revset = repo.set('heads((%ln + parents(%ln)) - (%ln::%ln))',
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   401
                      heads, roots, roots, heads)
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   402
    return [c.node() for c in revset]
b345f851d056 phase: extracts heads computation logics from analyzeremotephases
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15953
diff changeset
   403
16030
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   404
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   405
def newcommitphase(ui):
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   406
    """helper to get the target phase of new commit
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   407
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   408
    Handle all possible values for the phases.new-commit options.
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   409
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   410
    """
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   411
    v = ui.config('phases', 'new-commit', draft)
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   412
    try:
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   413
        return phasenames.index(v)
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   414
    except ValueError:
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   415
        try:
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   416
            return int(v)
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   417
        except ValueError:
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   418
            msg = _("phases.new-commit: not a valid phase name ('%s')")
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   419
            raise error.ConfigError(msg % v)
308406677e9d phases: allow phase name in phases.new-commit settings
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 16025
diff changeset
   420