mercurial/repair.py
author Matt Harbison <matt_harbison@yahoo.com>
Sun, 14 Jul 2019 01:31:42 -0400
changeset 42601 862f6bddacce
parent 42282 d811f17090a3
child 42656 a1f10edcf6a6
permissions -rw-r--r--
automation: correct the path separator in LIBPATH on Windows I haven't tried building the x86 installer, but happened to notice this when working on the thg installer. Experimenting in PowerShell seems to show that LIBPATH was expanded at the end, but with ':' between, it effectively corrupted `${root}\WinSDK\Lib` and the first path in LIBPATH. Differential Revision: https://phab.mercurial-scm.org/D6642
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# repair.py - functions for repository repair for mercurial
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2005, 2006 Chris Mason <mason@suse.com>
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
# Copyright 2007 Matt Mackall
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8073
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9150
diff changeset
     7
# GNU General Public License version 2 or any later version.
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
     9
from __future__ import absolute_import
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    10
16440
692bf06bb1af repair: fix missing import
Alain Leufroy <alain.leufroy@logilab.fr>
parents: 16388
diff changeset
    11
import errno
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29196
diff changeset
    12
import hashlib
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    14
from .i18n import _
34229
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    15
from .node import (
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    16
    hex,
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    17
    short,
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    18
)
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    19
from . import (
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    20
    bundle2,
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    21
    changegroup,
32502
4c4d91908492 strip: use the 'writenewbundle' function to get bundle on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32336
diff changeset
    22
    discovery,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26425
diff changeset
    23
    error,
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    24
    exchange,
28868
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
    25
    obsolete,
33149
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33120
diff changeset
    26
    obsutil,
39761
b2ec79559a4b strip: ignore orphaned internal changesets while computing safe strip roots
Boris Feld <boris.feld@octobus.net>
parents: 39702
diff changeset
    27
    phases,
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38529
diff changeset
    28
    pycompat,
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    29
    util,
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    30
)
37087
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
    31
from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
    32
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37019
diff changeset
    33
)
25970
d1419cfbd4f4 repair: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25874
diff changeset
    34
37019
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36725
diff changeset
    35
def backupbundle(repo, bases, heads, node, suffix, compress=True,
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36725
diff changeset
    36
                 obsolescence=True):
5905
3afbd82a6c82 repair.py: don't use nested functions.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5904
diff changeset
    37
    """create a bundle with the specified revisions as a backup"""
23898
b21c2e0ee8a3 repair: add experimental option to write bundle2 files
Eric Sumner <ericsumner@fb.com>
parents: 23895
diff changeset
    38
20977
a57dcd11be34 repair: make paths in "_bundle()" relative to ".hg"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20975
diff changeset
    39
    backupdir = "strip-backup"
a57dcd11be34 repair: make paths in "_bundle()" relative to ".hg"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20975
diff changeset
    40
    vfs = repo.vfs
a57dcd11be34 repair: make paths in "_bundle()" relative to ".hg"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20975
diff changeset
    41
    if not vfs.isdir(backupdir):
a57dcd11be34 repair: make paths in "_bundle()" relative to ".hg"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 20975
diff changeset
    42
        vfs.mkdir(backupdir)
23835
aa4a1672583e bundles: do not overwrite existing backup bundles (BC)
Durham Goode <durham@fb.com>
parents: 22818
diff changeset
    43
aa4a1672583e bundles: do not overwrite existing backup bundles (BC)
Durham Goode <durham@fb.com>
parents: 22818
diff changeset
    44
    # Include a hash of all the nodes in the filename for uniqueness
25340
28800ab40395 repair: use _hexlist() to build revset expression from binary nodes
Yuya Nishihara <yuya@tcha.org>
parents: 25300
diff changeset
    45
    allcommits = repo.set('%ln::%ln', bases, heads)
23835
aa4a1672583e bundles: do not overwrite existing backup bundles (BC)
Durham Goode <durham@fb.com>
parents: 22818
diff changeset
    46
    allhashes = sorted(c.hex() for c in allcommits)
34229
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    47
    totalhash = hashlib.sha1(''.join(allhashes)).digest()
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    48
    name = "%s/%s-%s-%s.hg" % (backupdir, short(node),
6193d810f7bb repair: reliably obtain bytestr of node ids
Augie Fackler <raf@durin42.com>
parents: 33751
diff changeset
    49
                               hex(totalhash[:4]), suffix)
23835
aa4a1672583e bundles: do not overwrite existing backup bundles (BC)
Durham Goode <durham@fb.com>
parents: 22818
diff changeset
    50
33676
91f0677dc920 repair: preserve phase also when not using generaldelta (issue5678)
Martin von Zweigbergk <martinvonz@google.com>
parents: 33490
diff changeset
    51
    cgversion = changegroup.localversion(repo)
26425
eb21b6679dc6 strip: compress bundle2 backup using BZ
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26423
diff changeset
    52
    comp = None
26423
c93f91c1db1c strip: use bundle2 + cg2 by default when repository use general delta
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26014
diff changeset
    53
    if cgversion != '01':
