mercurial/obsolete.py
author Augie Fackler <raf@durin42.com>
Fri, 03 Mar 2017 14:42:56 -0500
changeset 31306 c920efa9d34b
parent 31018 cb5888c00410
child 31476 413b44003462
permissions -rw-r--r--
config: guard against setconfig specifying unicode values on py3 This was leading to some difficult to trace problems because the values were set in one place, but then blew up much later in the program. Exploding violently with an assertion seems reasonable here.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     1
# obsolete.py - obsolete markers handling
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     2
#
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     3
# Copyright 2012 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     4
#                Logilab SA        <contact@logilab.fr>
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     5
#
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     7
# GNU General Public License version 2 or any later version.
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
     8
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
     9
"""Obsolete marker handling
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    10
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    11
An obsolete marker maps an old changeset to a list of new
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    12
changesets. If the list of new changesets is empty, the old changeset
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    13
is said to be "killed". Otherwise, the old changeset is being
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    14
"replaced" by the new changesets.
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    15
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    16
Obsolete markers can be used to record and distribute changeset graph
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    17
transformations performed by history rewrite operations, and help
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    18
building new tools to reconcile conflicting rewrite actions. To
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    19
facilitate conflict resolution, markers include various annotations
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    20
besides old and news changeset identifiers, such as creation date or
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    21
author name.
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    22
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    23
The old obsoleted changeset is called a "precursor" and possible
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    24
replacements are called "successors". Markers that used changeset X as
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    25
a precursor are called "successor markers of X" because they hold
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    26
information about the successors of X. Markers that use changeset Y as
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    27
a successors are call "precursor markers of Y" because they hold
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    28
information about the precursors of Y.
17776
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
    29
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    30
Examples:
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    31
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    32
- When changeset A is replaced by changeset A', one marker is stored:
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    33
21166
bf2891877378 obsolete: fix one-element tuple in module docstring
Martin Geisler <martin@geisler.net>
parents: 21165
diff changeset
    34
    (A, (A',))
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    35
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    36
- When changesets A and B are folded into a new changeset C, two markers are
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    37
  stored:
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    38
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    39
    (A, (C,)) and (B, (C,))
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    40
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    41
- When changeset A is simply "pruned" from the graph, a marker is created:
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    42
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    43
    (A, ())
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    44
29894
02c150850e16 obsolete: fix minor module documentation issues
liscju <piotr.listkiewicz@gmail.com>
parents: 29389
diff changeset
    45
- When changeset A is split into B and C, a single marker is used:
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    46
29894
02c150850e16 obsolete: fix minor module documentation issues
liscju <piotr.listkiewicz@gmail.com>
parents: 29389
diff changeset
    47
    (A, (B, C))
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    48
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    49
  We use a single marker to distinguish the "split" case from the "divergence"
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    50
  case. If two independent operations rewrite the same changeset A in to A' and
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    51
  A'', we have an error case: divergent rewriting. We can detect it because
17775
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    52
  two markers will be created independently:
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    53
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    54
  (A, (B,)) and (A, (C,))
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    55
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    56
Format
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    57
------
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    58
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    59
Markers are stored in an append-only file stored in
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    60
'.hg/store/obsstore'.
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    61
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    62
The file starts with a version header:
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    63
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    64
- 1 unsigned byte: version number, starting at zero.
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    65
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
    66
The header is followed by the markers. Marker format depend of the version. See
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
    67
comment associated with each format for details.
21164
2efcef493aa2 obsolete: fix language and grammar in module docstring
Martin Geisler <martin@geisler.net>
parents: 21098
diff changeset
    68
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    69
"""
27332
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    70
from __future__ import absolute_import
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    71
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    72
import errno
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    73
import struct
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    74
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    75
from .i18n import _
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    76
from . import (
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    77
    base85,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    78
    error,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    79
    node,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    80
    parsers,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    81
    phases,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    82
    util,
04f346b8768f obsolete: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26684
diff changeset
    83
)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    84
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    85
_pack = struct.pack
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    86
_unpack = struct.unpack
23498
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
    87
_calcsize = struct.calcsize
24046
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
    88
propertycache = util.propertycache
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    89
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17405
diff changeset
    90
# the obsolete feature is not mature enough to be enabled by default.
17296
a1f8869f2eee obsolete: introduce an `_enabled` switch to disable the feature by default
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17295
diff changeset
    91
# you have to rely on third party extension extension to enable this.
a1f8869f2eee obsolete: introduce an `_enabled` switch to disable the feature by default
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17295
diff changeset
    92
_enabled = False
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
    93
22951
6c86c673dde6 obsolete: add createmarkers option
Durham Goode <durham@fb.com>
parents: 22950
diff changeset
    94
# Options for obsolescence
6c86c673dde6 obsolete: add createmarkers option
Durham Goode <durham@fb.com>
parents: 22950
diff changeset
    95
createmarkersopt = 'createmarkers'
22952
8792ac090e3b obsolete: add allowunstable option
Durham Goode <durham@fb.com>
parents: 22951
diff changeset
    96
allowunstableopt = 'allowunstable'
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 22952
diff changeset
    97
exchangeopt = 'exchange'
22951
6c86c673dde6 obsolete: add createmarkers option
Durham Goode <durham@fb.com>
parents: 22950
diff changeset
    98
17831
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
    99
### obsolescence marker flag
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   100
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   101
## bumpedfix flag
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   102
#
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   103
# When a changeset A' succeed to a changeset A which became public, we call A'
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   104
# "bumped" because it's a successors of a public changesets
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   105
#
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   106
# o    A' (bumped)
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   107
# |`:
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   108
# | o  A
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   109
# |/
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   110
# o    Z
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   111
#
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   112
# The way to solve this situation is to create a new changeset Ad as children
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   113
# of A. This changeset have the same content than A'. So the diff from A to A'
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   114
# is the same than the diff from A to Ad. Ad is marked as a successors of A'
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   115
#
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   116
# o   Ad
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   117
# |`:
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   118
# | x A'
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   119
# |'|
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   120
# o | A
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   121
# |/
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   122
# o Z
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   123
#
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   124
# But by transitivity Ad is also a successors of A. To avoid having Ad marked
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   125
# as bumped too, we add the `bumpedfix` flag to the marker. <A', (Ad,)>.
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18365
diff changeset
   126
# This flag mean that the successors express the changes between the public and
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18365
diff changeset
   127
# bumped version and fix the situation, breaking the transitivity of
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18365
diff changeset
   128
# "bumped" here.
17831
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   129
bumpedfix = 1
22850
b078e4dc9f9a obsstore: add a flag for sha256 hashes
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22849
diff changeset
   130
usingsha256 = 2
17831
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   131
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   132
## Parsing and writing of version "0"
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   133
#
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   134
# The header is followed by the markers. Each marker is made of:
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   135
#
22849
fd759142c6e5 obsolete: use uint## in the format documention
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22848
diff changeset
   136
# - 1 uint8 : number of new changesets "N", can be zero.
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   137
#
22849
fd759142c6e5 obsolete: use uint## in the format documention
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22848
diff changeset
   138
# - 1 uint32: metadata size "M" in bytes.
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   139
#
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   140
# - 1 byte: a bit field. It is reserved for flags used in common
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   141
#   obsolete marker operations, to avoid repeated decoding of metadata
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   142
#   entries.
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   143
#
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   144
# - 20 bytes: obsoleted changeset identifier.
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   145
#
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   146
# - N*20 bytes: new changesets identifiers.
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   147
#
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   148
# - M bytes: metadata as a sequence of nul-terminated strings. Each
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   149
#   string contains a key and a value, separated by a colon ':', without
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   150
#   additional encoding. Keys cannot contain '\0' or ':' and values
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   151
#   cannot contain '\0'.
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   152
_fm0version = 0
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   153
_fm0fixed   = '>BIB20s'
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   154
_fm0node = '20s'
23498
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
   155
_fm0fsize = _calcsize(_fm0fixed)
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
   156
_fm0fnodesize = _calcsize(_fm0node)
22334
f2c3cfc30e9c obsolete: move _encodemarkers next to _readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22333
diff changeset
   157
24014
7d9367de2654 obsolete: make optional offset parameter to fm*readmarkers required
Augie Fackler <augie@google.com>
parents: 23973
diff changeset
   158
def _fm0readmarkers(data, off):
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   159
    # Loop on markers
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   160
    l = len(data)
22327
f737631a9f0a obsolete: rename all _fm to _fm0
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22326
diff changeset
   161
    while off + _fm0fsize <= l:
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   162
        # read fixed part
22327
f737631a9f0a obsolete: rename all _fm to _fm0
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22326
diff changeset
   163
        cur = data[off:off + _fm0fsize]
f737631a9f0a obsolete: rename all _fm to _fm0
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22326
diff changeset
   164
        off += _fm0fsize
22685
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   165
        numsuc, mdsize, flags, pre = _unpack(_fm0fixed, cur)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   166
        # read replacement
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   167
        sucs = ()
22685
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   168
        if numsuc:
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   169
            s = (_fm0fnodesize * numsuc)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   170
            cur = data[off:off + s]
22685
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   171
            sucs = _unpack(_fm0node * numsuc, cur)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   172
            off += s
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   173
        # read metadata
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   174
        # (metadata will be decoded on demand)
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   175
        metadata = data[off:off + mdsize]
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   176
        if len(metadata) != mdsize:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
   177
            raise error.Abort(_('parsing obsolete marker: metadata is too '
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   178
                               'short, %d bytes expected, got %d')
17253
67f56ff5afcd obsolete: fix decoding error message arguments
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17220
diff changeset
   179
                             % (mdsize, len(metadata)))
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   180
        off += mdsize
