hgext/strip.py
author Boris Feld <boris.feld@octobus.net>
Tue, 17 Oct 2017 15:56:49 +0200
changeset 34870 64f29fff1877
parent 34621 5613fb1583d6
child 35824 011ca2d795d6
permissions -rw-r--r--
config: rename stabilization.track-operation We want to get rid of stabilization.* configuration, back out to the old configuration 'evolution.track-operation'. Differential Revision: https://phab.mercurial-scm.org/D1153
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 22925
diff changeset
     1
"""strip changesets and their descendants from history
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
     2
19945
3d42a85f6922 strip: fix spelling: "allows to" -> "allows you to"
Javi Merino <cibervicho@gmail.com>
parents: 19828
diff changeset
     3
This extension allows you to strip changesets and all their descendants from the
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
     4
repository. See the command help for details.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
     5
"""
28377
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
     6
from __future__ import absolute_import
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
     7
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28377
diff changeset
     8
from mercurial.i18n import _
28377
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
     9
from mercurial import (
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    10
    bookmarks as bookmarksmod,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    11
    cmdutil,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    12
    error,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    13
    hg,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    14
    lock as lockmod,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    15
    merge,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    16
    node as nodemod,
32897
799db2af824c py3: convert keys of kwargs back to bytes using pycompat.byteskwargs()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32337
diff changeset
    17
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 29841
diff changeset
    18
    registrar,
28377
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    19
    repair,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    20
    scmutil,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    21
    util,
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    22
)
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    23
nullid = nodemod.nullid
81ad683278b8 strip: use absolute_import
timeless <timeless@mozdev.org>
parents: 28288
diff changeset
    24
release = lockmod.release
19822
a194a33f8cb2 mq: prepare a strip extension for extraction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    25
a194a33f8cb2 mq: prepare a strip extension for extraction
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
    26
cmdtable = {}
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 29841
diff changeset
    27
command = registrar.command(cmdtable)
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29205
diff changeset
    28
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24947
diff changeset
    29
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24947
diff changeset
    30
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24947
diff changeset
    31
# leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29205
diff changeset
    32
testedwith = 'ships-with-hg-core'
19823
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    33
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    34
def checksubstate(repo, baserev=None):
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    35
    '''return list of subrepos at a different revision than substate.
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    36
    Abort if any subrepos have uncommitted changes.'''
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    37
    inclsubs = []
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    38
    wctx = repo[None]
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    39
    if baserev:
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    40
        bctx = repo[baserev]
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    41
    else:
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    42
        bctx = wctx.parents()[0]
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    43
    for s in sorted(wctx.substate):
24471
1ff35d76421c subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24364
diff changeset
    44
        wctx.sub(s).bailifchanged(True)
1ff35d76421c subrepo: add bailifchanged to centralize raising Abort if subrepo is dirty
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 24364
diff changeset
    45
        if s not in bctx.substate or bctx.sub(s).dirty():
19823
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    46
            inclsubs.append(s)
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    47
    return inclsubs
6fb14d21fe9d strip: move checksubstate from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19822
diff changeset
    48
19824
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    49
def checklocalchanges(repo, force=False, excsuffix=''):
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    50
    cmdutil.checkunfinished(repo)
22925
68df36ce3d8a strip: make checklocalchanges() return full status tuple
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22057
diff changeset
    51
    s = repo.status()
19824
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    52
    if not force:
22925
68df36ce3d8a strip: make checklocalchanges() return full status tuple
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22057
diff changeset
    53
        if s.modified or s.added or s.removed or s.deleted:
19824
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    54
            _("local changes found") # i18n tool detection
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25186
diff changeset
    55
            raise error.Abort(_("local changes found" + excsuffix))
19824
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    56
        if checksubstate(repo):
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    57
            _("local changed subrepos found") # i18n tool detection
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25186
diff changeset
    58
            raise error.Abort(_("local changed subrepos found" + excsuffix))
22925
68df36ce3d8a strip: make checklocalchanges() return full status tuple
Martin von Zweigbergk <martinvonz@gmail.com>
parents: 22057
diff changeset
    59
    return s
19824
237e40b2c1ff strip: move checklocalchanges from mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19823
diff changeset
    60
34574
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    61
def _findupdatetarget(repo, nodes):
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    62
    unode, p2 = repo.changelog.parents(nodes[0])
34621
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    63
    currentbranch = repo[None].branch()