24686
e0e28e910fa3 bundle2: rename format, parts and config to final names
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24252
diff changeset
    54
        bundletype = "HG20"
26425
eb21b6679dc6 strip: compress bundle2 backup using BZ
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26423
diff changeset
    55
        if compress:
eb21b6679dc6 strip: compress bundle2 backup using BZ
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26423
diff changeset
    56
            comp = 'BZ'
23898
b21c2e0ee8a3 repair: add experimental option to write bundle2 files
Eric Sumner <ericsumner@fb.com>
parents: 23895
diff changeset
    57
    elif compress:
11791
00cde9bddbe4 repair: do not compress partial bundle if we do not keep it on disk
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11600
diff changeset
    58
        bundletype = "HG10BZ"
00cde9bddbe4 repair: do not compress partial bundle if we do not keep it on disk
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11600
diff changeset
    59
    else:
00cde9bddbe4 repair: do not compress partial bundle if we do not keep it on disk
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11600
diff changeset
    60
        bundletype = "HG10UN"
32502
4c4d91908492 strip: use the 'writenewbundle' function to get bundle on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32336
diff changeset
    61
4c4d91908492 strip: use the 'writenewbundle' function to get bundle on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32336
diff changeset
    62
    outgoing = discovery.outgoing(repo, missingroots=bases, missingheads=heads)