22847
37460ee2003c obsolete: _rename decodemeta to _fm0decodemeta
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22846
diff changeset
   181
        metadata = _fm0decodemeta(metadata)
22222
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   182
        try:
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   183
            when, offset = metadata.pop('date', '0 0').split(' ')
22309
a65697c3f20e obsolete: avoid slow, generic date parsing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22274
diff changeset
   184
            date = float(when), int(offset)
a65697c3f20e obsolete: avoid slow, generic date parsing
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22274
diff changeset
   185
        except ValueError:
22222
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   186
            date = (0., 0)
22258
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   187
        parents = None
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   188
        if 'p2' in metadata:
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   189
            parents = (metadata.pop('p1', None), metadata.pop('p2', None))
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   190
        elif 'p1' in metadata:
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   191
            parents = (metadata.pop('p1', None),)
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   192
        elif 'p0' in metadata:
22258
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   193
            parents = ()
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   194
        if parents is not None:
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   195
            try:
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   196
                parents = tuple(node.bin(p) for p in parents)
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   197
                # if parent content is not a nodeid, drop the data
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   198
                for p in parents:
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   199
                    if len(p) != 20:
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   200
                        parents = None
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   201
                        break
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   202
            except TypeError:
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   203
                # if content cannot be translated to nodeid drop the data.
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   204
                parents = None
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   205
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   206
        metadata = tuple(sorted(metadata.iteritems()))
22222
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   207
22258
cf414981978a obsstore: also store the 'parents' field on disk
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22257
diff changeset
   208
        yield (pre, sucs, flags, metadata, date, parents)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   209
22330
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   210
def _fm0encodeonemarker(marker):
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   211
    pre, sucs, flags, metadata, date, parents = marker
22850
b078e4dc9f9a obsstore: add a flag for sha256 hashes
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22849
diff changeset
   212
    if flags & usingsha256:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
   213
        raise error.Abort(_('cannot handle sha256 with old obsstore format'))
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   214
    metadata = dict(metadata)
23002
2920a96f5839 obsstore: record data as floating point in fm0 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22954
diff changeset
   215
    time, tz = date
2920a96f5839 obsstore: record data as floating point in fm0 format
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22954
diff changeset
   216
    metadata['date'] = '%r %i' % (time, tz)
22330
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   217
    if parents is not None:
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   218
        if not parents:
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   219
            # mark that we explicitly recorded no parents
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   220
            metadata['p0'] = ''
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   221
        for i, p in enumerate(parents):
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   222
            metadata['p%i' % (i + 1)] = node.hex(p)
22846
b1efc4893da4 obsolete: _rename encodemeta to _fm0encodemeta
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22845
diff changeset
   223
    metadata = _fm0encodemeta(metadata)
22685
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   224
    numsuc = len(sucs)
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   225
    format = _fm0fixed + (_fm0node * numsuc)
753515d9e274 obsolete: replace "nb" notation with "num" (for "number")
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22614
diff changeset
   226
    data = [numsuc, len(metadata), flags, pre]
22330
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   227
    data.extend(sucs)
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   228
    return _pack(format, *data) + metadata
e74f8a65252d obsolete: move _fm0encodeonemarker next to _fm0readmarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22329
diff changeset
   229
22848
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   230
def _fm0encodemeta(meta):
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   231
    """Return encoded metadata string to string mapping.
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   232
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   233
    Assume no ':' in key and no '\0' in both key and value."""
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   234
    for key, value in meta.iteritems():
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   235
        if ':' in key or '\0' in key:
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   236
            raise ValueError("':' and '\0' are forbidden in metadata key'")
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   237
        if '\0' in value:
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   238
            raise ValueError("':' is forbidden in metadata value'")
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   239
    return '\0'.join(['%s:%s' % (k, meta[k]) for k in sorted(meta)])
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   240
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   241
def _fm0decodemeta(data):
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   242
    """Return string to string dictionary from encoded version."""
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   243
    d = {}
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   244
    for l in data.split('\0'):
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   245
        if l:
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   246
            key, value = l.split(':')
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   247
            d[key] = value
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   248
    return d
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   249
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   250
## Parsing and writing of version "1"
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   251
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   252
# The header is followed by the markers. Each marker is made of:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   253
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   254
# - uint32: total size of the marker (including this field)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   255
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   256
# - float64: date in seconds since epoch
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   257
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   258
# - int16: timezone offset in minutes
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   259
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   260
# - uint16: a bit field. It is reserved for flags used in common
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   261
#   obsolete marker operations, to avoid repeated decoding of metadata
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   262
#   entries.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   263
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   264
# - uint8: number of successors "N", can be zero.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   265
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   266
# - uint8: number of parents "P", can be zero.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   267
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   268
#     0: parents data stored but no parent,
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   269
#     1: one parent stored,
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   270
#     2: two parents stored,
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   271
#     3: no parent data stored
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   272
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   273
# - uint8: number of metadata entries M
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   274
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   275
# - 20 or 32 bytes: precursor changeset identifier.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   276
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   277
# - N*(20 or 32) bytes: successors changesets identifiers.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   278
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   279
# - P*(20 or 32) bytes: parents of the precursors changesets.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   280
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   281
# - M*(uint8, uint8): size of all metadata entries (key and value)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   282
#
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   283
# - remaining bytes: the metadata, each (key, value) pair after the other.
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   284
_fm1version = 1
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   285
_fm1fixed = '>IdhHBBB20s'
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   286
_fm1nodesha1 = '20s'
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   287
_fm1nodesha256 = '32s'
23499
b46876c94a93 obsstore: cache size computation for fm1 node
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23498
diff changeset
   288
_fm1nodesha1size = _calcsize(_fm1nodesha1)
b46876c94a93 obsstore: cache size computation for fm1 node
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23498
diff changeset
   289
_fm1nodesha256size = _calcsize(_fm1nodesha256)
23498
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
   290
_fm1fsize = _calcsize(_fm1fixed)
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   291
_fm1parentnone = 3
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   292
_fm1parentshift = 14
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   293
_fm1parentmask = (_fm1parentnone << _fm1parentshift)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   294
_fm1metapair = 'BB'
23498
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
   295
_fm1metapairsize = _calcsize('BB')
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   296
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   297
def _fm1purereadmarkers(data, off):
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   298
    # make some global constants local for performance
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   299
    noneflag = _fm1parentnone
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   300
    sha2flag = usingsha256
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   301
    sha1size = _fm1nodesha1size
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   302
    sha2size = _fm1nodesha256size
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   303
    sha1fmt = _fm1nodesha1
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   304
    sha2fmt = _fm1nodesha256
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   305
    metasize = _fm1metapairsize
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   306
    metafmt = _fm1metapair
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   307
    fsize = _fm1fsize
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   308
    unpack = _unpack
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   309
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   310
    # Loop on markers
23799
ffca0a14b566 readmarkers: hoist subtraction out of loop comparison
Matt Mackall <mpm@selenic.com>
parents: 23798
diff changeset
   311
    stop = len(data) - _fm1fsize
25211
22f4ce49044d util: drop the 'unpacker' helper
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25149
diff changeset
   312
    ufixed = struct.Struct(_fm1fixed).unpack
24018
26d6a6a78c1d obsolete: use parsers.fm1readmarker if it exists for a ~38% perf win
Augie Fackler <augie@google.com>
parents: 24014
diff changeset
   313
23799
ffca0a14b566 readmarkers: hoist subtraction out of loop comparison
Matt Mackall <mpm@selenic.com>
parents: 23798
diff changeset
   314
    while off <= stop:
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   315
        # read fixed part
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   316
        o1 = off + fsize
23800
83f361a21d31 readmarkers: drop a temporary
Matt Mackall <mpm@selenic.com>
parents: 23799
diff changeset
   317
        t, secs, tz, flags, numsuc, numpar, nummeta, prec = ufixed(data[off:o1])
23792
db3bc2bcb689 readmarkers: add some whitespace
Matt Mackall <mpm@selenic.com>
parents: 23791
diff changeset
   318
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   319
        if flags & sha2flag:
23805
345042e024dc readmarkers: add a SHA256 fixme note
Matt Mackall <mpm@selenic.com>
parents: 23804
diff changeset
   320
            # FIXME: prec was read as a SHA1, needs to be amended
345042e024dc readmarkers: add a SHA256 fixme note
Matt Mackall <mpm@selenic.com>
parents: 23804
diff changeset
   321
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   322
            # read 0 or more successors
23804
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   323
            if numsuc == 1:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   324
                o2 = o1 + sha2size
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   325
                sucs = (data[o1:o2],)
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   326
            else:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   327
                o2 = o1 + sha2size * numsuc
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   328
                sucs = unpack(sha2fmt * numsuc, data[o1:o2])
23792
db3bc2bcb689 readmarkers: add some whitespace
Matt Mackall <mpm@selenic.com>
parents: 23791
diff changeset
   329
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   330
            # read parents
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   331
            if numpar == noneflag:
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   332
                o3 = o2
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   333
                parents = None
23804
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   334
            elif numpar == 1:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   335
                o3 = o2 + sha2size
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   336
                parents = (data[o2:o3],)
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   337
            else:
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   338
                o3 = o2 + sha2size * numpar
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   339
                parents = unpack(sha2fmt * numpar, data[o2:o3])
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   340
        else:
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   341
            # read 0 or more successors
