mercurial/context.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Tue, 10 Oct 2006 18:43:20 -0300
changeset 3347 25d270e0b27f
parent 3319 6c68bc1e7873
child 3334 e44eadc92ec4
child 3351 50a18815e3f0
permissions -rw-r--r--
ui.py: untangle updateopts The code in ui.updateopts that handles ui.quiet, ui.verbose and ui.debugflag is too smart, making it somewhat hard to see what are the exact constraints placed on the values of these variables, hiding some buglets. This patch makes these constraints more explicit, fixing these buglets and changing the behaviour slightly. It also adds a test to make sure things work as expected in the future. The buglets: - setting ui.debug = True in a hgrc wouldn't turn on verbose mode - additionally, setting ui.quiet = True or using --quiet would give you a "quiet debug" mode. The behaviour change: - previously, in a hgrc file, ui.quiet wins against ui.verbose (i.e. the final result would be quiet mode), but --verbose wins against --quiet - now ui.quiet nullifies ui.verbose and --verbose nullifies --quiet. As a consequence, using -qv always gives you normal mode (unless debug mode was turned on somewhere)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# context.py - changeset and file context objects for mercurial
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
2858
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2652
diff changeset
     3
# Copyright 2006 Matt Mackall <mpm@selenic.com>
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
     8
from node import *
3217
dedddde58c5b Raise LookupError in changectx.filectx if filenode can't be found
Brendan Cully <brendan@kublai.com>
parents: 3215
diff changeset
     9
from i18n import gettext as _
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
    10
from demandload import demandload
3308
192085505f6f filectx: add size method
Matt Mackall <mpm@selenic.com>
parents: 3304
diff changeset
    11
demandload(globals(), "ancestor bdiff repo revlog util os")
3130
da85145d4571 filectx: add rename traversal for parents()
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
    12
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
class changectx(object):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
    """A changecontext object makes access to data related to a particular
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
    changeset convenient."""
