hgext3rd/evolve/rewriteutil.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Mon, 24 Jul 2017 01:04:40 +0200
changeset 2778 766b38594ded
parent 2777 7d86d88b2fa8
child 2779 f51efb2bb8c9
permissions -rw-r--r--
precheck: use 'changesets' in the message instead of 'revisions' This match the message `hg commit --amend` issue in core.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2756
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
# Module dedicated to host utility code dedicated to changeset rewrite
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
#
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     3
# Copyright 2017 Octobus <contact@octobus.net>
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     4
#
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     7
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     8
# Status: Stabilization of the API in progress
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     9
#
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    10
#   The content of this module should move into core incrementally once we are
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    11
#   happy one piece of it (and hopefully, able to reuse it in other core
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    12
#   commands).
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    13
2757
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    14
from mercurial import (
2759
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
    15
    cmdutil,
2762
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
    16
    commands,
2759
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
    17
    context,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
    18
    copies,
2758
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    19
    error,
2762
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
    20
    hg,
2759
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
    21
    lock as lockmod,
2757
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    22
    obsolete,
2758
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    23
    phases,
2764
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
    24
    repair,
2757
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    25
    revset,
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    26
)
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    27
2758
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    28
from mercurial.i18n import _
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    29
2756
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    30
from . import (
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    31
    compat,
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    32
)
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    33
2777
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    34
def precheck(repo, revs, action='rewrite'):
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    35
    """check if <revs> can be rewritten
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    36
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    37
    <action> can be used to control the commit message.
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    38
    """
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    39
    if repo.revs('%ld and public()', revs):
2778
766b38594ded precheck: use 'changesets' in the message instead of 'revisions'
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2777
diff changeset
    40
        raise error.Abort(_("cannot %s public changesets") % action)
2777
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    41
2756
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    42
def bookmarksupdater(repo, oldid, tr):
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    43
    """Return a callable update(newid) updating the current bookmark
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    44
    and bookmarks bound to oldid to newid.
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    45
    """
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    46
    def updatebookmarks(newid):
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    47
        oldbookmarks = repo.nodebookmarks(oldid)
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    48
        bmchanges = [(b, newid) for b in oldbookmarks]
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    49
        if bmchanges:
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    50
            compat.bookmarkapplychanges(repo, tr, bmchanges)
f4dd6e6d4c73 rewriteutil: create a rewriteutil module to host utility function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    51
    return updatebookmarks
2757
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    52
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    53
def disallowednewunstable(repo, revs):
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    54
    """Check that editing <revs> will not create disallowed unstable
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    55
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    56
    (unstable creation is controled by some special config).
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    57
    """
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    58
    allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    59
    if allowunstable:
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    60
        return revset.baseset()
2878c8a686ab rewriteutil: move disallowednewunstable in the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2756
diff changeset
    61
    return repo.revs("(%ld::) - %ld", revs, revs)
2758
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    62
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    63
def foldcheck(repo, revs):
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    64
    """check that <revs> can be folded"""
2777
7d86d88b2fa8 rewriteutil: add a precheck function to validate rewrite beforehand
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2765
diff changeset
    65
    precheck(repo, revs, action='fold')
2758
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    66
    roots = repo.revs('roots(%ld)', revs)
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    67
    if len(roots) > 1:
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    68
        raise error.Abort(_("cannot fold non-linear revisions "
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    69
                            "(multiple roots given)"))
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    70
    root = repo[roots.first()]
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    71
    if root.phase() <= phases.public:
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    72
        raise error.Abort(_("cannot fold public revisions"))
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    73
    heads = repo.revs('heads(%ld)', revs)
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    74
    if len(heads) > 1:
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    75
        raise error.Abort(_("cannot fold non-linear revisions "
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    76
                            "(multiple heads given)"))
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    77
    head = repo[heads.first()]
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    78
    if disallowednewunstable(repo, revs):
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    79
        msg = _("cannot fold chain not ending with a head or with branching")
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    80
        hint = _("new unstable changesets are not allowed")
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    81
        raise error.Abort(msg, hint=hint)
684feae20be5 rewriteutil: move 'foldcheck' to the new module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2757
diff changeset
    82
    return root, head
2759
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
    83
2765
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    84
def deletebookmark(repo, repomarks, bookmarks):
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    85
    wlock = lock = tr = None
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    86
    try:
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    87
        wlock = repo.wlock()
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    88
        lock = repo.lock()
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    89
        tr = repo.transaction('prune')
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    90
        bmchanges = []
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    91
        for bookmark in bookmarks:
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    92
            bmchanges.append((bookmark, None))
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    93
        compat.bookmarkapplychanges(repo, tr, bmchanges)
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    94
        tr.close()
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    95
        for bookmark in sorted(bookmarks):
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    96
            repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    97
    finally:
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    98
        lockmod.release(tr, lock, wlock)
8a2e1aac6b41 rewriteutil: move 'deletebookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2764
diff changeset
    99