23804
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   342
            if numsuc == 1:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   343
                o2 = o1 + sha1size
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   344
                sucs = (data[o1:o2],)
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   345
            else:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   346
                o2 = o1 + sha1size * numsuc
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   347
                sucs = unpack(sha1fmt * numsuc, data[o1:o2])
23792
db3bc2bcb689 readmarkers: add some whitespace
Matt Mackall <mpm@selenic.com>
parents: 23791
diff changeset
   348
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   349
            # read parents
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   350
            if numpar == noneflag:
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   351
                o3 = o2
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   352
                parents = None
23804
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   353
            elif numpar == 1:
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   354
                o3 = o2 + sha1size
e880036719e3 readmarkers: fast-path single successors and parents
Matt Mackall <mpm@selenic.com>
parents: 23803
diff changeset
   355
                parents = (data[o2:o3],)
23801
20b5701cd90a readmarkers: read node reading into node length conditional
Matt Mackall <mpm@selenic.com>
parents: 23800
diff changeset
   356
            else:
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   357
                o3 = o2 + sha1size * numpar
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   358
                parents = unpack(sha1fmt * numpar, data[o2:o3])
23792
db3bc2bcb689 readmarkers: add some whitespace
Matt Mackall <mpm@selenic.com>
parents: 23791
diff changeset
   359
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   360
        # read metadata
23803
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   361
        off = o3 + metasize * nummeta
2763edaba857 readmarkers: promote global constants to locals for performance
Matt Mackall <mpm@selenic.com>
parents: 23802
diff changeset
   362
        metapairsize = unpack('>' + (metafmt * nummeta), data[o3:off])
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   363
        metadata = []
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   364
        for idx in xrange(0, len(metapairsize), 2):
23798
86d2a0c41f44 readmarkers: streamline offset tracking
Matt Mackall <mpm@selenic.com>
parents: 23797
diff changeset
   365
            o1 = off + metapairsize[idx]
86d2a0c41f44 readmarkers: streamline offset tracking
Matt Mackall <mpm@selenic.com>
parents: 23797
diff changeset
   366
            o2 = o1 + metapairsize[idx + 1]
86d2a0c41f44 readmarkers: streamline offset tracking
Matt Mackall <mpm@selenic.com>
parents: 23797
diff changeset
   367
            metadata.append((data[off:o1], data[o1:o2]))
86d2a0c41f44 readmarkers: streamline offset tracking
Matt Mackall <mpm@selenic.com>
parents: 23797
diff changeset
   368
            off = o2
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   369
23800
83f361a21d31 readmarkers: drop a temporary
Matt Mackall <mpm@selenic.com>
parents: 23799
diff changeset
   370
        yield (prec, sucs, flags, tuple(metadata), (secs, tz * 60), parents)
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   371
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   372
def _fm1encodeonemarker(marker):
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   373
    pre, sucs, flags, metadata, date, parents = marker
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   374
    # determine node size
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   375
    _fm1node = _fm1nodesha1
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   376
    if flags & usingsha256:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   377
        _fm1node = _fm1nodesha256
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   378
    numsuc = len(sucs)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   379
    numextranodes = numsuc
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   380
    if parents is None:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   381
        numpar = _fm1parentnone
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   382
    else:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   383
        numpar = len(parents)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   384
        numextranodes += numpar
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   385
    formatnodes = _fm1node * numextranodes
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   386
    formatmeta = _fm1metapair * len(metadata)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   387
    format = _fm1fixed + formatnodes + formatmeta
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   388
    # tz is stored in minutes so we divide by 60
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   389
    tz = date[1]//60
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   390
    data = [None, date[0], tz, flags, numsuc, numpar, len(metadata), pre]
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   391
    data.extend(sucs)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   392
    if parents is not None:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   393
        data.extend(parents)
23498
ac910b1f5658 obsstore: prefetch struct.calcsize
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23497
diff changeset
   394
    totalsize = _calcsize(format)
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   395
    for key, value in metadata:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   396
        lk = len(key)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   397
        lv = len(value)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   398
        data.append(lk)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   399
        data.append(lv)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   400
        totalsize += lk + lv
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   401
    data[0] = totalsize
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   402
    data = [_pack(format, *data)]
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   403
    for key, value in metadata:
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   404
        data.append(key)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   405
        data.append(value)
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   406
    return ''.join(data)
22848
72100c1d53d4 obsolete: gather _fm0 meta encoding with other _fm0 code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22847
diff changeset
   407
24019
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   408
def _fm1readmarkers(data, off):
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   409
    native = getattr(parsers, 'fm1readmarkers', None)
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   410
    if not native:
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   411
        return _fm1purereadmarkers(data, off)
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   412
    stop = len(data) - _fm1fsize
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   413
    return native(data, off, stop)
26fbf07482b2 _fm1readmarkers: generate list in C
Martin von Zweigbergk <martinvonz@google.com>
parents: 24018
diff changeset
   414
22331
b130b241718e obsolete: support for any known obsstore format when reading or writing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22330
diff changeset
   415
# mapping to read/write various marker formats
b130b241718e obsolete: support for any known obsstore format when reading or writing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22330
diff changeset
   416
# <version> -> (decoder, encoder)
22851
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   417
formats = {_fm0version: (_fm0readmarkers, _fm0encodeonemarker),
974389427e5f obsolete: introduce a new binary encoding for obsmarkers (version 1)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22850
diff changeset
   418
           _fm1version: (_fm1readmarkers, _fm1encodeonemarker)}
22331
b130b241718e obsolete: support for any known obsstore format when reading or writing
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22330
diff changeset
   419
23497
5817f71c2336 obsstore: disable garbage collection during initialization (issue4456)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23002
diff changeset
   420
@util.nogc
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   421
def _readmarkers(data):
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   422
    """Read and enumerate markers from raw data"""
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   423
    off = 0
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   424
    diskversion = _unpack('>B', data[off:off + 1])[0]
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   425
    off += 1
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   426
    if diskversion not in formats:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
   427
        raise error.Abort(_('parsing obsolete marker: unknown version %r')
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   428
                         % diskversion)
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   429
    return diskversion, formats[diskversion][0](data, off)
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   430
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   431
def encodemarkers(markers, addheader=False, version=_fm0version):
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   432
    # Kept separate from flushmarkers(), it will be reused for
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   433
    # markers exchange.
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   434
    encodeone = formats[version][1]
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   435
    if addheader:
22613
e623898b80f5 obsolete: use the `version` argument in encodemarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22612
diff changeset
   436
        yield _pack('>B', version)
22612
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   437
    for marker in markers:
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   438
        yield encodeone(marker)
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   439
fdfa40ee75cf obsolete: gather all contents related to format version 0 in a single place
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22507
diff changeset
   440
17072
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   441
class marker(object):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   442
    """Wrap obsolete marker raw data"""
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   443
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   444
    def __init__(self, repo, data):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   445
        # the repo argument will be used to create changectx in later version
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   446
        self._repo = repo
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   447
        self._data = data
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   448
        self._decodedmeta = None
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   449
20031
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   450
    def __hash__(self):
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   451
        return hash(self._data)
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   452
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   453
    def __eq__(self, other):
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   454
        if type(other) != type(self):
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   455
            return False
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   456
        return self._data == other._data
6c1adf2067bb obsolete: add __eq__ and __hash__ to marker to make set() deduplication work
Augie Fackler <raf@durin42.com>
parents: 20030
diff changeset
   457
17072
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   458
    def precnode(self):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   459
        """Precursor changeset node identifier"""
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   460
        return self._data[0]
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   461
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   462
    def succnodes(self):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   463
        """List of successor changesets node identifiers"""
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   464
        return self._data[1]
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   465
22259
2e6f03a193f9 obsmarkers: add a `parentnodes` method to retrieve parent information
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22258
diff changeset
   466
    def parentnodes(self):
2e6f03a193f9 obsmarkers: add a `parentnodes` method to retrieve parent information
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22258
diff changeset
   467
        """Parents of the precursors (None if not recorded)"""
2e6f03a193f9 obsmarkers: add a `parentnodes` method to retrieve parent information
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22258
diff changeset
   468
        return self._data[5]
2e6f03a193f9 obsmarkers: add a `parentnodes` method to retrieve parent information
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22258
diff changeset
   469
17072
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   470
    def metadata(self):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   471
        """Decoded metadata dictionary"""
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   472
        return dict(self._data[3])
17072
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   473
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   474
    def date(self):
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   475
        """Creation date as (unixtime, offset)"""
22222
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   476
        return self._data[4]
17072
517af63ba382 obsolete: helper class to access obsolete marker data
Pierre-Yves.David@ens-lyon.org
parents: 17071
diff changeset
   477
22215
525cde5d954d obsmarker: add a `flags` method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22207
diff changeset
   478
    def flags(self):
525cde5d954d obsmarker: add a `flags` method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22207
diff changeset
   479
        """The flags field of the marker"""
525cde5d954d obsmarker: add a `flags` method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22207
diff changeset
   480
        return self._data[2]
525cde5d954d obsmarker: add a `flags` method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22207
diff changeset
   481
24044
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   482
@util.nogc
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   483
def _addsuccessors(successors, markers):
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   484
    for mark in markers:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   485
        successors.setdefault(mark[0], set()).add(mark)
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   486
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   487
@util.nogc
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   488
def _addprecursors(precursors, markers):
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   489
    for mark in markers:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   490
        for suc in mark[1]:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   491
            precursors.setdefault(suc, set()).add(mark)
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   492
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   493
@util.nogc
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   494
def _addchildren(children, markers):
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   495
    for mark in markers:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   496
        parents = mark[5]
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   497
        if parents is not None:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   498
            for p in parents:
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   499
                children.setdefault(p, set()).add(mark)
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   500
24045
43061f96e40e obsolete: pass only new markers to _checkinvalidmarkers()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24044
diff changeset
   501