3127
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    16
    def __init__(self, repo, changeid=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
        """changeid is a revision number, node, or tag"""
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
        self._repo = repo
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
3143
db25f7b80fdb context: handle fileid or changeid == 0
Brendan Cully <brendan@kublai.com>
parents: 3136
diff changeset
    20
        if not changeid and changeid != 0:
3127
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    21
            p1, p2 = self._repo.dirstate.parents()
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    22
            self._rev = self._repo.changelog.rev(p1)
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    23
            if self._rev == -1:
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    24
                changeid = 'tip'
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    25
            else:
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    26
                self._node = p1
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    27
                return
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
    28
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
    29
        self._node = self._repo.lookup(changeid)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
        self._rev = self._repo.changelog.rev(self._node)
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
3199
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
    32
    def __str__(self):
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
    33
        return short(self.node())
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
    34
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
    35
    def __repr__(self):
3238
d865390c1781 context: simplify repr methods
Matt Mackall <mpm@selenic.com>
parents: 3237
diff changeset
    36
        return "<changectx %s>" % str(self)
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
    37
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
    38
    def __eq__(self, other):
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
    39
        return self._rev == other._rev
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
    40
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
    41
    def __nonzero__(self):
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
    42
        return self._rev != -1
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
    43
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    44
    def __getattr__(self, name):
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    45
        if name == '_changeset':
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
            self._changeset = self._repo.changelog.read(self.node())
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
            return self._changeset
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    48
        elif name == '_manifest':
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    49
            self._manifest = self._repo.manifest.read(self._changeset[0])
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
            return self._manifest
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    51
        else:
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    52
            raise AttributeError, name
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    53
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    54
    def changeset(self): return self._changeset
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    55
    def manifest(self): return self._manifest
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
    def rev(self): return self._rev
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
    def node(self): return self._node
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    59
    def user(self): return self._changeset[1]
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    60
    def date(self): return self._changeset[2]
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    61
    def files(self): return self._changeset[3]
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    62
    def description(self): return self._changeset[4]
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
    def parents(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
        """return contexts for each parent changeset"""
2627
b779319a532b context.py: self.repo is not defined, change to self._repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2566
diff changeset
    66
        p = self._repo.changelog.parents(self._node)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
        return [ changectx(self._repo, x) for x in p ]
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
    def children(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
        """return contexts for each child changeset"""
2627
b779319a532b context.py: self.repo is not defined, change to self._repo
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2566
diff changeset
    71
        c = self._repo.changelog.children(self._node)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
        return [ changectx(self._repo, x) for x in c ]
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
    def filenode(self, path):
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    75
        if hasattr(self, "_manifest"):
3242
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    76
            try:
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    77
                return self._manifest[path]
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    78
            except KeyError:
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    79
                raise repo.LookupError(_("'%s' not found in manifest") % path)
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
    80
        node, flag = self._repo.manifest.find(self._changeset[0], path)
3242
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    81
        if not node:
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    82
            raise repo.LookupError(_("'%s' not found in manifest") % path)
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
    83
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
        return node
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
2628
9999a796d389 context.py: filectxs was using a keyword arg, add it to filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2627
diff changeset
    86
    def filectx(self, path, fileid=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
        """get a file context from this changeset"""
2628
9999a796d389 context.py: filectxs was using a keyword arg, add it to filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2627
diff changeset
    88
        if fileid is None:
9999a796d389 context.py: filectxs was using a keyword arg, add it to filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2627
diff changeset
    89
            fileid = self.filenode(path)
3236
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
    90
        return filectx(self._repo, path, fileid=fileid, changectx=self)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
    def filectxs(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
        """generate a file context for each file in this changeset's
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
           manifest"""
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
        mf = self.manifest()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
        m = mf.keys()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
        m.sort()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
        for f in m:
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
            yield self.filectx(f, fileid=mf[f])
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
3133
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   101
    def ancestor(self, c2):
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   102
        """
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   103
        return the ancestor context of self and c2
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   104
        """
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   105
        n = self._repo.changelog.ancestor(self._node, c2._node)
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   106
        return changectx(self._repo, n)
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
   107
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   108
class filectx(object):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   109
    """A filecontext object makes access to data related to a particular
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   110
       filerevision convenient."""
3236
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
   111
    def __init__(self, repo, path, changeid=None, fileid=None,
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
   112
                 filelog=None, changectx=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   113
        """changeid can be a changeset revision, node, or tag.
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   114
           fileid can be a file revision or node."""
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   115
        self._repo = repo
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   116
        self._path = path
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   117
3143
db25f7b80fdb context: handle fileid or changeid == 0
Brendan Cully <brendan@kublai.com>
parents: 3136
diff changeset
   118
        assert changeid is not None or fileid is not None
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
   119
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   120
        if filelog:
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   121
            self._filelog = filelog
3236
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
   122
        if changectx:
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
   123
            self._changectx = changectx
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
   124
            self._changeid = changectx.node()
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   125
3143
db25f7b80fdb context: handle fileid or changeid == 0
Brendan Cully <brendan@kublai.com>
parents: 3136
diff changeset
   126
        if fileid is None:
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
   127
            self._changeid = changeid
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
   128
        else:
3235
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   129
            self._fileid = fileid
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   130
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   131
    def __getattr__(self, name):
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   132
        if name == '_changectx':
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
   133
            self._changectx = changectx(self._repo, self._changeid)
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
   134
            return self._changectx
3235
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   135
        elif name == '_filelog':
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   136
            self._filelog = self._repo.file(self._path)
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   137
            return self._filelog
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   138
        elif name == '_changeid':
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   139
            self._changeid = self._filelog.linkrev(self._filenode)
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
   140
            return self._changeid
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   141
        elif name == '_filenode':
3241
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   142
            try:
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   143
                if hasattr(self, "_fileid"):
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   144
                    self._filenode = self._filelog.lookup(self._fileid)
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   145
                else:
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   146
                    self._filenode = self._changectx.filenode(self._path)
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   147
            except revlog.RevlogError, inst:
a184cd0c2db9 Merge with upstream
Brendan Cully <brendan@kublai.com>
parents: 3229 3240
diff changeset
   148
                raise repo.LookupError(str(inst))
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   149
            return self._filenode
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   150
        elif name == '_filerev':
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   151
            self._filerev = self._filelog.rev(self._filenode)
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   152
            return self._filerev
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   153
        else:
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   154
            raise AttributeError, name
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   155
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
   156
    def __nonzero__(self):
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
   157
        return self._filerev != nullid
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
   158
3199
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
   159
    def __str__(self):
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
   160
        return "%s@%s" % (self.path(), short(self.node()))
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
   161
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
   162
    def __repr__(self):
3238
d865390c1781 context: simplify repr methods
Matt Mackall <mpm@selenic.com>
parents: 3237
diff changeset
   163
        return "<filectx %s>" % str(self)
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
   164
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
   165
    def __eq__(self, other):
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
   166
        return self._path == other._path and self._changeid == other._changeid
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
   167
3207
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   168
    def filectx(self, fileid):
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   169
        '''opens an arbitrary revision of the file without
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   170
        opening a new filelog'''
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   171
        return filectx(self._repo, self._path, fileid=fileid,
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   172
                       filelog=self._filelog)
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
   173
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   174
    def filerev(self): return self._filerev
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   175
    def filenode(self): return self._filenode
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   176
    def filelog(self): return self._filelog
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   177
3150
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
   178
    def rev(self):
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
   179
        if hasattr(self, "_changectx"):
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
   180
            return self._changectx.rev()
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
   181
        return self._filelog.linkrev(self._filenode)
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
   182
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   183
    def node(self): return self._changectx.node()
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   184
    def user(self): return self._changectx.user()
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   185
    def date(self): return self._changectx.date()
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   186
    def files(self): return self._changectx.files()
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   187
    def description(self): return self._changectx.description()
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
   188
    def manifest(self): return self._changectx.manifest()
3149
ff1ab08e6732 restore filectx.changectx() method
Matt Mackall <mpm@selenic.com>
parents: 3146
diff changeset
   189
    def changectx(self): return self._changectx
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   190
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   191
    def data(self): return self._filelog.read(self._filenode)
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   192
    def renamed(self): return self._filelog.renamed(self._filenode)
3130
da85145d4571 filectx: add rename traversal for parents()
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
   193
    def path(self): return self._path
3308
192085505f6f filectx: add size method
Matt Mackall <mpm@selenic.com>
parents: 3304
diff changeset
   194
    def size(self): return self._filelog.size(self._filerev)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   195
3316
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   196
    def cmp(self, text): return self._filelog.cmp(self._filenode, text)
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   197
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   198
    def parents(self):
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   199
        p = self._path
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   200
        fl = self._filelog
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   201
        pl = [ (p, n, fl) for n in self._filelog.parents(self._filenode) ]
3131
4ea58eb3f0c9 filelog: make metadata method private
Matt Mackall <mpm@selenic.com>
parents: 3130
diff changeset
   202
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   203
        r = self.renamed()
3130
da85145d4571 filectx: add rename traversal for parents()
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
   204
        if r:
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   205
            pl[0] = (r[0], r[1], None)
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   206
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   207
        return [ filectx(self._repo, p, fileid=n, filelog=l)
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   208
                 for p,n,l in pl if n != nullid ]
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   209
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   210
    def children(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   211
        # hard for renames
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   212
        c = self._filelog.children(self._filenode)
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   213
        return [ filectx(self._repo, self._path, fileid=x,
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   214
                         filelog=self._filelog) for x in c ]
2566
d8560b458f76 Convert hg annotate to context api
Matt Mackall <mpm@selenic.com>
parents: 2563
diff changeset
   215
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   216
    def annotate(self, follow=False):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   217
        '''returns a list of tuples of (ctx, line) for each line
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   218
        in the file, where ctx is the filectx of the node where
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   219
        that line was last changed'''
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   220
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   221
        def decorate(text, rev):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   222
            return ([rev] * len(text.splitlines()), text)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   223
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   224
        def pair(parent, child):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   225
            for a1, a2, b1, b2 in bdiff.blocks(parent[1], child[1]):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   226
                child[0][b1:b2] = parent[0][a1:a2]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   227
            return child
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   228
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   229
        getlog = util.cachefunc(lambda x: self._repo.file(x))
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   230
        def getctx(path, fileid):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   231
            log = path == self._path and self._filelog or getlog(path)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   232
            return filectx(self._repo, path, fileid=fileid, filelog=log)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   233
        getctx = util.cachefunc(getctx)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   234
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   235
        def parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   236
            # we want to reuse filectx objects as much as possible
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   237
            p = f._path
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   238
            if f._filerev is None: # working dir
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   239
                pl = [ (n.path(), n.filerev()) for n in f.parents() ]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   240
            else:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   241
                pl = [ (p, n) for n in f._filelog.parentrevs(f._filerev) ]
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   242
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   243
            if follow:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   244
                r = f.renamed()
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   245
                if r:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   246
                    pl[0] = (r[0], getlog(r[0]).rev(r[1]))
3146
e69a0cbe268e filectx.annotate: return filectx for each line instead of rev
Brendan Cully <brendan@kublai.com>
parents: 3144
diff changeset
   247
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   248
            return [ getctx(p, n) for p, n in pl if n != -1 ]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   249
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   250
        # find all ancestors
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   251
        needed = {self: 1}
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   252
        visit = [self]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   253
        files = [self._path]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   254
        while visit:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   255
            f = visit.pop(0)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   256
            for p in parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   257
                if p not in needed:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   258
                    needed[p] = 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   259
                    visit.append(p)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   260
                    if p._path not in files:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   261
                        files.append(p._path)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   262
                else:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   263
                    # count how many times we'll use this
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   264
                    needed[p] += 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   265
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   266
        # sort by revision (per file) which is a topological order
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   267
        visit = []
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   268
        files.reverse()
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   269
        for f in files:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   270
            fn = [(n._filerev, n) for n in needed.keys() if n._path == f]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   271
            fn.sort()
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   272
            visit.extend(fn)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   273
        hist = {}
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   274
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   275
        for r, f in visit:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   276
            curr = decorate(f.data(), f)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   277
            for p in parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   278
                if p != nullid:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   279
                    curr = pair(hist[p], curr)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   280
                    # trim the history of unneeded revs
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   281
                    needed[p] -= 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   282
                    if not needed[p]:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   283
                        del hist[p]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   284
            hist[f] = curr
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   285
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
   286
        return zip(hist[f][0], hist[f][1].splitlines(1))
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
   287
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   288
    def ancestor(self, fc2):
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   289
        """
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   290
        find the common ancestor file context, if any, of self, and fc2
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   291
        """
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   292
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   293
        acache = {}
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   294
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   295
        # prime the ancestor cache for the working directory
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   296
        for c in (self, fc2):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   297
            if c._filerev == None:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   298
                pl = [ (n.path(), n.filenode()) for n in c.parents() ]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   299
                acache[(c._path, None)] = pl
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   300
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   301
        flcache = {self._path:self._filelog, fc2._path:fc2._filelog}
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   302
        def parents(vertex):
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   303
            if vertex in acache:
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   304
                return acache[vertex]
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   305
            f, n = vertex
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   306
            if f not in flcache:
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   307
                flcache[f] = self._repo.file(f)
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   308
            fl = flcache[f]
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   309
            pl = [ (f,p) for p in fl.parents(n) if p != nullid ]
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   310
            re = fl.renamed(n)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   311
            if re:
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   312
                pl.append(re)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   313
            acache[vertex]=pl
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   314
            return pl
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   315
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   316
        a, b = (self._path, self._filenode), (fc2._path, fc2._filenode)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   317
        v = ancestor.ancestor(a, b, parents)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   318
        if v:
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   319
            f,n = v
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   320
            return filectx(self._repo, f, fileid=n, filelog=flcache[f])
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
   321
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
   322
        return None
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   323
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   324
class workingctx(changectx):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   325
    """A workingctx object makes access to data related to
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   326
    the current working directory convenient."""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   327
    def __init__(self, repo):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   328
        self._repo = repo
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   329
        self._rev = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   330
        self._node = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   331
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   332
    def __str__(self):
3319
6c68bc1e7873 context: change workingctx str() from . to <node>+
Matt Mackall <mpm@selenic.com>
parents: 3316
diff changeset
   333
        return str(self._parents[0]) + "+"
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   334
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   335
    def __nonzero__(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   336
        return True
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   337
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   338
    def __getattr__(self, name):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   339
        if name == '_parents':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   340
            self._parents = self._repo.parents()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   341
            return self._parents
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   342
        if name == '_status':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   343
            self._status = self._repo.status()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   344
            return self._status
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   345
        if name == '_manifest':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   346
            self._buildmanifest()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   347
            return self._manifest
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   348
        else:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   349
            raise AttributeError, name
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   350
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   351
    def _buildmanifest(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   352
        """generate a manifest corresponding to the working directory"""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   353
3240
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3239
diff changeset
   354
        man = self._parents[0].manifest().copy()
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   355
        copied = self._repo.dirstate.copies()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   356
        modified, added, removed, deleted, unknown = self._status[:5]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   357
        for i,l in (("a", added), ("m", modified), ("u", unknown)):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   358
            for f in l:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   359
                man[f] = man.get(copied.get(f, f), nullid) + i
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   360
                man.set(f, util.is_exec(self._repo.wjoin(f), man.execf(f)))
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   361
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   362
        for f in deleted + removed:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   363
            del man[f]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   364
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   365
        self._manifest = man
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   366
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   367
    def manifest(self): return self._manifest
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   368
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   369
    def user(self): return self._repo.ui.username()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   370
    def date(self): return util.makedate()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   371
    def description(self): return ""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   372
    def files(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   373
        f = self.modified() + self.added() + self.removed()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   374
        f.sort()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   375
        return f
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   376
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   377
    def modified(self): return self._status[0]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   378
    def added(self): return self._status[1]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   379
    def removed(self): return self._status[2]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   380
    def deleted(self): return self._status[3]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   381
    def unknown(self): return self._status[4]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   382
    def clean(self): return self._status[5]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   383
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   384
    def parents(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   385
        """return contexts for each parent changeset"""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   386
        return self._parents
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   387
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   388
    def children(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   389
        return []
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   390
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   391
    def filectx(self, path):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   392
        """get a file context from the working directory"""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   393
        return workingfilectx(self._repo, path, workingctx=self)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   394
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   395
    def ancestor(self, c2):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   396
        """return the ancestor context of self and c2"""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   397
        return self._parents[0].ancestor(c2) # punt on two parents for now
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   398
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   399
class workingfilectx(filectx):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   400
    """A workingfilectx object makes access to data related to a particular
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   401
       file in the working directory convenient."""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   402
    def __init__(self, repo, path, filelog=None, workingctx=None):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   403
        """changeid can be a changeset revision, node, or tag.
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   404
           fileid can be a file revision or node."""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   405
        self._repo = repo
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   406
        self._path = path
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   407
        self._changeid = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   408
        self._filerev = self._filenode = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   409
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   410
        if filelog:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   411
            self._filelog = filelog
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   412
        if workingctx:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   413
            self._changectx = workingctx
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   414
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   415
    def __getattr__(self, name):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   416
        if name == '_changectx':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   417
            self._changectx = workingctx(repo)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   418
            return self._changectx
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   419
        elif name == '_repopath':
3304
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
   420
            self._repopath = (self._repo.dirstate.copied(self._path)
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
   421
                              or self._path)
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
   422
            return self._repopath
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   423
        elif name == '_filelog':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   424
            self._filelog = self._repo.file(self._repopath)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   425
            return self._filelog
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   426
        else:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   427
            raise AttributeError, name
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   428
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   429
    def __nonzero__(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   430
        return True
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   431
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   432
    def __str__(self):
3319
6c68bc1e7873 context: change workingctx str() from . to <node>+
Matt Mackall <mpm@selenic.com>
parents: 3316
diff changeset
   433
        return "%s@%s" % (self.path(), self._changectx)
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   434
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   435
    def filectx(self, fileid):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   436
        '''opens an arbitrary revision of the file without
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   437
        opening a new filelog'''
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   438
        return filectx(self._repo, self._repopath, fileid=fileid,
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   439
                       filelog=self._filelog)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   440
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   441
    def rev(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   442
        if hasattr(self, "_changectx"):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   443
            return self._changectx.rev()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   444
        return self._filelog.linkrev(self._filenode)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   445
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   446
    def data(self): return self._repo.wread(self._path)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   447
    def renamed(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   448
        rp = self._repopath
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   449
        if rp == self._path:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   450
            return None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   451
        return rp, self._workingctx._parents._manifest.get(rp, nullid)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   452
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   453
    def parents(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   454
        '''return parent filectxs, following copies if necessary'''
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   455
        p = self._path
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   456
        rp = self._repopath
3304
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
   457
        pcl = self._changectx._parents
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   458
        fl = self._filelog
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   459
        pl = [ (rp, pcl[0]._manifest.get(rp, nullid), fl) ]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   460
        if len(pcl) > 1:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   461
            if rp != p:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   462
                fl = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   463
            pl.append((p, pcl[1]._manifest.get(p, nullid), fl))
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   464
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   465
        return [ filectx(self._repo, p, fileid=n, filelog=l)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   466
                 for p,n,l in pl if n != nullid ]
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   467
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   468
    def children(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   469
        return []
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
   470
3308
192085505f6f filectx: add size method
Matt Mackall <mpm@selenic.com>
parents: 3304
diff changeset
   471
    def size(self): return os.stat(self._repo.wjoin(self._path)).st_size
3316
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   472
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
   473
    def cmp(self, text): return self._repo.wread(self._path) == text