annotate mercurial/changelog.py @ 30155:b7a966ce89ed

changelog: disable delta chains This patch disables delta chains on changelogs. After this patch, new entries on changelogs - including existing changelogs - will be stored as the fulltext of that data (likely compressed). No delta computation will be performed. An overview of delta chains and data justifying this change follows. Revlogs try to store entries as a delta against a previous entry (either a parent revision in the case of generaldelta or the previous physical revision when not using generaldelta). Most of the time this is the correct thing to do: it frequently results in less CPU usage and smaller storage. Delta chains are most effective when the base revision being deltad against is similar to the current data. This tends to occur naturally for manifests and file data, since only small parts of each tend to change with each revision. Changelogs, however, are a different story. Changelog entries represent changesets/commits. And unless commits in a repository are homogonous (same author, changing same files, similar commit messages, etc), a delta from one entry to the next tends to be relatively large compared to the size of the entry. This means that delta chains tend to be short. How short? Here is the full vs delta revision breakdown on some real world repos: Repo % Full % Delta Max Length hg 45.8 54.2 6 mozilla-central 42.4 57.6 8 mozilla-unified 42.5 57.5 17 pypy 46.1 53.9 6 python-zstandard 46.1 53.9 3 (I threw in python-zstandard as an example of a repo that is homogonous. It contains a small Python project with changes all from the same author.) Contrast this with the manifest revlog for these repos, where 99+% of revisions are deltas and delta chains run into the thousands. So delta chains aren't as useful on changelogs. But even a short delta chain may provide benefits. Let's measure that. Delta chains may require less CPU to read revisions if the CPU time spent reading smaller deltas is less than the CPU time used to decompress larger individual entries. We can measure this via `hg perfrevlog -c -d 1` to iterate a revlog to resolve each revision's fulltext. Here are the results of that command on a repo using delta chains in its changelog and on a repo without delta chains: hg (forward) ! wall 0.407008 comb 0.410000 user 0.410000 sys 0.000000 (best of 25) ! wall 0.390061 comb 0.390000 user 0.390000 sys 0.000000 (best of 26) hg (reverse) ! wall 0.515221 comb 0.520000 user 0.520000 sys 0.000000 (best of 19) ! wall 0.400018 comb 0.400000 user 0.390000 sys 0.010000 (best of 25) mozilla-central (forward) ! wall 4.508296 comb 4.490000 user 4.490000 sys 0.000000 (best of 3) ! wall 4.370222 comb 4.370000 user 4.350000 sys 0.020000 (best of 3) mozilla-central (reverse) ! wall 5.758995 comb 5.760000 user 5.720000 sys 0.040000 (best of 3) ! wall 4.346503 comb 4.340000 user 4.320000 sys 0.020000 (best of 3) mozilla-unified (forward) ! wall 4.957088 comb 4.950000 user 4.940000 sys 0.010000 (best of 3) ! wall 4.660528 comb 4.650000 user 4.630000 sys 0.020000 (best of 3) mozilla-unified (reverse) ! wall 6.119827 comb 6.110000 user 6.090000 sys 0.020000 (best of 3) ! wall 4.675136 comb 4.670000 user 4.670000 sys 0.000000 (best of 3) pypy (forward) ! wall 1.231122 comb 1.240000 user 1.230000 sys 0.010000 (best of 8) ! wall 1.164896 comb 1.160000 user 1.160000 sys 0.000000 (best of 9) pypy (reverse) ! wall 1.467049 comb 1.460000 user 1.460000 sys 0.000000 (best of 7) ! wall 1.160200 comb 1.170000 user 1.160000 sys 0.010000 (best of 9) The data clearly shows that it takes less wall and CPU time to resolve revisions when there are no delta chains in the changelogs, regardless of the direction of traversal. Furthermore, not using a delta chain means that fulltext resolution in reverse is as fast as iterating forward. So not using delta chains on the changelog is a clear CPU win for reading operations. An example of a user-visible operation showing this speed-up is revset evaluation. Here are results for `hg perfrevset 'author(gps) or author(mpm)'`: hg ! wall 1.655506 comb 1.660000 user 1.650000 sys 0.010000 (best of 6) ! wall 1.612723 comb 1.610000 user 1.600000 sys 0.010000 (best of 7) mozilla-central ! wall 17.629826 comb 17.640000 user 17.600000 sys 0.040000 (best of 3) ! wall 17.311033 comb 17.300000 user 17.260000 sys 0.040000 (best of 3) What about 00changelog.i size? Repo Delta Chains No Delta Chains hg 7,033,250 6,976,771 mozilla-central 82,978,748 81,574,623 mozilla-unified 88,112,349 86,702,162 pypy 20,740,699 20,659,741 The data shows that removing delta chains from the changelog makes the changelog smaller. Delta chains are also used during changegroup generation. This operation essentially converts a series of revisions to one large delta chain. And changegroup generation is smart: if the delta in the revlog matches what the changegroup is emitting, it will reuse the delta instead of recalculating it. We can measure the impact removing changelog delta chains has on changegroup generation via `hg perfchangegroupchangelog`: hg ! wall 1.589245 comb 1.590000 user 1.590000 sys 0.000000 (best of 7) ! wall 1.788060 comb 1.790000 user 1.790000 sys 0.000000 (best of 6) mozilla-central ! wall 17.382585 comb 17.380000 user 17.340000 sys 0.040000 (best of 3) ! wall 20.161357 comb 20.160000 user 20.120000 sys 0.040000 (best of 3) mozilla-unified ! wall 18.722839 comb 18.720000 user 18.680000 sys 0.040000 (best of 3) ! wall 21.168075 comb 21.170000 user 21.130000 sys 0.040000 (best of 3) pypy ! wall 4.828317 comb 4.830000 user 4.820000 sys 0.010000 (best of 3) ! wall 5.415455 comb 5.420000 user 5.410000 sys 0.010000 (best of 3) The data shows eliminating delta chains makes the changelog part of changegroup generation slower. This is expected since we now have to compute deltas for revisions where we could recycle the delta before. It is worth putting this regression into context of overall changegroup times. Here is the rough total CPU time spent in changegroup generation for various repos while using delta chains on the changelog: Repo CPU Time (s) CPU Time w/ compression hg 4.50 7.05 mozilla-central 111.1 222.0 pypy 28.68 75.5 Before compression, removing delta chains from the changegroup adds ~4.4% overhead to hg changegroup generation, 1.3% to mozilla-central, and 2.0% to pypy. When you factor in zlib compression, these percentages are roughly divided by 2. While the increased CPU usage for changegroup generation is unfortunate, I think it is acceptable because the percentage is small, server operators (those likely impacted most by this) have other mechanisms to mitigate CPU consumption (namely reducing zlib compression level and pre-generated clone bundles), and because there is room to optimize this in the future. For example, we could use the nullid as the base revision, effectively encoding the full revision for each entry in the changegroup. When doing this, `hg perfchangegroupchangelog` nearly halves: mozilla-unified ! wall 21.168075 comb 21.170000 user 21.130000 sys 0.040000 (best of 3) ! wall 11.196461 comb 11.200000 user 11.190000 sys 0.010000 (best of 3) This looks very promising as a future optimization opportunity. It's worth that the changes in test-acl.t to the changegroup part size. This is because revision 6 in the changegroup had a delta chain of length 2 before and after this patch the base revision is nullrev. When the base revision is nullrev, cg2packer.deltaparent() hardcodes the *previous* revision from the changegroup as the delta parent. This caused the delta in the changegroup to switch base revisions, the delta to change, and the size to change accordingly. While the size increased in this case, I think sizes will remain the same on average, as the delta base for changelog revisions doesn't matter too much (as this patch shows). So, I don't consider this a regression.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 13 Oct 2016 12:50:27 +0200
parents 557454ce854a
children 5e4f16874a9f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1095
0a18374c0769 changelog: adjust imports, comment
mpm@selenic.com
parents: 1094 1089
diff changeset
1 # changelog.py - changelog class for mercurial
0
9117c6561b0b Add back links from file revisions to changeset revisions
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: 4269
diff changeset
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9677
diff changeset
6 # GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
7
25922
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
8 from __future__ import absolute_import
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
9
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
10 import collections
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
11
25922
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
12 from .i18n import _
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
13 from .node import (
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
14 bin,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
15 hex,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
16 nullid,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
17 )
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
18
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
19 from . import (
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
20 encoding,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
21 error,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
22 revlog,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
23 util,
85f442747153 changelog: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25814
diff changeset
24 )
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
25
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
26 _defaultextra = {'branch': 'default'}
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
27
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
28 def _string_escape(text):
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
29 """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
30 >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
31 >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
32 >>> s
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
33 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
34 >>> res = _string_escape(s)
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
35 >>> s == res.decode('string_escape')
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
36 True
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
37 """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
38 # subset of the string_escape codec
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
39 text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
40 return text.replace('\0', '\\0')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
41
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
42 def decodeextra(text):
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
43 """
18379
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
44 >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
45 ... ).iteritems())
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
46 [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
47 >>> sorted(decodeextra(encodeextra({'foo': 'bar',
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
48 ... 'baz': chr(92) + chr(0) + '2'})
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
49 ... ).iteritems())
e0c4f4ba624c tests: fix doctest stability over Python versions
Mads Kiilerich <madski@unity3d.com>
parents: 18378
diff changeset
50 [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
51 """
16267
aa6821a7b52f changelog: micro-optimizations to changelog.read()
Matt Mackall <mpm@selenic.com>
parents: 15661
diff changeset
52 extra = _defaultextra.copy()
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
53 for l in text.split('\0'):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
54 if l:
15661
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
55 if '\\0' in l:
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
56 # fix up \0 without getting into trouble with \\0
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
57 l = l.replace('\\\\', '\\\\\n')
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
58 l = l.replace('\\0', '\0')
20ae902c43ec changelog: handle decoding of NULs in extra more carefully (issue3156)
Matt Mackall <mpm@selenic.com>
parents: 14643
diff changeset
59 l = l.replace('\n', '')
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
60 k, v = l.decode('string_escape').split(':', 1)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
61 extra[k] = v
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
62 return extra
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
63
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
64 def encodeextra(d):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
65 # keys must be sorted to produce a deterministic changelog entry
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
66 items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
67 return "\0".join(items)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
68
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
69 def stripdesc(desc):
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
70 """strip trailing whitespace and leading and trailing empty lines"""
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
71 return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
72
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8644
diff changeset
73 class appender(object):
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
74 '''the changelog index must be updated last on disk, so we use this class
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
75 to delay writes to it'''
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
76 def __init__(self, vfs, name, mode, buf):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
77 self.data = buf
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
78 fp = vfs(name, mode)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
79 self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
80 self.offset = fp.tell()
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
81 self.size = vfs.fstat(fp).st_size
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
82
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
83 def end(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
84 return self.size + len("".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
85 def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
86 return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
87 def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
88 pass
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
89 def close(self):
4961
3fdd09ad6cce fix bogus close spotted by pychecker (no close() in global scope)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 4635
diff changeset
90 self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
91
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
92 def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
93 '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
94 if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
95 self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
96 elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
97 self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
98 elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
99 self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
100 if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
101 self.fp.seek(self.offset)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
102
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
103 def read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
104 '''only trick here is reads that span real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
105 ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
106 if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
107 s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
108 ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
109 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
110 if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
111 count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
112 if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
113 doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
114 self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
115 del self.data[1:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
116 s = self.data[0][doff:doff + count]
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
117 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
118 ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
119 return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
120
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
121 def write(self, s):
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 4963
diff changeset
122 self.data.append(str(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
123 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
124
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
125 def _divertopener(opener, target):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
126 """build an opener that writes in 'target.a' instead of 'target'"""
29997
b5e5ddf48bd2 revlog: specify checkambig at writing to avoid file stat ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29696
diff changeset
127 def _divert(name, mode='r', checkambig=False):
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
128 if name != target:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
129 return opener(name, mode)
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
130 return opener(name + ".a", mode)
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
131 return _divert
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
132
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
133 def _delayopener(opener, target, buf):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
134 """build an opener that stores chunks in 'buf' instead of 'target'"""
29997
b5e5ddf48bd2 revlog: specify checkambig at writing to avoid file stat ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29696
diff changeset
135 def _delay(name, mode='r', checkambig=False):
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
136 if name != target:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
137 return opener(name, mode)
19899
8c3dcbbfb5de changelog: use "vfs.fstat()" instead of "util.fstat()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19898
diff changeset
138 return appender(opener, name, mode, buf)
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
139 return _delay
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
140
29696
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
141 _changelogrevision = collections.namedtuple(u'changelogrevision',
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
142 (u'manifest', u'user', u'date',
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
143 u'files', u'description',
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
144 u'extra'))
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
145
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
146 class changelogrevision(object):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
147 """Holds results of a parsed changelog revision.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
148
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
149 Changelog revisions consist of multiple pieces of data, including
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
150 the manifest node, user, and date. This object exposes a view into
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
151 the parsed object.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
152 """
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
153
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
154 __slots__ = (
29696
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
155 u'_offsets',
2f64e5a6efb8 py3: use unicode literals in changelog.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28495
diff changeset
156 u'_text',
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
157 )
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
158
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
159 def __new__(cls, text):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
160 if not text:
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
161 return _changelogrevision(
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
162 manifest=nullid,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
163 user='',
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
164 date=(0, 0),
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
165 files=[],
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
166 description='',
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
167 extra=_defaultextra,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
168 )
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
169
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
170 self = super(changelogrevision, cls).__new__(cls)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
171 # We could return here and implement the following as an __init__.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
172 # But doing it here is equivalent and saves an extra function call.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
173
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
174 # format used:
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
175 # nodeid\n : manifest node in ascii
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
176 # user\n : user, no \n or \r allowed
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
177 # time tz extra\n : date (time is int or float, timezone is int)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
178 # : extra is metadata, encoded and separated by '\0'
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
179 # : older versions ignore it
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
180 # files\n\n : files modified by the cset, no \n or \r allowed
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
181 # (.*) : comment (free text, ideally utf-8)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
182 #
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
183 # changelog v0 doesn't use extra
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
184
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
185 nl1 = text.index('\n')
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
186 nl2 = text.index('\n', nl1 + 1)
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
187 nl3 = text.index('\n', nl2 + 1)
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
188
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
189 # The list of files may be empty. Which means nl3 is the first of the
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
190 # double newline that precedes the description.
28494
63653147e9bb changelog: parse description last
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28493
diff changeset
191 if text[nl3 + 1] == '\n':
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
192 doublenl = nl3
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
193 else:
28494
63653147e9bb changelog: parse description last
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28493
diff changeset
194 doublenl = text.index('\n\n', nl3 + 1)
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
195
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
196 self._offsets = (nl1, nl2, nl3, doublenl)
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
197 self._text = text
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
198
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
199 return self
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
200
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
201 @property
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
202 def manifest(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
203 return bin(self._text[0:self._offsets[0]])
28490
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
204
959eadae589a changelog: lazily parse manifest node
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28489
diff changeset
205 @property
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
206 def user(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
207 off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
208 return encoding.tolocal(self._text[off[0] + 1:off[1]])
28491
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
209
f57f7500a095 changelog: lazily parse user
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28490
diff changeset
210 @property
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
211 def _rawdate(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
212 off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
213 dateextra = self._text[off[1] + 1:off[2]]
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
214 return dateextra.split(' ', 2)[0:2]
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
215
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
216 @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
217 def _rawextra(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
218 off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
219 dateextra = self._text[off[1] + 1:off[2]]
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
220 fields = dateextra.split(' ', 2)
28492
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
221 if len(fields) != 3:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
222 return None
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
223
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
224 return fields[2]
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
225
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
226 @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
227 def date(self):
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
228 raw = self._rawdate
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
229 time = float(raw[0])
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
230 # Various tools did silly things with the timezone.
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
231 try:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
232 timezone = int(raw[1])
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
233 except ValueError:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
234 timezone = 0
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
235
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
236 return time, timezone
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
237
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
238 @property
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
239 def extra(self):
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
240 raw = self._rawextra
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
241 if raw is None:
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
242 return _defaultextra
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
243
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
244 return decodeextra(raw)
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
245
837f1c437d58 changelog: lazily parse date/extra field
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28491
diff changeset
246 @property
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
247 def files(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
248 off = self._offsets
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
249 if off[2] == off[3]:
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
250 return []
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
251
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
252 return self._text[off[2] + 1:off[3]].split('\n')
28493
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
253
7796473c11b3 changelog: lazily parse files
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28492
diff changeset
254 @property
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
255 def description(self):
28495
70c2f8a98276 changelog: avoid slicing raw data until needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28494
diff changeset
256 return encoding.tolocal(self._text[self._offsets[3] + 2:])
28489
8939a95064f1 changelog: lazily parse description
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28487
diff changeset
257
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
258 class changelog(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
259 def __init__(self, opener):
30000
557454ce854a changelog: specify checkambig=True to revlog.__init__, to avoid ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29999
diff changeset
260 revlog.revlog.__init__(self, opener, "00changelog.i",
557454ce854a changelog: specify checkambig=True to revlog.__init__, to avoid ambiguity
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29999
diff changeset
261 checkambig=True)
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
262 if self._initempty:
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
263 # changelogs don't benefit from generaldelta
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
264 self.version &= ~revlog.REVLOGGENERALDELTA
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
265 self._generaldelta = False
30155
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
266
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
267 # Delta chains for changelogs tend to be very small because entries
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
268 # tend to be small and don't delta well with each. So disable delta
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
269 # chains.
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
270 self._storedeltachains = False
b7a966ce89ed changelog: disable delta chains
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30000
diff changeset
271
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
272 self._realopener = opener
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
273 self._delayed = False
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
274 self._delaybuf = None
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
275 self._divert = False
18231
c0c943ef4e55 clfilter: use empty frozenset intead of empty tuple
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17951
diff changeset
276 self.filteredrevs = frozenset()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
277
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
278 def tip(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
279 """filtered version of revlog.tip"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
280 for i in xrange(len(self) -1, -2, -1):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
281 if i not in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
282 return self.node(i)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
283
24030
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
284 def __contains__(self, rev):
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
285 """filtered version of revlog.__contains__"""
24662
b5cd8c2f6e65 changelog: inline revlog.__contains__ in case it is used in hot loop
Yuya Nishihara <yuya@tcha.org>
parents: 24030
diff changeset
286 return (0 <= rev < len(self)
24030
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
287 and rev not in self.filteredrevs)
828dc8db5515 revlog: add __contains__ for fast membership test
Yuya Nishihara <yuya@tcha.org>
parents: 23292
diff changeset
288
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
289 def __iter__(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
290 """filtered version of revlog.__iter__"""
17951
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
291 if len(self.filteredrevs) == 0:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
292 return revlog.revlog.__iter__(self)
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
293
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
294 def filterediter():
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
295 for i in xrange(len(self)):
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
296 if i not in self.filteredrevs:
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
297 yield i
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
298
6f79c32c0bdf commit: increase perf by avoiding unnecessary filteredrevs check
Durham Goode <durham@fb.com>
parents: 17810
diff changeset
299 return filterediter()
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
300
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
301 def revs(self, start=0, stop=None):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
302 """filtered version of revlog.revs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
303 for i in super(changelog, self).revs(start, stop):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
304 if i not in self.filteredrevs:
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
305 yield i
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
306
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
307 @util.propertycache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
308 def nodemap(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
309 # XXX need filtering too
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
310 self.rev(self.node(0))
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
311 return self._nodecache
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
312
26005
6f4a280298c1 changelog: add way to call the reachableroots C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25922
diff changeset
313 def reachableroots(self, minroot, heads, roots, includepath=False):
26094
df41c7be16d6 reachableroots: construct and sort baseset in revset module
Yuya Nishihara <yuya@tcha.org>
parents: 26061
diff changeset
314 return self.index.reachableroots2(minroot, heads, roots, includepath)
26005
6f4a280298c1 changelog: add way to call the reachableroots C implementation
Laurent Charignon <lcharignon@fb.com>
parents: 25922
diff changeset
315
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
316 def headrevs(self):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
317 if self.filteredrevs:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
318 try:
23088
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
319 return self.index.headrevsfiltered(self.filteredrevs)
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
320 # AttributeError covers non-c-extension environments and
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
321 # old c extensions without filter handling.
fe5f044b753d changelog: use headrevsfiltered
Mads Kiilerich <madski@unity3d.com>
parents: 23015
diff changeset
322 except AttributeError:
22484
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
323 return self._headrevs()
2b5940f64750 obsolete: use C code for headrevs calculation
Durham Goode <durham@fb.com>
parents: 21544
diff changeset
324
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
325 return super(changelog, self).headrevs()
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
326
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
327 def strip(self, *args, **kwargs):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
328 # XXX make something better than assert
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
329 # We can't expect proper strip behavior if we are filtered.
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
330 assert not self.filteredrevs
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
331 super(changelog, self).strip(*args, **kwargs)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
332
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
333 def rev(self, node):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
334 """filtered version of revlog.rev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
335 r = super(changelog, self).rev(node)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
336 if r in self.filteredrevs:
23015
21c44c1aed87 repoview: add a FilteredLookupError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23014
diff changeset
337 raise error.FilteredLookupError(hex(node), self.indexfile,
21c44c1aed87 repoview: add a FilteredLookupError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23014
diff changeset
338 _('filtered node'))
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
339 return r
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
340
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
341 def node(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
342 """filtered version of revlog.node"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
343 if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
344 raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
345 return super(changelog, self).node(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
346
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
347 def linkrev(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
348 """filtered version of revlog.linkrev"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
349 if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
350 raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
351 return super(changelog, self).linkrev(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
352
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
353 def parentrevs(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
354 """filtered version of revlog.parentrevs"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
355 if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
356 raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
357 return super(changelog, self).parentrevs(rev)
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
358
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
359 def flags(self, rev):
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
360 """filtered version of revlog.flags"""
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
361 if rev in self.filteredrevs:
23014
f00813325c5a repoview: add a FilteredIndexError class
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22484
diff changeset
362 raise error.FilteredIndexError(rev)
17677
5c89e7fa5bc2 clfilter: introduce `filteredrevs` attribute on changelog
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17424
diff changeset
363 return super(changelog, self).flags(rev)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
364
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23201
diff changeset
365 def delayupdate(self, tr):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
366 "delay visibility of index updates to other readers"
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
367
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
368 if not self._delayed:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
369 if len(self) == 0:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
370 self._divert = True
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
371 if self._realopener.exists(self.indexfile + '.a'):
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
372 self._realopener.unlink(self.indexfile + '.a')
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
373 self.opener = _divertopener(self._realopener, self.indexfile)
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
374 else:
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
375 self._delaybuf = []
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
376 self.opener = _delayopener(self._realopener, self.indexfile,
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
377 self._delaybuf)
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
378 self._delayed = True
23203
3872d563e01a changelog: handle writepending in the transaction
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23201
diff changeset
379 tr.addpending('cl-%i' % id(self), self._writepending)
23281
f60ed8cf4afc transaction: pass the transaction to 'finalize' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23280
diff changeset
380 tr.addfinalize('cl-%i' % id(self), self._finalize)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
381
23205
2d54aa5397cd changelog: rely on transaction for finalization
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23203
diff changeset
382 def _finalize(self, tr):
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
383 "finalize index updates"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
384 self._delayed = False
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
385 self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
386 # move redirected index data back into place
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
387 if self._divert:
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
388 assert not self._delaybuf
19898
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
389 tmpname = self.indexfile + ".a"
3f92e749d381 changelog: use "vfs.rename()" instead of "util.rename()"
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 18587
diff changeset
390 nfile = self.opener.open(tmpname)
14207
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
391 nfile.close()
29999
003c41edc5f5 changelog: specify checkambig=True to avoid ambiguity around truncation
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29997
diff changeset
392 self.opener.rename(tmpname, self.indexfile, checkambig=True)
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
393 elif self._delaybuf:
29999
003c41edc5f5 changelog: specify checkambig=True to avoid ambiguity around truncation
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 29997
diff changeset
394 fp = self.opener(self.indexfile, 'a', checkambig=True)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
395 fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
396 fp.close()
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
397 self._delaybuf = None
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
398 self._divert = False
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
399 # split when we're done
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
400 self.checkinlinesize(tr)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
401
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
402 def readpending(self, file):
25635
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
403 """read index data from a "pending" file
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
404
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
405 During a transaction, the actual changeset data is already stored in the
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
406 main file, but not yet finalized in the on-disk index. Instead, a
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
407 "pending" index is written by the transaction logic. If this function
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
408 is running, we are likely in a subprocess invoked in a hook. The
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
409 subprocess is informed that it is within a transaction and needs to
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
410 access its content.
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
411
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
412 This function will read all the index data out of the pending file and
25814
dc1a49264628 changelog: update read pending documentation
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25635
diff changeset
413 overwrite the main index."""
25635
7fdd1782fc4e changelog: document the 'readpending' method
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24961
diff changeset
414
24822
8678b1eafbcf changelog: fix readpending if no pending data exist (issue4609)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24662
diff changeset
415 if not self.opener.exists(file):
8678b1eafbcf changelog: fix readpending if no pending data exist (issue4609)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 24662
diff changeset
416 return # no pending data for changelog
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
417 r = revlog.revlog(self.opener, file)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
418 self.index = r.index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
419 self.nodemap = r.nodemap
16619
bc84a1aeaf5a changelog: ensure that nodecache is valid (issue3428)
Bryan O'Sullivan <bryano@fb.com>
parents: 16267
diff changeset
420 self._nodecache = r._nodecache
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
421 self._chunkcache = r._chunkcache
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
422
23280
b01c491af0cf transaction: pass the transaction to 'pending' callback
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23205
diff changeset
423 def _writepending(self, tr):
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
424 "create a file containing the unfinalized state for pretxnchangegroup"
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
425 if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
426 # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
427 fp1 = self._realopener(self.indexfile)
23292
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
428 pendingfilename = self.indexfile + ".a"
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
429 # register as a temp file to ensure cleanup on failure
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
430 tr.registertmp(pendingfilename)
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
431 # write existing data
e44399c494ab changelog: register changelog.i.a as a temporary file
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23281
diff changeset
432 fp2 = self._realopener(pendingfilename, "w")
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
433 fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
434 # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
435 fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
436 fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
437 # switch modes so finalize can simply rename
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
438 self._delaybuf = None
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
439 self._divert = True
23201
7e97bf6ee2d6 changelog: rework the delayupdate mechanism
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23088
diff changeset
440 self.opener = _divertopener(self._realopener, self.indexfile)
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
441
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
442 if self._divert:
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
443 return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
444
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
445 return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
446
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
447 def checkinlinesize(self, tr, fp=None):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
448 if not self._delayed:
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
449 revlog.revlog.checkinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
450
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
451 def read(self, node):
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
452 """Obtain data from a parsed changelog revision.
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
453
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
454 Returns a 6-tuple of:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
455
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
456 - manifest node in binary
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
457 - author/user as a localstr
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
458 - date as a 2-tuple of (time, timezone)
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
459 - list of files
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
460 - commit message as a localstr
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
461 - dict of extra metadata
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
462
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
463 Unless you need to access all fields, consider calling
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
464 ``changelogrevision`` instead, as it is faster for partial object
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
465 access.
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
466 """
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
467 c = changelogrevision(self.revision(node))
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
468 return (
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
469 c.manifest,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
470 c.user,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
471 c.date,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
472 c.files,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
473 c.description,
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
474 c.extra
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
475 )
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
476
28487
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
477 def changelogrevision(self, nodeorrev):
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
478 """Obtain a ``changelogrevision`` for a node or revision."""
98d98a645e9d changelog: add class to represent parsed changelog revisions
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28315
diff changeset
479 return changelogrevision(self.revision(nodeorrev))
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
480
27439
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
481 def readfiles(self, node):
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
482 """
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
483 short version of read that only returns the files modified by the cset
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
484 """
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
485 text = self.revision(node)
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
486 if not text:
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
487 return []
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
488 last = text.index("\n\n")
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
489 l = text[:last].split('\n')
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
490 return l[3:]
ed003859f1d8 changelog: add a new method to get files modified by a changeset
Laurent Charignon <lcharignon@fb.com>
parents: 26094
diff changeset
491
8422
437e06bbd11e changelog: removed bad default arguments in add method
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
492 def add(self, manifest, files, desc, transaction, p1, p2,
9677
0c072e63e3e7 changelog: do not use a mutable default value
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9166
diff changeset
493 user, date=None, extra=None):
14379
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
494 # Convert to UTF-8 encoded bytestrings as the very first
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
495 # thing: calling any method on a localstr object will turn it
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
496 # into a str object and the cached UTF-8 string is thus lost.
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
497 user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
bd23d5f28bbb changelog: convert user and desc from local encoding early
Martin Geisler <mg@aragost.com>
parents: 10420
diff changeset
498
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
499 user = user.strip()
8424
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
500 # An empty username or a username with a "\n" will make the
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
501 # revision text contain two "\n\n" sequences -> corrupt
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
502 # repository since read cannot unpack the revision.
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
503 if not user:
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
504 raise error.RevlogError(_("empty username"))
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
505 if "\n" in user:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
506 raise error.RevlogError(_("username %s contains a newline")
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
507 % repr(user))
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
508
17810
2894d180afa1 changelog: extract description cleaning logic in a dedicated function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17677
diff changeset
509 desc = stripdesc(desc)
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
510
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
511 if date:
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
512 parseddate = "%d %d" % util.parsedate(date)
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
513 else:
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2142
diff changeset
514 parseddate = "%d %d" % util.makedate()
10417
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
515 if extra:
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
516 branch = extra.get("branch")
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
517 if branch in ("default", ""):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
518 del extra["branch"]
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
519 elif branch in (".", "null", "tip"):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
520 raise error.RevlogError(_('the name \'%s\' is reserved')
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
521 % branch)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
522 if extra:
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
523 extra = encodeextra(extra)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
524 parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
525 l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
526 text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
527 return self.addrevision(text, transaction, len(self), p1, p2)
18306
06185554e7e3 changelog: add a `branch` method, bypassing changectx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18231
diff changeset
528
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
529 def branchinfo(self, rev):
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
530 """return the branch name and open/close state of a revision
18306
06185554e7e3 changelog: add a `branch` method, bypassing changectx
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18231
diff changeset
531
18308
4e27b06a0fd9 changelog: please check-code and remove tabs
Mads Kiilerich <mads@kiilerich.com>
parents: 18306
diff changeset
532 This function exists because creating a changectx object
4e27b06a0fd9 changelog: please check-code and remove tabs
Mads Kiilerich <mads@kiilerich.com>
parents: 18306
diff changeset
533 just to access this is costly."""
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
534 extra = self.read(rev)[5]
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 19899
diff changeset
535 return encoding.tolocal(extra.get("branch")), 'close' in extra