2762
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   100
def presplitupdate(repo, ui, prev, ctx):
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   101
    """prepare the working directory for a split (for topic hooking)
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   102
    """
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   103
    hg.update(repo, prev)
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   104
    commands.revert(ui, repo, rev=ctx.rev(), all=True)
610581a2fb74 commands: move split to the 'evocommands' module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2759
diff changeset
   105
2764
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   106
def reachablefrombookmark(repo, revs, bookmarks):
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   107
    """filter revisions and bookmarks reachable from the given bookmark
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   108
    yoinked from mq.py
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   109
    """
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   110
    repomarks = repo._bookmarks
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   111
    if not bookmarks.issubset(repomarks):
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   112
        raise error.Abort(_("bookmark '%s' not found") %
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   113
                          ','.join(sorted(bookmarks - set(repomarks.keys()))))
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   114
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   115
    # If the requested bookmark is not the only one pointing to a
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   116
    # a revision we have to only delete the bookmark and not strip
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   117
    # anything. revsets cannot detect that case.
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   118
    nodetobookmarks = {}
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   119
    for mark, bnode in repomarks.iteritems():
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   120
        nodetobookmarks.setdefault(bnode, []).append(mark)
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   121
    for marks in nodetobookmarks.values():
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   122
        if bookmarks.issuperset(marks):
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   123
            rsrevs = repair.stripbmrevset(repo, marks[0])
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   124
            revs = set(revs)
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   125
            revs.update(set(rsrevs))
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   126
            revs = sorted(revs)
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   127
    return repomarks, revs
a4a6f4128be5 rewriteutil: move 'reachablefrombookmark' to the module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2762
diff changeset
   128
2759
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   129
def rewrite(repo, old, updates, head, newbases, commitopts):
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   130
    """Return (nodeid, created) where nodeid is the identifier of the
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   131
    changeset generated by the rewrite process, and created is True if
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   132
    nodeid was actually created. If created is False, nodeid
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   133
    references a changeset existing before the rewrite call.
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   134
    """
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   135
    wlock = lock = tr = None
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   136
    try:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   137
        wlock = repo.wlock()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   138
        lock = repo.lock()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   139
        tr = repo.transaction('rewrite')
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   140
        if len(old.parents()) > 1: # XXX remove this unnecessary limitation.
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   141
            raise error.Abort(_('cannot amend merge changesets'))
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   142
        base = old.p1()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   143
        updatebookmarks = bookmarksupdater(repo, old.node(), tr)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   144
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   145
        # commit a new version of the old changeset, including the update
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   146
        # collect all files which might be affected
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   147
        files = set(old.files())
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   148
        for u in updates:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   149
            files.update(u.files())
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   150
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   151
        # Recompute copies (avoid recording a -> b -> a)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   152
        copied = copies.pathcopies(base, head)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   153
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   154
        # prune files which were reverted by the updates
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   155
        def samefile(f):
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   156
            if f in head.manifest():
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   157
                a = head.filectx(f)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   158
                if f in base.manifest():
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   159
                    b = base.filectx(f)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   160
                    return (a.data() == b.data()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   161
                            and a.flags() == b.flags())
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   162
                else:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   163
                    return False
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   164
            else:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   165
                return f not in base.manifest()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   166
        files = [f for f in files if not samefile(f)]
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   167
        # commit version of these files as defined by head
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   168
        headmf = head.manifest()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   169
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   170
        def filectxfn(repo, ctx, path):
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   171
            if path in headmf:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   172
                fctx = head[path]
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   173
                flags = fctx.flags()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   174
                mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   175
                                          islink='l' in flags,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   176
                                          isexec='x' in flags,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   177
                                          copied=copied.get(path))
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   178
                return mctx
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   179
            return None
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   180
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   181
        message = cmdutil.logmessage(repo.ui, commitopts)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   182
        if not message:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   183
            message = old.description()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   184
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   185
        user = commitopts.get('user') or old.user()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   186
        # TODO: In case not date is given, we should take the old commit date
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   187
        # if we are working one one changeset or mimic the fold behavior about
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   188
        # date
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   189
        date = commitopts.get('date') or None
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   190
        extra = dict(commitopts.get('extra', old.extra()))
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   191
        extra['branch'] = head.branch()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   192
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   193
        new = context.memctx(repo,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   194
                             parents=newbases,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   195
                             text=message,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   196
                             files=files,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   197
                             filectxfn=filectxfn,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   198
                             user=user,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   199
                             date=date,
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   200
                             extra=extra)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   201
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   202
        if commitopts.get('edit'):
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   203
            new._text = cmdutil.commitforceeditor(repo, new, [])
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   204
        revcount = len(repo)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   205
        newid = repo.commitctx(new)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   206
        new = repo[newid]
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   207
        created = len(repo) != revcount
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   208
        updatebookmarks(newid)
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   209
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   210
        tr.close()
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   211
        return newid, created
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   212
    finally:
3137185b1bfe rewriteutil: move the 'rewrite' function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 2758
diff changeset
   213
        lockmod.release(tr, lock, wlock)