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. Th |
|
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 |
|
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 |
|
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 |
|
49 | al = splitnewlines(a) | |
41 |
bl = b |
|
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 |
|
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, |
|
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 |
|
|
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 |
|
35 | |||
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 |
|
|
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() |
|
196 | ref_out = splitnewlines(f.read()) | |
184 | f.close() |
|
197 | f.close() | |
185 | if out != ref_out: |
|
198 | else: | |
186 |
|
|
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