hgext/obsolete.py
author Pierre-Yves David <pierre-yves.david@logilab.fr>
Thu, 08 Sep 2011 17:32:51 +0200
changeset 52 62bdc2567099
parent 51 d98e06ab8320
child 53 0bcbf690dfca
permissions -rw-r--r--
Rollback support
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     1
# obsolete.py - introduce the obsolete concept in mercurial.
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     2
#
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     3
# Copyright 2011 Pierre-Yves David <pierre-yves.david@ens-lyon.org>
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     4
#                Logilab SA        <contact@logilab.fr>
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     5
#
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     7
# GNU General Public License version 2 or any later version.
52
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
     8
import os
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
     9
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    10
from mercurial import util
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    11
from mercurial import context
39
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    12
from mercurial import revset
40
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    13
from mercurial import scmutil
42
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    14
from mercurial import extensions
44
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    15
from mercurial import pushkey
46
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    16
from mercurial import discovery
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    17
from mercurial import error
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    18
from mercurial.node import hex, bin
52
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
    19
from mercurial.lock import release
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    20
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    21
# Patch changectx
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    22
#############################
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    23
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    24
def obsolete(ctx):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
    25
    """is the changeset obsolete by other"""
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    26
    if ctx.node()is None:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    27
        return False
38
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 37
diff changeset
    28
    return bool(ctx._repo.obsoletedby(ctx.node()))
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    29
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    30
context.changectx.obsolete = obsolete
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    31
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    32
ohidden = context.changectx.hidden
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    33
def hidden(ctx):
40
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    34
    # hack to fill hiddenrevs
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    35
    # compute hidden (XXX should move elsewhere)
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    36
    if not getattr(ctx._repo.changelog, 'hiddeninit', False):
41
99c131e97bb3 Do not hide current and bookmarked
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 40
diff changeset
    37
        basicquery = 'obsolete() - (ancestors(not obsolete() or . or bookmark()))'
40
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    38
        for rev in scmutil.revrange(ctx._repo, [basicquery]):
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    39
            ctx._repo.changelog.hiddenrevs.add(rev)
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    40
        ctx._repo.changelog.hiddeninit = True
b9a5a596d9ef proper computation of hidden changeset.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 39
diff changeset
    41
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    42
    return ohidden(ctx)
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    43
context.changectx.hidden = hidden
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
    44
39
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    45
# revset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    46
#############################
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    47
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    48
def revsetobsolete(repo, subset, x):
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    49
    args = revset.getargs(x, 0, 0, 'publicheads takes no arguments')
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    50
    return [r for r in subset if repo[r].obsolete()] # XXX slow
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    51
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    52
def extsetup(ui):
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    53
    revset.symbols["obsolete"] = revsetobsolete
46
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    54
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    55
    def filterobsoleteout(orig, repo, remote, *args,**kwargs):
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    56
        common, heads = orig(repo, remote, *args, **kwargs)
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    57
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    58
        # filter obsolete
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    59
        heads = set(map(repo.changelog.rev, heads))
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    60
        obsoletes = set()
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    61
        for obj in repo._obsobjrels:
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    62
            try:
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    63
                obsoletes.add(repo.changelog.rev(obj))
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    64
            except error.LookupError:
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    65
                pass # we don't have this node locally
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    66
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    67
        outgoing = set(repo.changelog.ancestors(*heads))
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    68
        outgoing.update(heads)
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    69
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    70
        selected = outgoing - obsoletes
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    71
        heads = sorted(map(repo.changelog.node, selected))
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    72
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    73
        return common, heads
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    74
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    75
    extensions.wrapfunction(discovery, 'findcommonoutgoing', filterobsoleteout)
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
    76
    
42
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    77
    try:
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    78
        rebase = extensions.find('rebase')
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    79
        if rebase:
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    80
            extensions.wrapfunction(rebase, 'concludenode', concludenode)
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    81
    except KeyError:
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
    82
        pass # rebase not found
39
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 38
diff changeset
    83