34574
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    64
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    65
    if (util.safehasattr(repo, 'mq') and p2 != nullid
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    66
        and p2 in [x.node for x in repo.mq.applied]):
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    67
        unode = p2
34621
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    68
    elif currentbranch != repo[unode].branch():
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    69
        pwdir = 'parents(wdir())'
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    70
        revset = 'max(((parents(%ln::%r) + %r) - %ln::%r) and branch(%s))'
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    71
        branchtarget = repo.revs(revset, nodes, pwdir, pwdir, nodes, pwdir,
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    72
                                 currentbranch)
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    73
        if branchtarget:
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    74
            cl = repo.changelog
5613fb1583d6 strip: take branch into account when selecting update target (issue5540)
Paul Morelle <paul.morelle@octobus.net>
parents: 34574
diff changeset
    75
            unode = cl.node(branchtarget.first())
34574
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    76
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    77
    return unode
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    78
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
    79
def strip(ui, repo, revs, update=True, backup=True, force=None, bookmarks=None):
32919
daceeed34ad2 strip: use context manager for locking in strip()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32897
diff changeset
    80
    with repo.wlock(), repo.lock():
19825
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    81
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    82
        if update:
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    83
            checklocalchanges(repo, force=force)
34574
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
    84
            urev = _findupdatetarget(repo, revs)
19825
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    85
            hg.clean(repo, urev)
26748
5ba0a99ff27f dirstate: make dirstate.write() callers pass transaction object to it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26624
diff changeset
    86
            repo.dirstate.write(repo.currenttransaction())
19825
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    87
4b4997068143 strip: move the strip helper function for mq to strip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19824
diff changeset
    88
        repair.strip(ui, repo, revs, backup)
21847
f6f122f4813b strip: remove bookmarks after strip succeed (issue4295)
David Soria Parra <davidsp@fb.com>
parents: 20102
diff changeset
    89
26972
4b0c3df5d635 strip: renaming local variables
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26748
diff changeset
    90
        repomarks = repo._bookmarks
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
    91
        if bookmarks:
27872
a54afc4475d7 with: use a context manager for transaction in strip
Bryan O'Sullivan <bryano@fb.com>
parents: 27839
diff changeset
    92
            with repo.transaction('strip') as tr:
27052
b9d0b45df7b2 strip: use repo._bookmarks.recordchange instead of repo._bookmarks.write
Laurent Charignon <lcharignon@fb.com>
parents: 27030
diff changeset
    93
                if repo._activebookmark in bookmarks:
b9d0b45df7b2 strip: use repo._bookmarks.recordchange instead of repo._bookmarks.write
Laurent Charignon <lcharignon@fb.com>
parents: 27030
diff changeset
    94
                    bookmarksmod.deactivate(repo)
33488
eb344bbac18c bookmark: use 'applychanges' when stripping
Boris Feld <boris.feld@octobus.net>
parents: 32920
diff changeset
    95
                repomarks.applychanges(repo, tr, [(b, None) for b in bookmarks])
27872
a54afc4475d7 with: use a context manager for transaction in strip
Bryan O'Sullivan <bryano@fb.com>
parents: 27839
diff changeset
    96
            for bookmark in sorted(bookmarks):
a54afc4475d7 with: use a context manager for transaction in strip
Bryan O'Sullivan <bryano@fb.com>
parents: 27839
diff changeset
    97
                ui.write(_("bookmark '%s' deleted\n") % bookmark)
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
    98
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
    99
