##// END OF EJS Templates
merge with crew.
Vadim Gelfer -
r2262:3d48eb68 merge default
parent child Browse files
Show More
@@ -0,0 +1,8 b''
1 #!/bin/sh
2
3 hg init
4 python -c 'print "confuse str.splitlines\nembedded\rnewline"' > a
5 hg ci -Ama -d '1 0'
6 echo clean diff >> a
7 hg ci -mb -d '2 0'
8 hg diff -r0 -r1
@@ -0,0 +1,8 b''
1 adding a
2 diff -r 107ba6f817b5 -r 310ce7989cdc a
3 --- a/a Thu Jan 01 00:00:01 1970 +0000
4 +++ b/a Thu Jan 01 00:00:02 1970 +0000
5 @@ -1,2 +1,3 @@ confuse str.splitlines
6 confuse str.splitlines
7 embedded newline
8 +clean diff
@@ -0,0 +1,46 b''
1 #!/bin/sh
2
3 mkdir test
4 cd test
5 hg init
6 for i in 0 1 2 3 4 5 6 7 8; do
7 echo $i >> foo
8 hg commit -A -m $i -d "1000000 0"
9 done
10 hg verify
11 hg serve -p 20059 -d --pid-file=hg.pid
12 cd ..
13
14 hg init new
15 # http incoming
16 http_proxy= hg -R new incoming http://localhost:20059/
17 # local incoming
18 hg -R new incoming test
19
20 # test with --bundle
21 http_proxy= hg -R new incoming --bundle test.hg http://localhost:20059/
22 hg -R new incoming --bundle test2.hg test
23
24 # test the resulting bundles
25 hg init temp
26 hg init temp2
27 hg -R temp unbundle test.hg
28 hg -R temp2 unbundle test2.hg
29 hg -R temp tip
30 hg -R temp2 tip
31
32 rm -rf temp temp2 new
33
34 # test outgoing
35 hg clone test test-dev
36 cd test-dev
37 for i in 9 10 11 12 13; do
38 echo $i >> foo
39 hg commit -A -m $i -d "1000000 0"
40 done
41 hg verify
42 cd ..
43 hg -R test-dev outgoing test
44 http_proxy= hg -R test-dev outgoing http://localhost:20059/
45
46 kill `cat test/hg.pid`
@@ -0,0 +1,272 b''
1 adding foo
2 checking changesets
3 checking manifests
4 crosschecking files in changesets and manifests
5 checking files
6 1 files, 9 changesets, 9 total revisions
7 changeset: 0:9cb21d99fe27
8 user: test
9 date: Mon Jan 12 13:46:40 1970 +0000
10 summary: 0
11
12 changeset: 1:d717f5dfad6a
13 user: test
14 date: Mon Jan 12 13:46:40 1970 +0000
15 summary: 1
16
17 changeset: 2:c0d6b86da426
18 user: test
19 date: Mon Jan 12 13:46:40 1970 +0000
20 summary: 2
21
22 changeset: 3:dfacbd43b3fe
23 user: test
24 date: Mon Jan 12 13:46:40 1970 +0000
25 summary: 3
26
27 changeset: 4:1f3a964b6022
28 user: test
29 date: Mon Jan 12 13:46:40 1970 +0000
30 summary: 4
31
32 changeset: 5:c028bcc7a28a
33 user: test
34 date: Mon Jan 12 13:46:40 1970 +0000
35 summary: 5
36
37 changeset: 6:a0c0095f3389
38 user: test
39 date: Mon Jan 12 13:46:40 1970 +0000
40 summary: 6
41
42 changeset: 7:d4be65f4e891
43 user: test
44 date: Mon Jan 12 13:46:40 1970 +0000
45 summary: 7
46
47 changeset: 8:92b83e334ef8
48 tag: tip
49 user: test
50 date: Mon Jan 12 13:46:40 1970 +0000
51 summary: 8
52
53 changeset: 0:9cb21d99fe27
54 user: test
55 date: Mon Jan 12 13:46:40 1970 +0000
56 summary: 0
57
58 changeset: 1:d717f5dfad6a
59 user: test
60 date: Mon Jan 12 13:46:40 1970 +0000
61 summary: 1
62
63 changeset: 2:c0d6b86da426
64 user: test
65 date: Mon Jan 12 13:46:40 1970 +0000
66 summary: 2
67
68 changeset: 3:dfacbd43b3fe
69 user: test
70 date: Mon Jan 12 13:46:40 1970 +0000
71 summary: 3
72
73 changeset: 4:1f3a964b6022
74 user: test
75 date: Mon Jan 12 13:46:40 1970 +0000
76 summary: 4
77
78 changeset: 5:c028bcc7a28a
79 user: test
80 date: Mon Jan 12 13:46:40 1970 +0000
81 summary: 5
82
83 changeset: 6:a0c0095f3389
84 user: test
85 date: Mon Jan 12 13:46:40 1970 +0000
86 summary: 6
87
88 changeset: 7:d4be65f4e891
89 user: test
90 date: Mon Jan 12 13:46:40 1970 +0000
91 summary: 7
92
93 changeset: 8:92b83e334ef8
94 tag: tip
95 user: test
96 date: Mon Jan 12 13:46:40 1970 +0000
97 summary: 8
98
99 changeset: 0:9cb21d99fe27
100 user: test
101 date: Mon Jan 12 13:46:40 1970 +0000
102 summary: 0
103
104 changeset: 1:d717f5dfad6a
105 user: test
106 date: Mon Jan 12 13:46:40 1970 +0000
107 summary: 1
108
109 changeset: 2:c0d6b86da426
110 user: test
111 date: Mon Jan 12 13:46:40 1970 +0000
112 summary: 2
113
114 changeset: 3:dfacbd43b3fe
115 user: test
116 date: Mon Jan 12 13:46:40 1970 +0000
117 summary: 3
118
119 changeset: 4:1f3a964b6022
120 user: test
121 date: Mon Jan 12 13:46:40 1970 +0000
122 summary: 4
123
124 changeset: 5:c028bcc7a28a
125 user: test
126 date: Mon Jan 12 13:46:40 1970 +0000
127 summary: 5
128
129 changeset: 6:a0c0095f3389
130 user: test
131 date: Mon Jan 12 13:46:40 1970 +0000
132 summary: 6
133
134 changeset: 7:d4be65f4e891
135 user: test
136 date: Mon Jan 12 13:46:40 1970 +0000
137 summary: 7
138
139 changeset: 8:92b83e334ef8
140 tag: tip
141 user: test
142 date: Mon Jan 12 13:46:40 1970 +0000
143 summary: 8
144
145 changeset: 0:9cb21d99fe27
146 user: test
147 date: Mon Jan 12 13:46:40 1970 +0000
148 summary: 0
149
150 changeset: 1:d717f5dfad6a
151 user: test
152 date: Mon Jan 12 13:46:40 1970 +0000
153 summary: 1
154
155 changeset: 2:c0d6b86da426
156 user: test
157 date: Mon Jan 12 13:46:40 1970 +0000
158 summary: 2
159
160 changeset: 3:dfacbd43b3fe
161 user: test
162 date: Mon Jan 12 13:46:40 1970 +0000
163 summary: 3
164
165 changeset: 4:1f3a964b6022
166 user: test
167 date: Mon Jan 12 13:46:40 1970 +0000
168 summary: 4
169
170 changeset: 5:c028bcc7a28a
171 user: test
172 date: Mon Jan 12 13:46:40 1970 +0000
173 summary: 5
174
175 changeset: 6:a0c0095f3389
176 user: test
177 date: Mon Jan 12 13:46:40 1970 +0000
178 summary: 6
179
180 changeset: 7:d4be65f4e891
181 user: test
182 date: Mon Jan 12 13:46:40 1970 +0000
183 summary: 7
184
185 changeset: 8:92b83e334ef8
186 tag: tip
187 user: test
188 date: Mon Jan 12 13:46:40 1970 +0000
189 summary: 8
190
191 adding changesets
192 adding manifests
193 adding file changes
194 added 9 changesets with 9 changes to 1 files
195 (run 'hg update' to get a working copy)
196 adding changesets
197 adding manifests
198 adding file changes
199 added 9 changesets with 9 changes to 1 files
200 (run 'hg update' to get a working copy)
201 changeset: 8:92b83e334ef8
202 tag: tip
203 user: test
204 date: Mon Jan 12 13:46:40 1970 +0000
205 summary: 8
206
207 changeset: 8:92b83e334ef8
208 tag: tip
209 user: test
210 date: Mon Jan 12 13:46:40 1970 +0000
211 summary: 8
212
213 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
214 checking changesets
215 checking manifests
216 crosschecking files in changesets and manifests
217 checking files
218 1 files, 14 changesets, 14 total revisions
219 searching for changes
220 changeset: 9:3741c3ad1096
221 user: test
222 date: Mon Jan 12 13:46:40 1970 +0000
223 summary: 9
224
225 changeset: 10:de4143c8d9a5
226 user: test
227 date: Mon Jan 12 13:46:40 1970 +0000
228 summary: 10
229
230 changeset: 11:0e1c188b9a7a
231 user: test
232 date: Mon Jan 12 13:46:40 1970 +0000
233 summary: 11
234
235 changeset: 12:251354d0fdd3
236 user: test
237 date: Mon Jan 12 13:46:40 1970 +0000
238 summary: 12
239
240 changeset: 13:bdaadd969642
241 tag: tip
242 user: test
243 date: Mon Jan 12 13:46:40 1970 +0000
244 summary: 13
245
246 searching for changes
247 changeset: 9:3741c3ad1096
248 user: test
249 date: Mon Jan 12 13:46:40 1970 +0000
250 summary: 9
251
252 changeset: 10:de4143c8d9a5
253 user: test
254 date: Mon Jan 12 13:46:40 1970 +0000
255 summary: 10
256
257 changeset: 11:0e1c188b9a7a
258 user: test
259 date: Mon Jan 12 13:46:40 1970 +0000
260 summary: 11
261
262 changeset: 12:251354d0fdd3
263 user: test
264 date: Mon Jan 12 13:46:40 1970 +0000
265 summary: 12
266
267 changeset: 13:bdaadd969642
268 tag: tip
269 user: test
270 date: Mon Jan 12 13:46:40 1970 +0000
271 summary: 13
272
@@ -10,3 +10,4 b' eac9c8efcd9bd8244e72fb6821f769f450457a32'
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
10 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
11 3a56574f329a368d645853e0f9e09472aee62349 0.8
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
12 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1
13 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9
@@ -2,7 +2,25 b' PREFIX=/usr/local'
2 export PREFIX
2 export PREFIX
3 PYTHON=python
3 PYTHON=python
4
4
5 all: local build doc
5 help:
6 @echo 'Commonly used make targets:'
7 @echo ' all - build program and documentation'
8 @echo ' install - install program and man pages to PREFIX ($(PREFIX))'
9 @echo ' install-home - install with setup.py install --home=HOME ($(HOME))'
10 @echo ' local - build C extensions for inplace usage'
11 @echo ' tests - run all tests in the automatic test suite'
12 @echo ' test-foo - run only specified tests (e.g. test-merge1)'
13 @echo ' dist - run all tests and create a source tarball in dist/'
14 @echo ' clean - remove files created by other targets'
15 @echo ' (except installed files or dist source tarball)'
16 @echo
17 @echo 'Example for a system-wide installation under /usr/local:'
18 @echo ' make all && su -c "make install" && hg version'
19 @echo
20 @echo 'Example for a local installation (usable in this directory):'
21 @echo ' make local && ./hg version'
22
23 all: build doc
6
24
7 local:
25 local:
8 $(PYTHON) setup.py build_ext -i
26 $(PYTHON) setup.py build_ext -i
@@ -16,6 +34,7 b' doc:'
16 clean:
34 clean:
17 -$(PYTHON) setup.py clean --all # ignore errors of this command
35 -$(PYTHON) setup.py clean --all # ignore errors of this command
18 find . -name '*.py[co]' -exec rm -f '{}' ';'
36 find . -name '*.py[co]' -exec rm -f '{}' ';'
37 rm -f MANIFEST mercurial/__version__.py mercurial/*.so tests/*.err
19 $(MAKE) -C doc clean
38 $(MAKE) -C doc clean
20
39
21 install: all
40 install: all
@@ -38,5 +57,5 b' test-%:'
38 cd tests && $(PYTHON) run-tests.py $@
57 cd tests && $(PYTHON) run-tests.py $@
39
58
40
59
41 .PHONY: all local build doc clean install install-home dist dist-notests tests
60 .PHONY: help all local build doc clean install install-home dist dist-notests tests
42
61
@@ -50,7 +50,7 b' class bundlerevlog(revlog.revlog):'
50 continue
50 continue
51 for p in (p1, p2):
51 for p in (p1, p2):
52 if not p in self.nodemap:
52 if not p in self.nodemap:
53 raise RevlogError(_("unknown parent %s") % short(p1))
53 raise revlog.RevlogError(_("unknown parent %s") % short(p1))
54 if linkmapper is None:
54 if linkmapper is None:
55 link = n
55 link = n
56 else:
56 else:
@@ -76,12 +76,12 b' class bundlerevlog(revlog.revlog):'
76 return False
76 return False
77 return rev in self.basemap
77 return rev in self.basemap
78 def bundlebase(self, rev): return self.basemap[rev]
78 def bundlebase(self, rev): return self.basemap[rev]
79 def chunk(self, rev, df=None):
79 def chunk(self, rev, df=None, cachelen=4096):
80 # Warning: in case of bundle, the diff is against bundlebase,
80 # Warning: in case of bundle, the diff is against bundlebase,
81 # not against rev - 1
81 # not against rev - 1
82 # XXX: could use some caching
82 # XXX: could use some caching
83 if not self.bundle(rev):
83 if not self.bundle(rev):
84 return revlog.revlog.chunk(self, rev)
84 return revlog.revlog.chunk(self, rev, df, cachelen)
85 self.bundlefile.seek(self.start(rev))
85 self.bundlefile.seek(self.start(rev))
86 return self.bundlefile.read(self.length(rev))
86 return self.bundlefile.read(self.length(rev))
87
87
@@ -123,8 +123,8 b' class bundlerevlog(revlog.revlog):'
123
123
124 p1, p2 = self.parents(node)
124 p1, p2 = self.parents(node)
125 if node != revlog.hash(text, p1, p2):
125 if node != revlog.hash(text, p1, p2):
126 raise RevlogError(_("integrity check failed on %s:%d")
126 raise revlog.RevlogError(_("integrity check failed on %s:%d")
127 % (self.datafile, self.rev(node)))
127 % (self.datafile, self.rev(node)))
128
128
129 self.cache = (node, self.rev(node), text)
129 self.cache = (node, self.rev(node), text)
130 return text
130 return text
@@ -160,7 +160,6 b' class bundlerepository(localrepo.localre'
160 def __init__(self, ui, path, bundlename):
160 def __init__(self, ui, path, bundlename):
161 localrepo.localrepository.__init__(self, ui, path)
161 localrepo.localrepository.__init__(self, ui, path)
162 f = open(bundlename, "rb")
162 f = open(bundlename, "rb")
163 s = util.fstat(f)
164 self.bundlefile = f
163 self.bundlefile = f
165 header = self.bundlefile.read(6)
164 header = self.bundlefile.read(6)
166 if not header.startswith("HG"):
165 if not header.startswith("HG"):
@@ -756,13 +756,20 b' def archive(ui, repo, dest, **opts):'
756 def backout(ui, repo, rev, **opts):
756 def backout(ui, repo, rev, **opts):
757 '''reverse effect of earlier changeset
757 '''reverse effect of earlier changeset
758
758
759 Commit the backed out changes as a new changeset.
759 Commit the backed out changes as a new changeset. The new
760 changeset is a child of the backed out changeset.
760
761
761 If you back out a changeset other than the tip, a new head is
762 If you back out a changeset other than the tip, a new head is
762 created. The --merge option remembers the parent of the working
763 created. This head is the parent of the working directory. If
763 directory before starting the backout, then merges the new head
764 you back out an old changeset, your working directory will appear
764 with it afterwards, to save you from doing this by hand. The
765 old after the backout. You should merge the backout changeset
765 result of this merge is not committed, as for a normal merge.'''
766 with another head.
767
768 The --merge option remembers the parent of the working directory
769 before starting the backout, then merges the new head with that
770 changeset afterwards. This saves you from doing the merge by
771 hand. The result of this merge is not committed, as for a normal
772 merge.'''
766
773
767 bail_if_changed(repo)
774 bail_if_changed(repo)
768 op1, op2 = repo.dirstate.parents()
775 op1, op2 = repo.dirstate.parents()
@@ -3021,7 +3028,7 b' table = {'
3021 "recover": (recover, [], _('hg recover')),
3028 "recover": (recover, [], _('hg recover')),
3022 "^remove|rm":
3029 "^remove|rm":
3023 (remove,
3030 (remove,
3024 [('', 'after', None, _('record remove that has already occurred')),
3031 [('A', 'after', None, _('record remove that has already occurred')),
3025 ('f', 'force', None, _('remove file even if modified')),
3032 ('f', 'force', None, _('remove file even if modified')),
3026 ('I', 'include', [], _('include names matching the given patterns')),
3033 ('I', 'include', [], _('include names matching the given patterns')),
3027 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
3034 ('X', 'exclude', [], _('exclude names matching the given patterns'))],
@@ -3096,7 +3103,7 b' table = {'
3096 [('u', 'update', None,
3103 [('u', 'update', None,
3097 _('update the working directory to tip after unbundle'))],
3104 _('update the working directory to tip after unbundle'))],
3098 _('hg unbundle [-u] FILE')),
3105 _('hg unbundle [-u] FILE')),
3099 "undo": (undo, [], _('hg undo')),
3106 "debugundo|undo": (undo, [], _('hg undo')),
3100 "^update|up|checkout|co":
3107 "^update|up|checkout|co":
3101 (update,
3108 (update,
3102 [('b', 'branch', '', _('checkout the head of a specific branch')),
3109 [('b', 'branch', '', _('checkout the head of a specific branch')),
@@ -1544,8 +1544,9 b' class localrepository(object):'
1544 " with %d changes to %d files%s\n")
1544 " with %d changes to %d files%s\n")
1545 % (changesets, revisions, files, heads))
1545 % (changesets, revisions, files, heads))
1546
1546
1547 self.hook('pretxnchangegroup', throw=True,
1547 if changesets > 0:
1548 node=hex(self.changelog.node(cor+1)), source=srctype)
1548 self.hook('pretxnchangegroup', throw=True,
1549 node=hex(self.changelog.node(cor+1)), source=srctype)
1549
1550
1550 tr.close()
1551 tr.close()
1551
1552
@@ -9,6 +9,15 b' from demandload import demandload'
9 import struct, bdiff, util, mpatch
9 import struct, bdiff, util, mpatch
10 demandload(globals(), "re")
10 demandload(globals(), "re")
11
11
12 def splitnewlines(text):
13 '''like str.splitlines, but only split on newlines.'''
14 lines = [l + '\n' for l in text.split('\n')]
15 if lines:
16 if lines[-1] == '\n':
17 lines.pop()
18 else:
19 lines[-1] = lines[-1][:-1]
20 return lines
12
21
13 def unidiff(a, ad, b, bd, fn, r=None, text=False,
22 def unidiff(a, ad, b, bd, fn, r=None, text=False,
14 showfunc=False, ignorews=False):
23 showfunc=False, ignorews=False):
@@ -19,7 +28,7 b' def unidiff(a, ad, b, bd, fn, r=None, te'
19 if not text and (util.binary(a) or util.binary(b)):
28 if not text and (util.binary(a) or util.binary(b)):
20 l = ['Binary file %s has changed\n' % fn]
29 l = ['Binary file %s has changed\n' % fn]
21 elif not a:
30 elif not a:
22 b = b.splitlines(1)
31 b = splitnewlines(b)
23 if a is None:
32 if a is None:
24 l1 = "--- %s\t%s\n" % ("/dev/null", epoch)
33 l1 = "--- %s\t%s\n" % ("/dev/null", epoch)
25 else:
34 else:
@@ -28,7 +37,7 b' def unidiff(a, ad, b, bd, fn, r=None, te'
28 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
37 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
29 l = [l1, l2, l3] + ["+" + e for e in b]
38 l = [l1, l2, l3] + ["+" + e for e in b]
30 elif not b:
39 elif not b:
31 a = a.splitlines(1)
40 a = splitnewlines(a)
32 l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
41 l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
33 if b is None:
42 if b is None:
34 l2 = "+++ %s\t%s\n" % ("/dev/null", epoch)
43 l2 = "+++ %s\t%s\n" % ("/dev/null", epoch)
@@ -37,8 +46,8 b' def unidiff(a, ad, b, bd, fn, r=None, te'
37 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
46 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
38 l = [l1, l2, l3] + ["-" + e for e in a]
47 l = [l1, l2, l3] + ["-" + e for e in a]
39 else:
48 else:
40 al = a.splitlines(1)
49 al = splitnewlines(a)
41 bl = b.splitlines(1)
50 bl = splitnewlines(b)
42 l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
51 l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
43 showfunc=showfunc, ignorews=ignorews))
52 showfunc=showfunc, ignorews=ignorews))
44 if not l: return ""
53 if not l: return ""
@@ -87,6 +87,13 b' class lazyparser(object):'
87 """
87 """
88 this class avoids the need to parse the entirety of large indices
88 this class avoids the need to parse the entirety of large indices
89 """
89 """
90
91 # lazyparser is not safe to use on windows if win32 extensions not
92 # available. it keeps file handle open, which make it not possible
93 # to break hardlinks on local cloned repos.
94 safe_to_use = os.name != 'nt' or (not util.is_win_9x() and
95 hasattr(util, 'win32api'))
96
90 def __init__(self, dataf, size, indexformat, shaoffset):
97 def __init__(self, dataf, size, indexformat, shaoffset):
91 self.dataf = dataf
98 self.dataf = dataf
92 self.format = indexformat
99 self.format = indexformat
@@ -362,18 +369,14 b' class revlog(object):'
362 shaoffset = ngshaoffset
369 shaoffset = ngshaoffset
363
370
364 if i:
371 if i:
365 if not self.inlinedata() and st and st.st_size > 10000:
372 if (lazyparser.safe_to_use and not self.inlinedata() and
373 st and st.st_size > 10000):
366 # big index, let's parse it on demand
374 # big index, let's parse it on demand
367 parser = lazyparser(f, st.st_size, self.indexformat, shaoffset)
375 parser = lazyparser(f, st.st_size, self.indexformat, shaoffset)
368 self.index = lazyindex(parser)
376 self.index = lazyindex(parser)
369 self.nodemap = lazymap(parser)
377 self.nodemap = lazymap(parser)
370 else:
378 else:
371 i = f.read()
379 self.parseindex(f, st)
372 self.parseindex(i)
373 if self.inlinedata():
374 # we've already got the entire data file read in, save it
375 # in the chunk data
376 self.chunkcache = (0, i)
377 if self.version != REVLOGV0:
380 if self.version != REVLOGV0:
378 e = list(self.index[0])
381 e = list(self.index[0])
379 type = self.ngtype(e[0])
382 type = self.ngtype(e[0])
@@ -384,22 +387,49 b' class revlog(object):'
384 self.index = []
387 self.index = []
385
388
386
389
387 def parseindex(self, data):
390 def parseindex(self, fp, st):
388 s = struct.calcsize(self.indexformat)
391 s = struct.calcsize(self.indexformat)
389 l = len(data)
390 self.index = []
392 self.index = []
391 self.nodemap = {nullid: -1}
393 self.nodemap = {nullid: -1}
392 inline = self.inlinedata()
394 inline = self.inlinedata()
393 off = 0
394 n = 0
395 n = 0
395 while off < l:
396 leftover = None
396 e = struct.unpack(self.indexformat, data[off:off + s])
397 while True:
397 self.index.append(e)
398 if st:
398 self.nodemap[e[-1]] = n
399 data = fp.read(65536)
399 n += 1
400 else:
400 off += s
401 # hack for httprangereader, it doesn't do partial reads well
401 if inline:
402 data = fp.read()
402 off += e[1]
403 if not data:
404 break
405 if n == 0 and self.inlinedata():
406 # cache the first chunk
407 self.chunkcache = (0, data)
408 off = 0
409 l = len(data)
410 while off < l:
411 if l - off < s:
412 leftover = data[off:]
413 break
414 if leftover:
415 cur = leftover + data[off:off + s - len(leftover)]
416 off += s - len(leftover)
417 leftover = None
418 else:
419 cur = data[off:off + s]
420 off += s
421 e = struct.unpack(self.indexformat, cur)
422 self.index.append(e)
423 self.nodemap[e[-1]] = n
424 n += 1
425 if inline:
426 off += e[1]
427 if off > l:
428 # some things don't seek well, just read it
429 fp.read(off - l)
430 if not st:
431 break
432
403
433
404 def ngoffset(self, q):
434 def ngoffset(self, q):
405 if q & 0xFFFF:
435 if q & 0xFFFF:
@@ -489,6 +489,13 b' def fstat(fp):'
489
489
490 posixfile = file
490 posixfile = file
491
491
492 def is_win_9x():
493 '''return true if run on windows 95, 98 or me.'''
494 try:
495 return sys.getwindowsversion()[3] == 1
496 except AttributeError:
497 return os.name == 'nt' and 'command' in os.environ.get('comspec', '')
498
492 # Platform specific variants
499 # Platform specific variants
493 if os.name == 'nt':
500 if os.name == 'nt':
494 demandload(globals(), "msvcrt")
501 demandload(globals(), "msvcrt")
@@ -570,6 +577,8 b" if os.name == 'nt':"
570 try:
577 try:
571 # override functions with win32 versions if possible
578 # override functions with win32 versions if possible
572 from util_win32 import *
579 from util_win32 import *
580 if not is_win_9x():
581 posixfile = posixfile_nt
573 except ImportError:
582 except ImportError:
574 pass
583 pass
575
584
@@ -183,11 +183,11 b' def system_rcpath_win32():'
183 filename = win32process.GetModuleFileNameEx(proc, 0)
183 filename = win32process.GetModuleFileNameEx(proc, 0)
184 return [os.path.join(os.path.dirname(filename), 'mercurial.ini')]
184 return [os.path.join(os.path.dirname(filename), 'mercurial.ini')]
185
185
186 class posixfile(object):
186 class posixfile_nt(object):
187 '''file object with posix-like semantics. on windows, normal
187 '''file object with posix-like semantics. on windows, normal
188 files can not be deleted or renamed if they are open. must open
188 files can not be deleted or renamed if they are open. must open
189 with win32file.FILE_SHARE_DELETE. this flag does not exist on
189 with win32file.FILE_SHARE_DELETE. this flag does not exist on
190 windows <= nt.'''
190 windows < nt, so do not use this class there.'''
191
191
192 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
192 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
193 # but does not work at all. wrap win32 file api instead.
193 # but does not work at all. wrap win32 file api instead.
@@ -220,6 +220,10 b' class posixfile(object):'
220 self.name = name
220 self.name = name
221 self.mode = mode
221 self.mode = mode
222
222
223 def __iter__(self):
224 for line in self.read().splitlines(True):
225 yield line
226
223 def read(self, count=-1):
227 def read(self, count=-1):
224 try:
228 try:
225 cs = cStringIO.StringIO()
229 cs = cStringIO.StringIO()
@@ -34,10 +34,25 b' def vlog(*msg):'
34 print m,
34 print m,
35 print
35 print
36
36
37 def splitnewlines(text):
38 '''like str.splitlines, but only split on newlines.
39 keep line endings.'''
40 i = 0
41 lines = []
42 while True:
43 n = text.find('\n', i)
44 if n == -1:
45 last = text[i:]
46 if last:
47 lines.append(last)
48 return lines
49 lines.append(text[i:n+1])
50 i = n + 1
51
37 def show_diff(expected, output):
52 def show_diff(expected, output):
38 for line in difflib.unified_diff(expected, output,
53 for line in difflib.unified_diff(expected, output,
39 "Expected output", "Test output", lineterm=''):
54 "Expected output", "Test output", lineterm=''):
40 print line
55 sys.stdout.write(line)
41
56
42 def find_program(program):
57 def find_program(program):
43 """Search PATH for a executable program"""
58 """Search PATH for a executable program"""
@@ -125,7 +140,7 b' def output_coverage():'
125 vlog("# Running: "+cmd)
140 vlog("# Running: "+cmd)
126 os.system(cmd)
141 os.system(cmd)
127
142
128 def run(cmd, split_lines=True):
143 def run(cmd):
129 """Run command in a sub-process, capturing the output (stdout and stderr).
144 """Run command in a sub-process, capturing the output (stdout and stderr).
130 Return the exist code, and output."""
145 Return the exist code, and output."""
131 # TODO: Use subprocess.Popen if we're running on Python 2.4
146 # TODO: Use subprocess.Popen if we're running on Python 2.4
@@ -141,9 +156,7 b' def run(cmd, split_lines=True):'
141 proc.tochild.close()
156 proc.tochild.close()
142 output = proc.fromchild.read()
157 output = proc.fromchild.read()
143 ret = proc.wait()
158 ret = proc.wait()
144 if split_lines:
159 return ret, splitnewlines(output)
145 output = output.splitlines()
146 return ret, output
147
160
148 def run_one(test):
161 def run_one(test):
149 vlog("# Test", test)
162 vlog("# Test", test)
@@ -180,22 +193,23 b' def run_one(test):'
180 # If reference output file exists, check test output against it
193 # If reference output file exists, check test output against it
181 if os.path.exists(ref):
194 if os.path.exists(ref):
182 f = open(ref, "r")
195 f = open(ref, "r")
183 ref_out = f.read().splitlines()
196 ref_out = splitnewlines(f.read())
184 f.close()
197 f.close()
185 if out != ref_out:
198 else:
186 diffret = 1
199 ref_out = ['']
187 print "\nERROR: %s output changed" % (test)
200 if out != ref_out:
188 show_diff(ref_out, out)
201 diffret = 1
202 print "\nERROR: %s output changed" % (test)
203 show_diff(ref_out, out)
189 if ret:
204 if ret:
190 print "\nERROR: %s failed with error code %d" % (test, ret)
205 print "\nERROR: %s failed with error code %d" % (test, ret)
191 elif diffret:
206 elif diffret:
192 ret = diffret
207 ret = diffret
193
208
194 if ret != 0: # Save errors to a file for diagnosis
209 if ret != 0: # Save errors to a file for diagnosis
195 f = open(err, "w")
210 f = open(err, "wb")
196 for line in out:
211 for line in out:
197 f.write(line)
212 f.write(line)
198 f.write("\n")
199 f.close()
213 f.close()
200
214
201 os.chdir(TESTDIR)
215 os.chdir(TESTDIR)
@@ -228,24 +242,28 b' PYTHONDIR = os.path.join(INST, "lib", "p'
228 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
242 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
229
243
230 try:
244 try:
231 install_hg()
245 try:
246 install_hg()
232
247
233 tests = 0
248 tests = 0
234 failed = 0
249 failed = 0
235
250
236 if len(args) == 0:
251 if len(args) == 0:
237 args = os.listdir(".")
252 args = os.listdir(".")
238 for test in args:
253 for test in args:
239 if test.startswith("test-"):
254 if test.startswith("test-"):
240 if '~' in test or re.search(r'\.(out|err)$', test):
255 if '~' in test or re.search(r'\.(out|err)$', test):
241 continue
256 continue
242 if not run_one(test):
257 if not run_one(test):
243 failed += 1
258 failed += 1
244 tests += 1
259 tests += 1
245
260
246 print "\n# Ran %d tests, %d failed." % (tests, failed)
261 print "\n# Ran %d tests, %d failed." % (tests, failed)
247 if coverage:
262 if coverage:
248 output_coverage()
263 output_coverage()
264 except KeyboardInterrupt:
265 failed = True
266 print "\ninterrupted!"
249 finally:
267 finally:
250 cleanup_exit()
268 cleanup_exit()
251
269
@@ -77,7 +77,6 b' list of commands (use "hg help -v" to sh'
77 tags list repository tags
77 tags list repository tags
78 tip show the tip revision
78 tip show the tip revision
79 unbundle apply a changegroup file
79 unbundle apply a changegroup file
80 undo undo the last commit or pull (DEPRECATED)
81 update update or merge working directory
80 update update or merge working directory
82 verify verify the integrity of the repository
81 verify verify the integrity of the repository
83 version output version and copyright information
82 version output version and copyright information
@@ -120,7 +119,6 b' list of commands (use "hg help -v" to sh'
120 tags list repository tags
119 tags list repository tags
121 tip show the tip revision
120 tip show the tip revision
122 unbundle apply a changegroup file
121 unbundle apply a changegroup file
123 undo undo the last commit or pull (DEPRECATED)
124 update update or merge working directory
122 update update or merge working directory
125 verify verify the integrity of the repository
123 verify verify the integrity of the repository
126 version output version and copyright information
124 version output version and copyright information
General Comments 0
You need to be logged in to leave comments. Login now