annotate mercurial/context.py @ 5338:f87685355c9c

revlog: fix revlogio.packentry corner case We want to store version information about the revlog in the first entry of its index. The code in packentry was using some heuristics to detect whether this was the first entry, but these heuristics could fail in some cases (e.g. rev 0 was empty; rev 1 descends directly from the nullid and is stored as a delta). We now give the revision number to packentry to avoid heuristics.
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
date Wed, 26 Sep 2007 01:58:45 -0300
parents 1fd7a99d98f6
children 26c060922085
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 #
4635
63b9d2deed48 Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4417
diff changeset
3 # Copyright 2006, 2007 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 *
3893
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3886
diff changeset
9 from i18n import _
3962
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
10 import ancestor, bdiff, repo, revlog, util, os, errno
3130
da85145d4571 filectx: add rename traversal for parents()
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
11
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12 class changectx(object):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
13 """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
14 changeset convenient."""
3127
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
15 def __init__(self, repo, changeid=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
16 """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
17 self._repo = repo
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
18
3143
db25f7b80fdb context: handle fileid or changeid == 0
Brendan Cully <brendan@kublai.com>
parents: 3136
diff changeset
19 if not changeid and changeid != 0:
3127
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
20 p1, p2 = self._repo.dirstate.parents()
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
21 self._rev = self._repo.changelog.rev(p1)
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
22 if self._rev == -1:
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
23 changeid = 'tip'
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
24 else:
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
25 self._node = p1
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
26 return
81da3c45aabd Move defaultrev into changectx
Brendan Cully <brendan@kublai.com>
parents: 2858
diff changeset
27
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
28 self._node = self._repo.lookup(changeid)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
29 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
30
3199
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
31 def __str__(self):
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
32 return short(self.node())
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
33
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
34 def __repr__(self):
3238
d865390c1781 context: simplify repr methods
Matt Mackall <mpm@selenic.com>
parents: 3237
diff changeset
35 return "<changectx %s>" % str(self)
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
36
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
37 def __eq__(self, other):
3715
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
38 try:
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
39 return self._rev == other._rev
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
40 except AttributeError:
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
41 return False
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
42
4815
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
43 def __ne__(self, other):
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
44 return not (self == other)
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
45
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
46 def __nonzero__(self):
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3495
diff changeset
47 return self._rev != nullrev
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
48
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
49 def __getattr__(self, name):
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
50 if name == '_changeset':
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 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
52 return self._changeset
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
53 elif name == '_manifest':
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
54 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
55 return self._manifest
3335
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
56 elif name == '_manifestdelta':
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
57 md = self._repo.manifest.readdelta(self._changeset[0])
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
58 self._manifestdelta = md
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
59 return self._manifestdelta
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
60 else:
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
61 raise AttributeError, name
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
62
4953
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
63 def __contains__(self, key):
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
64 return key in self._manifest
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
65
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
66 def __getitem__(self, key):
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
67 return self.filectx(key)
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
68
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
69 def __iter__(self):
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
70 a = self._manifest.keys()
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
71 a.sort()
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
72 for f in a:
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
73 return f
1fd7a99d98f6 context: add __contains__, __getitem__, and __iter__
Matt Mackall <mpm@selenic.com>
parents: 4892
diff changeset
74
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
75 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
76 def manifest(self): return self._manifest
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78 def rev(self): return self._rev
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 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
80 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
81 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
82 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
83 def description(self): return self._changeset[4]
4206
0b48e3985765 Minor default branch cleanups
Matt Mackall <mpm@selenic.com>
parents: 4204
diff changeset
84 def branch(self): return self._changeset[5].get("branch")
4663
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
85 def tags(self): return self._repo.nodetags(self._node)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
86
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 def parents(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 """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
89 p = self._repo.changelog.parents(self._node)
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
90 return [changectx(self._repo, x) for x in p]
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 children(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93 """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
94 c = self._repo.changelog.children(self._node)
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
95 return [changectx(self._repo, x) for x in c]
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
96
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97 def filenode(self, path):
3334
e44eadc92ec4 context: check self.__dict__ instead of using hasattr
Brendan Cully <brendan@kublai.com>
parents: 3319
diff changeset
98 if '_manifest' in self.__dict__:
3242
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
99 try:
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
100 return self._manifest[path]
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
101 except KeyError:
3930
01d98d68d697 Add revlog.LookupError exception, and use it instead of RevlogError.
Brendan Cully <brendan@kublai.com>
parents: 3893
diff changeset
102 raise revlog.LookupError(_("'%s' not found in manifest") % path)
3335
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
103 if '_manifestdelta' in self.__dict__ or path in self.files():
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
104 if path in self._manifestdelta:
b02e60097bbe changectx: search manifest delta for filenode
Brendan Cully <brendan@kublai.com>
parents: 3334
diff changeset
105 return self._manifestdelta[path]
3237
931288cf58a7 contexts: use __getattr__ rather than try/except in changectx
Matt Mackall <mpm@selenic.com>
parents: 3236
diff changeset
106 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
107 if not node:
3930
01d98d68d697 Add revlog.LookupError exception, and use it instead of RevlogError.
Brendan Cully <brendan@kublai.com>
parents: 3893
diff changeset
108 raise revlog.LookupError(_("'%s' not found in manifest") % path)
3242
1539f788e913 Make changectx.filenode raise repo.LookupError on failure
Brendan Cully <brendan@kublai.com>
parents: 3241
diff changeset
109
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110 return node
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
111
3966
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
112 def filectx(self, path, fileid=None, filelog=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113 """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
114 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
115 fileid = self.filenode(path)
3966
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
116 return filectx(self._repo, path, fileid=fileid,
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
117 changectx=self, filelog=filelog)
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 def filectxs(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
120 """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
121 manifest"""
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 mf = self.manifest()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
123 m = mf.keys()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124 m.sort()
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125 for f in m:
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 yield self.filectx(f, fileid=mf[f])
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127
3133
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
128 def ancestor(self, c2):
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
129 """
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
130 return the ancestor context of self and c2
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
131 """
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
132 n = self._repo.changelog.ancestor(self._node, c2._node)
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
133 return changectx(self._repo, n)
02b22fefc01f changectx: add ancestor function
Matt Mackall <mpm@selenic.com>
parents: 3132
diff changeset
134
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
135 class filectx(object):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
136 """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
137 filerevision convenient."""
3236
696c656202a0 context: make filectx remember changectx in changectx.filectx
Matt Mackall <mpm@selenic.com>
parents: 3235
diff changeset
138 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
139 filelog=None, changectx=None):
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
140 """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
141 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
142 self._repo = repo
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
143 self._path = path
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
144
3964
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
145 assert (changeid is not None
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
146 or fileid is not None
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
147 or changectx is not None)
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
148
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
149 if filelog:
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
150 self._filelog = filelog
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
151
3143
db25f7b80fdb context: handle fileid or changeid == 0
Brendan Cully <brendan@kublai.com>
parents: 3136
diff changeset
152 if fileid is None:
3964
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
153 if changectx is None:
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
154 self._changeid = changeid
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
155 else:
2308c39b9521 make it possible to use changectx to create a filectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3962
diff changeset
156 self._changectx = changectx
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
157 else:
3235
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
158 self._fileid = fileid
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
160 def __getattr__(self, name):
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
161 if name == '_changectx':
2652
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
162 self._changectx = changectx(self._repo, self._changeid)
f23973ea3107 fix filectxt to really work
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2629
diff changeset
163 return self._changectx
3235
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
164 elif name == '_filelog':
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
165 self._filelog = self._repo.file(self._path)
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
166 return self._filelog
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
167 elif name == '_changeid':
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
168 self._changeid = self._filelog.linkrev(self._filenode)
e8199702cf4e Make filectx lazier
Matt Mackall <mpm@selenic.com>
parents: 3209
diff changeset
169 return self._changeid
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
170 elif name == '_filenode':
3961
a4edadd807dd fix tab vs space
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3930
diff changeset
171 if '_fileid' in self.__dict__:
a4edadd807dd fix tab vs space
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3930
diff changeset
172 self._filenode = self._filelog.lookup(self._fileid)
a4edadd807dd fix tab vs space
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3930
diff changeset
173 else:
a4edadd807dd fix tab vs space
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3930
diff changeset
174 self._filenode = self._changectx.filenode(self._path)
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
175 return self._filenode
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
176 elif name == '_filerev':
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
177 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
178 return self._filerev
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
179 else:
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
180 raise AttributeError, name
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
181
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
182 def __nonzero__(self):
3712
1bd70d40ec57 context: None is not a valid filenode (revert from 23ede9e7ad4d)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3673
diff changeset
183 try:
1bd70d40ec57 context: None is not a valid filenode (revert from 23ede9e7ad4d)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3673
diff changeset
184 n = self._filenode
1bd70d40ec57 context: None is not a valid filenode (revert from 23ede9e7ad4d)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3673
diff changeset
185 return True
3930
01d98d68d697 Add revlog.LookupError exception, and use it instead of RevlogError.
Brendan Cully <brendan@kublai.com>
parents: 3893
diff changeset
186 except revlog.LookupError:
3712
1bd70d40ec57 context: None is not a valid filenode (revert from 23ede9e7ad4d)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3673
diff changeset
187 # file is missing
1bd70d40ec57 context: None is not a valid filenode (revert from 23ede9e7ad4d)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3673
diff changeset
188 return False
3201
05c588e1803d context: add __nonzero__ methods
Matt Mackall <mpm@selenic.com>
parents: 3199
diff changeset
189
3199
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
190 def __str__(self):
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
191 return "%s@%s" % (self.path(), short(self.node()))
ebdb3f616bc0 Add str methods to contexts
Matt Mackall <mpm@selenic.com>
parents: 3198
diff changeset
192
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
193 def __repr__(self):
3238
d865390c1781 context: simplify repr methods
Matt Mackall <mpm@selenic.com>
parents: 3237
diff changeset
194 return "<filectx %s>" % str(self)
3151
6719b3dd7d50 context: add __repr__ methods
Matt Mackall <mpm@selenic.com>
parents: 3150
diff changeset
195
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
196 def __eq__(self, other):
3715
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
197 try:
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
198 return (self._path == other._path
4892
3b081f2a77b2 contexts: improve filectx eq test
Matt Mackall <mpm@selenic.com>
parents: 4846
diff changeset
199 and self._fileid == other._fileid)
3715
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
200 except AttributeError:
6cb3aca69cdc Make context __eq__ handle arbitrary RHS values
Brendan Cully <brendan@kublai.com>
parents: 3712
diff changeset
201 return False
3198
e78185746554 Add equality operators to changectx and filectx
Matt Mackall <mpm@selenic.com>
parents: 3154
diff changeset
202
4815
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
203 def __ne__(self, other):
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
204 return not (self == other)
8808ea7da86b merge: make test for fast-forward merge stricter (issue619)
Matt Mackall <mpm@selenic.com>
parents: 4663
diff changeset
205
3207
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
206 def filectx(self, fileid):
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
207 '''opens an arbitrary revision of the file without
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
208 opening a new filelog'''
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
209 return filectx(self._repo, self._path, fileid=fileid,
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
210 filelog=self._filelog)
0790dce2f3a8 Add lookup method to filectx
Brendan Cully <brendan@kublai.com>
parents: 3165
diff changeset
211
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 def filerev(self): return self._filerev
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 def filenode(self): return self._filenode
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 def filelog(self): return self._filelog
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215
3150
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
216 def rev(self):
3334
e44eadc92ec4 context: check self.__dict__ instead of using hasattr
Brendan Cully <brendan@kublai.com>
parents: 3319
diff changeset
217 if '_changectx' in self.__dict__:
3150
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
218 return self._changectx.rev()
3402
372999405787 Back out d8eba1c3ce9b and a004164dbeef
Brendan Cully <brendan@kublai.com>
parents: 3400
diff changeset
219 return self._filelog.linkrev(self._filenode)
3150
a5e4c8172ace filectx: lazy linkrev usage
Matt Mackall <mpm@selenic.com>
parents: 3149
diff changeset
220
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
221 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
222 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
223 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
224 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
225 def description(self): return self._changectx.description()
3428
cc9c31b07c2c Add branch method to contexts
Matt Mackall <mpm@selenic.com>
parents: 3353
diff changeset
226 def branch(self): return self._changectx.branch()
3144
8342ad5abe0b Make filectx lazier - some users never use filenode
Brendan Cully <brendan@kublai.com>
parents: 3143
diff changeset
227 def manifest(self): return self._changectx.manifest()
3149
ff1ab08e6732 restore filectx.changectx() method
Matt Mackall <mpm@selenic.com>
parents: 3146
diff changeset
228 def changectx(self): return self._changectx
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
229
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
230 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
231 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
232 def path(self): return self._path
3308
192085505f6f filectx: add size method
Matt Mackall <mpm@selenic.com>
parents: 3304
diff changeset
233 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
234
3316
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
235 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
236
2563
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
237 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
238 p = self._path
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
239 fl = self._filelog
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
240 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
241
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
242 r = self.renamed()
3130
da85145d4571 filectx: add rename traversal for parents()
Matt Mackall <mpm@selenic.com>
parents: 2858
diff changeset
243 if r:
3132
4d021b91cb26 filectx: allow passing filelog in init to avoid opening new filelogs
Matt Mackall <mpm@selenic.com>
parents: 3131
diff changeset
244 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
245
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
246 return [filectx(self._repo, p, fileid=n, filelog=l)
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
247 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
248
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
249 def children(self):
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
250 # hard for renames
482c524dd9ab Add context.py: changeset and file revision contexts
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
251 c = self._filelog.children(self._filenode)
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
252 return [filectx(self._repo, self._path, fileid=x,
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
253 filelog=self._filelog) for x in c]
2566
d8560b458f76 Convert hg annotate to context api
Matt Mackall <mpm@selenic.com>
parents: 2563
diff changeset
254
4846
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
255 def annotate(self, follow=False, linenumber=None):
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
256 '''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
257 in the file, where ctx is the filectx of the node where
4846
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
258 that line was last changed.
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
259 This returns tuples of ((ctx, linenumber), line) for each line,
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
260 if "linenumber" parameter is NOT "None".
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
261 In such tuples, linenumber means one at the first appearance
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
262 in the managed file.
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
263 To reduce annotation cost,
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
264 this returns fixed value(False is used) as linenumber,
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
265 if "linenumber" parameter is "False".'''
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
266
4846
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
267 def decorate_compat(text, rev):
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
268 return ([rev] * len(text.splitlines()), text)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
269
4846
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
270 def without_linenumber(text, rev):
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
271 return ([(rev, False)] * len(text.splitlines()), text)
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
272
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
273 def with_linenumber(text, rev):
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
274 size = len(text.splitlines())
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
275 return ([(rev, i) for i in xrange(1, size + 1)], text)
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
276
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
277 decorate = (((linenumber is None) and decorate_compat) or
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
278 (linenumber and with_linenumber) or
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
279 without_linenumber)
e45c5120ca27 Allow filectx.annotate to return the line number of first appearance.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 4815
diff changeset
280
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
281 def pair(parent, child):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
282 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
283 child[0][b1:b2] = parent[0][a1:a2]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
284 return child
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 getlog = util.cachefunc(lambda x: self._repo.file(x))
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
287 def getctx(path, fileid):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
288 log = path == self._path and self._filelog or getlog(path)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
289 return filectx(self._repo, path, fileid=fileid, filelog=log)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
290 getctx = util.cachefunc(getctx)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
291
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
292 def parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
293 # we want to reuse filectx objects as much as possible
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
294 p = f._path
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
295 if f._filerev is None: # working dir
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
296 pl = [(n.path(), n.filerev()) for n in f.parents()]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
297 else:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
298 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
299
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
300 if follow:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
301 r = f.renamed()
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
302 if r:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
303 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
304
3578
3b4e00cba57a Define and use nullrev (revision of nullid) instead of -1.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3495
diff changeset
305 return [getctx(p, n) for p, n in pl if n != nullrev]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
306
3403
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
307 # use linkrev to find the first changeset where self appeared
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
308 if self.rev() != self._filelog.linkrev(self._filenode):
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
309 base = self.filectx(self.filerev())
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
310 else:
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
311 base = self
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
312
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
313 # find all ancestors
3403
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
314 needed = {base: 1}
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
315 visit = [base]
1a437b0f4902 Fix annotate where linkrev != rev without exporting linkrev
Brendan Cully <brendan@kublai.com>
parents: 3402
diff changeset
316 files = [base._path]
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
317 while visit:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
318 f = visit.pop(0)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
319 for p in parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
320 if p not in needed:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
321 needed[p] = 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
322 visit.append(p)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
323 if p._path not in files:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
324 files.append(p._path)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
325 else:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
326 # count how many times we'll use this
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
327 needed[p] += 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
328
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
329 # sort by revision (per file) which is a topological order
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
330 visit = []
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
331 for f in files:
4638
3c7fc13c4bfa Fix issue 589: "undelete" sequence leads to crash.
Patrick Mezard <pmezard@gmail.com>
parents: 4414
diff changeset
332 fn = [(n.rev(), n) for n in needed.keys() if n._path == f]
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
333 visit.extend(fn)
4638
3c7fc13c4bfa Fix issue 589: "undelete" sequence leads to crash.
Patrick Mezard <pmezard@gmail.com>
parents: 4414
diff changeset
334 visit.sort()
3165
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
335 hist = {}
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
336
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
337 for r, f in visit:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
338 curr = decorate(f.data(), f)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
339 for p in parents(f):
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
340 if p != nullid:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
341 curr = pair(hist[p], curr)
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
342 # trim the history of unneeded revs
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
343 needed[p] -= 1
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
344 if not needed[p]:
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
345 del hist[p]
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
346 hist[f] = curr
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
347
5c93dd0ae413 Refactor annotate copy support.
Brendan Cully <brendan@kublai.com>
parents: 3154
diff changeset
348 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
349
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
350 def ancestor(self, fc2):
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
351 """
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
352 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
353 """
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
354
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
355 acache = {}
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
356
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
357 # 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
358 for c in (self, fc2):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
359 if c._filerev == None:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
360 pl = [(n.path(), n.filenode()) for n in c.parents()]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
361 acache[(c._path, None)] = pl
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
362
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
363 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
364 def parents(vertex):
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
365 if vertex in acache:
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
366 return acache[vertex]
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
367 f, n = vertex
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
368 if f not in flcache:
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
369 flcache[f] = self._repo.file(f)
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
370 fl = flcache[f]
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
371 pl = [(f, p) for p in fl.parents(n) if p != nullid]
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
372 re = fl.renamed(n)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
373 if re:
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
374 pl.append(re)
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
375 acache[vertex] = pl
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
376 return pl
3134
4bf2e895cf86 filectx: add rename-aware ancestor algorithm
Matt Mackall <mpm@selenic.com>
parents: 3133
diff changeset
377
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
378 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
379 v = ancestor.ancestor(a, b, parents)
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
380 if v:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
381 f, n = v
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
382 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
383
3136
b1db258e875c Abstract ancestor algorithm into generic function
Matt Mackall <mpm@selenic.com>
parents: 3135
diff changeset
384 return None
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
385
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
386 class workingctx(changectx):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
387 """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
388 the current working directory convenient."""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
389 def __init__(self, repo):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
390 self._repo = repo
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
391 self._rev = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
392 self._node = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
393
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
394 def __str__(self):
3319
6c68bc1e7873 context: change workingctx str() from . to <node>+
Matt Mackall <mpm@selenic.com>
parents: 3316
diff changeset
395 return str(self._parents[0]) + "+"
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
396
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
397 def __nonzero__(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
398 return True
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
399
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
400 def __getattr__(self, name):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
401 if name == '_parents':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
402 self._parents = self._repo.parents()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
403 return self._parents
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
404 if name == '_status':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
405 self._status = self._repo.status()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
406 return self._status
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
407 if name == '_manifest':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
408 self._buildmanifest()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
409 return self._manifest
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
410 else:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
411 raise AttributeError, name
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
412
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
413 def _buildmanifest(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
414 """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
415
3240
8d4855fd9d7b merge: use new working context object in update
Matt Mackall <mpm@selenic.com>
parents: 3239
diff changeset
416 man = self._parents[0].manifest().copy()
3996
c190df14338c exec: add execfunc to simplify exec flag support on non-exec filesystems
Matt Mackall <mpm@selenic.com>
parents: 3966
diff changeset
417 is_exec = util.execfunc(self._repo.root, man.execf)
4002
d7b9ec589546 symlinks: use is_link wherever is_exec is used
Matt Mackall <mpm@selenic.com>
parents: 3996
diff changeset
418 is_link = util.linkfunc(self._repo.root, man.linkf)
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
419 copied = self._repo.dirstate.copies()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
420 modified, added, removed, deleted, unknown = self._status[:5]
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
421 for i, l in (("a", added), ("m", modified), ("u", unknown)):
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
422 for f in l:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
423 man[f] = man.get(copied.get(f, f), nullid) + i
3829
676b75547d13 context: don't spuriously raise abort when a file goes missing.
Matt Mackall <mpm@selenic.com>
parents: 3715
diff changeset
424 try:
4002
d7b9ec589546 symlinks: use is_link wherever is_exec is used
Matt Mackall <mpm@selenic.com>
parents: 3996
diff changeset
425 man.set(f, is_exec(f), is_link(f))
3829
676b75547d13 context: don't spuriously raise abort when a file goes missing.
Matt Mackall <mpm@selenic.com>
parents: 3715
diff changeset
426 except OSError:
676b75547d13 context: don't spuriously raise abort when a file goes missing.
Matt Mackall <mpm@selenic.com>
parents: 3715
diff changeset
427 pass
3239
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 for f in deleted + removed:
3351
50a18815e3f0 Revert changeset c67920d78248.
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 3319
diff changeset
430 if f in man:
50a18815e3f0 Revert changeset c67920d78248.
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 3319
diff changeset
431 del man[f]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
432
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
433 self._manifest = man
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 manifest(self): return self._manifest
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
436
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
437 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
438 def date(self): return util.makedate()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
439 def description(self): return ""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
440 def files(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
441 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
442 f.sort()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
443 return f
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
444
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
445 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
446 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
447 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
448 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
449 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
450 def clean(self): return self._status[5]
4207
7e1c8a565a4f Move branch read/write to dirstate where it belongs
Matt Mackall <mpm@selenic.com>
parents: 4206
diff changeset
451 def branch(self): return self._repo.dirstate.branch()
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
452
4663
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
453 def tags(self):
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
454 t = []
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
455 [t.extend(p.tags()) for p in self.parents()]
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
456 return t
6b2e8cb39583 context: add tags() method
Matt Mackall <mpm@selenic.com>
parents: 4640
diff changeset
457
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
458 def parents(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
459 """return contexts for each parent changeset"""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
460 return self._parents
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
461
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
462 def children(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
463 return []
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
464
3966
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
465 def filectx(self, path, filelog=None):
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
466 """get a file context from the working directory"""
3966
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
467 return workingfilectx(self._repo, path, workingctx=self,
b4eaa68dea1b context: create a filectxt with filelog reuse
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3965
diff changeset
468 filelog=filelog)
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
469
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
470 def ancestor(self, c2):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
471 """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
472 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
473
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
474 class workingfilectx(filectx):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
475 """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
476 file in the working directory convenient."""
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
477 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
478 """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
479 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
480 self._repo = repo
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
481 self._path = path
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
482 self._changeid = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
483 self._filerev = self._filenode = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
484
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
485 if filelog:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
486 self._filelog = filelog
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
487 if workingctx:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
488 self._changectx = workingctx
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
489
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
490 def __getattr__(self, name):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
491 if name == '_changectx':
4414
b6146466b92a context: fix workingfilectx._changectx
Matt Mackall <mpm@selenic.com>
parents: 4207
diff changeset
492 self._changectx = workingctx(self._repo)
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
493 return self._changectx
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
494 elif name == '_repopath':
3304
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
495 self._repopath = (self._repo.dirstate.copied(self._path)
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
496 or self._path)
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
497 return self._repopath
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
498 elif name == '_filelog':
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
499 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
500 return self._filelog
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
501 else:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
502 raise AttributeError, name
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
503
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
504 def __nonzero__(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
505 return True
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
506
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
507 def __str__(self):
3319
6c68bc1e7873 context: change workingctx str() from . to <node>+
Matt Mackall <mpm@selenic.com>
parents: 3316
diff changeset
508 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
509
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
510 def filectx(self, fileid):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
511 '''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
512 opening a new filelog'''
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
513 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
514 filelog=self._filelog)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
515
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
516 def rev(self):
3334
e44eadc92ec4 context: check self.__dict__ instead of using hasattr
Brendan Cully <brendan@kublai.com>
parents: 3319
diff changeset
517 if '_changectx' in self.__dict__:
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
518 return self._changectx.rev()
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
519 return self._filelog.linkrev(self._filenode)
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
520
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
521 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
522 def renamed(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
523 rp = self._repopath
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
524 if rp == self._path:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
525 return None
3965
2e5161335e65 context: fix a bug in workingfilectx.renamed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3964
diff changeset
526 return rp, self._changectx._parents[0]._manifest.get(rp, nullid)
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
527
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
528 def parents(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
529 '''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
530 p = self._path
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
531 rp = self._repopath
3304
45f0c49f0449 fix workingfilectx parents and ancestor functions
Matt Mackall <mpm@selenic.com>
parents: 3242
diff changeset
532 pcl = self._changectx._parents
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
533 fl = self._filelog
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
534 pl = [(rp, pcl[0]._manifest.get(rp, nullid), fl)]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
535 if len(pcl) > 1:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
536 if rp != p:
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
537 fl = None
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
538 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
539
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
540 return [filectx(self._repo, p, fileid=n, filelog=l)
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3578
diff changeset
541 for p,n,l in pl if n != nullid]
3239
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
542
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
543 def children(self):
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
544 return []
6d98149d70fe contexts: add working dir and working file contexts
Matt Mackall <mpm@selenic.com>
parents: 3238
diff changeset
545
3308
192085505f6f filectx: add size method
Matt Mackall <mpm@selenic.com>
parents: 3304
diff changeset
546 def size(self): return os.stat(self._repo.wjoin(self._path)).st_size
3962
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
547 def date(self):
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
548 t, tz = self._changectx.date()
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
549 try:
4115
eb0967c6e77b Use only integer part of mtime in workingfilectx.date(), fixes test-context.py
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4108
diff changeset
550 return (int(os.lstat(self._repo.wjoin(self._path)).st_mtime), tz)
3962
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
551 except OSError, err:
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
552 if err.errno != errno.ENOENT: raise
2b8825c94c5a add date attribute to workingfilectx
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3961
diff changeset
553 return (t, tz)
3316
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
554
0e370798eebf context: add cmp for filectxs
Matt Mackall <mpm@selenic.com>
parents: 3308
diff changeset
555 def cmp(self, text): return self._repo.wread(self._path) == text