def _checkinvalidmarkers(markers):
23973
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   502
    """search for marker with invalid data and raise error if needed
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   503
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   504
    Exist as a separated function to allow the evolve extension for a more
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   505
    subtle handling.
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   506
    """
24045
43061f96e40e obsolete: pass only new markers to _checkinvalidmarkers()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24044
diff changeset
   507
    for mark in markers:
43061f96e40e obsolete: pass only new markers to _checkinvalidmarkers()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24044
diff changeset
   508
        if node.nullid in mark[1]:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
   509
            raise error.Abort(_('bad obsolescence marker detected: '
24045
43061f96e40e obsolete: pass only new markers to _checkinvalidmarkers()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24044
diff changeset
   510
                               'invalid successors nullid'))
23973
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   511
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   512
class obsstore(object):
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   513
    """Store obsolete markers
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   514
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   515
    Markers can be accessed with two mappings:
17776
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
   516
    - precursors[x] -> set(markers on precursors edges of x)
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
   517
    - successors[x] -> set(markers on successors edges of x)
22270
e5adb6935239 obsstore: keep track of children information
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22268
diff changeset
   518
    - children[x]   -> set(markers on precursors edges of children(x)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   519
    """
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   520
22254
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   521
    fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   522
    # prec:    nodeid, precursor changesets
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   523
    # succs:   tuple of nodeid, successor changesets (0-N length)
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   524
    # flag:    integer, flag field carrying modifier for the markers (see doc)
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   525
    # meta:    binary blob, encoded metadata dictionary
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   526
    # date:    (float, int) tuple, date of marker creation
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   527
    # parents: (tuple of nodeid) or None, parents of precursors
b8a0e8176693 obsstore: add a `parents` field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22253
diff changeset
   528
    #          None is used when no data has been recorded
22221
e75b1a3c1dbc obsstore: add fields attribute to track each field in a marker
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22219
diff changeset
   529
25669
8d94861842e5 obsolete: replace references to 'sopener' with 'svfs'
Siddharth Agarwal <sid0@fb.com>
parents: 25412
diff changeset
   530
    def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
   531
        # caches for various obsolescence related cache
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
   532
        self.caches = {}
25669
8d94861842e5 obsolete: replace references to 'sopener' with 'svfs'
Siddharth Agarwal <sid0@fb.com>
parents: 25412
diff changeset
   533
        self.svfs = svfs
22852
e994b034e91e obsolete: add a "format.obsstore-version" config option
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22851
diff changeset
   534
        self._version = defaultformat
22950
bb8278b289ee obsolete: add readonly flag to obstore constructor
Durham Goode <durham@fb.com>
parents: 22949
diff changeset
   535
        self._readonly = readonly
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   536
17073
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   537
    def __iter__(self):
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   538
        return iter(self._all)
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   539
20585
f3c8db3d6d66 obsstore: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20584
diff changeset
   540
    def __len__(self):
f3c8db3d6d66 obsstore: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20584
diff changeset
   541
        return len(self._all)
f3c8db3d6d66 obsstore: add a __len__ method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20584
diff changeset
   542
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   543
    def __nonzero__(self):
26310
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   544
        if not self._cached('_all'):
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   545
            try:
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   546
                return self.svfs.stat('obsstore').st_size > 1
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   547
            except OSError as inst:
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   548
                if inst.errno != errno.ENOENT:
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   549
                    raise
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   550
                # just build an empty _all list if no obsstore exists, which
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   551
                # avoids further stat() syscalls
61efe9ef6ad4 obsstore: fast path to check if obsstore is empty
Yuya Nishihara <yuya@tcha.org>
parents: 26309
diff changeset
   552
                pass
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   553
        return bool(self._all)
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   554
26684
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   555
    @property
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   556
    def readonly(self):
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   557
        """True if marker creation is disabled
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   558
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   559
        Remove me in the future when obsolete marker is always on."""
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   560
        return self._readonly
74ff350c208c obsstore: make the readonly attribute accessible
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26587
diff changeset
   561
22255
adb3798dce49 obsstore: add a `parents` argument to obsstore.create
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22254
diff changeset
   562
    def create(self, transaction, prec, succs=(), flag=0, parents=None,
adb3798dce49 obsstore: add a `parents` argument to obsstore.create
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22254
diff changeset
   563
               date=None, metadata=None):
17071
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   564
        """obsolete: add a new obsolete marker
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   565
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   566
        * ensuring it is hashable
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   567
        * check mandatory metadata
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   568
        * encode metadata
20516
3af218cf2007 obsstore: update create docstring to point to the coder friendly function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   569
3af218cf2007 obsstore: update create docstring to point to the coder friendly function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   570
        If you are a human writing code creating marker you want to use the
3af218cf2007 obsstore: update create docstring to point to the coder friendly function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20476
diff changeset
   571
        `createmarkers` function in this module instead.
20584
224a058f7cd1 obsstore: `create` method return True if a marker is actually added
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20549
diff changeset
   572
224a058f7cd1 obsstore: `create` method return True if a marker is actually added
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20549
diff changeset
   573
        return True if a new marker have been added, False if the markers
224a058f7cd1 obsstore: `create` method return True if a marker is actually added
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20549
diff changeset
   574
        already existed (no op).
17071
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   575
        """
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   576
        if metadata is None:
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   577
            metadata = {}
22222
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   578
        if date is None:
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   579
            if 'date' in metadata:
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   580
                # as a courtesy for out-of-tree extensions
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   581
                date = util.parsedate(metadata.pop('date'))
883e8b6bd461 obsmarker: add `date` as an explicit field
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22221
diff changeset
   582
            else:
22217
570f87422f54 obsstore: add an explicit `date` argument to obsstore.create
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22216
diff changeset
   583
                date = util.makedate()
17071
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   584
        if len(prec) != 20:
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   585
            raise ValueError(prec)
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   586
        for succ in succs:
11f26e2669aa command: creation of obsolete marker
Pierre-Yves.David@ens-lyon.org
parents: 17070
diff changeset
   587
            if len(succ) != 20:
17117
217bfb10e6db obsolete: fix error message at marker creation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17076
diff changeset
   588
                raise ValueError(succ)
22177
a56038e6a3c9 obsstore.create: add a simple safeguard against cyclic markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21166
diff changeset
   589
        if prec in succs:
a56038e6a3c9 obsstore.create: add a simple safeguard against cyclic markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21166
diff changeset
   590
            raise ValueError(_('in-marker cycle with %s') % node.hex(prec))
22845
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   591
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   592
        metadata = tuple(sorted(metadata.iteritems()))
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   593
ef880e28e56a obsolete: store metadata as a tuple of (key, value) pairs (API)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22685
diff changeset
   594
        marker = (str(prec), tuple(succs), int(flag), metadata, date, parents)
20584
224a058f7cd1 obsstore: `create` method return True if a marker is actually added
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20549
diff changeset
   595
        return bool(self.add(transaction, [marker]))
17220
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   596
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   597
    def add(self, transaction, markers):
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   598
        """Add new markers to the store
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   599
17220
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   600
        Take care of filtering duplicate.
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   601
        Return the number of new marker."""
22950
bb8278b289ee obsolete: add readonly flag to obstore constructor
Durham Goode <durham@fb.com>
parents: 22949
diff changeset
   602
        if self._readonly:
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29281
diff changeset
   603
            raise error.Abort(_('creating obsolete markers is not enabled on '
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29281
diff changeset
   604
                              'this repo'))
20028
28445179df90 obsolete: stop doing membership test on list
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19951
diff changeset
   605
        known = set(self._all)
20030
5931489b65e0 obsolete: do not accept duplicated marker during exchange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20028
diff changeset
   606
        new = []
5931489b65e0 obsolete: do not accept duplicated marker during exchange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20028
diff changeset
   607
        for m in markers:
5931489b65e0 obsolete: do not accept duplicated marker during exchange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20028
diff changeset
   608
            if m not in known:
5931489b65e0 obsolete: do not accept duplicated marker during exchange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20028
diff changeset
   609
                known.add(m)
5931489b65e0 obsolete: do not accept duplicated marker during exchange
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20028
diff changeset
   610
                new.append(m)
17220
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   611
        if new:
25669
8d94861842e5 obsolete: replace references to 'sopener' with 'svfs'
Siddharth Agarwal <sid0@fb.com>
parents: 25412
diff changeset
   612
            f = self.svfs('obsstore', 'ab')
17124
f1b7683f3f95 obsolete: move obsolete markers read/write logic to obsstore object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17117
diff changeset
   613
            try:
17126
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   614
                offset = f.tell()
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   615
                transaction.add('obsstore', offset)
17219
494a970f68de obsolete: refactor writemarkers to only encode them
Pierre-Yves.David@ens-lyon.org
parents: 17213
diff changeset
   616
                # offset == 0: new file - add the version header
22335
7c4c19dfd484 obsolete: make encodemarkers a public function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22334
diff changeset
   617
                for bytes in encodemarkers(new, offset == 0, self._version):
17219
494a970f68de obsolete: refactor writemarkers to only encode them
Pierre-Yves.David@ens-lyon.org
parents: 17213
diff changeset
   618
                    f.write(bytes)