44
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    84
# Pushkey mechanism for mutable
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    85
#########################################
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    86
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    87
def pushobsolete(repo, key, old, relations):
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    88
    assert key == "relations"
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    89
    w = repo.wlock()
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    90
    try:
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    91
        for sub, objs in relations.iteritems():
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    92
            for obj in objs:
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    93
                repo.addobsolete(sub, obj)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    94
    finally:
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    95
        w.release()
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    96
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    97
def listobsolete(repo):
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    98
    return {'relations': repo._obssubrels}
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
    99
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   100
pushkey.register('obsolete', pushobsolete, listobsolete)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   101
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   102
# New commands
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   103
#############################
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   104
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   105
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   106
def cmddebugobsolete(ui, repo, subject, object):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   107
    """Add an obsolete relation between a too node
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   108
    
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   109
    The subject is expected to be a newer version of the object"""
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   110
    sub = repo[subject]
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   111
    obj = repo[object]
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   112
    repo.addobsolete(sub.node(), obj.node())
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   113
    return 0
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   114
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   115
cmdtable = {'debugobsolete': (cmddebugobsolete, [], '<subject> <object>')}
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   116
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   117
def reposetup(ui, repo):
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   118
47
b73b3e3c9560 Don't overwrite non local repo.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 46
diff changeset
   119
    if not repo.local():
b73b3e3c9560 Don't overwrite non local repo.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 46
diff changeset
   120
        return
b73b3e3c9560 Don't overwrite non local repo.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 46
diff changeset
   121
44
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   122
    opull = repo.pull
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   123
    opush = repo.push
52
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   124
    orollback = repo.rollback
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   125
    o_writejournal = repo._writejournal
44
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   126
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   127
    class obsoletingrepo(repo.__class__):
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   128
43
20fca307d9f0 more comment
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 42
diff changeset
   129
20fca307d9f0 more comment
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 42
diff changeset
   130
        ### Hidden revision support
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   131
        @util.propertycache
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   132
        def hiddenrevs(self):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   133
            # It's a property because It simpler that to handle the __init__
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   134
            revs = set()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   135
            return revs
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   136
43
20fca307d9f0 more comment
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 42
diff changeset
   137
        ### obsolete storage
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   138
        @util.propertycache
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   139
        def _obsobjrels(self):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   140
            """{<old-node> -> set(<new-node>)}
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   141
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   142
            also compute hidden revision"""
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   143
            #reverse sub -> objs mapping
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   144
            objrels = {}
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   145
            for sub, objs in self._obssubrels.iteritems():
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   146
                for obj in objs:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   147
                    objrels.setdefault(obj, set()).add(sub)
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   148
            return objrels
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   149
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   150
        @util.propertycache
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   151
        def _obssubrels(self):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   152
            """{<new-node> -> set(<old-node>)}"""
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   153
            return self._readobsrels()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   154
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   155
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   156
        ### Disk IO
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   157
        def _readobsrels(self):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   158
            """Write obsolete relation on disk"""
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   159
            # XXX handle lock
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   160
            rels = {}
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   161
            try:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   162
                f = self.opener('obsolete-relations')
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   163
                try:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   164
                    for line in f:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   165
                        subhex, objhex = line.split()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   166
                        rels.setdefault(bin(subhex), set()).add(bin(objhex))
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   167
                finally:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   168
                    f.close()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   169
            except IOError:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   170
                pass
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   171
            return rels
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   172
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   173
        def _writeobsrels(self):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   174
            """Write obsolete relation on disk"""
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   175
            # XXX handle lock
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   176
            f = self.opener('obsolete-relations', 'w', atomictemp=True)
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   177
            try:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   178
                for sub, objs in self._obssubrels.iteritems():
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   179
                    for obj in objs:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   180
                        f.write('%s %s\n' % (hex(sub), hex(obj)))
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   181
                f.rename()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   182
            finally:
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   183
                f.close()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   184
50
19b22ad56b32 clone support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 47
diff changeset
   185
        ### local clone support
19b22ad56b32 clone support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 47
diff changeset
   186
19b22ad56b32 clone support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 47
diff changeset
   187
        def cancopy(self):
19b22ad56b32 clone support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 47
diff changeset
   188
            return not bool(self._obsobjrels) # you can't copy if there is obsolete