@command("strip",
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   100
         [
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   101
          ('r', 'rev', [], _('strip specified revision (optional, '
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   102
                               'can specify revisions without this '
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   103
                               'option)'), _('REV')),
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   104
          ('f', 'force', None, _('force removal of changesets, discard '
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   105
                                 'uncommitted changes (no backup)')),
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   106
          ('', 'no-backup', None, _('no backups')),
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   107
          ('', 'nobackup', None, _('no backups (DEPRECATED)')),
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   108
          ('n', '', None, _('ignored  (DEPRECATED)')),
24364
135b23868f45 commands: replace "working copy" with "working directory" in help/messages
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
   109
          ('k', 'keep', None, _("do not modify working directory during "
135b23868f45 commands: replace "working copy" with "working directory" in help/messages
Yuya Nishihara <yuya@tcha.org>
parents: 23139
diff changeset
   110
                                "strip")),
27030
cf9ed6d32ccb strip: changing bookmark argument to be a list
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 27029
diff changeset
   111
          ('B', 'bookmark', [], _("remove revs only reachable from given"
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   112
                                  " bookmark"))],
28288
e417e4512b0f doc: remove deprecated option from synopsis of command help
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 27872
diff changeset
   113
          _('hg strip [-k] [-f] [-B bookmark] [-r] REV...'))
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   114
def stripcmd(ui, repo, *revs, **opts):
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   115
    """strip changesets and all their descendants from the repository
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   116
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   117
    The strip command removes the specified changesets and all their
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   118
    descendants. If the working directory has uncommitted changes, the
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   119
    operation is aborted unless the --force flag is supplied, in which
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   120
    case changes will be discarded.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   121
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   122
    If a parent of the working directory is stripped, then the working
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   123
    directory will automatically be updated to the most recent
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   124
    available ancestor of the stripped parent after the operation
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   125
    completes.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   126
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   127
    Any stripped changesets are stored in ``.hg/strip-backup`` as a
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   128
    bundle (see :hg:`help bundle` and :hg:`help unbundle`). They can
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   129
    be restored by running :hg:`unbundle .hg/strip-backup/BUNDLE`,
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   130
    where BUNDLE is the bundle file created by the strip. Note that
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   131
    the local revision numbers will in general be different after the
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   132
    restore.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   133
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   134
    Use the --no-backup option to discard the backup bundle once the
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   135
    operation completes.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   136
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   137
    Strip is not a history-rewriting operation and can be used on
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   138
    changesets in the public phase. But if the stripped changesets have
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   139
    been pushed to a remote repository you will likely pull them again.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   140
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   141
    Return 0 on success.
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   142
    """
32897
799db2af824c py3: convert keys of kwargs back to bytes using pycompat.byteskwargs()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32337
diff changeset
   143
    opts = pycompat.byteskwargs(opts)
22057
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21854
diff changeset
   144
    backup = True
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21854
diff changeset
   145
    if opts.get('no_backup') or opts.get('nobackup'):
445472225ccd strip: remove -b/--backup codepaths
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 21854
diff changeset
   146
        backup = False
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   147
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   148
    cl = repo.changelog
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   149
    revs = list(revs) + opts.get('rev')
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   150
    revs = set(scmutil.revrange(repo, revs))
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   151
27839
7ec3cb246291 with: use context manager for wlock in shelve stripcmd
Bryan O'Sullivan <bryano@fb.com>
parents: 27052
diff changeset
   152
    with repo.wlock():
27030
cf9ed6d32ccb strip: changing bookmark argument to be a list
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 27029
diff changeset
   153
        bookmarks = set(opts.get('bookmark'))
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   154
        if bookmarks:
26972
4b0c3df5d635 strip: renaming local variables
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26748
diff changeset
   155
            repomarks = repo._bookmarks
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   156
            if not bookmarks.issubset(repomarks):
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   157
                raise error.Abort(_("bookmark '%s' not found") %
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   158
                    ','.join(sorted(bookmarks - set(repomarks.keys()))))
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   159
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   160
            # If the requested bookmark is not the only one pointing to a
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   161
            # a revision we have to only delete the bookmark and not strip
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   162
            # anything. revsets cannot detect that case.
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   163
            nodetobookmarks = {}
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   164
            for mark, node in repomarks.iteritems():
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   165
                nodetobookmarks.setdefault(node, []).append(mark)
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   166
            for marks in nodetobookmarks.values():
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   167
                if bookmarks.issuperset(marks):
27030
cf9ed6d32ccb strip: changing bookmark argument to be a list
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 27029
diff changeset
   168
                    rsrevs = repair.stripbmrevset(repo, marks[0])
cf9ed6d32ccb strip: changing bookmark argument to be a list
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 27029
diff changeset
   169
                    revs.update(set(rsrevs))
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   170
            if not revs:
32920
8dbcb66ac160 strip: use context manager for locking and transaction in stripcmd()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32919
diff changeset
   171
                with repo.lock(), repo.transaction('bookmark') as tr:
33488
eb344bbac18c bookmark: use 'applychanges' when stripping
Boris Feld <boris.feld@octobus.net>
parents: 32920
diff changeset
   172
                    bmchanges = [(b, None) for b in bookmarks]
eb344bbac18c bookmark: use 'applychanges' when stripping
Boris Feld <boris.feld@octobus.net>
parents: 32920
diff changeset
   173
                    repomarks.applychanges(repo, tr, bmchanges)
32920
8dbcb66ac160 strip: use context manager for locking and transaction in stripcmd()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32919
diff changeset
   174
                for bookmark in sorted(bookmarks):