17126
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   619
            finally:
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   620
                # XXX: f.close() == filecache invalidation == obsstore rebuilt.
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   621
                # call 'filecacheentry.refresh()'  here
17124
f1b7683f3f95 obsolete: move obsolete markers read/write logic to obsstore object
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17117
diff changeset
   622
                f.close()
24046
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   623
            self._addmarkers(new)
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
   624
            # new marker *may* have changed several set. invalidate the cache.
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
   625
            self.caches.clear()
22339
9680da73cfe0 obsmarker: record the number of new markers in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22335
diff changeset
   626
        # records the number of new markers for the transaction hooks
9680da73cfe0 obsmarker: record the number of new markers in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22335
diff changeset
   627
        previous = int(transaction.hookargs.get('new_obsmarkers', '0'))
9680da73cfe0 obsmarker: record the number of new markers in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22335
diff changeset
   628
        transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
17220
bdac214a4705 obsolete: obsstore.add now takes a list of markers.
Pierre-Yves.David@ens-lyon.org
parents: 17219
diff changeset
   629
        return len(new)
17126
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   630
17524
a736e1e15e46 spelling: transaction
timeless@mozdev.org
parents: 17516
diff changeset
   631
    def mergemarkers(self, transaction, data):
22325
3363f2d36015 obsstore: have the `mergemarkers` method return the number of new markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22309
diff changeset
   632
        """merge a binary stream of markers inside the obsstore
3363f2d36015 obsstore: have the `mergemarkers` method return the number of new markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22309
diff changeset
   633
3363f2d36015 obsstore: have the `mergemarkers` method return the number of new markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22309
diff changeset
   634
        Returns the number of new markers added."""
22332
13e22358e9d2 obsolete: have _readmarkers return the format version
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22331
diff changeset
   635
        version, markers = _readmarkers(data)
22325
3363f2d36015 obsstore: have the `mergemarkers` method return the number of new markers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22309
diff changeset
   636
        return self.add(transaction, markers)
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   637
24046
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   638
    @propertycache
26309
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   639
    def _all(self):
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   640
        data = self.svfs.tryread('obsstore')
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   641
        if not data:
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   642
            return []
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   643
        self._version, markers = _readmarkers(data)
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   644
        markers = list(markers)
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   645
        _checkinvalidmarkers(markers)
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   646
        return markers
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   647
44918682093f obsstore: delay loading markers from obsstore file
Yuya Nishihara <yuya@tcha.org>
parents: 26308
diff changeset
   648
    @propertycache
24046
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   649
    def successors(self):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   650
        successors = {}
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   651
        _addsuccessors(successors, self._all)
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   652
        return successors
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   653
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   654
    @propertycache
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   655
    def precursors(self):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   656
        precursors = {}
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   657
        _addprecursors(precursors, self._all)
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   658
        return precursors
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   659
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   660
    @propertycache
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   661
    def children(self):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   662
        children = {}
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   663
        _addchildren(children, self._all)
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   664
        return children
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   665
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   666
    def _cached(self, attr):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   667
        return attr in self.__dict__
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   668
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   669
    def _addmarkers(self, markers):
24044
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   670
        markers = list(markers) # to allow repeated iteration
e0e6dd806b23 obsolete: extract helpers from _load()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24019
diff changeset
   671
        self._all.extend(markers)
24046
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   672
        if self._cached('successors'):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   673
            _addsuccessors(self.successors, markers)
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   674
        if self._cached('precursors'):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   675
            _addprecursors(self.precursors, markers)
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   676
        if self._cached('children'):
6e1d9f9932a9 obsolete: populate successors, precursors, children lazily
Martin von Zweigbergk <martinvonz@google.com>
parents: 24045
diff changeset
   677
            _addchildren(self.children, markers)
24045
43061f96e40e obsolete: pass only new markers to _checkinvalidmarkers()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24044
diff changeset
   678
        _checkinvalidmarkers(markers)
23973
18d431147cc1 obsstore: make the invalid markers check wrap-able
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23805
diff changeset
   679
22271
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   680
    def relevantmarkers(self, nodes):
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   681
        """return a set of all obsolescence markers relevant to a set of nodes.
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   682
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   683
        "relevant" to a set of nodes mean:
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   684
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   685
        - marker that use this changeset as successor
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   686
        - prune marker of direct children on this changeset
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   687
        - recursive application of the two rules on precursors of these markers
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   688
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   689
        It is a set so you cannot rely on order."""
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   690
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   691
        pendingnodes = set(nodes)
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   692
        seenmarkers = set()
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   693
        seennodes = set(pendingnodes)
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   694
        precursorsmarkers = self.precursors
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   695
        children = self.children
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   696
        while pendingnodes:
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   697
            direct = set()
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   698
            for current in pendingnodes:
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   699
                direct.update(precursorsmarkers.get(current, ()))
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   700
                pruned = [m for m in children.get(current, ()) if not m[1]]
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   701
                direct.update(pruned)
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   702
            direct -= seenmarkers
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   703
            pendingnodes = set([m[0] for m in direct])
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   704
            seenmarkers |= direct
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   705
            pendingnodes -= seennodes
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   706
            seennodes |= pendingnodes
8c69262df82d obsstore: add relevantmarkers method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22270
diff changeset
   707
        return seenmarkers
17070
ad0d6c2b3279 obsolete: introduction of obsolete markers
Pierre-Yves.David@ens-lyon.org
parents:
diff changeset
   708
22345
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   709
def commonversion(versions):
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   710
    """Return the newest version listed in both versions and our local formats.
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   711
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   712
    Returns None if no common version exists.
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   713
    """
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   714
    versions.sort(reverse=True)
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   715
    # search for highest version known on both side
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   716
    for v in versions:
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   717
        if v in formats:
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   718
            return v
cf7014c5f087 obsolete: add a `commonversion` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22339
diff changeset
   719
    return None
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   720
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   721
# arbitrary picked to fit into 8K limit from HTTP server
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   722
# you have to take in account:
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   723
# - the version header
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   724
# - the base85 encoding
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   725
_maxpayload = 5300
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   726
20599
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   727
def _pushkeyescape(markers):
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   728
    """encode markers into a dict suitable for pushkey exchange
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   729
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20599
diff changeset
   730
    - binary data is base85 encoded
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20599
diff changeset
   731
    - split in chunks smaller than 5300 bytes"""
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   732
    keys = {}
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   733
    parts = []
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   734
    currentlen = _maxpayload * 2  # ensure we create a new part
20599
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   735
    for marker in markers:
22329
ed37aa74d208 obsolete: rename _encodeonemarker to _fm0encodeonemarkers
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22328
diff changeset
   736
        nextdata = _fm0encodeonemarker(marker)
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   737
        if (len(nextdata) + currentlen > _maxpayload):
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   738
            currentpart = []
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   739
            currentlen = 0
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   740
            parts.append(currentpart)
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   741
        currentpart.append(nextdata)
17304
0368fc55d572 obsolete: properly increment currentlen when building pushkey payload
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17298
diff changeset
   742
        currentlen += len(nextdata)
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   743
    for idx, part in enumerate(reversed(parts)):
22327
f737631a9f0a obsolete: rename all _fm to _fm0
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22326
diff changeset
   744
        data = ''.join([_pack('>B', _fm0version)] + part)
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   745
        keys['dump%i' % idx] = base85.b85encode(data)
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   746
    return keys
17073
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   747
20599
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   748
def listmarkers(repo):
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   749
    """List markers over pushkey"""
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   750
    if not repo.obsstore:
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   751
        return {}
25118
e632a2429982 obsolete: sort obsmarkers during exchange
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24928
diff changeset
   752
    return _pushkeyescape(sorted(repo.obsstore))
20599
dad29624b056 obsolete: extract encoding of marker for pushkey from the list key function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 20585
diff changeset
   753
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   754
def pushmarker(repo, key, old, new):
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   755
    """Push markers over pushkey"""
17295
1f08ecc7febb pushkey: splits obsolete marker exchange into multiple keys
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17253
diff changeset
   756
    if not key.startswith('dump'):
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   757
        repo.ui.warn(_('unknown key: %r') % key)
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   758
        return 0
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   759
    if old:
21098
399d7770eef2 obsolete: add '%' specifier to the format string to avoid TypeError at runtime
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 21024
diff changeset
   760
        repo.ui.warn(_('unexpected old value for %r') % key)
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   761
        return 0
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   762
    data = base85.b85decode(new)
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   763
    lock = repo.lock()
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   764
    try:
17126
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   765
        tr = repo.transaction('pushkey: obsolete markers')
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   766
        try:
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   767
            repo.obsstore.mergemarkers(tr, data)
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   768
            tr.close()
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   769
            return 1
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   770
        finally:
8fa8717b47b6 obsolete: write obsolete marker inside a transaction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17125
diff changeset
   771
            tr.release()
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   772
    finally:
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 17073
diff changeset
   773
        lock.release()
17073
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   774
22274
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   775
def getmarkers(repo, nodes=None):
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   776
    """returns markers known in a repository
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   777
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   778
    If <nodes> is specified, only markers "relevant" to those nodes are are
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   779
    returned"""
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   780
    if nodes is None:
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   781
        rawmarkers = repo.obsstore
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   782
    else:
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   783
        rawmarkers = repo.obsstore.relevantmarkers(nodes)
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   784
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   785
    for markerdata in rawmarkers:
17073
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   786
        yield marker(repo, markerdata)
3a79a5682af1 obsolete: add easy way to iterate over obsolete marker object
Pierre-Yves.David@ens-lyon.org
parents: 17072
diff changeset
   787
