annotate mercurial/changelog.py @ 15004:d06b9c55ddab stable

hgweb: raw file mimetype guessing configurable, off by default (BC) (issue2923) Before: hgweb made it possible to download file content with a content type detected from the file extension. It would serve .html files as text/html and could thus cause XSS vulnerabilities if the web site had any kind of session authorization and the repository content wasn't fully trusted. Now: all files default to "application/binary", which all important browsers will refuse to treat as text/html. See the table here: https://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors
author Matt Mackall <mpm@selenic.com>
date Sun, 31 Jul 2011 01:46:52 +0200
parents 7e295dd10d40
children 20ae902c43ec
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
6211
f89fd07fc51d Expand import * to allow Pyflakes to find problems
Joel Rosdahl <joel@rosdahl.net>
parents: 5791
diff changeset
8 from node import bin, hex, nullid
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
9 from i18n import _
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
10 import util, error, revlog, encoding
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
11
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
12 def _string_escape(text):
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
13 """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
14 >>> 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
15 >>> 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
16 >>> s
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
17 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
18 >>> res = _string_escape(s)
5745
234e40e636a8 changelog: inline trivial call for extra data unescaping
Matt Mackall <mpm@selenic.com>
parents: 5744
diff changeset
19 >>> s == res.decode('string_escape')
3232
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
20 True
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
21 """
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
22 # subset of the string_escape codec
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
23 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
24 return text.replace('\0', '\\0')
394ac87f3b74 [extendedchangelog] encode/decode function
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3077
diff changeset
25
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
26 def decodeextra(text):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
27 extra = {}
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
28 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
29 if l:
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
30 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
31 extra[k] = v
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
32 return extra
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
33
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
34 def encodeextra(d):
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
35 # 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
36 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
37 return "\0".join(items)
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
38
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8644
diff changeset
39 class appender(object):
7807
bd8f44638847 help: miscellaneous language fixes
timeless <timeless@gmail.com>
parents: 7787
diff changeset
40 '''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
41 to delay writes to it'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
42 def __init__(self, fp, buf):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
43 self.data = buf
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
44 self.fp = fp
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
45 self.offset = fp.tell()
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
46 self.size = util.fstat(fp).st_size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
47
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
48 def end(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
49 return self.size + len("".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
50 def tell(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
51 return self.offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
52 def flush(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
53 pass
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
54 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
55 self.fp.close()
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
56
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
57 def seek(self, offset, whence=0):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
58 '''virtual file offset spans real file and data'''
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
59 if whence == 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
60 self.offset = offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
61 elif whence == 1:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
62 self.offset += offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
63 elif whence == 2:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
64 self.offset = self.end() + offset
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
65 if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
66 self.fp.seek(self.offset)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
67
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
68 def read(self, count=-1):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
69 '''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
70 ret = ""
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
71 if self.offset < self.size:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
72 s = self.fp.read(count)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
73 ret = s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
74 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
75 if count > 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
76 count -= len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
77 if count != 0:
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
78 doff = self.offset - self.size
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
79 self.data.insert(0, "".join(self.data))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
80 del self.data[1:]
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
81 s = self.data[0][doff:doff + count]
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
82 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
83 ret += s
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
84 return ret
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
85
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
86 def write(self, s):
5450
c728424d44c6 revlog: fix caching of buffer objects
Matt Mackall <mpm@selenic.com>
parents: 4963
diff changeset
87 self.data.append(str(s))
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
88 self.offset += len(s)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
89
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
90 def delayopener(opener, target, divert, buf):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
91 def o(name, mode='r'):
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
92 if name != target:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
93 return opener(name, mode)
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
94 if divert:
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
95 return opener(name + ".a", mode.replace('a', 'w'))
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
96 # otherwise, divert to memory
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
97 return appender(opener(name, mode), buf)
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
98 return o
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
99
7634
14a4337a9b9b revlog: kill from-style imports
Matt Mackall <mpm@selenic.com>
parents: 7633
diff changeset
100 class changelog(revlog.revlog):
4258
b11a2fb59cf5 revlog: simplify revlog version handling
Matt Mackall <mpm@selenic.com>
parents: 4257
diff changeset
101 def __init__(self, opener):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
102 revlog.revlog.__init__(self, opener, "00changelog.i")
14334
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
103 if self._initempty:
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
104 # changelogs don't benefit from generaldelta
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
105 self.version &= ~revlog.REVLOGGENERALDELTA
85c82ebc96a3 changelog: don't use generaldelta
Sune Foldager <cryo@cyanite.org>
parents: 14207
diff changeset
106 self._generaldelta = False
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
107 self._realopener = opener
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
108 self._delayed = False
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
109 self._divert = False
14643
7e295dd10d40 hidden: Add a hiddenrevs attributes to changelog.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14380
diff changeset
110 # hiddenrevs: revs that should be hidden by command and tools
7e295dd10d40 hidden: Add a hiddenrevs attributes to changelog.
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 14380
diff changeset
111 self.hiddenrevs = set()
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
112
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
113 def delayupdate(self):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
114 "delay visibility of index updates to other readers"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
115 self._delayed = True
9163
f193b643d1b1 changelog: _delaycount -> _divert
Matt Mackall <mpm@selenic.com>
parents: 8778
diff changeset
116 self._divert = (len(self) == 0)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
117 self._delaybuf = []
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
118 self.opener = delayopener(self._realopener, self.indexfile,
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
119 self._divert, self._delaybuf)
4261
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 finalize(self, tr):
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
122 "finalize index updates"
8644
c2ef478b2efa changelog: make delayopener less intrusive
Matt Mackall <mpm@selenic.com>
parents: 8499
diff changeset
123 self._delayed = False
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
124 self.opener = self._realopener
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
125 # move redirected index data back into place
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
126 if self._divert:
14207
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
127 nfile = self.opener(self.indexfile + ".a")
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
128 n = nfile.name
c1cca38818b9 changelog: fixes leaked file handle
Zachary Gramana <zgramana@pottsconsultinggroup.com>
parents: 14004
diff changeset
129 nfile.close()
9166
e6162b854ed5 changelog: move delayopener outside of class to eliminate reference cycle
Matt Mackall <mpm@selenic.com>
parents: 9165
diff changeset
130 util.rename(n, n[:-2])
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
131 elif self._delaybuf:
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
132 fp = self.opener(self.indexfile, 'a')
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
133 fp.write("".join(self._delaybuf))
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
134 fp.close()
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
135 self._delaybuf = []
4269
73c918c71300 changelog: optimize delayed updates for clone vs pull
Matt Mackall <mpm@selenic.com>
parents: 4261
diff changeset
136 # split when we're done
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
137 self.checkinlinesize(tr)
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
138
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
139 def readpending(self, file):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
140 r = revlog.revlog(self.opener, file)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
141 self.index = r.index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
142 self.nodemap = r.nodemap
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
143 self._chunkcache = r._chunkcache
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
144
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
145 def writepending(self):
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
146 "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
147 if self._delaybuf:
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
148 # make a temporary copy of the index
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
149 fp1 = self._realopener(self.indexfile)
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
150 fp2 = self._realopener(self.indexfile + ".a", "w")
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
151 fp2.write(fp1.read())
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
152 # add pending data
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
153 fp2.write("".join(self._delaybuf))
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
154 fp2.close()
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
155 # switch modes so finalize can simply rename
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
156 self._delaybuf = []
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
157 self._divert = True
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
158
9164
b0d995b6b0a6 changelog: factor out _delayname
Matt Mackall <mpm@selenic.com>
parents: 9163
diff changeset
159 if self._divert:
7787
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
160 return True
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
161
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
162 return False
b8d750daadde Introduce HG_PREPEND to solve pretxn races
Matt Mackall <mpm@selenic.com>
parents: 7634
diff changeset
163
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
164 def checkinlinesize(self, tr, fp=None):
9165
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
165 if not self._delayed:
07f9b2f4a9aa changelog: swap opener to switch delay modes
Matt Mackall <mpm@selenic.com>
parents: 9164
diff changeset
166 revlog.revlog.checkinlinesize(self, tr, fp)
4261
cd7b36b7869c restructure changelog file appending
Matt Mackall <mpm@selenic.com>
parents: 4258
diff changeset
167
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
168 def read(self, node):
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
169 """
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
170 format used:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
171 nodeid\n : manifest node in ascii
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
172 user\n : user, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
173 time tz extra\n : date (time is int or float, timezone is int)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
174 : extra is metadatas, encoded and separated by '\0'
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
175 : older versions ignore it
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
176 files\n\n : files modified by the cset, no \n or \r allowed
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
177 (.*) : comment (free text, ideally utf-8)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
178
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
179 changelog v0 doesn't use extra
3077
ad6aecaf4eed document changelog format
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
180 """
5744
9db7fd77417d changelog: remove extract function
Matt Mackall <mpm@selenic.com>
parents: 5450
diff changeset
181 text = self.revision(node)
37
a8811676c85a Move hex/bin bits to revlog
mpm@selenic.com
parents: 33
diff changeset
182 if not text:
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
183 return (nullid, "", (0, 0), [], "", {'branch': 'default'})
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
184 last = text.index("\n\n")
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
185 desc = encoding.tolocal(text[last + 2:])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
186 l = text[:last].split('\n')
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
187 manifest = bin(l[0])
7948
de377b1a9a84 move encoding bits from util to encoding
Matt Mackall <mpm@selenic.com>
parents: 7807
diff changeset
188 user = encoding.tolocal(l[1])
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
189
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
190 extra_data = l[2].split(' ', 2)
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
191 if len(extra_data) != 3:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
192 time = float(extra_data.pop(0))
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
193 try:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
194 # various tools did silly things with the time zone field.
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
195 timezone = int(extra_data[0])
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 10420
diff changeset
196 except ValueError:
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
197 timezone = 0
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
198 extra = {}
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
199 else:
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
200 time, timezone, extra = extra_data
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
201 time, timezone = float(time), int(timezone)
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
202 extra = decodeextra(extra)
4176
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
203 if not extra.get('branch'):
f9bbcebcacea "default" is the default branch name
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3771
diff changeset
204 extra['branch'] = 'default'
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
205 files = l[3:]
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
206 return (manifest, user, (time, timezone), files, desc, extra)
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
207
8422
437e06bbd11e changelog: removed bad default arguments in add method
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
208 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
209 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
210 # 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
211 # 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
212 # 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
213 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
214
7035
9d023ef7b467 forbid username with '\n' at the changelog level
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6259
diff changeset
215 user = user.strip()
8424
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
216 # 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
217 # 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
218 # 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
219 if not user:
c5b3d3e30de7 changelog: refuse to add revisions with empty usernames
Martin Geisler <mg@lazybytes.net>
parents: 7807
diff changeset
220 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
221 if "\n" in user:
7633
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
222 raise error.RevlogError(_("username %s contains a newline")
08cabecfa8a8 errors: move revlog errors
Matt Mackall <mpm@selenic.com>
parents: 7470
diff changeset
223 % repr(user))
8499
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
224
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
225 # strip trailing whitespace and leading and trailing empty lines
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
226 desc = '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
fb9b83df45f3 commit: move description trimming into changelog
Matt Mackall <mpm@selenic.com>
parents: 8443
diff changeset
227
1195
f92af8d53330 Validate user input of dates when adding a changelog entry.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1095
diff changeset
228 if date:
2523
4ab59a3acd16 validate the resulting date in parsedate
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2522
diff changeset
229 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
230 else:
2522
85f796baab10 Allow the use of human readable dates (issue 251)
Jose M. Prieto <jmprieto@gmx.net>
parents: 2142
diff changeset
231 parseddate = "%d %d" % util.makedate()
10417
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
232 if extra:
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
233 branch = extra.get("branch")
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
234 if branch in ("default", ""):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
235 del extra["branch"]
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
236 elif branch in (".", "null", "tip"):
58e040c51231 branch: avoid using reserved tag names
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 10263
diff changeset
237 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
238 % branch)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
239 if extra:
8443
53ff4a5af284 changelog: turn {de,en}code_extra methods into functions
Martin Geisler <mg@lazybytes.net>
parents: 8442
diff changeset
240 extra = encodeextra(extra)
3233
2f35961854fb [extendedchangelog] add extra metadata in the changelog entry
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3232
diff changeset
241 parseddate = "%s %s" % (parseddate, extra)
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7948
diff changeset
242 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
243 text = "\n".join(l)
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6259
diff changeset
244 return self.addrevision(text, transaction, len(self), p1, p2)