Status: | Merged |
---|---|
Approved by: | Vincent Ladeuil |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~vila/brz/trunk |
Merge into: | lp:brz |
Diff against target: |
637 lines (+270/-56) 20 files modified
breezy/__init__.py (+1/-1) breezy/_static_tuple_c.c (+73/-0) breezy/bzr/_dirstate_helpers_pyx.pyx (+13/-2) breezy/git/annotate.py (+2/-1) breezy/git/filegraph.py (+2/-2) breezy/git/remote.py (+5/-7) breezy/git/tests/test_blackbox.py (+22/-0) breezy/git/tests/test_remote.py (+10/-0) breezy/ignores.py (+2/-2) breezy/plugins/launchpad/lp_api.py (+0/-17) breezy/plugins/launchpad/lp_directory.py (+1/-1) breezy/plugins/launchpad/lp_registration.py (+1/-1) breezy/plugins/launchpad/test_lp_directory.py (+1/-1) breezy/plugins/launchpad/test_lp_service.py (+2/-2) breezy/plugins/launchpad/uris.py (+36/-0) breezy/tests/blackbox/test_testament.py (+10/-11) breezy/tests/test_ignores.py (+18/-0) breezy/tests/test_server.py (+5/-1) doc/en/release-notes/brz-3.0.txt (+65/-6) doc/en/release-notes/release-template.txt (+1/-1) |
To merge this branch: | bzr merge lp:~vila/brz/trunk |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Vincent Ladeuil | Approve | ||
Review via email: mp+375724@code.launchpad.net |
Commit message
Merge lp:brz/3.0 after 3.0.2 release.
Description of the change
Merge lp:brz/3.0
To post a comment you must log in.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/__init__.py' |
2 | --- breezy/__init__.py 2019-06-18 11:21:15 +0000 |
3 | +++ breezy/__init__.py 2019-11-19 20:09:35 +0000 |
4 | @@ -53,7 +53,7 @@ |
5 | # Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a |
6 | # releaselevel of 'dev' for unreleased under-development code. |
7 | |
8 | -version_info = (3, 1, 0, 'dev', 1) |
9 | +version_info = (3, 1, 0, 'dev', 0) |
10 | |
11 | |
12 | def _format_version_tuple(version_info): |
13 | |
14 | === modified file 'breezy/_static_tuple_c.c' |
15 | --- breezy/_static_tuple_c.c 2017-06-27 00:56:24 +0000 |
16 | +++ breezy/_static_tuple_c.c 2019-11-19 20:09:35 +0000 |
17 | @@ -320,6 +320,78 @@ |
18 | return result; |
19 | } |
20 | |
21 | +/* adapted from tuplehash(), is the specific hash value considered |
22 | + * 'stable'? |
23 | + */ |
24 | + |
25 | +#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8) |
26 | +/* Hash for tuples. This is a slightly simplified version of the xxHash |
27 | + non-cryptographic hash: |
28 | + - we do not use any parallellism, there is only 1 accumulator. |
29 | + - we drop the final mixing since this is just a permutation of the |
30 | + output space: it does not help against collisions. |
31 | + - at the end, we mangle the length with a single constant. |
32 | + For the xxHash specification, see |
33 | + https://github.com/Cyan4973/xxHash/blob/master/doc/xxhash_spec.md |
34 | + |
35 | + Below are the official constants from the xxHash specification. Optimizing |
36 | + compilers should emit a single "rotate" instruction for the |
37 | + _PyHASH_XXROTATE() expansion. If that doesn't happen for some important |
38 | + platform, the macro could be changed to expand to a platform-specific rotate |
39 | + spelling instead. |
40 | +*/ |
41 | +#if SIZEOF_PY_UHASH_T > 4 |
42 | +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) |
43 | +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) |
44 | +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) |
45 | +#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ |
46 | +#else |
47 | +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) |
48 | +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) |
49 | +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL) |
50 | +#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ |
51 | +#endif |
52 | + |
53 | +/* Tests have shown that it's not worth to cache the hash value, see |
54 | + https://bugs.python.org/issue9685 */ |
55 | +static Py_hash_t |
56 | +StaticTuple_hash(StaticTuple *self) |
57 | +{ |
58 | + Py_ssize_t i, len = self->size; |
59 | + PyObject **item = self->items; |
60 | + |
61 | +#if STATIC_TUPLE_HAS_HASH |
62 | + if (self->hash != -1) { |
63 | + return self->hash; |
64 | + } |
65 | +#endif |
66 | + |
67 | + Py_uhash_t acc = _PyHASH_XXPRIME_5; |
68 | + for (i = 0; i < len; i++) { |
69 | + Py_uhash_t lane = PyObject_Hash(item[i]); |
70 | + if (lane == (Py_uhash_t)-1) { |
71 | + return -1; |
72 | + } |
73 | + acc += lane * _PyHASH_XXPRIME_2; |
74 | + acc = _PyHASH_XXROTATE(acc); |
75 | + acc *= _PyHASH_XXPRIME_1; |
76 | + } |
77 | + |
78 | + /* Add input length, mangled to keep the historical value of hash(()). */ |
79 | + acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL); |
80 | + |
81 | + if (acc == (Py_uhash_t)-1) { |
82 | + acc = 1546275796; |
83 | + } |
84 | + |
85 | +#if STATIC_TUPLE_HAS_HASH |
86 | + self->hash = acc; |
87 | +#endif |
88 | + return acc; |
89 | +} |
90 | + |
91 | + |
92 | +#else |
93 | static long |
94 | StaticTuple_hash(StaticTuple *self) |
95 | { |
96 | @@ -357,6 +429,7 @@ |
97 | #endif |
98 | return x; |
99 | } |
100 | +#endif |
101 | |
102 | static PyObject * |
103 | StaticTuple_richcompare_to_tuple(StaticTuple *v, PyObject *wt, int op) |
104 | |
105 | === modified file 'breezy/bzr/_dirstate_helpers_pyx.pyx' |
106 | --- breezy/bzr/_dirstate_helpers_pyx.pyx 2019-09-22 02:25:23 +0000 |
107 | +++ breezy/bzr/_dirstate_helpers_pyx.pyx 2019-11-19 20:09:35 +0000 |
108 | @@ -109,6 +109,9 @@ |
109 | int PyBytes_Size(object p) |
110 | int PyBytes_GET_SIZE_void "PyBytes_GET_SIZE" (void *p) |
111 | int PyBytes_CheckExact(object p) |
112 | + int PyFloat_Check(object p) |
113 | + double PyFloat_AsDouble(object p) |
114 | + int PyLong_Check(object p) |
115 | void Py_INCREF(object o) |
116 | void Py_DECREF(object o) |
117 | |
118 | @@ -794,6 +797,14 @@ |
119 | _encode = binascii.b2a_base64 |
120 | |
121 | |
122 | +cdef unsigned long _time_to_unsigned(object t): # cannot_raise |
123 | + cdef double dt |
124 | + if PyFloat_Check(t): |
125 | + dt = PyFloat_AsDouble(t) |
126 | + return <unsigned long>dt |
127 | + return PyInt_AsUnsignedLongMask(t) |
128 | + |
129 | + |
130 | cdef _pack_stat(stat_value): |
131 | """return a string representing the stat value's key fields. |
132 | |
133 | @@ -805,8 +816,8 @@ |
134 | aliased = <int *>result |
135 | aliased[0] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_size)) |
136 | # mtime and ctime will often be floats but get converted to PyInt within |
137 | - aliased[1] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_mtime)) |
138 | - aliased[2] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_ctime)) |
139 | + aliased[1] = htonl(_time_to_unsigned(stat_value.st_mtime)) |
140 | + aliased[2] = htonl(_time_to_unsigned(stat_value.st_ctime)) |
141 | aliased[3] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_dev)) |
142 | aliased[4] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_ino)) |
143 | aliased[5] = htonl(PyInt_AsUnsignedLongMask(stat_value.st_mode)) |
144 | |
145 | === modified file 'breezy/git/annotate.py' |
146 | --- breezy/git/annotate.py 2018-11-11 14:23:06 +0000 |
147 | +++ breezy/git/annotate.py 2019-11-19 20:09:35 +0000 |
148 | @@ -100,11 +100,12 @@ |
149 | self.change_scanner.repository.lookup_bzr_revision_id( |
150 | text_revision)) |
151 | text_parents = [] |
152 | + path = path.encode('utf-8') |
153 | for commit_parent in self.store[commit_id].parents: |
154 | try: |
155 | (path, text_parent) = ( |
156 | self.change_scanner.find_last_change_revision( |
157 | - path.encode('utf-8'), commit_parent)) |
158 | + path, commit_parent)) |
159 | except KeyError: |
160 | continue |
161 | if text_parent not in text_parents: |
162 | |
163 | === modified file 'breezy/git/filegraph.py' |
164 | --- breezy/git/filegraph.py 2018-11-11 14:23:06 +0000 |
165 | +++ breezy/git/filegraph.py 2019-11-19 20:09:35 +0000 |
166 | @@ -84,7 +84,7 @@ |
167 | self.change_scanner.repository.lookup_bzr_revision_id( |
168 | text_revision)) |
169 | try: |
170 | - path = mapping.parse_file_id(file_id) |
171 | + path = mapping.parse_file_id(file_id).encode('utf-8') |
172 | except ValueError: |
173 | raise KeyError(file_id) |
174 | text_parents = [] |
175 | @@ -92,7 +92,7 @@ |
176 | try: |
177 | (path, text_parent) = ( |
178 | self.change_scanner.find_last_change_revision( |
179 | - path.encode('utf-8'), commit_parent)) |
180 | + path, commit_parent)) |
181 | except KeyError: |
182 | continue |
183 | if text_parent not in text_parents: |
184 | |
185 | === modified file 'breezy/git/remote.py' |
186 | --- breezy/git/remote.py 2019-08-11 16:27:38 +0000 |
187 | +++ breezy/git/remote.py 2019-11-19 20:09:35 +0000 |
188 | @@ -123,10 +123,10 @@ |
189 | |
190 | try: |
191 | import urllib.parse as urlparse |
192 | - from urllib.parse import splituser, splitnport |
193 | + from urllib.parse import splituser |
194 | except ImportError: |
195 | import urlparse |
196 | - from urllib import splituser, splitnport |
197 | + from urllib import splituser |
198 | |
199 | # urlparse only supports a limited number of schemes by default |
200 | register_urlparse_netloc_protocol('git') |
201 | @@ -165,13 +165,11 @@ |
202 | :param url: Git URL |
203 | :return: Tuple with host, port, username, path. |
204 | """ |
205 | - (scheme, netloc, loc, _, _) = urlparse.urlsplit(url) |
206 | - path = urlparse.unquote(loc) |
207 | + parsed_url = urlparse.urlparse(url) |
208 | + path = urlparse.unquote(parsed_url.path) |
209 | if path.startswith("/~"): |
210 | path = path[1:] |
211 | - (username, hostport) = splituser(netloc) |
212 | - (host, port) = splitnport(hostport, None) |
213 | - return (host, port, username, path) |
214 | + return ((parsed_url.hostname or '', parsed_url.port, parsed_url.username, path)) |
215 | |
216 | |
217 | class RemoteGitError(BzrError): |
218 | |
219 | === modified file 'breezy/git/tests/test_blackbox.py' |
220 | --- breezy/git/tests/test_blackbox.py 2019-06-22 18:46:21 +0000 |
221 | +++ breezy/git/tests/test_blackbox.py 2019-11-19 20:09:35 +0000 |
222 | @@ -216,6 +216,28 @@ |
223 | self.assertNotContainsRe(error, 'Committed revision 2.') |
224 | self.assertContainsRe(error, 'Committed revid .*.') |
225 | |
226 | + def test_log_file(self): |
227 | + # Smoke test for "bzr log" in a git repository. |
228 | + repo = GitRepo.init(self.test_dir) |
229 | + builder = tests.GitBranchBuilder() |
230 | + builder.set_file('a', b'text for a\n', False) |
231 | + r1 = builder.commit(b'Joe Foo <joe@foo.com>', u'First') |
232 | + builder.set_file('a', b'text 3a for a\n', False) |
233 | + r2a = builder.commit(b'Joe Foo <joe@foo.com>', u'Second a', base=r1) |
234 | + builder.set_file('a', b'text 3b for a\n', False) |
235 | + r2b = builder.commit(b'Joe Foo <joe@foo.com>', u'Second b', base=r1) |
236 | + builder.set_file('a', b'text 4 for a\n', False) |
237 | + builder.commit(b'Joe Foo <joe@foo.com>', u'Third', merge=[r2a], base=r2b) |
238 | + builder.finish() |
239 | + |
240 | + # Check that bzr log does not fail and includes the revision. |
241 | + output, error = self.run_bzr(['log', '-n2', 'a']) |
242 | + self.assertEqual(error, '') |
243 | + self.assertIn('Second a', output) |
244 | + self.assertIn('Second b', output) |
245 | + self.assertIn('First', output) |
246 | + self.assertIn('Third', output) |
247 | + |
248 | def test_tags(self): |
249 | git_repo, commit_sha1 = self.simple_commit() |
250 | git_repo.refs[b"refs/tags/foo"] = commit_sha1 |
251 | |
252 | === modified file 'breezy/git/tests/test_remote.py' |
253 | --- breezy/git/tests/test_remote.py 2019-08-06 07:11:09 +0000 |
254 | +++ breezy/git/tests/test_remote.py 2019-11-19 20:09:35 +0000 |
255 | @@ -65,6 +65,11 @@ |
256 | self.assertEqual(("foo", None, "la", "/bar"), |
257 | split_git_url("git://la@foo/bar")) |
258 | |
259 | + def test_username_password(self): |
260 | + self.assertEqual( |
261 | + ("foo", None, "la", "/bar"), |
262 | + split_git_url("git://la:passwd@foo/bar")) |
263 | + |
264 | def test_nopath(self): |
265 | self.assertEqual(("foo", None, None, "/"), |
266 | split_git_url("git://foo/")) |
267 | @@ -77,6 +82,11 @@ |
268 | self.assertEqual(("foo", None, None, "~bar"), |
269 | split_git_url("git://foo/~bar")) |
270 | |
271 | + def test_file(self): |
272 | + self.assertEqual( |
273 | + ("", None, None, "/bar"), |
274 | + split_git_url("file:///bar")) |
275 | + |
276 | |
277 | class ParseGitErrorTests(TestCase): |
278 | |
279 | |
280 | === modified file 'breezy/ignores.py' |
281 | --- breezy/ignores.py 2019-06-16 01:03:51 +0000 |
282 | +++ breezy/ignores.py 2019-11-19 20:09:35 +0000 |
283 | @@ -101,8 +101,8 @@ |
284 | # since get_* should be a safe operation |
285 | try: |
286 | _set_user_ignores(USER_DEFAULTS) |
287 | - except (IOError, OSError) as e: |
288 | - if e.errno not in (errno.EPERM,): |
289 | + except EnvironmentError as e: |
290 | + if e.errno not in (errno.EPERM, errno.ENOENT): |
291 | raise |
292 | return patterns |
293 | |
294 | |
295 | === modified file 'breezy/plugins/launchpad/lp_api.py' |
296 | --- breezy/plugins/launchpad/lp_api.py 2019-07-15 23:23:48 +0000 |
297 | +++ breezy/plugins/launchpad/lp_api.py 2019-11-19 20:09:35 +0000 |
298 | @@ -69,23 +69,6 @@ |
299 | MINIMUM_LAUNCHPADLIB_VERSION = (1, 6, 3) |
300 | |
301 | |
302 | -# We use production as the default because edge has been deprecated circa |
303 | -# 2010-11 (see bug https://bugs.launchpad.net/bzr/+bug/583667) |
304 | -DEFAULT_INSTANCE = 'production' |
305 | - |
306 | -LAUNCHPAD_DOMAINS = { |
307 | - 'production': 'launchpad.net', |
308 | - 'staging': 'staging.launchpad.net', |
309 | - 'qastaging': 'qastaging.launchpad.net', |
310 | - 'demo': 'demo.launchpad.net', |
311 | - 'dev': 'launchpad.test', |
312 | - } |
313 | - |
314 | -LAUNCHPAD_BAZAAR_DOMAINS = [ |
315 | - 'bazaar.%s' % domain |
316 | - for domain in LAUNCHPAD_DOMAINS.values()] |
317 | - |
318 | - |
319 | def get_cache_directory(): |
320 | """Return the directory to cache launchpadlib objects in.""" |
321 | return osutils.pathjoin(bedding.cache_dir(), 'launchpad') |
322 | |
323 | === modified file 'breezy/plugins/launchpad/lp_directory.py' |
324 | --- breezy/plugins/launchpad/lp_directory.py 2019-05-29 09:48:08 +0000 |
325 | +++ breezy/plugins/launchpad/lp_directory.py 2019-11-19 20:09:35 +0000 |
326 | @@ -35,7 +35,7 @@ |
327 | ) |
328 | from ...i18n import gettext |
329 | |
330 | -from .lp_api import ( |
331 | +from .uris import ( |
332 | DEFAULT_INSTANCE, |
333 | LAUNCHPAD_DOMAINS, |
334 | ) |
335 | |
336 | === modified file 'breezy/plugins/launchpad/lp_registration.py' |
337 | --- breezy/plugins/launchpad/lp_registration.py 2019-05-20 02:22:19 +0000 |
338 | +++ breezy/plugins/launchpad/lp_registration.py 2019-11-19 20:09:35 +0000 |
339 | @@ -48,7 +48,7 @@ |
340 | ) |
341 | from ...transport import http, get_transport |
342 | |
343 | -from .lp_api import ( |
344 | +from .uris import ( |
345 | DEFAULT_INSTANCE, |
346 | LAUNCHPAD_DOMAINS, |
347 | LAUNCHPAD_BAZAAR_DOMAINS, |
348 | |
349 | === modified file 'breezy/plugins/launchpad/test_lp_directory.py' |
350 | --- breezy/plugins/launchpad/test_lp_directory.py 2019-05-29 09:48:08 +0000 |
351 | +++ breezy/plugins/launchpad/test_lp_directory.py 2019-11-19 20:09:35 +0000 |
352 | @@ -213,7 +213,7 @@ |
353 | 'lp:///apt') |
354 | self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt', |
355 | 'lp://production/apt') |
356 | - self.assertResolve('bzr+ssh://bazaar.launchpad.test/+branch/apt', |
357 | + self.assertResolve('bzr+ssh://bazaar.launchpad.dev/+branch/apt', |
358 | 'lp://dev/apt') |
359 | self.assertResolve('bzr+ssh://bazaar.staging.launchpad.net/+branch/apt', |
360 | 'lp://staging/apt') |
361 | |
362 | === modified file 'breezy/plugins/launchpad/test_lp_service.py' |
363 | --- breezy/plugins/launchpad/test_lp_service.py 2019-05-29 09:48:08 +0000 |
364 | +++ breezy/plugins/launchpad/test_lp_service.py 2019-11-19 20:09:35 +0000 |
365 | @@ -62,7 +62,7 @@ |
366 | |
367 | def test_dev_service(self): |
368 | service = LaunchpadService(lp_instance='dev') |
369 | - self.assertEqual('https://xmlrpc.launchpad.test/bazaar/', |
370 | + self.assertEqual('https://xmlrpc.launchpad.dev/bazaar/', |
371 | service.service_url) |
372 | |
373 | def test_demo_service(self): |
374 | @@ -178,7 +178,7 @@ |
375 | web_url = service.get_web_url_from_branch_url( |
376 | 'bzr+ssh://bazaar.launchpad.net/~foo/bar/baz') |
377 | self.assertEqual( |
378 | - 'https://code.launchpad.test/~foo/bar/baz', web_url) |
379 | + 'https://code.launchpad.dev/~foo/bar/baz', web_url) |
380 | |
381 | def test_demo_url(self): |
382 | service = LaunchpadService(lp_instance='demo') |
383 | |
384 | === added file 'breezy/plugins/launchpad/uris.py' |
385 | --- breezy/plugins/launchpad/uris.py 1970-01-01 00:00:00 +0000 |
386 | +++ breezy/plugins/launchpad/uris.py 2019-11-19 20:09:35 +0000 |
387 | @@ -0,0 +1,36 @@ |
388 | +# Copyright (C) 2009-2012 Canonical Ltd |
389 | +# |
390 | +# This program is free software; you can redistribute it and/or modify |
391 | +# it under the terms of the GNU General Public License as published by |
392 | +# the Free Software Foundation; either version 2 of the License, or |
393 | +# (at your option) any later version. |
394 | +# |
395 | +# This program is distributed in the hope that it will be useful, |
396 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
397 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
398 | +# GNU General Public License for more details. |
399 | +# |
400 | +# You should have received a copy of the GNU General Public License |
401 | +# along with this program; if not, write to the Free Software |
402 | +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
403 | + |
404 | +"""Launchpad URIs.""" |
405 | + |
406 | +from __future__ import absolute_import |
407 | + |
408 | + |
409 | +# We use production as the default because edge has been deprecated circa |
410 | +# 2010-11 (see bug https://bugs.launchpad.net/bzr/+bug/583667) |
411 | +DEFAULT_INSTANCE = 'production' |
412 | + |
413 | +LAUNCHPAD_DOMAINS = { |
414 | + 'production': 'launchpad.net', |
415 | + 'staging': 'staging.launchpad.net', |
416 | + 'qastaging': 'qastaging.launchpad.net', |
417 | + 'demo': 'demo.launchpad.net', |
418 | + 'dev': 'launchpad.dev', |
419 | + } |
420 | + |
421 | +LAUNCHPAD_BAZAAR_DOMAINS = [ |
422 | + 'bazaar.%s' % domain |
423 | + for domain in LAUNCHPAD_DOMAINS.values()] |
424 | |
425 | === modified file 'breezy/tests/blackbox/test_testament.py' |
426 | --- breezy/tests/blackbox/test_testament.py 2018-11-11 04:08:32 +0000 |
427 | +++ breezy/tests/blackbox/test_testament.py 2019-11-19 20:09:35 +0000 |
428 | @@ -35,28 +35,27 @@ |
429 | """Testament containing a file and a directory.""" |
430 | out, err = self.run_bzr('testament --long') |
431 | self.assertEqualDiff(err, '') |
432 | - self.assertEqualDiff(out, REV_2_TESTAMENT.decode('utf-8')) |
433 | + self.assertEqualDiff(out, REV_2_TESTAMENT.decode('ascii')) |
434 | |
435 | def test_testament_command_2(self): |
436 | """Command getting short testament of previous version.""" |
437 | out, err = self.run_bzr('testament -r1') |
438 | self.assertEqualDiff(err, '') |
439 | - self.assertEqualDiff(out, REV_1_SHORT.decode('utf-8')) |
440 | + self.assertEqualDiff(out, REV_1_SHORT.decode('ascii')) |
441 | |
442 | def test_testament_command_3(self): |
443 | """Command getting short testament of previous version.""" |
444 | out, err = self.run_bzr('testament -r1 --strict') |
445 | self.assertEqualDiff(err, '') |
446 | - self.assertEqualDiff(out, REV_1_SHORT_STRICT.decode('utf-8')) |
447 | + self.assertEqualDiff(out, REV_1_SHORT_STRICT.decode('ascii')) |
448 | |
449 | def test_testament_non_ascii(self): |
450 | self.wt.commit(u"Non \xe5ssci message") |
451 | - long_out, err = self.run_bzr('testament --long') |
452 | - self.assertEqualDiff(err, '') |
453 | - short_out, err = self.run_bzr('testament') |
454 | - self.assertEqualDiff(err, '') |
455 | - sha1_re = re.compile('sha1: (?P<sha1>[a-f0-9]+)$', re.M) |
456 | + long_out, err = self.run_bzr_raw('testament --long', encoding='utf-8') |
457 | + self.assertEqualDiff(err, b'') |
458 | + long_out, err = self.run_bzr_raw('testament --long', encoding='ascii') |
459 | + short_out, err = self.run_bzr_raw('testament', encoding='ascii') |
460 | + self.assertEqualDiff(err, b'') |
461 | + sha1_re = re.compile(b'sha1: (?P<sha1>[a-f0-9]+)$', re.M) |
462 | sha1 = sha1_re.search(short_out).group('sha1') |
463 | - self.assertEqual( |
464 | - sha1.encode('ascii'), |
465 | - osutils.sha_string(long_out.encode('utf-8') if PY3 else long_out)) |
466 | + self.assertEqual(sha1, osutils.sha_string(long_out)) |
467 | |
468 | === modified file 'breezy/tests/test_ignores.py' |
469 | --- breezy/tests/test_ignores.py 2019-06-16 01:03:51 +0000 |
470 | +++ breezy/tests/test_ignores.py 2019-11-19 20:09:35 +0000 |
471 | @@ -16,6 +16,8 @@ |
472 | |
473 | """Tests for handling of ignore files""" |
474 | |
475 | +import os |
476 | + |
477 | from .. import ( |
478 | bedding, |
479 | ignores, |
480 | @@ -86,6 +88,22 @@ |
481 | entries = ignores.parse_ignore_file(f) |
482 | self.assertEqual(set(ignores.USER_DEFAULTS), entries) |
483 | |
484 | + def test_create_with_intermediate_missing(self): |
485 | + # $HOME should be set to '.' |
486 | + ignore_path = bedding.user_ignore_config_path() |
487 | + self.assertPathDoesNotExist(ignore_path) |
488 | + os.mkdir('empty-home') |
489 | + |
490 | + config_path = os.path.join(self.test_dir, 'empty-home', '.config') |
491 | + self.overrideEnv('BRZ_HOME', config_path) |
492 | + self.assertPathDoesNotExist(config_path) |
493 | + |
494 | + user_ignores = ignores.get_user_ignores() |
495 | + self.assertEqual(set(ignores.USER_DEFAULTS), user_ignores) |
496 | + |
497 | + ignore_path = bedding.user_ignore_config_path() |
498 | + self.assertPathDoesNotExist(ignore_path) |
499 | + |
500 | def test_use_existing(self): |
501 | patterns = [u'*.o', u'*.py[co]', u'\xe5*'] |
502 | ignores._set_user_ignores(patterns) |
503 | |
504 | === modified file 'breezy/tests/test_server.py' |
505 | --- breezy/tests/test_server.py 2018-11-12 01:41:38 +0000 |
506 | +++ breezy/tests/test_server.py 2019-11-19 20:09:35 +0000 |
507 | @@ -249,6 +249,10 @@ |
508 | |
509 | class TestThread(cethread.CatchingExceptionThread): |
510 | |
511 | + if not getattr(cethread.CatchingExceptionThread, 'is_alive', None): |
512 | + def is_alive(self): |
513 | + return self.isAlive() |
514 | + |
515 | def join(self, timeout=5): |
516 | """Overrides to use a default timeout. |
517 | |
518 | @@ -256,7 +260,7 @@ |
519 | serving a client connection is hung. |
520 | """ |
521 | super(TestThread, self).join(timeout) |
522 | - if timeout and self.isAlive(): |
523 | + if timeout and self.is_alive(): |
524 | # The timeout expired without joining the thread, the thread is |
525 | # therefore stucked and that's a failure as far as the test is |
526 | # concerned. We used to hang here. |
527 | |
528 | === modified file 'doc/en/release-notes/brz-3.0.txt' |
529 | --- doc/en/release-notes/brz-3.0.txt 2019-10-14 00:07:00 +0000 |
530 | +++ doc/en/release-notes/brz-3.0.txt 2019-11-19 20:09:35 +0000 |
531 | @@ -5,10 +5,10 @@ |
532 | .. toctree:: |
533 | :maxdepth: 1 |
534 | |
535 | -brz 3.0.2 |
536 | +brz 3.0.3 |
537 | ######### |
538 | |
539 | -:3.0.2: NOT RELEASED YET |
540 | +:3.0.3: NOT RELEASED YET |
541 | |
542 | External Compatibility Breaks |
543 | ***************************** |
544 | @@ -32,10 +32,6 @@ |
545 | .. Fixes for situations where brz would previously crash or give incorrect |
546 | or undesirable results. |
547 | |
548 | - * Disable loading from entrypoints by default, since it can |
549 | - significantly slow down startup on some platforms. |
550 | - (Jelmer Vernooij, #1832868) |
551 | - |
552 | Documentation |
553 | ************* |
554 | |
555 | @@ -61,6 +57,69 @@ |
556 | spurious test failures and changes to the way things should be tested. |
557 | |
558 | |
559 | +brz 3.0.2 |
560 | +######### |
561 | + |
562 | +:3.0.2: 2019-11-19 |
563 | + |
564 | +External Compatibility Breaks |
565 | +***************************** |
566 | + |
567 | +None. |
568 | + |
569 | +New Features |
570 | +************ |
571 | + |
572 | +None. |
573 | + |
574 | +Improvements |
575 | +************ |
576 | + |
577 | +None. |
578 | + |
579 | +Bug Fixes |
580 | +********* |
581 | + |
582 | + * Disable loading from entrypoints by default, since it can |
583 | + significantly slow down startup on some platforms. |
584 | + (Jelmer Vernooij, #1832868) |
585 | + |
586 | + * Don't fail when unable to write per-user ignore list due to |
587 | + one of the intermediate directories not existing |
588 | + (Jelmer Vernooij, #1851904) |
589 | + |
590 | + * Fix file graph operations on Git repositories. |
591 | + (Jelmer Vernooij, #1847913) |
592 | + |
593 | + * Allow running tests without launchpadlib installed. |
594 | + (Jelmer Vernooij, #1849988) |
595 | + |
596 | + * Fix compatibility with Python 3.8. |
597 | + (Jelmer Vernooij, Victor Stinner, #1844684) |
598 | + |
599 | +Documentation |
600 | +************* |
601 | + |
602 | +None |
603 | + |
604 | +API Changes |
605 | +*********** |
606 | + |
607 | +None. |
608 | + |
609 | +Internals |
610 | +********* |
611 | + |
612 | +None. |
613 | + |
614 | +Testing |
615 | +******* |
616 | + |
617 | + * Fix bb.test_testament.TestTestament.test_testament_non_ascii |
618 | + when the host encoding is non-utf8. |
619 | + (Jelmer Vernooij, #1849986) |
620 | + |
621 | + |
622 | bzr 3.0.1 |
623 | ######### |
624 | |
625 | |
626 | === modified file 'doc/en/release-notes/release-template.txt' |
627 | --- doc/en/release-notes/release-template.txt 2017-05-21 18:10:28 +0000 |
628 | +++ doc/en/release-notes/release-template.txt 2019-11-19 20:09:35 +0000 |
629 | @@ -2,7 +2,7 @@ |
630 | ######### |
631 | |
632 | :Codename: Nirvana |
633 | -:2.x.y: NOT RELEASED YET |
634 | +:3.y.z: NOT RELEASED YET |
635 | |
636 | External Compatibility Breaks |
637 | ***************************** |
RM self-approval.