22274
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   788
def relevantmarkers(repo, node):
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   789
    """all obsolete markers relevant to some revision"""
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   790
    for markerdata in repo.obsstore.relevantmarkers(node):
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   791
        yield marker(repo, markerdata)
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   792
10e87c67f1c7 debugobsolete: add a --rev argument
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22273
diff changeset
   793
17076
75f4180509a4 obsolete: function and method to access some obsolete data
Pierre-Yves.David@ens-lyon.org
parents: 17075
diff changeset
   794
def precursormarkers(ctx):
17776
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
   795
    """obsolete marker marking this changeset as a successors"""
24335
d6440a5076a5 obsolete: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24053
diff changeset
   796
    for data in ctx.repo().obsstore.precursors.get(ctx.node(), ()):
d6440a5076a5 obsolete: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24053
diff changeset
   797
        yield marker(ctx.repo(), data)
17076
75f4180509a4 obsolete: function and method to access some obsolete data
Pierre-Yves.David@ens-lyon.org
parents: 17075
diff changeset
   798
75f4180509a4 obsolete: function and method to access some obsolete data
Pierre-Yves.David@ens-lyon.org
parents: 17075
diff changeset
   799
def successormarkers(ctx):
17776
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
   800
    """obsolete marker making this changeset obsolete"""
24335
d6440a5076a5 obsolete: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24053
diff changeset
   801
    for data in ctx.repo().obsstore.successors.get(ctx.node(), ()):
d6440a5076a5 obsolete: replace 'ctx._repo' with 'ctx.repo()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 24053
diff changeset
   802
        yield marker(ctx.repo(), data)
17076
75f4180509a4 obsolete: function and method to access some obsolete data
Pierre-Yves.David@ens-lyon.org
parents: 17075
diff changeset
   803
17831
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   804
def allsuccessors(obsstore, nodes, ignoreflags=0):
17827
612db9d7e76a obsolete: have `allsuccessors` takes a list of nodes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17826
diff changeset
   805
    """Yield node for every successor of <nodes>.
612db9d7e76a obsolete: have `allsuccessors` takes a list of nodes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17826
diff changeset
   806
612db9d7e76a obsolete: have `allsuccessors` takes a list of nodes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17826
diff changeset
   807
    Some successors may be unknown locally.
17213
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   808
20204
b0c14c5d44b1 obsolete: improve allsuccessors doc string
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20203
diff changeset
   809
    This is a linear yield unsuited to detecting split changesets. It includes
b0c14c5d44b1 obsolete: improve allsuccessors doc string
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20203
diff changeset
   810
    initial nodes too."""
17827
612db9d7e76a obsolete: have `allsuccessors` takes a list of nodes
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17826
diff changeset
   811
    remaining = set(nodes)
17213
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   812
    seen = set(remaining)
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   813
    while remaining:
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   814
        current = remaining.pop()
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   815
        yield current
17776
072812e9f570 obsolete: flip `obstore.successors` and `obsolete.precursors`
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17775
diff changeset
   816
        for mark in obsstore.successors.get(current, ()):
20203
509768fc7542 obsolete: fix bad comment
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20031
diff changeset
   817
            # ignore marker flagged with specified flag
17831
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   818
            if mark[2] & ignoreflags:
70b08df24fef obsolete: add a flag that allows fixing "bumped" changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17828
diff changeset
   819
                continue
17213
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   820
            for suc in mark[1]:
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   821
                if suc not in seen:
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   822
                    seen.add(suc)
7eb5aa1f83fd obsolete: add an any successors function
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17200
diff changeset
   823
                    remaining.add(suc)
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
   824
20206
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   825
def allprecursors(obsstore, nodes, ignoreflags=0):
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   826
    """Yield node for every precursors of <nodes>.
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   827
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   828
    Some precursors may be unknown locally.
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   829
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   830
    This is a linear yield unsuited to detecting folded changesets. It includes
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   831
    initial nodes too."""
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   832
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   833
    remaining = set(nodes)
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   834
    seen = set(remaining)
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   835
    while remaining:
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   836
        current = remaining.pop()
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   837
        yield current
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   838
        for mark in obsstore.precursors.get(current, ()):
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   839
            # ignore marker flagged with specified flag
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   840
            if mark[2] & ignoreflags:
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   841
                continue
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   842
            suc = mark[0]
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   843
            if suc not in seen:
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   844
                seen.add(suc)
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   845
                remaining.add(suc)
cdcbe103b69a obsolete: add an allprecursors method mirroring allsuccessors one.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20204
diff changeset
   846
18984
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   847
def foreground(repo, nodes):
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   848
    """return all nodes in the "foreground" of other node
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   849
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   850
    The foreground of a revision is anything reachable using parent -> children
19951
d51c4d85ec23 spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents: 19618
diff changeset
   851
    or precursor -> successor relation. It is very similar to "descendant" but
18984
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   852
    augmented with obsolescence information.
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   853
19951
d51c4d85ec23 spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents: 19618
diff changeset
   854
    Beware that possible obsolescence cycle may result if complex situation.
18984
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   855
    """
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   856
    repo = repo.unfiltered()
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   857
    foreground = set(repo.set('%ln::', nodes))
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   858
    if repo.obsstore:
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   859
        # We only need this complicated logic if there is obsolescence
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   860
        # XXX will probably deserve an optimised revset.
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   861
        nm = repo.changelog.nodemap
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   862
        plen = -1
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   863
        # compute the whole set of successors or descendants
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   864
        while len(foreground) != plen:
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   865
            plen = len(foreground)
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   866
            succs = set(c.node() for c in foreground)
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   867
            mutable = [c.node() for c in foreground if c.mutable()]
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   868
            succs.update(allsuccessors(repo.obsstore, mutable))
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   869
            known = (n for n in succs if n in nm)
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   870
            foreground = set(repo.set('%ln::', known))
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   871
    return set(c.node() for c in foreground)
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   872
efef056b1ae9 obsolete: extract foreground computation from bookmark.validdest
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18904
diff changeset
   873
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   874
def successorssets(repo, initialnode, cache=None):
26265
077f20eed4b2 obsolete: clarify that 'successorssets' returns the latest successors
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26264
diff changeset
   875
    """Return set of all latest successors of initial nodes
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   876
26204
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   877
    The successors set of a changeset A are the group of revisions that succeed
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   878
    A. It succeeds A as a consistent whole, each revision being only a partial
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   879
    replacement. The successors set contains non-obsolete changesets only.
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   880
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   881
    This function returns the full list of successor sets which is why it
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   882
    returns a list of tuples and not just a single tuple. Each tuple is a valid
26204
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   883
    successors set. Note that (A,) may be a valid successors set for changeset A
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   884
    (see below).
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   885
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   886
    In most cases, a changeset A will have a single element (e.g. the changeset
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   887
    A is replaced by A') in its successors set. Though, it is also common for a
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   888
    changeset A to have no elements in its successor set (e.g. the changeset
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   889
    has been pruned). Therefore, the returned list of successors sets will be
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   890
    [(A',)] or [], respectively.
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   891
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   892
    When a changeset A is split into A' and B', however, it will result in a
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   893
    successors set containing more than a single element, i.e. [(A',B')].
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   894
    Divergent changesets will result in multiple successors sets, i.e. [(A',),
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   895
    (A'')].
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   896
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   897
    If a changeset A is not obsolete, then it will conceptually have no
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   898
    successors set. To distinguish this from a pruned changeset, the successor
26204
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   899
    set will contain itself only, i.e. [(A,)].
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   900
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   901
    Finally, successors unknown locally are considered to be pruned (obsoleted
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   902
    without any successors).
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   903
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   904
    The optional `cache` parameter is a dictionary that may contain precomputed
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   905
    successors sets. It is meant to reuse the computation of a previous call to
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   906
    `successorssets` when multiple calls are made at the same time. The cache
26204
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   907
    dictionary is updated in place. The caller is responsible for its life
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   908
    span. Code that makes multiple calls to `successorssets` *must* use this
54875a6c3714 obsolete: improve English of successorssets
timeless@mozdev.org
parents: 25669
diff changeset
   909
    cache mechanism or suffer terrible performance.
20277
c05b968d05eb obsolete: clarify documentation for succcessorssets
Sean Farley <sean.michael.farley@gmail.com>
parents: 20207
diff changeset
   910
    """
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   911
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   912
    succmarkers = repo.obsstore.successors
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   913
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   914
    # Stack of nodes we search successors sets for
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   915
    toproceed = [initialnode]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   916
    # set version of above list for fast loop detection
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   917
    # element added to "toproceed" must be added here
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   918
    stackedset = set(toproceed)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   919
    if cache is None:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   920
        cache = {}
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   921
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   922
    # This while loop is the flattened version of a recursive search for
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   923
    # successors sets
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   924
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   925
    # def successorssets(x):
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   926
    #    successors = directsuccessors(x)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   927
    #    ss = [[]]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   928
    #    for succ in directsuccessors(x):
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   929
    #        # product as in itertools cartesian product
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   930
    #        ss = product(ss, successorssets(succ))
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   931
    #    return ss
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   932
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   933
    # But we can not use plain recursive calls here:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   934
    # - that would blow the python call stack
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   935
    # - obsolescence markers may have cycles, we need to handle them.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   936
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   937
    # The `toproceed` list act as our call stack. Every node we search
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   938
    # successors set for are stacked there.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   939
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   940
    # The `stackedset` is set version of this stack used to check if a node is
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   941
    # already stacked. This check is used to detect cycles and prevent infinite
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   942
    # loop.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   943
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   944
    # successors set of all nodes are stored in the `cache` dictionary.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   945
    #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   946
    # After this while loop ends we use the cache to return the successors sets
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   947
    # for the node requested by the caller.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   948
    while toproceed:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   949
        # Every iteration tries to compute the successors sets of the topmost
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   950
        # node of the stack: CURRENT.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   951
        #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   952
        # There are four possible outcomes:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   953
        #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   954
        # 1) We already know the successors sets of CURRENT:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   955
        #    -> mission accomplished, pop it from the stack.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   956
        # 2) Node is not obsolete:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   957
        #    -> the node is its own successors sets. Add it to the cache.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   958
        # 3) We do not know successors set of direct successors of CURRENT:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   959
        #    -> We add those successors to the stack.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   960
        # 4) We know successors sets of all direct successors of CURRENT:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   961
        #    -> We can compute CURRENT successors set and add it to the
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   962
        #       cache.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   963
        #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   964
        current = toproceed[-1]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   965
        if current in cache:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   966
            # case (1): We already know the successors sets
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   967
            stackedset.remove(toproceed.pop())
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   968
        elif current not in succmarkers:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   969
            # case (2): The node is not obsolete.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   970
            if current in repo:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   971
                # We have a valid last successors.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   972
                cache[current] = [(current,)]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   973
            else:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   974
                # Final obsolete version is unknown locally.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   975
                # Do not count that as a valid successors
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   976
                cache[current] = []
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   977
        else:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   978
            # cases (3) and (4)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   979
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   980
            # We proceed in two phases. Phase 1 aims to distinguish case (3)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   981
            # from case (4):
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   982
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   983
            #     For each direct successors of CURRENT, we check whether its
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   984
            #     successors sets are known. If they are not, we stack the
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   985
            #     unknown node and proceed to the next iteration of the while
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   986
            #     loop. (case 3)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   987
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   988
            #     During this step, we may detect obsolescence cycles: a node
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   989
            #     with unknown successors sets but already in the call stack.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   990
            #     In such a situation, we arbitrary set the successors sets of
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   991
            #     the node to nothing (node pruned) to break the cycle.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   992
            #
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18365
diff changeset
   993
            #     If no break was encountered we proceed to phase 2.
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   994
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   995
            # Phase 2 computes successors sets of CURRENT (case 4); see details
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   996
            # in phase 2 itself.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   997
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   998
            # Note the two levels of iteration in each phase.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
   999
            # - The first one handles obsolescence markers using CURRENT as
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1000
            #   precursor (successors markers of CURRENT).
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1001
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1002
            #   Having multiple entry here means divergence.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1003
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1004
            # - The second one handles successors defined in each marker.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1005
            #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1006
            #   Having none means pruned node, multiple successors means split,
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1007
            #   single successors are standard replacement.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1008
            #
