mercurial/obsolete.py
author Anton Shestakov <av6@dwimlabs.net>
Fri, 01 Apr 2016 21:18:24 +0800
changeset 28719 dd2cf90a3731
parent 27984 e60e13a86529
child 28795 f456834b2f7e
permissions -rw-r--r--
hgweb: fix links in atom-branches
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
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    45
- When changeset A is split into B and C, a single marker are used:
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    46
13744acc4ad7 obsolete: add example of marker usage in the documentation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17774
diff changeset
    47
    (A, (C, C))
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:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
   603
            raise error.Abort('creating obsolete markers is not enabled on '
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
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
432242f41d9f obsolete: make _computeobsoleteset much faster
Laurent Charignon <lc2817@columbia.edu>
parents: 27332
diff changeset
  1123
    notpublic = repo.revs("not public()")
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):
cd0068232ec0 obsolete: speed up computation of bumped revset
Laurent Charignon <lcharignon@fb.com>
parents: 24393
diff changeset
  1174
                # we have a public precursors
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():
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
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,
443d4635e630 phases: add `hg help phases` hint to failures to edit public commits
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 25411
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:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26310
diff changeset
  1246
                raise error.Abort("changeset %s cannot obsolete itself" % prec)
27984
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1247
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1248
            # 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
  1249
            # 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
  1250
            # 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
  1251
            # first, then create the markers.
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1252
            markerargs.append((nprec, nsucs, npare, localmetadata))
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1253
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1254
        for args in markerargs:
e60e13a86529 obsolete: fix n^2 marker computation behavior
Durham Goode <durham@fb.com>
parents: 27784
diff changeset
  1255
            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
  1256
            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
  1257
                                 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
  1258
            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
  1259
        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
  1260
    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
  1261
        tr.release()
22949
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1262
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1263
def isenabled(repo, option):
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1264
    """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
  1265
    enabled.
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1266
    """
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1267
    result = set(repo.ui.configlist('experimental', 'evolution'))
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1268
    if 'all' in result:
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1269
        return True
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1270
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1271
    # 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
  1272
    # set but _enabled is true.
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1273
    if len(result) == 0 and _enabled:
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1274
        return True
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1275
22954
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1276
    # 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
  1277
    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
  1278
        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
  1279
        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
  1280
                           "if other obsolete options are enabled"))
32f15b361f36 obsolete: prevent options from being used without createmarkers
Durham Goode <durham@fb.com>
parents: 22953
diff changeset
  1281
22949
714f6ef43f3a obsolete: add isenabled function for option checking
Durham Goode <durham@fb.com>
parents: 22854
diff changeset
  1282
    return option in result