33044
8e3021fd1a44 strip: include phases in bundle (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32948
diff changeset
    63
    contentopts = {
8e3021fd1a44 strip: include phases in bundle (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32948
diff changeset
    64
        'cg.version': cgversion,
8e3021fd1a44 strip: include phases in bundle (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32948
diff changeset
    65
        'obsolescence': obsolescence,
8e3021fd1a44 strip: include phases in bundle (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32948
diff changeset
    66
        'phases': True,
8e3021fd1a44 strip: include phases in bundle (BC)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32948
diff changeset
    67
    }
32502
4c4d91908492 strip: use the 'writenewbundle' function to get bundle on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32336
diff changeset
    68
    return bundle2.writenewbundle(repo.ui, repo, 'strip', name, bundletype,
4c4d91908492 strip: use the 'writenewbundle' function to get bundle on disk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32336
diff changeset
    69
                                  outgoing, contentopts, vfs, compression=comp)
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
5910
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
    71
def _collectfiles(repo, striprev):
b9a830fa10f6 simplify revlog.strip interface and callers; add docstring
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5909
diff changeset
    72
    """find out the filelogs affected by the strip"""
8462
e7e4e41b3bbc repair: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8363
diff changeset
    73
    files = set()
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
38823
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38529
diff changeset
    75
    for x in pycompat.xrange(striprev, len(repo)):
8479
3e16c0fc2241 repair: bulk update sets
Martin Geisler <mg@lazybytes.net>
parents: 8462
diff changeset
    76
        files.update(repo[x].files())
5902
98f8dec8f437 repair.py: split stripall into two functions; clean it up a bit
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5901
diff changeset
    77
8462
e7e4e41b3bbc repair: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8363
diff changeset
    78
    return sorted(files)
5902
98f8dec8f437 repair.py: split stripall into two functions; clean it up a bit
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5901
diff changeset
    79
33750
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    80
def _collectrevlog(revlog, striprev):
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    81
    _, brokenset = revlog.getstrippoint(striprev)
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    82
    return [revlog.linkrev(r) for r in brokenset]
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    83
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    84
def _collectmanifest(repo, striprev):
39272
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38839
diff changeset
    85
    return _collectrevlog(repo.manifestlog.getstorage(b''), striprev)
33750
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    86
13702
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
    87
def _collectbrokencsets(repo, files, striprev):
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
    88
    """return the changesets which will be broken by the truncation"""
13705
73cfb7a5aa56 strip: simplify collectone
Matt Mackall <mpm@selenic.com>
parents: 13702
diff changeset
    89
    s = set()
5909
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5905
diff changeset
    90
33750
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    91
    s.update(_collectmanifest(repo, striprev))
13705
73cfb7a5aa56 strip: simplify collectone
Matt Mackall <mpm@selenic.com>
parents: 13702
diff changeset
    92
    for fname in files:
33750
6626d12e7a85 repair: refactor broken linkrev collection
Durham Goode <durham@fb.com>
parents: 33490
diff changeset
    93
        s.update(_collectrevlog(repo.file(fname), striprev))
5909
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5905
diff changeset
    94
13705
73cfb7a5aa56 strip: simplify collectone
Matt Mackall <mpm@selenic.com>
parents: 13702
diff changeset
    95
    return s
5909
f45f7390c1c5 strip: calculate list of extra nodes to save and pass it to changegroupsubset
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5905
diff changeset
    96
22057
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
    97
def strip(ui, repo, nodelist, backup=True, topic='backup'):
32940
eb84b4ad41e5 repair: clarify in comment that caller must take lock, but not transaction
Martin von Zweigbergk <martinvonz@google.com>
parents: 32901
diff changeset
    98
    # This function requires the caller to lock the repo, but it operates
eb84b4ad41e5 repair: clarify in comment that caller must take lock, but not transaction
Martin von Zweigbergk <martinvonz@google.com>
parents: 32901
diff changeset
    99
    # within a transaction of its own, and thus requires there to be no current
eb84b4ad41e5 repair: clarify in comment that caller must take lock, but not transaction
Martin von Zweigbergk <martinvonz@google.com>
parents: 32901
diff changeset
   100
    # transaction when it is called.
32942
f044295cdb7a repair: move check for existing transaction earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 32941
diff changeset
   101
    if repo.currenttransaction() is not None:
f044295cdb7a repair: move check for existing transaction earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 32941
diff changeset
   102
        raise error.ProgrammingError('cannot strip from inside a transaction')
f044295cdb7a repair: move check for existing transaction earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 32941
diff changeset
   103
22057
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   104
    # Simple way to maintain backwards compatibility for this
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   105
    # argument.
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   106
    if backup in ['none', 'strip']:
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   107
        backup = False
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   108
18004
747a2f43d5d9 clfilter: strip logic should be unfiltered
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17922
diff changeset
   109
    repo = repo.unfiltered()
18310
4499ba5ac35c localrepo: introduce destroying function
Idan Kamara <idankk86@gmail.com>
parents: 18121
diff changeset
   110
    repo.destroying()
41101
cfd95219102d strip: move attributes shortcut assigned earlier
Boris Feld <boris.feld@octobus.net>
parents: 41079
diff changeset
   111
    vfs = repo.vfs
cfd95219102d strip: move attributes shortcut assigned earlier
Boris Feld <boris.feld@octobus.net>
parents: 41079
diff changeset
   112
    cl = repo.changelog
17013
c8eda7bbdcab strip: incrementally update the branchheads cache after a strip
Joshua Redstone <joshua.redstone@fb.com>
parents: 16867
diff changeset
   113
16237
b5c0c7d0f83f repair: remove undo files after strip
Idan Kamara <idankk86@gmail.com>
parents: 15901
diff changeset
   114
    # TODO handle undo of merge sets
16252
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   115
    if isinstance(nodelist, str):
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   116
        nodelist = [nodelist]
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   117
    striplist = [cl.rev(node) for node in nodelist]
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   118
    striprev = min(striplist)
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   119
30707
987dbe87aad6 repair: combine two loops over changelog revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 30706
diff changeset
   120
    files = _collectfiles(repo, striprev)
987dbe87aad6 repair: combine two loops over changelog revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 30706
diff changeset
   121
    saverevs = _collectbrokencsets(repo, files, striprev)
987dbe87aad6 repair: combine two loops over changelog revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 30706
diff changeset
   122
6147
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   123
    # Some revisions with rev > striprev may not be descendants of striprev.
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   124
    # We have to find these revisions and put them in a bundle, so that
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   125
    # we can restore them after the truncations.
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   126
    # To create the bundle we use repo.changegroupsubset which requires
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   127
    # the list of heads and bases of the set of interesting revisions.
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   128
    # (head = revision in the set that has no descendant in the set;
53ae5af55db3 repair.py: rewrite a loop, making it cleaner and faster
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5910
diff changeset
   129
    #  base = revision in the set that has no ancestor in the set)
16252
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   130
    tostrip = set(striplist)
30707
987dbe87aad6 repair: combine two loops over changelog revisions
Martin von Zweigbergk <martinvonz@google.com>
parents: 30706
diff changeset
   131
    saveheads = set(saverevs)
30706
2e4862646f02 repair: speed up stripping of many roots
Martin von Zweigbergk <martinvonz@google.com>
parents: 30385
diff changeset
   132
    for r in cl.revs(start=striprev + 1):
2e4862646f02 repair: speed up stripping of many roots
Martin von Zweigbergk <martinvonz@google.com>
parents: 30385
diff changeset
   133
        if any(p in tostrip for p in cl.parentrevs(r)):
2e4862646f02 repair: speed up stripping of many roots
Martin von Zweigbergk <martinvonz@google.com>
parents: 30385
diff changeset
   134
            tostrip.add(r)
13702
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   135
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   136
        if r not in tostrip:
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   137
            saverevs.add(r)
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   138
            saveheads.difference_update(cl.parentrevs(r))
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   139
            saveheads.add(r)
ffd370aa050b strip: remove usage of extranodes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 13362
diff changeset
   140
    saveheads = [cl.node(r) for r in saveheads]
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   141
15386
6051d8e7e133 strip: backout 73307643a09f (issue3077)
Matt Mackall <mpm@selenic.com>
parents: 15068
diff changeset
   142
    # compute base nodes
6051d8e7e133 strip: backout 73307643a09f (issue3077)
Matt Mackall <mpm@selenic.com>
parents: 15068
diff changeset
   143
    if saverevs:
16867
1093ad1e8903 revlog: descendants(*revs) becomes descendants(revs) (API)
Bryan O'Sullivan <bryano@fb.com>
parents: 16745
diff changeset
   144
        descendants = set(cl.descendants(saverevs))
15386
6051d8e7e133 strip: backout 73307643a09f (issue3077)
Matt Mackall <mpm@selenic.com>
parents: 15068
diff changeset
   145
        saverevs.difference_update(descendants)
6051d8e7e133 strip: backout 73307643a09f (issue3077)
Matt Mackall <mpm@selenic.com>
parents: 15068
diff changeset
   146
    savebases = [cl.node(r) for r in saverevs]
16252
cf17e76be4dd strip: enhance repair.strip to receive a list of nodes (issue3299)
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 15901
diff changeset
   147
    stripbases = [cl.node(r) for r in tostrip]
18040
fe8caf28d580 strip: make query to get new bookmark target cheaper
Siddharth Agarwal <sid0@fb.com>
parents: 18004
diff changeset
   148
32652
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   149
    stripobsidx = obsmarkers = ()
33172
5c9ad50fd62f config: register the 'devel.strip-obsmarkers' config
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33149
diff changeset
   150
    if repo.ui.configbool('devel', 'strip-obsmarkers'):
33149
d09ae850296d obsutil: move 'exclusivemarkers' to the new modules
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 33120
diff changeset
   151
        obsmarkers = obsutil.exclusivemarkers(repo, stripbases)
32652
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   152
    if obsmarkers:
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   153
        stripobsidx = [i for i, m in enumerate(repo.obsstore)
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   154
                       if m in obsmarkers]
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   155
41105
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   156
    newbmtarget, updatebm = _bookmarkmovements(repo, tostrip)
13362
ee01d9d84115 bookmarks: move strip support to repair
Matt Mackall <mpm@selenic.com>
parents: 12057
diff changeset
   157
11197
4bb4895e1693 strip: be quiet about temporary internal bundle
Matt Mackall <mpm@selenic.com>
parents: 10881
diff changeset
   158
    backupfile = None
24252
f962692853c0 repair: define explicit local variable, don't reuse a comprehension variable
Mike Edgar <adgar@google.com>
parents: 24170
diff changeset
   159
    node = nodelist[-1]
22057
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21064
diff changeset
   160
    if backup:
41103
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   161
        backupfile = _createstripbackup(repo, stripbases, node, topic)
41102
e80329a3952c strip: clarify comment around bundle create
Boris Feld <boris.feld@octobus.net>
parents: 41101
diff changeset
   162
    # create a changegroup for all the branches we need to keep
29958
769aee32fae0 strip: don't use "full" and "partial" to describe bundles
Martin von Zweigbergk <martinvonz@google.com>
parents: 29957
diff changeset
   163
    tmpbundlefile = None
29955
e7acbe538baf strip: simplify some repeated conditions
Martin von Zweigbergk <martinvonz@google.com>
parents: 29721
diff changeset
   164
    if saveheads:
29958
769aee32fae0 strip: don't use "full" and "partial" to describe bundles
Martin von Zweigbergk <martinvonz@google.com>
parents: 29957
diff changeset
   165
        # do not compress temporary bundle if we remove it from disk later
32651
5732e6d2b369 strip: do not include obsolescence markers for the temporary bundle
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32646
diff changeset
   166
        #
5732e6d2b369 strip: do not include obsolescence markers for the temporary bundle
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32646
diff changeset
   167
        # We do not include obsolescence, it might re-introduce prune markers
5732e6d2b369 strip: do not include obsolescence markers for the temporary bundle
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32646
diff changeset
   168
        # we are trying to strip.  This is harmless since the stripped markers
5732e6d2b369 strip: do not include obsolescence markers for the temporary bundle
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32646
diff changeset
   169
        # are already backed up and we did not touched the markers for the
5732e6d2b369 strip: do not include obsolescence markers for the temporary bundle
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32646
diff changeset
   170
        # saved changesets.
37019
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36725
diff changeset
   171
        tmpbundlefile = backupbundle(repo, savebases, saveheads, node, 'temp',
17692fefc8f2 repair: rename _backup to backupbundle
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36725
diff changeset
   172
                                     compress=False, obsolescence=False)
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   173
41079
8ecb17b7f432 procutil: correct spelling of uninterruptable -> uninterruptible
Kyle Lippincott <spectral@google.com>
parents: 39761
diff changeset
   174
    with ui.uninterruptible():
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   175
        try:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   176
            with repo.transaction("strip") as tr:
39702
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   177
                # TODO this code violates the interface abstraction of the
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   178
                # transaction and makes assumptions that file storage is
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   179
                # using append-only files. We'll need some kind of storage
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   180
                # API to handle stripping for us.
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   181
                offset = len(tr._entries)
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 7361
diff changeset
   182
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   183
                tr.startgroup()
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   184
                cl.strip(striprev, tr)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   185
                stripmanifest(repo, striprev, tr, files)
8073
e8a28556a0a8 strip: make repair.strip transactional to avoid repository corruption
Henrik Stuart <henrik.stuart@edlund.dk>
parents: 7361
diff changeset
   186
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   187
                for fn in files:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   188
                    repo.file(fn).strip(striprev, tr)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   189
                tr.endgroup()
11197
4bb4895e1693 strip: be quiet about temporary internal bundle
Matt Mackall <mpm@selenic.com>
parents: 10881
diff changeset
   190
39702
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   191
                for i in pycompat.xrange(offset, len(tr._entries)):
3d22aef3ecd5 transaction: make entries a private attribute (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39272
diff changeset
   192
                    file, troffset, ignore = tr._entries[i]
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   193
                    with repo.svfs(file, 'a', checkambig=True) as fp:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   194
                        fp.truncate(troffset)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   195
                    if troffset == 0:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   196
                        repo.store.markremoved(file)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   197
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   198
                deleteobsmarkers(repo.obsstore, stripobsidx)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   199
                del repo.obsstore
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   200
                repo.invalidatevolatilesets()
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   201
                repo._phasecache.filterunknown(repo)
32652
71eb6a098315 strip: strip obsmarkers exclusive to the stripped changeset
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 32651
diff changeset
   202
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   203
            if tmpbundlefile:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   204
                ui.note(_("adding branch\n"))
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   205
                f = vfs.open(tmpbundlefile, "rb")
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   206
                gen = exchange.readbundle(ui, f, tmpbundlefile, vfs)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   207
                if not repo.ui.verbose:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   208
                    # silence internal shuffling chatter
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   209
                    repo.ui.pushbuffer()
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   210
                tmpbundleurl = 'bundle:' + vfs.join(tmpbundlefile)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   211
                txnname = 'strip'
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   212
                if not isinstance(gen, bundle2.unbundle20):
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   213
                    txnname = "strip\n%s" % util.hidepassword(tmpbundleurl)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   214
                with repo.transaction(txnname) as tr:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   215
                    bundle2.applybundle(repo, gen, tr, source='strip',
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   216
                                        url=tmpbundleurl)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   217
                if not repo.ui.verbose:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   218
                    repo.ui.popbuffer()
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   219
                f.close()
31631
0febf8e4e2ce repair: use context manager for lock management
Matt Harbison <matt_harbison@yahoo.com>
parents: 31333
diff changeset
   220
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   221
            with repo.transaction('repair') as tr:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   222
                bmchanges = [(m, repo[newbmtarget].node()) for m in updatebm]
41105
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   223
                repo._bookmarks.applychanges(repo, tr, bmchanges)
27157
5f2e4eb08e41 repair: use bookmarks.recordchange instead of bookmarks.write
Laurent Charignon <lcharignon@fb.com>
parents: 26797
diff changeset
   224
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   225
            # remove undo files
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   226
            for undovfs, undofile in repo.undofiles():
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   227
                try:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   228
                    undovfs.unlink(undofile)
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   229
                except OSError as e:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   230
                    if e.errno != errno.ENOENT:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   231
                        ui.warn(_('error removing %s: %s\n') %
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   232
                                (undovfs.join(undofile),
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   233
                                 stringutil.forcebytestr(e)))
16237
b5c0c7d0f83f repair: remove undo files after strip
Idan Kamara <idankk86@gmail.com>
parents: 15901
diff changeset
   234
38529
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   235
        except: # re-raises
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   236
            if backupfile:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   237
                ui.warn(_("strip failed, backup bundle stored in '%s'\n")
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   238
                        % vfs.join(backupfile))
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   239
            if tmpbundlefile:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   240
                ui.warn(_("strip failed, unrecovered changes stored in '%s'\n")
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   241
                        % vfs.join(tmpbundlefile))
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   242
                ui.warn(_("(fix the problem, then recover the changesets with "
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   243
                          "\"hg unbundle '%s'\")\n") % vfs.join(tmpbundlefile))
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   244
            raise
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   245
        else:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   246
            if tmpbundlefile:
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   247
                # Remove temporary bundle only if there were no exceptions
6e0c66ef8cd0 repair: mark the critical section of strip() as unsafe
Augie Fackler <augie@google.com>
parents: 38400
diff changeset
   248
                vfs.unlink(tmpbundlefile)
4702
18e91c9def0c strip: move strip code to a new repair module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   249
18395
904b7109938e destroyed: drop complex branchcache rebuilt logic
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18311
diff changeset
   250
    repo.destroyed()
30288
c1345969f6c5 repair: make strip() return backup file path
Martin von Zweigbergk <martinvonz@google.com>
parents: 30005
diff changeset
   251
    # return the backup file path (or None if 'backup' was False) so
c1345969f6c5 repair: make strip() return backup file path
Martin von Zweigbergk <martinvonz@google.com>
parents: 30005
diff changeset
   252
    # extensions can use it
c1345969f6c5 repair: make strip() return backup file path
Martin von Zweigbergk <martinvonz@google.com>
parents: 30005
diff changeset
   253
    return backupfile
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   254
41803
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   255
def softstrip(ui, repo, nodelist, backup=True, topic='backup'):
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   256
    """perform a "soft" strip using the archived phase"""
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   257
    tostrip = [c.node() for c in repo.set('sort(%ln::)', nodelist)]
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   258
    if not tostrip:
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   259
        return None
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   260
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   261
    newbmtarget, updatebm = _bookmarkmovements(repo, tostrip)
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   262
    if backup:
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   263
        node = tostrip[0]
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   264
        backupfile = _createstripbackup(repo, tostrip, node, topic)
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   265
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   266
    with repo.transaction('strip') as tr:
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   267
        phases.retractboundary(repo, tr, phases.archived, tostrip)
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   268
        bmchanges = [(m, repo[newbmtarget].node()) for m in updatebm]
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   269
        repo._bookmarks.applychanges(repo, tr, bmchanges)
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   270
    return backupfile
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   271
8c42b4a3d447 strip: introduce a soft strip option
Boris Feld <boris.feld@octobus.net>
parents: 41105
diff changeset
   272
41105
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   273
def _bookmarkmovements(repo, tostrip):
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   274
    # compute necessary bookmark movement
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   275
    bm = repo._bookmarks
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   276
    updatebm = []
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   277
    for m in bm:
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   278
        rev = repo[bm[m]].rev()
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   279
        if rev in tostrip:
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   280
            updatebm.append(m)
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   281
    newbmtarget = None
42275
e10b8058da84 repair: reword comment about bookmarks logic
Augie Fackler <augie@google.com>
parents: 41803
diff changeset
   282
    # If we need to move bookmarks, compute bookmark
e10b8058da84 repair: reword comment about bookmarks logic
Augie Fackler <augie@google.com>
parents: 41803
diff changeset
   283
    # targets. Otherwise we can skip doing this logic.
e10b8058da84 repair: reword comment about bookmarks logic
Augie Fackler <augie@google.com>
parents: 41803
diff changeset
   284
    if updatebm:
41105
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   285
        # For a set s, max(parents(s) - s) is the same as max(heads(::s - s)),
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   286
        # but is much faster
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   287
        newbmtarget = repo.revs('max(parents(%ld) - (%ld))', tostrip, tostrip)
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   288
        if newbmtarget:
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   289
            newbmtarget = repo[newbmtarget.first()].node()
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   290
        else:
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   291
            newbmtarget = '.'
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   292
    return newbmtarget, updatebm
c9a2c4d0e80f strip: extract bookmark movement into a separate function
Boris Feld <boris.feld@octobus.net>
parents: 41104
diff changeset
   293
41103
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   294
def _createstripbackup(repo, stripbases, node, topic):
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   295
    # backup the changeset we are about to strip
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   296
    vfs = repo.vfs
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   297
    cl = repo.changelog
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   298
    backupfile = backupbundle(repo, stripbases, cl.heads(), node, topic)
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   299
    repo.ui.status(_("saved backup bundle to %s\n") %
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   300
                   vfs.join(backupfile))
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   301
    repo.ui.log("backupbundle", "saved backup bundle to %s\n",
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   302
                vfs.join(backupfile))
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   303
    return backupfile
399010051cf4 strip: extract code to create strip backup
Boris Feld <boris.feld@octobus.net>
parents: 41102
diff changeset
   304
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   305
def safestriproots(ui, repo, nodes):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   306
    """return list of roots of nodes where descendants are covered by nodes"""
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   307
    torev = repo.unfiltered().changelog.rev
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   308
    revs = set(torev(n) for n in nodes)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   309
    # tostrip = wanted - unsafe = wanted - ancestors(orphaned)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   310
    # orphaned = affected - wanted
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   311
    # affected = descendants(roots(wanted))
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   312
    # wanted = revs
39761
b2ec79559a4b strip: ignore orphaned internal changesets while computing safe strip roots
Boris Feld <boris.feld@octobus.net>
parents: 39702
diff changeset
   313
    revset = '%ld - ( ::( (roots(%ld):: and not _phase(%s)) -%ld) )'
b2ec79559a4b strip: ignore orphaned internal changesets while computing safe strip roots
Boris Feld <boris.feld@octobus.net>
parents: 39702
diff changeset
   314
    tostrip = set(repo.revs(revset, revs, revs, phases.internal, revs))
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   315
    notstrip = revs - tostrip
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   316
    if notstrip:
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   317
        nodestr = ', '.join(sorted(short(repo[n].node()) for n in notstrip))
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   318
        ui.warn(_('warning: orphaned descendants detected, '
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   319
                  'not stripping %s\n') % nodestr)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   320
    return [c.node() for c in repo.set('roots(%ld)', tostrip)]
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   321
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   322
class stripcallback(object):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   323
    """used as a transaction postclose callback"""
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   324
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   325
    def __init__(self, ui, repo, backup, topic):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   326
        self.ui = ui
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   327
        self.repo = repo
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   328
        self.backup = backup
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   329
        self.topic = topic or 'backup'
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   330
        self.nodelist = []
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   331
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   332
    def addnodes(self, nodes):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   333
        self.nodelist.extend(nodes)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   334
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   335
    def __call__(self, tr):
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   336
        roots = safestriproots(self.ui, self.repo, self.nodelist)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   337
        if roots:
33120
208de1534ebd strip: respect the backup option in stripcallback
Jun Wu <quark@fb.com>
parents: 33099
diff changeset
   338
            strip(self.ui, self.repo, roots, self.backup, self.topic)
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   339
38839
2002c193f2bc rebase: support "history-editing-backup" config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38823
diff changeset
   340
def delayedstrip(ui, repo, nodelist, topic=None, backup=True):
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   341
    """like strip, but works inside transaction and won't strip irreverent revs
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   342
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   343
    nodelist must explicitly contain all descendants. Otherwise a warning will
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   344
    be printed that some nodes are not stripped.
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   345
38839
2002c193f2bc rebase: support "history-editing-backup" config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38823
diff changeset
   346
    Will do a backup if `backup` is True. The last non-None "topic" will be
2002c193f2bc rebase: support "history-editing-backup" config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38823
diff changeset
   347
    used as the backup topic name. The default backup topic name is "backup".
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   348
    """
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   349
    tr = repo.currenttransaction()
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   350
    if not tr:
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   351
        nodes = safestriproots(ui, repo, nodelist)
38839
2002c193f2bc rebase: support "history-editing-backup" config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38823
diff changeset
   352
        return strip(ui, repo, nodes, backup=backup, topic=topic)
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   353
    # transaction postclose callbacks are called in alphabet order.
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   354
    # use '\xff' as prefix so we are likely to be called last.
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   355
    callback = tr.getpostclose('\xffstrip')
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   356
    if callback is None:
38839
2002c193f2bc rebase: support "history-editing-backup" config option
Sushil khanchi <sushilkhanchi97@gmail.com>
parents: 38823
diff changeset
   357
        callback = stripcallback(ui, repo, backup=backup, topic=topic)
33099
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   358
        tr.addpostclose('\xffstrip', callback)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   359
    if topic:
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   360
        callback.topic = topic
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   361
    callback.addnodes(nodelist)
fcd1c483f5ea strip: add a delayedstrip method that works in a transaction
Jun Wu <quark@fb.com>
parents: 33055
diff changeset
   362
33751
86ea201eaeb9 repair: move manifest strip to a separate function
Durham Goode <durham@fb.com>
parents: 33750
diff changeset
   363
def stripmanifest(repo, striprev, tr, files):
39272
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38839
diff changeset
   364
    revlog = repo.manifestlog.getstorage(b'')
33751
86ea201eaeb9 repair: move manifest strip to a separate function
Durham Goode <durham@fb.com>
parents: 33750
diff changeset
   365
    revlog.strip(striprev, tr)
86ea201eaeb9 repair: move manifest strip to a separate function
Durham Goode <durham@fb.com>
parents: 33750
diff changeset
   366
    striptrees(repo, tr, striprev, files)
86ea201eaeb9 repair: move manifest strip to a separate function
Durham Goode <durham@fb.com>
parents: 33750
diff changeset
   367
32241
a2be2abe9476 strip: move tree strip logic to it's own function
Durham Goode <durham@fb.com>
parents: 31875
diff changeset
   368
def striptrees(repo, tr, striprev, files):
42282
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   369
    if 'treemanifest' in repo.requirements:
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   370
        # This logic is safe if treemanifest isn't enabled, but also
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   371
        # pointless, so we skip it if treemanifest isn't enabled.
32336
7e07d5836063 hg: backout optimizing for treemanifests
Durham Goode <durham@fb.com>
parents: 32242
diff changeset
   372
        for unencoded, encoded, size in repo.store.datafiles():
7e07d5836063 hg: backout optimizing for treemanifests
Durham Goode <durham@fb.com>
parents: 32242
diff changeset
   373
            if (unencoded.startswith('meta/') and
7e07d5836063 hg: backout optimizing for treemanifests
Durham Goode <durham@fb.com>
parents: 32242
diff changeset
   374
                unencoded.endswith('00manifest.i')):
7e07d5836063 hg: backout optimizing for treemanifests
Durham Goode <durham@fb.com>
parents: 32242
diff changeset
   375
                dir = unencoded[5:-12]
39272
73cf21b2e8a6 manifest: add getstorage() to manifestlog and use it globally
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38839
diff changeset
   376
                repo.manifestlog.getstorage(dir).strip(striprev, tr)
32241
a2be2abe9476 strip: move tree strip logic to it's own function
Durham Goode <durham@fb.com>
parents: 31875
diff changeset
   377
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   378
def rebuildfncache(ui, repo):
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   379
    """Rebuilds the fncache file from repo history.
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   380
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   381
    Missing entries will be added. Extra entries will be removed.
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   382
    """
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   383
    repo = repo.unfiltered()
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   384
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   385
    if 'fncache' not in repo.requirements:
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   386
        ui.warn(_('(not rebuilding fncache because repository does not '
25874
3e84f40232c7 repair: fix typo in warning message
Wagner Bruna <wbruna@yahoo.com>
parents: 25845
diff changeset
   387
                  'support fncache)\n'))
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   388
        return
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   389
27860
0da102e4f203 with: use context manager in rebuildfncache again
Bryan O'Sullivan <bryano@fb.com>
parents: 27553
diff changeset
   390
    with repo.lock():
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   391
        fnc = repo.store.fncache
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   392
        # Trigger load of fncache.
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   393
        if 'irrelevant' in fnc:
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   394
            pass
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   395
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   396
        oldentries = set(fnc.entries)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   397
        newentries = set()
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   398
        seenfiles = set()
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   399
38400
f0b0c853f598 repair: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38164
diff changeset
   400
        progress = ui.makeprogress(_('rebuilding'), unit=_('changesets'),
f0b0c853f598 repair: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38164
diff changeset
   401
                                   total=len(repo))
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   402
        for rev in repo:
38400
f0b0c853f598 repair: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38164
diff changeset
   403
            progress.update(rev)
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   404
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   405
            ctx = repo[rev]
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   406
            for f in ctx.files():
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   407
                # This is to minimize I/O.
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   408
                if f in seenfiles:
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   409
                    continue
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   410
                seenfiles.add(f)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   411
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   412
                i = 'data/%s.i' % f
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   413
                d = 'data/%s.d' % f
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   414
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   415
                if repo.store._exists(i):
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   416
                    newentries.add(i)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   417
                if repo.store._exists(d):
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   418
                    newentries.add(d)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   419
38400
f0b0c853f598 repair: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38164
diff changeset
   420
        progress.complete()
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   421
42282
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   422
        if 'treemanifest' in repo.requirements:
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   423
            # This logic is safe if treemanifest isn't enabled, but also
d811f17090a3 repair: reword comments that I noticed while working on source formatting
Augie Fackler <augie@google.com>
parents: 42275
diff changeset
   424
            # pointless, so we skip it if treemanifest isn't enabled.
28007
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   425
            for dir in util.dirs(seenfiles):
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   426
                i = 'meta/%s/00manifest.i' % dir
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   427
                d = 'meta/%s/00manifest.d' % dir
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   428
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   429
                if repo.store._exists(i):
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   430
                    newentries.add(i)
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   431
                if repo.store._exists(d):
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   432
                    newentries.add(d)
fb92927f9775 treemanifests: fix streaming clone
Martin von Zweigbergk <martinvonz@google.com>
parents: 27930
diff changeset
   433
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   434
        addcount = len(newentries - oldentries)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   435
        removecount = len(oldentries - newentries)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   436
        for p in sorted(oldentries - newentries):
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   437
            ui.write(_('removing %s\n') % p)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   438
        for p in sorted(newentries - oldentries):
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   439
            ui.write(_('adding %s\n') % p)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   440
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   441
        if addcount or removecount:
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   442
            ui.write(_('%d items added, %d removed from fncache\n') %
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   443
                     (addcount, removecount))
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   444
            fnc.entries = newentries
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   445
            fnc._dirty = True
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   446
27871
f1c316fd91f9 with: use context manager in rebuildfncache
Bryan O'Sullivan <bryano@fb.com>
parents: 27860
diff changeset
   447
            with repo.transaction('fncache') as tr:
25652
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   448
                fnc.write(tr)
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   449
        else:
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   450
            ui.write(_('fncache already up to date\n'))
2882d6886919 repair: add functionality to rebuild fncache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25404
diff changeset
   451
28868
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   452
def deleteobsmarkers(obsstore, indices):
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   453
    """Delete some obsmarkers from obsstore and return how many were deleted
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   454
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   455
    'indices' is a list of ints which are the indices
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   456
    of the markers to be deleted.
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   457
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   458
    Every invocation of this function completely rewrites the obsstore file,
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   459
    skipping the markers we want to be removed. The new temporary file is
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   460
    created, remaining markers are written there and on .close() this file
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   461
    gets atomically renamed to obsstore, thus guaranteeing consistency."""
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   462
    if not indices:
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   463
        # we don't want to rewrite the obsstore with the same content
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   464
        return
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   465
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   466
    left = []
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   467
    current = obsstore._all
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   468
    n = 0
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   469
    for i, m in enumerate(current):
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   470
        if i in indices:
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   471
            n += 1
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   472
            continue
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   473
        left.append(m)
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   474
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   475
    newobsstorefile = obsstore.svfs('obsstore', 'w', atomictemp=True)
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   476
    for bytes in obsolete.encodemarkers(left, True, obsstore._version):
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   477
        newobsstorefile.write(bytes)
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   478
    newobsstorefile.close()
445a25bb70be obsstore: move delete function from obsstore class to repair module
Kostia Balytskyi <ikostia@fb.com>
parents: 28666
diff changeset
   479
    return n