18365
4148414da120 obsolete: process markers in a stable order
Mads Kiilerich <mads@kiilerich.com>
parents: 18277
diff changeset
  1009
            for mark in sorted(succmarkers[current]):
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1010
                for suc in mark[1]:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1011
                    if suc not in cache:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1012
                        if suc in stackedset:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1013
                            # cycle breaking
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1014
                            cache[suc] = []
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1015
                        else:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1016
                            # case (3) If we have not computed successors sets
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1017
                            # of one of those successors we add it to the
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1018
                            # `toproceed` stack and stop all work for this
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1019
                            # iteration.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1020
                            toproceed.append(suc)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1021
                            stackedset.add(suc)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1022
                            break
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1023
                else:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1024
                    continue
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1025
                break
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1026
            else:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1027
                # case (4): we know all successors sets of all direct
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1028
                # successors
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1029
                #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1030
                # Successors set contributed by each marker depends on the
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1031
                # successors sets of all its "successors" node.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1032
                #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1033
                # Each different marker is a divergence in the obsolescence
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18365
diff changeset
  1034
                # history. It contributes successors sets distinct from other
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1035
                # markers.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1036
                #
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1037
                # Within a marker, a successor may have divergent successors
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1038
                # sets. In such a case, the marker will contribute multiple
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1039
                # divergent successors sets. If multiple successors have
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20599
diff changeset
  1040
                # divergent successors sets, a Cartesian product is used.
18069
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1041
                #
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1042
                # At the end we post-process successors sets to remove
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1043
                # duplicated entry and successors set that are strict subset of
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1044
                # another one.
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1045
                succssets = []
18365
4148414da120 obsolete: process markers in a stable order
Mads Kiilerich <mads@kiilerich.com>
parents: 18277
diff changeset
  1046
                for mark in sorted(succmarkers[current]):
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1047
                    # successors sets contributed by this marker
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1048
                    markss = [[]]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1049
                    for suc in mark[1]:
18069
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1050
                        # cardinal product with previous successors
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1051
                        productresult = []
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1052
                        for prefix in markss:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1053
                            for suffix in cache[suc]:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1054
                                newss = list(prefix)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1055
                                for part in suffix:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1056
                                    # do not duplicated entry in successors set
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1057
                                    # first entry wins.
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1058
                                    if part not in newss:
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1059
                                        newss.append(part)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1060
                                productresult.append(newss)
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1061
                        markss = productresult
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1062
                    succssets.extend(markss)
18069
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1063
                # remove duplicated and subset
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1064
                seen = []
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1065
                final = []
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1066
                candidate = sorted(((set(s), s) for s in succssets if s),
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1067
                                   key=lambda x: len(x[1]), reverse=True)
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1068
                for setversion, listversion in candidate:
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1069
                    for seenset in seen:
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1070
                        if setversion.issubset(seenset):
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1071
                            break
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1072
                    else:
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1073
                        final.append(listversion)
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1074
                        seen.append(setversion)
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1075
                final.reverse() # put small successors set first
f84e731cbd20 obsolete: drop successors sets which are subset of another one
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18068
diff changeset
  1076
                cache[current] = final
18068
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1077
    return cache[initialnode]
4bec77e62c00 obsolete: compute successors set
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18001
diff changeset
  1078
17828
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1079
# mapping of 'set-name' -> <function to compute this set>
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1080
cachefuncs = {}
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1081
def cachefor(name):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1082
    """Decorator to register a function as computing the cache for a set"""
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1083
    def decorator(func):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1084
        assert name not in cachefuncs
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1085
        cachefuncs[name] = func
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1086
        return func
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1087
    return decorator
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1088
17825
3cc06457f15e obsolete: rename `getobscache` into `getrevs`
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17776
diff changeset
  1089
def getrevs(repo, name):
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1090
    """Return the set of revision that belong to the <name> set
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1091
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1092
    Such access may compute the set and cache it for future use"""
18001
e02feadd15ea clfilter: unfilter computation of obsolescence related computation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17831
diff changeset
  1093
    repo = repo.unfiltered()
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1094
    if not repo.obsstore:
22507
5c00c5298f98 obsolete: ensure that `getrevs` always return a set
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22394
diff changeset
  1095
        return frozenset()
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1096
    if name not in repo.obsstore.caches:
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1097
        repo.obsstore.caches[name] = cachefuncs[name](repo)
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1098
    return repo.obsstore.caches[name]
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1099
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1100
# To be simple we need to invalidate obsolescence cache when:
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1101
#
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1102
# - new changeset is added:
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1103
# - public phase is changed
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1104
# - obsolescence marker are added
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1105
# - strip is used a repo
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1106
def clearobscaches(repo):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1107
    """Remove all obsolescence related cache from a repo
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1108
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1109
    This remove all cache in obsstore is the obsstore already exist on the
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1110
    repo.
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1111
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1112
    (We could be smarter here given the exact event that trigger the cache
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1113
    clearing)"""
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1114
    # only clear cache is there is obsstore data in this repo
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1115
    if 'obsstore' in repo._filecache:
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1116
        repo.obsstore.caches.clear()
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1117
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1118
@cachefor('obsolete')
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1119
def _computeobsoleteset(repo):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1120
    """the set of obsolete revisions"""
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1121
    obs = set()
27784
432242f41d9f obsolete: make _computeobsoleteset much faster
Laurent Charignon <lc2817@columbia.edu>
parents: 27332
diff changeset
  1122
    getnode = repo.changelog.node
31018
cb5888c00410 obsolete: avoid using revset language to compute the obsolete revset
Jun Wu <quark@fb.com>
parents: 29976
diff changeset
  1123
    notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret))
27784
432242f41d9f obsolete: make _computeobsoleteset much faster
Laurent Charignon <lc2817@columbia.edu>
parents: 27332
diff changeset
  1124
    for r in notpublic:
432242f41d9f obsolete: make _computeobsoleteset much faster
Laurent Charignon <lc2817@columbia.edu>
parents: 27332
diff changeset
  1125
        if getnode(r) in repo.obsstore.successors:
432242f41d9f obsolete: make _computeobsoleteset much faster
Laurent Charignon <lc2817@columbia.edu>
parents: 27332
diff changeset
  1126
            obs.add(r)
18271
67872e939945 performance: speedup computation of obsolete revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18101
diff changeset
  1127
    return obs
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1128
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1129
@cachefor('unstable')
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1130
def _computeunstableset(repo):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1131
    """the set of non obsolete revisions with obsolete parents"""