19b22ad56b32 clone support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 47
diff changeset
   189
44
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   190
        ### pull // push support
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   191
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   192
        def pull(self, remote, *args, **kwargs):
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   193
            obskey = remote.listkeys('obsolete')
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   194
            obsrels = obskey.get('relations', {})
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   195
            result = opull(remote, *args, **kwargs)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   196
            for sub, objs in obsrels.iteritems():
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   197
                for obj in objs:
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   198
                    self.addobsolete(sub, obj)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   199
            return result
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   200
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   201
        def push(self, remote, *args, **opts):
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   202
            obskey = remote.listkeys('obsolete')
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   203
            obssupport = 'relations' in obskey
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   204
            result = opush(remote, *args, **opts)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   205
            if obssupport:
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   206
                remote.pushkey('obsolete', 'relations', {}, self._obssubrels)
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   207
            return result
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   208
b243c10a5fbe Add pushkey support for pull and push
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 43
diff changeset
   209
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   210
        ### Public method
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   211
        def obsoletedby(self, node):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   212
            """return the set of node that make <node> obsolete (obj)"""
38
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 37
diff changeset
   213
            return self._obsobjrels.get(node, set())
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   214
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   215
        def obsolete(self, node):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   216
            """return the set of node that <node> make obsolete (sub)"""
38
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 37
diff changeset
   217
            return self._obssubrels.get(node, set())
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   218
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   219
        def addobsolete(self, sub, obj):
37
9493ffa68633 Documentation !
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 32
diff changeset
   220
            """Add a relation marking that node <sub> is a new version of <obj>"""
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   221
            self._obssubrels.setdefault(sub, set()).add(obj)
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   222
            self._obsobjrels.setdefault(obj, set()).add(sub)
46
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
   223
            try:
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
   224
                self.changelog.hiddenrevs.add(repo[obj].rev())
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
   225
            except error.RepoLookupError:
3b0364fc822f Do not propagate obsolete changeset
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 44
diff changeset
   226
                pass #unknow revision (but keep propagating the data
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   227
            self._writeobsrels()
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   228
52
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   229
        ### rollback support
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   230
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   231
        def _writejournal(self, desc):
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   232
            entries = list(o_writejournal(desc))
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   233
            filename = 'obsolete-relations'
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   234
            filepath = self.join(filename)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   235
            if  os.path.exists(filepath):
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   236
                journalname = 'journal.' + filename
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   237
                journalpath = self.join(journalname)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   238
                util.copyfile(filepath, journalpath)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   239
                entries.append(journalpath)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   240
            return tuple(entries)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   241
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   242
        def rollback(self, dryrun=False):
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   243
            wlock = lock = None
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   244
            try:
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   245
                wlock = self.wlock()
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   246
                lock = self.lock()
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   247
                ret = orollback(dryrun)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   248
                if not (ret or dryrun): #rollback did not failed
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   249
                    src = self.join('undo.obsolete-relations')
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   250
                    dst = self.join('obsolete-relations')
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   251
                    if os.path.exists(src):
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   252
                        util.rename(src, dst)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   253
                    elif os.path.exists(dst): #unlink in any case
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   254
                        os.unlink(dst)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   255
                    # invalidate cache
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   256
                    self.__dict__.pop('_obssubrels', None)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   257
                    self.__dict__.pop('_obsobjrels', None)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   258
                return ret
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   259
            finally:
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   260
                release(lock, wlock)
62bdc2567099 Rollback support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 51
diff changeset
   261
32
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   262
    repo.__class__ = obsoletingrepo
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   263
c27491be4431 obsolet: basic support (hide changeset)
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents:
diff changeset
   264
42
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   265
### Other Extension compat
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   266
############################
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   267
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   268
def concludenode(orig, repo, rev, *args, **kwargs):
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   269
    newrev = orig(repo, rev, *args, **kwargs)
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   270
    oldnode = repo[rev].node()
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   271
    newnode = repo[newrev].node()
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   272
    repo.addobsolete(newnode, oldnode)
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   273
    return newrev
eb6a06d7eae3 Make rebase set-obsolete relation
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 41
diff changeset
   274