8dbcb66ac160 strip: use context manager for locking and transaction in stripcmd()
Martin von Zweigbergk <martinvonz@google.com>
parents: 32919
diff changeset
   175
                    ui.write(_("bookmark '%s' deleted\n") % bookmark)
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   176
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   177
        if not revs:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25186
diff changeset
   178
            raise error.Abort(_('empty revision set'))
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   179
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   180
        descendants = set(cl.descendants(revs))
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   181
        strippedrevs = revs.union(descendants)
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   182
        roots = revs.difference(descendants)
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   183
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   184
        update = False
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   185
        # if one of the wdir parent is stripped we'll need
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   186
        # to update away to an earlier revision
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   187
        for p in repo.dirstate.parents():
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   188
            if p != nullid and cl.rev(p) in strippedrevs:
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   189
                update = True
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   190
                break
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   191
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   192
        rootnodes = set(cl.node(r) for r in roots)
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   193
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   194
        q = getattr(repo, 'mq', None)
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   195
        if q is not None and q.applied:
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   196
            # refresh queue state if we're about to strip
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   197
            # applied patches
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   198
            if cl.rev(repo.lookup('qtip')) in strippedrevs:
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   199
                q.applieddirty = True
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   200
                start = 0
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   201
                end = len(q.applied)
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   202
                for i, statusentry in enumerate(q.applied):
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   203
                    if statusentry.node in rootnodes:
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   204
                        # if one of the stripped roots is an applied
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   205
                        # patch, only part of the queue is stripped
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   206
                        start = i
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   207
                        break
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   208
                del q.applied[start:end]
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   209
                q.savedirty()
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   210
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   211
        revs = sorted(rootnodes)
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   212
        if update and opts.get('keep'):
34574
05c2a9f37a1d strip: factor out update target selection
Paul Morelle <paul.morelle@octobus.net>
parents: 33488
diff changeset
   213
            urev = _findupdatetarget(repo, revs)
20102
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   214
            uctx = repo[urev]
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   215
20102
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   216
            # only reset the dirstate for files that would actually change
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   217
            # between the working context and uctx
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   218
            descendantrevs = repo.revs("%s::." % uctx.rev())
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   219
            changedfiles = []
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   220
            for rev in descendantrevs:
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   221
                # blindly reset the files, regardless of what actually changed
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   222
                changedfiles.extend(repo[rev].files())
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   223
20102
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   224
            # reset files that only changed in the dirstate too
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   225
            dirstate = repo.dirstate
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   226
            dirchanges = [f for f in dirstate if dirstate[f] != 'n']
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   227
            changedfiles.extend(dirchanges)
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   228
20102
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   229
            repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles)
26748
5ba0a99ff27f dirstate: make dirstate.write() callers pass transaction object to it
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 26624
diff changeset
   230
            repo.dirstate.write(repo.currenttransaction())
24709
69154e0ae384 strip: properly clear resolve state with --keep (issue4593)
Matt Mackall <mpm@selenic.com>
parents: 24471
diff changeset
   231
69154e0ae384 strip: properly clear resolve state with --keep (issue4593)
Matt Mackall <mpm@selenic.com>
parents: 24471
diff changeset
   232
            # clear resolve state
26988
7e38d49bc713 strip: switch to mergestate.clean()
Siddharth Agarwal <sid0@fb.com>
parents: 26972
diff changeset
   233
            merge.mergestate.clean(repo, repo['.'].node())
24709
69154e0ae384 strip: properly clear resolve state with --keep (issue4593)
Matt Mackall <mpm@selenic.com>
parents: 24471
diff changeset
   234
20102
04eaa8eec6a0 strip.stripcmd: remove redundant wlock acquire/release
Siddharth Agarwal <sid0@fb.com>
parents: 20101
diff changeset
   235
            update = False
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   236
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   237
20096
88e172871ad7 strip: hold wlock for entire duration
Siddharth Agarwal <sid0@fb.com>
parents: 20009
diff changeset
   238
        strip(ui, repo, revs, backup=backup, update=update,
27029
8279c5d116a0 strip: strip a list of bookmarks
Shubhanshu Agrawal <agrawal.shubhanshu@gmail.com>
parents: 26988
diff changeset
   239
              force=opts.get('force'), bookmarks=bookmarks)
19826
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   240
4b1cbcfdabf7 mq: extract strip function as its standalone extension (issue3824)
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19825
diff changeset
   241
    return 0