24928
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1132
    revs = [(ctx.rev(), ctx) for ctx in
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1133
            repo.set('(not public()) and (not obsolete())')]
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1134
    revs.sort(key=lambda x:x[0])
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1135
    unstable = set()
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1136
    for rev, ctx in revs:
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1137
        # A rev is unstable if one of its parent is obsolete or unstable
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1138
        # this works since we traverse following growing rev order
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 25118
diff changeset
  1139
        if any((x.obsolete() or (x.rev() in unstable))
24928
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1140
                for x in ctx.parents()):
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1141
            unstable.add(rev)
876a2ebfbf4f obsolete: speed up unstable computation
Laurent Charignon <lcharignon@fb.com>
parents: 24927
diff changeset
  1142
    return unstable
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1143
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1144
@cachefor('suspended')
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1145
def _computesuspendedset(repo):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1146
    """the set of obsolete parents with non obsolete descendants"""
18276
834ef7e70d0f performance: speedup computation of suspended revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18275
diff changeset
  1147
    suspended = repo.changelog.ancestors(getrevs(repo, 'unstable'))
834ef7e70d0f performance: speedup computation of suspended revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18275
diff changeset
  1148
    return set(r for r in getrevs(repo, 'obsolete') if r in suspended)
17469
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1149
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1150
@cachefor('extinct')
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1151
def _computeextinctset(repo):
fb72eec7efd8 obsolete: introduce caches for all meaningful sets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17429
diff changeset
  1152
    """the set of obsolete parents without non obsolete descendants"""
18277
a58260bc101f performance: speedup computation of extinct revisions
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18276
diff changeset
  1153
    return getrevs(repo, 'obsolete') - getrevs(repo, 'suspended')
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1154
17828
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1155
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1156
@cachefor('bumped')
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1157
def _computebumpedset(repo):
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1158
    """the set of revs trying to obsolete public revisions"""
20207
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1159
    bumped = set()
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20599
diff changeset
  1160
    # util function (avoid attribute lookup in the loop)
20207
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1161
    phase = repo._phasecache.phase # would be faster to grab the full list
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1162
    public = phases.public
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1163
    cl = repo.changelog
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1164
    torev = cl.nodemap.get
24927
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1165
    for ctx in repo.set('(not public()) and (not obsolete())'):
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1166
        rev = ctx.rev()
20207
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1167
        # We only evaluate mutable, non-obsolete revision
24927
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1168
        node = ctx.node()
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1169
        # (future) A cache of precursors may worth if split is very common
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1170
        for pnode in allprecursors(repo.obsstore, [node],
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1171
                                   ignoreflags=bumpedfix):
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1172
            prev = torev(pnode) # unfiltered! but so is phasecache
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1173
            if (prev is not None) and (phase(repo, prev) <= public):
29281
9ac309946df9 obsolete: fix grammar
timeless <timeless@mozdev.org>
parents: 28868
diff changeset
  1174
                # we have a public precursor
24927
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1175
                bumped.add(rev)
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1176
                break # Next draft!
20207
cd62532c62a1 obsolete: order of magnitude speedup in _computebumpedset
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20206
diff changeset
  1177
    return bumped
17828
9495be4126ef obsolete: add the detection of bumped changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17827
diff changeset
  1178
18070
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1179
@cachefor('divergent')
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1180
def _computedivergentset(repo):
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1181
    """the set of rev that compete to be the final successors of some revision.
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1182
    """
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1183
    divergent = set()
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1184
    obsstore = repo.obsstore
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1185
    newermap = {}
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1186
    for ctx in repo.set('(not public()) - obsolete()'):
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1187
        mark = obsstore.precursors.get(ctx.node(), ())
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1188
        toprocess = set(mark)
24393
77eace2a63cb obsolete: avoid infinite loop from obs-cycle in divergence (issue4126)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24335
diff changeset
  1189
        seen = set()
18070
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1190
        while toprocess:
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1191
            prec = toprocess.pop()[0]
24393
77eace2a63cb obsolete: avoid infinite loop from obs-cycle in divergence (issue4126)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24335
diff changeset
  1192
            if prec in seen:
77eace2a63cb obsolete: avoid infinite loop from obs-cycle in divergence (issue4126)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24335
diff changeset
  1193
                continue # emergency cycle hanging prevention
77eace2a63cb obsolete: avoid infinite loop from obs-cycle in divergence (issue4126)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24335
diff changeset
  1194
            seen.add(prec)
18070
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1195
            if prec not in newermap:
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1196
                successorssets(repo, prec, newermap)
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1197
            newer = [n for n in newermap[prec] if n]
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1198
            if len(newer) > 1:
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1199
                divergent.add(ctx.rev())
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1200
                break
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1201
            toprocess.update(obsstore.precursors.get(prec, ()))
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1202
    return divergent
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1203
af632936d3d9 obsolete: detect divergent changesets
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18069
diff changeset
  1204
22219
79c686267486 obsolete: add a date argument to the `createmarkers` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22217
diff changeset
  1205
def createmarkers(repo, relations, flag=0, date=None, metadata=None):
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1206
    """Add obsolete markers between changesets in a repo
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1207
20517
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1208
    <relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}])
21024
7731a2281cf0 spelling: fixes from spell checker
Mads Kiilerich <madski@unity3d.com>
parents: 20599
diff changeset
  1209
    tuple. `old` and `news` are changectx. metadata is an optional dictionary
20517
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1210
    containing metadata for this marker only. It is merged with the global
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1211
    metadata specified through the `metadata` argument of this function,
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1212
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1213
    Trying to obsolete a public changeset will raise an exception.
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1214
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1215
    Current user and date are used except if specified otherwise in the
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1216
    metadata attribute.
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1217
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1218
    This function operates within a transaction of its own, but does
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1219
    not take any lock on the repo.
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1220
    """
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1221
    # prepare metadata
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1222
    if metadata is None:
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1223
        metadata = {}
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1224
    if 'user' not in metadata:
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1225
        metadata['user'] = repo.ui.username()
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1226
    tr = repo.transaction('add-obsolescence-marker')
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1227
    try:
27984
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1228
        markerargs = []
20517
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1229
        for rel in relations:
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1230
            prec = rel[0]
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1231
            sucs = rel[1]
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1232
            localmetadata = metadata.copy()
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1233
            if 2 < len(rel):
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1234
                localmetadata.update(rel[2])
2158e8f3cbd2 createmarkers: allow to pass metadata for a marker only
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 20516
diff changeset
  1235
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1236
            if not prec.mutable():
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29281
diff changeset
  1237
                raise error.Abort(_("cannot obsolete public changeset: %s")
25412
443d4635e630 phases: add `hg help phases` hint to failures to edit public commits
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25411
diff changeset
  1238
                                 % prec,
29976
42d031560294 obsolete: use single quotes in use warning
timeless <timeless@mozdev.org>
parents: 29894
diff changeset
  1239
                                 hint="see 'hg help phases' for details")
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1240
            nprec = prec.node()
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1241
            nsucs = tuple(s.node() for s in sucs)
22256
3ae6cc6173e3 createmarkers: automatically record the parent of pruned changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22255
diff changeset
  1242
            npare = None
3ae6cc6173e3 createmarkers: automatically record the parent of pruned changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22255
diff changeset
  1243
            if not nsucs:
3ae6cc6173e3 createmarkers: automatically record the parent of pruned changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22255
diff changeset
  1244
                npare = tuple(p.node() for p in prec.parents())
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1245
            if nprec in nsucs:
29389
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29281
diff changeset
  1246
                raise error.Abort(_("changeset %s cannot obsolete itself")
98e8313dcd9e i18n: translate abort messages
liscju <piotr.listkiewicz@gmail.com>
parents: 29281
diff changeset
  1247
                                  % prec)
27984
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1248
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1249
            # Creating the marker causes the hidden cache to become invalid,
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1250
            # which causes recomputation when we ask for prec.parents() above.
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1251
            # Resulting in n^2 behavior.  So let's prepare all of the args
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1252
            # first, then create the markers.
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1253
            markerargs.append((nprec, nsucs, npare, localmetadata))
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1254
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1255
        for args in markerargs:
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1256
            nprec, nsucs, npare, localmetadata = args
22256
3ae6cc6173e3 createmarkers: automatically record the parent of pruned changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22255
diff changeset
  1257
            repo.obsstore.create(tr, nprec, nsucs, flag, parents=npare,
3ae6cc6173e3 createmarkers: automatically record the parent of pruned changesets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22255
diff changeset
  1258
                                 date=date, metadata=localmetadata)
18101
a464deecc9dd clfilter: add a cache on repo for set of revision to filter for a given set.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18070
diff changeset
  1259
            repo.filteredrevcache.clear()
17474
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1260
        tr.close()
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1261
    finally:
f85816af6294 obsolete: add a high level function to create an obsolete marker
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17469
diff changeset
  1262
        tr.release()
22949
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1263
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1264
def isenabled(repo, option):
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1265
    """Returns True if the given repository has the given obsolete option
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1266
    enabled.
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1267
    """
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1268
    result = set(repo.ui.configlist('experimental', 'evolution'))
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1269
    if 'all' in result:
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1270
        return True
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1271
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1272
    # For migration purposes, temporarily return true if the config hasn't been
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1273
    # set but _enabled is true.
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1274
    if len(result) == 0 and _enabled:
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1275
        return True
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1276
22954
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1277
    # createmarkers must be enabled if other options are enabled
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1278
    if ((allowunstableopt in result or exchangeopt in result) and
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1279
        not createmarkersopt in result):
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
  1280
        raise error.Abort(_("'createmarkers' obsolete option must be enabled "
22954
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1281
                           "if other obsolete options are enabled"))
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1282
22949
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1283
    return option in result