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: |
1624 lines (+483/-193) 42 files modified
.bzrignore (+1/-0) breezy/__init__.py (+1/-1) breezy/builtins.py (+35/-26) breezy/git/cache.py (+1/-3) breezy/git/git-remote-bzr (+7/-2) breezy/git/git_remote_helper.py (+1/-1) breezy/git/memorytree.py (+4/-0) breezy/git/object_store.py (+2/-2) breezy/git/tests/test_blackbox.py (+9/-0) breezy/git/tests/test_branch.py (+7/-1) breezy/git/tests/test_git_remote_helper.py (+31/-2) breezy/git/tests/test_object_store.py (+30/-2) breezy/globbing.py (+3/-1) breezy/ignores.py (+1/-1) breezy/memorytree.py (+18/-4) breezy/plugins/propose/launchpad.py (+1/-0) breezy/tests/blackbox/test_push.py (+20/-0) breezy/tests/blackbox/test_uncommit.py (+14/-0) breezy/tests/features.py (+14/-0) breezy/tests/test_memorytree.py (+65/-70) breezy/tests/test_urlutils.py (+3/-0) breezy/transport/memory.py (+50/-32) breezy/urlutils.py (+4/-1) brz (+1/-1) byov.conf (+4/-2) doc/developers/apport.txt (+1/-1) doc/developers/configuration.txt (+0/-14) doc/developers/contribution-quickstart.txt (+1/-1) doc/developers/plugin-development.txt (+1/-1) doc/en/admin-guide/hooks-plugins.txt (+4/-4) doc/en/admin-guide/migration.txt (+1/-1) doc/en/index.txt (+1/-1) doc/en/release-notes/brz-3.0.txt (+16/-6) doc/en/release-notes/brz-3.1.txt (+62/-0) doc/en/user-guide/controlling_registration.txt (+3/-3) doc/en/user-guide/git_limitations.txt (+18/-0) doc/en/user-guide/index-plain.txt (+1/-0) doc/en/user-guide/installing_breezy.txt (+1/-1) doc/en/user-guide/plugins.txt (+2/-2) doc/en/whats-new/template.txt (+3/-3) doc/en/whats-new/whats-new-in-3.1.txt (+22/-0) setup.py (+19/-3) |
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+364041@code.launchpad.net |
Commit message
Open trunk again as 3.1.0dev1
Description of the change
To post a comment you must log in.
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
There was nothing to merge
https:/
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2018-11-18 18:55:35 +0000 |
3 | +++ .bzrignore 2019-03-06 14:35:55 +0000 |
4 | @@ -2,6 +2,7 @@ |
5 | # These are created as byproducts of our test suite |
6 | ./test*.tmp |
7 | ./.python-eggs |
8 | +./breezy.egg-info |
9 | ./.bzr.log |
10 | # Generated files |
11 | CHANGELOG |
12 | |
13 | === modified file 'breezy/__init__.py' |
14 | --- breezy/__init__.py 2019-01-14 01:27:55 +0000 |
15 | +++ breezy/__init__.py 2019-03-06 14:35:55 +0000 |
16 | @@ -50,7 +50,7 @@ |
17 | # Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a |
18 | # releaselevel of 'dev' for unreleased under-development code. |
19 | |
20 | -version_info = (3, 0, 0, 'beta', 1) |
21 | +version_info = (3, 1, 0, 'dev', 1) |
22 | |
23 | |
24 | def _format_version_tuple(version_info): |
25 | |
26 | === modified file 'breezy/builtins.py' |
27 | --- breezy/builtins.py 2019-02-09 03:23:20 +0000 |
28 | +++ breezy/builtins.py 2019-03-06 14:35:55 +0000 |
29 | @@ -348,7 +348,7 @@ |
30 | Not versioned and not matching an ignore pattern. |
31 | |
32 | Additionally for directories, symlinks and files with a changed |
33 | - executable bit, Bazaar indicates their type using a trailing |
34 | + executable bit, Breezy indicates their type using a trailing |
35 | character: '/', '@' or '*' respectively. These decorations can be |
36 | disabled using the '--no-classify' option. |
37 | |
38 | @@ -454,11 +454,11 @@ |
39 | |
40 | b = controldir.ControlDir.open_containing_tree_or_branch(directory)[1] |
41 | |
42 | - revisions = b.repository.revisions |
43 | + revisions = getattr(b.repository, "revisions", None) |
44 | if revisions is None: |
45 | raise errors.BzrCommandError( |
46 | gettext('Repository %r does not support ' |
47 | - 'access to raw revision texts')) |
48 | + 'access to raw revision texts') % b.repository) |
49 | |
50 | with b.repository.lock_read(): |
51 | # TODO: jam 20060112 should cat-revision always output utf-8? |
52 | @@ -1344,6 +1344,7 @@ |
53 | use_existing_dir=False, directory=None, stacked_on=None, |
54 | stacked=False, strict=None, no_tree=False, |
55 | overwrite_tags=False, lossy=False): |
56 | + from .location import location_to_url |
57 | from .push import _show_push_branch |
58 | |
59 | if overwrite: |
60 | @@ -1371,6 +1372,7 @@ |
61 | more_warning='Uncommitted changes will not be pushed.') |
62 | # Get the stacked_on branch, if any |
63 | if stacked_on is not None: |
64 | + stacked_on = location_to_url(stacked_on, 'read') |
65 | stacked_on = urlutils.normalize_url(stacked_on) |
66 | elif stacked: |
67 | parent_url = br_from.get_parent() |
68 | @@ -1728,7 +1730,7 @@ |
69 | If the tree's branch is bound to a master branch, brz will also update |
70 | the branch from the master. |
71 | |
72 | - You cannot update just a single file or directory, because each Bazaar |
73 | + You cannot update just a single file or directory, because each Breezy |
74 | working tree has just a single basis revision. If you want to restore a |
75 | file that has been removed locally, use 'brz revert' instead of 'brz |
76 | update'. If you want to restore a file to its state in a previous |
77 | @@ -1871,11 +1873,11 @@ |
78 | class cmd_remove(Command): |
79 | __doc__ = """Remove files or directories. |
80 | |
81 | - This makes Bazaar stop tracking changes to the specified files. Bazaar will |
82 | + This makes Breezy stop tracking changes to the specified files. Breezy will |
83 | delete them if they can easily be recovered using revert otherwise they |
84 | will be backed up (adding an extension of the form .~#~). If no options or |
85 | - parameters are given Bazaar will scan for files that are being tracked by |
86 | - Bazaar but missing in your tree and stop tracking them for you. |
87 | + parameters are given Breezy will scan for files that are being tracked by |
88 | + Breezy but missing in your tree and stop tracking them for you. |
89 | """ |
90 | takes_args = ['file*'] |
91 | takes_options = ['verbose', |
92 | @@ -3091,9 +3093,10 @@ |
93 | using this command or directly by using an editor, be sure to commit |
94 | it. |
95 | |
96 | - Bazaar also supports a global ignore file ~/.bazaar/ignore. On Windows |
97 | - the global ignore file can be found in the application data directory as |
98 | - C:\\Documents and Settings\\<user>\\Application Data\\Bazaar\\2.0\\ignore. |
99 | + Breezy also supports a global ignore file ~/.config/breezy/ignore. On |
100 | + Windows the global ignore file can be found in the application data |
101 | + directory as |
102 | + C:\\Documents and Settings\\<user>\\Application Data\\Breezy\\3.0\\ignore. |
103 | Global ignores are not touched by this command. The global ignore file |
104 | can be edited directly using an editor. |
105 | |
106 | @@ -3732,7 +3735,7 @@ |
107 | unreferenced ancestors |
108 | Texts that are ancestors of other texts, but |
109 | are not properly referenced by the revision ancestry. This is a |
110 | - subtle problem that Bazaar can work around. |
111 | + subtle problem that Breezy can work around. |
112 | |
113 | unique file texts |
114 | This is the total number of unique file contents |
115 | @@ -3744,7 +3747,7 @@ |
116 | entries are modified, but the file contents are not. It does not |
117 | indicate a problem. |
118 | |
119 | - If no restrictions are specified, all Bazaar data that is found at the given |
120 | + If no restrictions are specified, all data that is found at the given |
121 | location will be checked. |
122 | |
123 | :Examples: |
124 | @@ -3786,10 +3789,10 @@ |
125 | __doc__ = """Upgrade a repository, branch or working tree to a newer format. |
126 | |
127 | When the default format has changed after a major new release of |
128 | - Bazaar, you may be informed during certain operations that you |
129 | + Bazaar/Breezy, you may be informed during certain operations that you |
130 | should upgrade. Upgrading to a newer format may improve performance |
131 | or make new features available. It may however limit interoperability |
132 | - with older repositories or with older versions of Bazaar. |
133 | + with older repositories or with older versions of Bazaar or Breezy. |
134 | |
135 | If you wish to upgrade to a particular format rather than the |
136 | current default, that can be specified using the --format option. |
137 | @@ -3811,7 +3814,7 @@ |
138 | If the conversion of a branch fails, remaining branches are still |
139 | tried. |
140 | |
141 | - For more information on upgrades, see the Bazaar Upgrade Guide, |
142 | + For more information on upgrades, see the Breezy Upgrade Guide, |
143 | https://www.breezy-vcs.org/doc/en/upgrade-guide/. |
144 | """ |
145 | |
146 | @@ -4312,7 +4315,7 @@ |
147 | through OTHER, excluding BASE but including OTHER, will be merged. If this |
148 | causes some revisions to be skipped, i.e. if the destination branch does |
149 | not already contain revision BASE, such a merge is commonly referred to as |
150 | - a "cherrypick". Unlike a normal merge, Bazaar does not currently track |
151 | + a "cherrypick". Unlike a normal merge, Breezy does not currently track |
152 | cherrypicks. The changes look like a normal commit, and the history of the |
153 | changes from the other branch is not stored in the commit. |
154 | |
155 | @@ -5133,8 +5136,8 @@ |
156 | |
157 | --verbose shows the path where each plugin is located. |
158 | |
159 | - A plugin is an external component for Bazaar that extends the |
160 | - revision control system, by adding or replacing code in Bazaar. |
161 | + A plugin is an external component for Breezy that extends the |
162 | + revision control system, by adding or replacing code in Breezy. |
163 | Plugins can do a variety of things, including overriding commands, |
164 | adding new commands, providing additional network transports and |
165 | customizing log output. |
166 | @@ -5420,10 +5423,10 @@ |
167 | else: |
168 | self.add_cleanup(b.lock_write().unlock) |
169 | return self._run(b, tree, dry_run, verbose, revision, force, |
170 | - local, keep_tags) |
171 | + local, keep_tags, location) |
172 | |
173 | def _run(self, b, tree, dry_run, verbose, revision, force, local, |
174 | - keep_tags): |
175 | + keep_tags, location): |
176 | from .log import log_formatter, show_log |
177 | from .uncommit import uncommit |
178 | |
179 | @@ -5477,10 +5480,16 @@ |
180 | last_rev_id, rev_id) |
181 | uncommit(b, tree=tree, dry_run=dry_run, verbose=verbose, |
182 | revno=revno, local=local, keep_tags=keep_tags) |
183 | - self.outf.write( |
184 | - gettext('You can restore the old tip by running:\n' |
185 | - ' brz pull . -r revid:%s\n') |
186 | - % last_rev_id.decode('utf-8')) |
187 | + if location != '.': |
188 | + self.outf.write( |
189 | + gettext('You can restore the old tip by running:\n' |
190 | + ' brz pull -d %s %s -r revid:%s\n') |
191 | + % (location, location, last_rev_id.decode('utf-8'))) |
192 | + else: |
193 | + self.outf.write( |
194 | + gettext('You can restore the old tip by running:\n' |
195 | + ' brz pull . -r revid:%s\n') |
196 | + % last_rev_id.decode('utf-8')) |
197 | |
198 | |
199 | class cmd_break_lock(Command): |
200 | @@ -5498,7 +5507,7 @@ |
201 | :Examples: |
202 | brz break-lock |
203 | brz break-lock brz+ssh://example.com/brz/foo |
204 | - brz break-lock --conf ~/.bazaar |
205 | + brz break-lock --conf ~/.config/breezy |
206 | """ |
207 | |
208 | takes_args = ['location?'] |
209 | @@ -5789,7 +5798,7 @@ |
210 | branch containing submit_branch in its ancestory without needing access to |
211 | the source branch. |
212 | |
213 | - If --no-bundle is specified, then Bazaar doesn't send the contents of the |
214 | + If --no-bundle is specified, then Breezy doesn't send the contents of the |
215 | revisions, but only a structured request to merge from the |
216 | public_location. In that case the public_branch is needed and it must be |
217 | up-to-date and accessible to the recipient. The public_branch is always |
218 | |
219 | === modified file 'breezy/git/cache.py' |
220 | --- breezy/git/cache.py 2018-11-12 01:41:38 +0000 |
221 | +++ breezy/git/cache.py 2019-03-06 14:35:55 +0000 |
222 | @@ -613,11 +613,9 @@ |
223 | |
224 | def open(self, transport): |
225 | try: |
226 | - basepath = transport.local_abspath(".").encode(osutils._fs_enc) |
227 | + basepath = transport.local_abspath(".") |
228 | except bzr_errors.NotLocalUrl: |
229 | basepath = get_cache_dir() |
230 | - if not isinstance(basepath, str): |
231 | - raise TypeError(basepath) |
232 | try: |
233 | return TdbBzrGitCache(os.path.join(basepath, "idmap.tdb")) |
234 | except ImportError: |
235 | |
236 | === modified file 'breezy/git/git-remote-bzr' |
237 | --- breezy/git/git-remote-bzr 2018-03-26 22:28:24 +0000 |
238 | +++ breezy/git/git-remote-bzr 2019-03-06 14:35:55 +0000 |
239 | @@ -32,10 +32,12 @@ |
240 | import breezy |
241 | breezy.initialize() |
242 | |
243 | +from breezy.sixish import PY3 |
244 | + |
245 | from breezy.plugin import load_plugins |
246 | load_plugins() |
247 | |
248 | -from breezy.plugins.git.git_remote_helper import ( |
249 | +from breezy.git.git_remote_helper import ( |
250 | RemoteHelper, |
251 | open_local_dir, |
252 | open_remote_dir, |
253 | @@ -46,4 +48,7 @@ |
254 | (shortname, url) = args |
255 | |
256 | helper = RemoteHelper(open_local_dir(), shortname, open_remote_dir(url)) |
257 | -helper.process(sys.stdin, sys.stdout) |
258 | +if PY3: |
259 | + helper.process(sys.stdin.buffer, sys.stdout.buffer) |
260 | +else: |
261 | + helper.process(sys.stdin, sys.stdout) |
262 | |
263 | === modified file 'breezy/git/git_remote_helper.py' |
264 | --- breezy/git/git_remote_helper.py 2018-11-11 14:23:06 +0000 |
265 | +++ breezy/git/git_remote_helper.py 2019-03-06 14:35:55 +0000 |
266 | @@ -186,7 +186,7 @@ |
267 | self.batchcmd = None |
268 | else: |
269 | try: |
270 | - self.commands[argv[0]](self, outf, argv) |
271 | + self.commands[argv[0].decode()](self, outf, argv) |
272 | except KeyError: |
273 | raise Exception("Unknown remote command %r" % argv) |
274 | outf.flush() |
275 | |
276 | === modified file 'breezy/git/memorytree.py' |
277 | --- breezy/git/memorytree.py 2018-11-18 00:25:19 +0000 |
278 | +++ breezy/git/memorytree.py 2019-03-06 14:35:55 +0000 |
279 | @@ -258,3 +258,7 @@ |
280 | def kind(self, p): |
281 | stat_value = self._file_transport.stat(p) |
282 | return osutils.file_kind_from_stat_mode(stat_value.st_mode) |
283 | + |
284 | + def get_symlink_target(self, path): |
285 | + with self.lock_read(): |
286 | + return self._file_transport.readlink(path) |
287 | |
288 | === modified file 'breezy/git/object_store.py' |
289 | --- breezy/git/object_store.py 2019-01-01 21:23:40 +0000 |
290 | +++ breezy/git/object_store.py 2019-03-06 14:35:55 +0000 |
291 | @@ -359,7 +359,7 @@ |
292 | continue |
293 | |
294 | if tree.kind(path) != 'directory': |
295 | - raise AssertionError |
296 | + continue |
297 | |
298 | obj = Tree() |
299 | for value in tree.iter_child_entries(path): |
300 | @@ -589,7 +589,7 @@ |
301 | for (file_id, revision, expected_sha), chunks in stream: |
302 | blob = Blob() |
303 | blob.chunked = chunks |
304 | - if blob.id != expected_sha and blob.data == "": |
305 | + if blob.id != expected_sha and blob.data == b"": |
306 | # Perhaps it's a symlink ? |
307 | tree = self.tree_cache.revision_tree(revision) |
308 | path = tree.id2path(file_id) |
309 | |
310 | === modified file 'breezy/git/tests/test_blackbox.py' |
311 | --- breezy/git/tests/test_blackbox.py 2019-02-14 04:20:37 +0000 |
312 | +++ breezy/git/tests/test_blackbox.py 2019-03-06 14:35:55 +0000 |
313 | @@ -78,6 +78,15 @@ |
314 | self.assertEqual(output, '') |
315 | self.assertFileEqual("foo\n", ".gitignore") |
316 | |
317 | + def test_cat_revision(self): |
318 | + self.simple_commit() |
319 | + output, error = self.run_bzr(['cat-revision', '-r-1'], retcode=3) |
320 | + self.assertContainsRe( |
321 | + error, |
322 | + 'brz: ERROR: Repository .* does not support access to raw ' |
323 | + 'revision texts') |
324 | + self.assertEqual(output, '') |
325 | + |
326 | def test_branch(self): |
327 | os.mkdir("gitbranch") |
328 | GitRepo.init(os.path.join(self.test_dir, "gitbranch")) |
329 | |
330 | === modified file 'breezy/git/tests/test_branch.py' |
331 | --- breezy/git/tests/test_branch.py 2019-01-19 17:13:53 +0000 |
332 | +++ breezy/git/tests/test_branch.py 2019-03-06 14:35:55 +0000 |
333 | @@ -112,6 +112,7 @@ |
334 | reva = self.simple_commit_a() |
335 | self.build_tree(['b']) |
336 | r = GitRepo(".") |
337 | + self.addCleanup(r.close) |
338 | r.stage("b") |
339 | revb = r.do_commit(b"b", committer=b"Somebody <foo@example.com>") |
340 | |
341 | @@ -129,6 +130,7 @@ |
342 | o.tag_timezone = 0 |
343 | o.tag_time = 42 |
344 | r = GitRepo(".") |
345 | + self.addCleanup(r.close) |
346 | r.object_store.add_object(o) |
347 | r[b'refs/tags/foo'] = o.id |
348 | thebranch = Branch.open('.') |
349 | @@ -138,6 +140,7 @@ |
350 | def test_tag(self): |
351 | reva = self.simple_commit_a() |
352 | r = GitRepo(".") |
353 | + self.addCleanup(r.close) |
354 | r.refs[b"refs/tags/foo"] = reva |
355 | thebranch = Branch.open('.') |
356 | self.assertEqual({"foo": default_mapping.revision_id_foreign_to_bzr(reva)}, |
357 | @@ -221,6 +224,7 @@ |
358 | def test_sprouted_tags(self): |
359 | path, gitsha = self.make_onerev_branch() |
360 | r = GitRepo(path) |
361 | + self.addCleanup(r.close) |
362 | r.refs[b"refs/tags/lala"] = r.head() |
363 | oldrepo = Repository.open(path) |
364 | revid = oldrepo.get_mapping().revision_id_foreign_to_bzr(gitsha) |
365 | @@ -231,6 +235,7 @@ |
366 | def test_sprouted_ghost_tags(self): |
367 | path, gitsha = self.make_onerev_branch() |
368 | r = GitRepo(path) |
369 | + self.addCleanup(r.close) |
370 | r.refs[b"refs/tags/lala"] = b"aa" * 20 |
371 | oldrepo = Repository.open(path) |
372 | revid = oldrepo.get_mapping().revision_id_foreign_to_bzr(gitsha) |
373 | @@ -238,7 +243,7 @@ |
374 | self.clone_git_branch, path, "f") |
375 | self.assertEqual({}, newbranch.tags.get_tag_dict()) |
376 | # Dulwich raises a UserWarning for tags with invalid target |
377 | - self.assertEqual(1, len(warnings)) |
378 | + self.assertIn(('ref refs/tags/lala points at non-present sha ' + ("aa" * 20), ), [w.args for w in warnings]) |
379 | |
380 | def test_interbranch_pull(self): |
381 | path, (gitsha1, gitsha2) = self.make_tworev_branch() |
382 | @@ -272,6 +277,7 @@ |
383 | def test_interbranch_pull_with_tags(self): |
384 | path, (gitsha1, gitsha2) = self.make_tworev_branch() |
385 | gitrepo = GitRepo(path) |
386 | + self.addCleanup(gitrepo.close) |
387 | gitrepo.refs[b"refs/tags/sometag"] = gitsha2 |
388 | oldrepo = Repository.open(path) |
389 | revid1 = oldrepo.get_mapping().revision_id_foreign_to_bzr(gitsha1) |
390 | |
391 | === modified file 'breezy/git/tests/test_git_remote_helper.py' |
392 | --- breezy/git/tests/test_git_remote_helper.py 2018-11-21 03:39:28 +0000 |
393 | +++ breezy/git/tests/test_git_remote_helper.py 2019-03-06 14:35:55 +0000 |
394 | @@ -23,12 +23,15 @@ |
395 | |
396 | from io import BytesIO |
397 | import os |
398 | +import subprocess |
399 | +import sys |
400 | |
401 | from dulwich.repo import Repo |
402 | |
403 | from ...tests import ( |
404 | TestCaseWithTransport, |
405 | ) |
406 | +from ...tests.features import PathFeature |
407 | |
408 | from ..object_store import get_object_store |
409 | from ..git_remote_helper import ( |
410 | @@ -46,6 +49,11 @@ |
411 | return object_store._lookup_revision_sha1(bzr_revid) |
412 | |
413 | |
414 | +git_remote_bzr_path = os.path.abspath( |
415 | + os.path.join(os.path.dirname(__file__), '..', 'git-remote-bzr')) |
416 | +git_remote_bzr_feature = PathFeature(git_remote_bzr_path) |
417 | + |
418 | + |
419 | class OpenLocalDirTests(TestCaseWithTransport): |
420 | |
421 | def test_from_env_dir(self): |
422 | @@ -86,8 +94,29 @@ |
423 | self.assertEqual(out, b"\n") |
424 | r = Repo('local') |
425 | self.assertTrue(git_sha1 in r.object_store) |
426 | - self.assertEqual({ |
427 | - }, r.get_refs()) |
428 | + self.assertEqual({}, r.get_refs()) |
429 | + |
430 | + |
431 | +class ExecuteRemoteHelperTests(TestCaseWithTransport): |
432 | + |
433 | + def test_run(self): |
434 | + self.requireFeature(git_remote_bzr_feature) |
435 | + local_dir = self.make_branch_and_tree('local', format='git').controldir |
436 | + local_path = local_dir.control_transport.local_abspath('.') |
437 | + remote_tree = self.make_branch_and_tree('remote') |
438 | + remote_dir = remote_tree.controldir |
439 | + shortname = 'bzr' |
440 | + env = dict(os.environ) |
441 | + env['GIT_DIR'] = local_path |
442 | + env['PYTHONPATH'] = ':'.join(sys.path) |
443 | + p = subprocess.Popen( |
444 | + [sys.executable, git_remote_bzr_path, local_path, remote_dir.user_url], |
445 | + stdin=subprocess.PIPE, stdout=subprocess.PIPE, |
446 | + stderr=subprocess.PIPE, env=env) |
447 | + (out, err) = p.communicate(b'capabilities\n') |
448 | + lines = out.splitlines() |
449 | + self.assertIn(b'push', lines, "no 'push' in %r, error: %r" % (lines, err)) |
450 | + self.assertEqual(b'', err) |
451 | |
452 | |
453 | class RemoteHelperTests(TestCaseWithTransport): |
454 | |
455 | === modified file 'breezy/git/tests/test_object_store.py' |
456 | --- breezy/git/tests/test_object_store.py 2018-11-11 04:08:32 +0000 |
457 | +++ breezy/git/tests/test_object_store.py 2019-03-06 14:35:55 +0000 |
458 | @@ -18,6 +18,9 @@ |
459 | |
460 | from __future__ import absolute_import |
461 | |
462 | +import os |
463 | +import shutil |
464 | + |
465 | from dulwich.objects import ( |
466 | Blob, |
467 | Tree, |
468 | @@ -144,11 +147,11 @@ |
469 | def setUp(self): |
470 | super(BazaarObjectStoreTests, self).setUp() |
471 | self.branch = self.make_branch(".") |
472 | - self.branch.lock_write() |
473 | - self.addCleanup(self.branch.unlock) |
474 | self.store = BazaarObjectStore(self.branch.repository) |
475 | |
476 | def test_get_blob(self): |
477 | + self.branch.lock_write() |
478 | + self.addCleanup(self.branch.unlock) |
479 | b = Blob() |
480 | b.data = b'a\nb\nc\nd\ne\n' |
481 | self.store.lock_read() |
482 | @@ -167,7 +170,30 @@ |
483 | self.store.lock_read() |
484 | self.assertEqual(b, self.store[b.id]) |
485 | |
486 | + def test_directory_converted_to_symlink(self): |
487 | + b = Blob() |
488 | + b.data = b'trgt' |
489 | + self.store.lock_read() |
490 | + self.addCleanup(self.store.unlock) |
491 | + self.assertRaises(KeyError, self.store.__getitem__, b.id) |
492 | + tree = self.branch.controldir.create_workingtree() |
493 | + self.build_tree_contents([ |
494 | + ('foo/', ), |
495 | + ('foo/bar', b'a\nb\nc\nd\ne\n')]) |
496 | + tree.add(['foo', 'foo/bar']) |
497 | + revid1 = tree.commit('commit 1') |
498 | + shutil.rmtree('foo') |
499 | + os.symlink('trgt', 'foo') |
500 | + revid2 = tree.commit('commit 2') |
501 | + # read locks cache |
502 | + self.assertRaises(KeyError, self.store.__getitem__, b.id) |
503 | + self.store.unlock() |
504 | + self.store.lock_read() |
505 | + self.assertEqual(b, self.store[b.id]) |
506 | + |
507 | def test_get_raw(self): |
508 | + self.branch.lock_write() |
509 | + self.addCleanup(self.branch.unlock) |
510 | b = Blob() |
511 | b.data = b'a\nb\nc\nd\ne\n' |
512 | self.store.lock_read() |
513 | @@ -187,6 +213,8 @@ |
514 | self.assertEqual(b.as_raw_string(), self.store.get_raw(b.id)[1]) |
515 | |
516 | def test_contains(self): |
517 | + self.branch.lock_write() |
518 | + self.addCleanup(self.branch.unlock) |
519 | b = Blob() |
520 | b.data = b'a\nb\nc\nd\ne\n' |
521 | self.store.lock_read() |
522 | |
523 | === modified file 'breezy/globbing.py' |
524 | --- breezy/globbing.py 2018-11-18 19:48:57 +0000 |
525 | +++ breezy/globbing.py 2019-03-06 14:35:55 +0000 |
526 | @@ -248,7 +248,9 @@ |
527 | # the combined pattern we sent to regex. Instead we indicate to |
528 | # the user that an ignore file needs fixing. |
529 | mutter('Invalid pattern found in regex: %s.', e.msg) |
530 | - e.msg = "File ~/.bazaar/ignore or .bzrignore contains error(s)." |
531 | + e.msg = ( |
532 | + "File ~/.config/breezy/ignore or " |
533 | + ".bzrignore contains error(s).") |
534 | bad_patterns = '' |
535 | for _, patterns in self._regex_patterns: |
536 | for p in patterns: |
537 | |
538 | === modified file 'breezy/ignores.py' |
539 | --- breezy/ignores.py 2018-11-12 01:41:38 +0000 |
540 | +++ breezy/ignores.py 2019-03-06 14:35:55 +0000 |
541 | @@ -33,7 +33,7 @@ |
542 | ) |
543 | """) |
544 | |
545 | -# ~/.bazaar/ignore will be filled out using |
546 | +# ~/.config/breezy/ignore will be filled out using |
547 | # this ignore list, if it does not exist |
548 | # please keep these sorted (in C locale order) to aid merging |
549 | USER_DEFAULTS = [ |
550 | |
551 | === modified file 'breezy/memorytree.py' |
552 | --- breezy/memorytree.py 2018-11-18 00:25:19 +0000 |
553 | +++ breezy/memorytree.py 2019-03-06 14:35:55 +0000 |
554 | @@ -22,6 +22,7 @@ |
555 | from __future__ import absolute_import |
556 | |
557 | import os |
558 | +import stat |
559 | |
560 | from . import ( |
561 | errors, |
562 | @@ -62,7 +63,15 @@ |
563 | with self.lock_tree_write(): |
564 | for f, file_id, kind in zip(files, ids, kinds): |
565 | if kind is None: |
566 | - kind = 'file' |
567 | + st_mode = self._file_transport.stat(f).st_mode |
568 | + if stat.S_ISREG(st_mode): |
569 | + kind = 'file' |
570 | + elif stat.S_ISLNK(st_mode): |
571 | + kind = 'symlink' |
572 | + elif stat.S_ISDIR(st_mode): |
573 | + kind = 'directory' |
574 | + else: |
575 | + raise AssertionError('Unknown file kind') |
576 | if file_id is None: |
577 | self._inventory.add_path(f, kind=kind) |
578 | else: |
579 | @@ -127,7 +136,7 @@ |
580 | # memory tree does not support nested trees yet. |
581 | return kind, None, None, None |
582 | elif kind == 'symlink': |
583 | - raise NotImplementedError('symlink support') |
584 | + return kind, None, None, self._inventory[id].symlink_target |
585 | else: |
586 | raise NotImplementedError('unknown kind') |
587 | |
588 | @@ -148,8 +157,7 @@ |
589 | return self._inventory.get_entry_by_path(path).executable |
590 | |
591 | def kind(self, path): |
592 | - file_id = self.path2id(path) |
593 | - return self._inventory[file_id].kind |
594 | + return self._inventory.get_entry_by_path(path).kind |
595 | |
596 | def mkdir(self, path, file_id=None): |
597 | """See MutableTree.mkdir().""" |
598 | @@ -227,6 +235,8 @@ |
599 | continue |
600 | if entry.kind == 'directory': |
601 | self._file_transport.mkdir(path) |
602 | + elif entry.kind == 'symlink': |
603 | + self._file_transport.symlink(entry.symlink_target, path) |
604 | elif entry.kind == 'file': |
605 | self._file_transport.put_file( |
606 | path, self._basis_tree.get_file(path)) |
607 | @@ -302,6 +312,10 @@ |
608 | else: |
609 | raise |
610 | |
611 | + def get_symlink_target(self, path): |
612 | + with self.lock_read(): |
613 | + return self._file_transport.readlink(path) |
614 | + |
615 | def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False): |
616 | """See MutableTree.set_parent_trees().""" |
617 | if len(parents_list) == 0: |
618 | |
619 | === modified file 'breezy/plugins/propose/launchpad.py' |
620 | --- breezy/plugins/propose/launchpad.py 2019-02-10 18:37:58 +0000 |
621 | +++ breezy/plugins/propose/launchpad.py 2019-03-06 14:35:55 +0000 |
622 | @@ -140,6 +140,7 @@ |
623 | |
624 | def set_description(self, description): |
625 | self._mp.description = description |
626 | + self._mp.lp_save() |
627 | |
628 | def close(self): |
629 | self._mp.setStatus(status='Rejected') |
630 | |
631 | === modified file 'breezy/tests/blackbox/test_push.py' |
632 | --- breezy/tests/blackbox/test_push.py 2018-11-16 12:08:41 +0000 |
633 | +++ breezy/tests/blackbox/test_push.py 2019-03-06 14:35:55 +0000 |
634 | @@ -22,6 +22,7 @@ |
635 | from breezy import ( |
636 | branch, |
637 | controldir, |
638 | + directory_service, |
639 | errors, |
640 | osutils, |
641 | tests, |
642 | @@ -498,6 +499,25 @@ |
643 | self.assertPublished(branch_tree.last_revision(), |
644 | trunk_tree.branch.base) |
645 | |
646 | + def test_push_new_branch_stacked_on(self): |
647 | + """Pushing a new branch with --stacked-on can use directory URLs.""" |
648 | + trunk_tree, branch_tree = self.create_trunk_and_feature_branch() |
649 | + class FooDirectory(object): |
650 | + def look_up(self, name, url, purpose=None): |
651 | + if url == 'foo:': |
652 | + return trunk_tree.branch.base |
653 | + return url |
654 | + directory_service.directories.register('foo:', FooDirectory, 'Foo directory') |
655 | + self.addCleanup(directory_service.directories.remove, 'foo:') |
656 | + # we publish branch_tree with a reference to the mainline. |
657 | + out, err = self.run_bzr(['push', '--stacked-on', 'foo:', |
658 | + self.get_url('published')], working_dir='branch') |
659 | + self.assertEqual('', out) |
660 | + self.assertEqual('Created new stacked branch referring to %s.\n' % |
661 | + trunk_tree.branch.base, err) |
662 | + self.assertPublished(branch_tree.last_revision(), |
663 | + trunk_tree.branch.base) |
664 | + |
665 | def test_push_new_branch_stacked_uses_parent_when_no_public_url(self): |
666 | """When the parent has no public url the parent is used as-is.""" |
667 | trunk_tree, branch_tree = self.create_trunk_and_feature_branch() |
668 | |
669 | === modified file 'breezy/tests/blackbox/test_uncommit.py' |
670 | --- breezy/tests/blackbox/test_uncommit.py 2018-11-18 19:48:57 +0000 |
671 | +++ breezy/tests/blackbox/test_uncommit.py 2019-03-06 14:35:55 +0000 |
672 | @@ -246,6 +246,20 @@ |
673 | brz pull . -r revid:a2 |
674 | """) |
675 | |
676 | + def test_uncommit_shows_pull_with_location(self): |
677 | + wt = self.create_simple_tree() |
678 | + |
679 | + script = ScriptRunner() |
680 | + script.run_script(self, """ |
681 | +$ brz uncommit --force tree |
682 | + 2 ... |
683 | + second commit |
684 | +... |
685 | +The above revision(s) will be removed. |
686 | +You can restore the old tip by running: |
687 | + brz pull -d tree tree -r revid:a2 |
688 | +""") |
689 | + |
690 | def test_uncommit_octopus_merge(self): |
691 | # Check that uncommit keeps the pending merges in the same order |
692 | # though it will also filter out ones in the ancestry |
693 | |
694 | === modified file 'breezy/tests/features.py' |
695 | --- breezy/tests/features.py 2019-01-19 01:44:20 +0000 |
696 | +++ breezy/tests/features.py 2019-03-06 14:35:55 +0000 |
697 | @@ -568,3 +568,17 @@ |
698 | |
699 | |
700 | BackslashFilenameFeature = _BackslashFilenameFeature() |
701 | + |
702 | + |
703 | +class PathFeature(Feature): |
704 | + """Feature testing whether a particular path exists.""" |
705 | + |
706 | + def __init__(self, path): |
707 | + super(PathFeature, self).__init__() |
708 | + self.path = path |
709 | + |
710 | + def _probe(self): |
711 | + return os.path.exists(self.path) |
712 | + |
713 | + def feature_name(self): |
714 | + return "%s exists" % self.path |
715 | |
716 | === modified file 'breezy/tests/test_memorytree.py' |
717 | --- breezy/tests/test_memorytree.py 2018-11-11 04:08:32 +0000 |
718 | +++ breezy/tests/test_memorytree.py 2019-03-06 14:35:55 +0000 |
719 | @@ -46,21 +46,17 @@ |
720 | rev_id = tree.commit('first post') |
721 | tree.unlock() |
722 | tree = MemoryTree.create_on_branch(branch) |
723 | - tree.lock_read() |
724 | - self.assertEqual([rev_id], tree.get_parent_ids()) |
725 | - with tree.get_file('foo') as f: |
726 | - self.assertEqual(b'contents of foo\n', f.read()) |
727 | - tree.unlock() |
728 | + with tree.lock_read(): |
729 | + self.assertEqual([rev_id], tree.get_parent_ids()) |
730 | + with tree.get_file('foo') as f: |
731 | + self.assertEqual(b'contents of foo\n', f.read()) |
732 | |
733 | def test_get_root_id(self): |
734 | branch = self.make_branch('branch') |
735 | tree = MemoryTree.create_on_branch(branch) |
736 | - tree.lock_write() |
737 | - try: |
738 | + with tree.lock_write(): |
739 | tree.add(['']) |
740 | self.assertIsNot(None, tree.get_root_id()) |
741 | - finally: |
742 | - tree.unlock() |
743 | |
744 | def test_lock_tree_write(self): |
745 | """Check we can lock_tree_write and unlock MemoryTrees.""" |
746 | @@ -73,9 +69,8 @@ |
747 | """Check that we error when trying to upgrade a read lock to write.""" |
748 | branch = self.make_branch('branch') |
749 | tree = MemoryTree.create_on_branch(branch) |
750 | - tree.lock_read() |
751 | - self.assertRaises(errors.ReadOnlyError, tree.lock_tree_write) |
752 | - tree.unlock() |
753 | + with tree.lock_read(): |
754 | + self.assertRaises(errors.ReadOnlyError, tree.lock_tree_write) |
755 | |
756 | def test_lock_write(self): |
757 | """Check we can lock_write and unlock MemoryTrees.""" |
758 | @@ -88,58 +83,63 @@ |
759 | """Check that we error when trying to upgrade a read lock to write.""" |
760 | branch = self.make_branch('branch') |
761 | tree = MemoryTree.create_on_branch(branch) |
762 | - tree.lock_read() |
763 | - self.assertRaises(errors.ReadOnlyError, tree.lock_write) |
764 | - tree.unlock() |
765 | + with tree.lock_read(): |
766 | + self.assertRaises(errors.ReadOnlyError, tree.lock_write) |
767 | |
768 | def test_add_with_kind(self): |
769 | branch = self.make_branch('branch') |
770 | tree = MemoryTree.create_on_branch(branch) |
771 | - tree.lock_write() |
772 | - tree.add(['', 'afile', 'adir'], None, |
773 | - ['directory', 'file', 'directory']) |
774 | - self.assertEqual('afile', tree.id2path(tree.path2id('afile'))) |
775 | - self.assertEqual('adir', tree.id2path(tree.path2id('adir'))) |
776 | - self.assertFalse(tree.has_filename('afile')) |
777 | - self.assertFalse(tree.has_filename('adir')) |
778 | - tree.unlock() |
779 | + with tree.lock_write(): |
780 | + tree.add(['', 'afile', 'adir'], None, |
781 | + ['directory', 'file', 'directory']) |
782 | + self.assertEqual('afile', tree.id2path(tree.path2id('afile'))) |
783 | + self.assertEqual('adir', tree.id2path(tree.path2id('adir'))) |
784 | + self.assertFalse(tree.has_filename('afile')) |
785 | + self.assertFalse(tree.has_filename('adir')) |
786 | |
787 | def test_put_new_file(self): |
788 | branch = self.make_branch('branch') |
789 | tree = MemoryTree.create_on_branch(branch) |
790 | - tree.lock_write() |
791 | - tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
792 | - kinds=['directory', 'file']) |
793 | - tree.put_file_bytes_non_atomic('foo', b'barshoom') |
794 | - self.assertEqual(b'barshoom', tree.get_file('foo').read()) |
795 | - tree.unlock() |
796 | + with tree.lock_write(): |
797 | + tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
798 | + kinds=['directory', 'file']) |
799 | + tree.put_file_bytes_non_atomic('foo', b'barshoom') |
800 | + with tree.get_file('foo') as f: |
801 | + self.assertEqual(b'barshoom', f.read()) |
802 | |
803 | def test_put_existing_file(self): |
804 | branch = self.make_branch('branch') |
805 | tree = MemoryTree.create_on_branch(branch) |
806 | - tree.lock_write() |
807 | - tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
808 | - kinds=['directory', 'file']) |
809 | - tree.put_file_bytes_non_atomic('foo', b'first-content') |
810 | - tree.put_file_bytes_non_atomic('foo', b'barshoom') |
811 | - self.assertEqual(b'barshoom', tree.get_file('foo').read()) |
812 | - tree.unlock() |
813 | + with tree.lock_write(): |
814 | + tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
815 | + kinds=['directory', 'file']) |
816 | + tree.put_file_bytes_non_atomic('foo', b'first-content') |
817 | + tree.put_file_bytes_non_atomic('foo', b'barshoom') |
818 | + self.assertEqual(b'barshoom', tree.get_file('foo').read()) |
819 | |
820 | def test_add_in_subdir(self): |
821 | branch = self.make_branch('branch') |
822 | tree = MemoryTree.create_on_branch(branch) |
823 | - tree.lock_write() |
824 | - self.addCleanup(tree.unlock) |
825 | - tree.add([''], [b'root-id'], ['directory']) |
826 | - # Unfortunately, the only way to 'mkdir' is to call 'tree.mkdir', but |
827 | - # that *always* adds the directory as well. So if you want to create a |
828 | - # file in a subdirectory, you have to split out the 'mkdir()' calls |
829 | - # from the add and put_file_bytes_non_atomic calls. :( |
830 | - tree.mkdir('adir', b'dir-id') |
831 | - tree.add(['adir/afile'], [b'file-id'], ['file']) |
832 | - self.assertEqual('adir/afile', tree.id2path(b'file-id')) |
833 | - self.assertEqual('adir', tree.id2path(b'dir-id')) |
834 | - tree.put_file_bytes_non_atomic('adir/afile', b'barshoom') |
835 | + with tree.lock_write(): |
836 | + tree.add([''], [b'root-id'], ['directory']) |
837 | + # Unfortunately, the only way to 'mkdir' is to call 'tree.mkdir', but |
838 | + # that *always* adds the directory as well. So if you want to create a |
839 | + # file in a subdirectory, you have to split out the 'mkdir()' calls |
840 | + # from the add and put_file_bytes_non_atomic calls. :( |
841 | + tree.mkdir('adir', b'dir-id') |
842 | + tree.add(['adir/afile'], [b'file-id'], ['file']) |
843 | + self.assertEqual('adir/afile', tree.id2path(b'file-id')) |
844 | + self.assertEqual('adir', tree.id2path(b'dir-id')) |
845 | + tree.put_file_bytes_non_atomic('adir/afile', b'barshoom') |
846 | + |
847 | + def test_add_symlink(self): |
848 | + branch = self.make_branch('branch') |
849 | + tree = MemoryTree.create_on_branch(branch) |
850 | + with tree.lock_write(): |
851 | + tree._file_transport.symlink('bar', 'foo') |
852 | + tree.add(['', 'foo']) |
853 | + self.assertEqual('symlink', tree.kind('foo')) |
854 | + self.assertEqual('bar', tree.get_symlink_target('foo')) |
855 | |
856 | def test_commit_trivial(self): |
857 | """Smoke test for commit on a MemoryTree. |
858 | @@ -149,40 +149,35 @@ |
859 | """ |
860 | branch = self.make_branch('branch') |
861 | tree = MemoryTree.create_on_branch(branch) |
862 | - tree.lock_write() |
863 | - tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
864 | - kinds=['directory', 'file']) |
865 | - tree.put_file_bytes_non_atomic('foo', b'barshoom') |
866 | - revision_id = tree.commit('message baby') |
867 | - # the parents list for the tree should have changed. |
868 | - self.assertEqual([revision_id], tree.get_parent_ids()) |
869 | - tree.unlock() |
870 | + with tree.lock_write(): |
871 | + tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
872 | + kinds=['directory', 'file']) |
873 | + tree.put_file_bytes_non_atomic('foo', b'barshoom') |
874 | + revision_id = tree.commit('message baby') |
875 | + # the parents list for the tree should have changed. |
876 | + self.assertEqual([revision_id], tree.get_parent_ids()) |
877 | # and we should have a revision that is accessible outside the tree lock |
878 | revtree = tree.branch.repository.revision_tree(revision_id) |
879 | - revtree.lock_read() |
880 | - self.addCleanup(revtree.unlock) |
881 | - with revtree.get_file('foo') as f: |
882 | + with revtree.lock_read(), revtree.get_file('foo') as f: |
883 | self.assertEqual(b'barshoom', f.read()) |
884 | |
885 | def test_unversion(self): |
886 | """Some test for unversion of a memory tree.""" |
887 | branch = self.make_branch('branch') |
888 | tree = MemoryTree.create_on_branch(branch) |
889 | - tree.lock_write() |
890 | - tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
891 | - kinds=['directory', 'file']) |
892 | - tree.unversion(['foo']) |
893 | - self.assertFalse(tree.is_versioned('foo')) |
894 | - self.assertFalse(tree.has_id(b'foo-id')) |
895 | - tree.unlock() |
896 | + with tree.lock_write(): |
897 | + tree.add(['', 'foo'], ids=[b'root-id', b'foo-id'], |
898 | + kinds=['directory', 'file']) |
899 | + tree.unversion(['foo']) |
900 | + self.assertFalse(tree.is_versioned('foo')) |
901 | + self.assertFalse(tree.has_id(b'foo-id')) |
902 | |
903 | def test_last_revision(self): |
904 | """There should be a last revision method we can call.""" |
905 | tree = self.make_branch_and_memory_tree('branch') |
906 | - tree.lock_write() |
907 | - tree.add('') |
908 | - rev_id = tree.commit('first post') |
909 | - tree.unlock() |
910 | + with tree.lock_write(): |
911 | + tree.add('') |
912 | + rev_id = tree.commit('first post') |
913 | self.assertEqual(rev_id, tree.last_revision()) |
914 | |
915 | def test_rename_file(self): |
916 | |
917 | === modified file 'breezy/tests/test_urlutils.py' |
918 | --- breezy/tests/test_urlutils.py 2018-11-23 03:06:01 +0000 |
919 | +++ breezy/tests/test_urlutils.py 2019-03-06 14:35:55 +0000 |
920 | @@ -599,6 +599,9 @@ |
921 | self.assertEqual(("foo/base,key1=val1/other/elements", |
922 | {"key2": "val2"}), split_segment_parameters( |
923 | "foo/base,key1=val1/other/elements,key2=val2")) |
924 | + self.assertRaises( |
925 | + urlutils.InvalidURL, split_segment_parameters, |
926 | + "foo/base,key1") |
927 | # TODO: Check full URLs as well as relative references |
928 | |
929 | def test_win32_strip_local_trailing_slash(self): |
930 | |
931 | === modified file 'breezy/transport/memory.py' |
932 | --- breezy/transport/memory.py 2018-11-17 16:53:10 +0000 |
933 | +++ breezy/transport/memory.py 2019-03-06 14:35:55 +0000 |
934 | @@ -26,9 +26,10 @@ |
935 | from io import ( |
936 | BytesIO, |
937 | ) |
938 | +import itertools |
939 | import os |
940 | import errno |
941 | -from stat import S_IFREG, S_IFDIR, S_IFLNK |
942 | +from stat import S_IFREG, S_IFDIR, S_IFLNK, S_ISDIR |
943 | |
944 | from .. import ( |
945 | transport, |
946 | @@ -50,20 +51,16 @@ |
947 | |
948 | class MemoryStat(object): |
949 | |
950 | - def __init__(self, size, kind, perms): |
951 | + def __init__(self, size, kind, perms=None): |
952 | self.st_size = size |
953 | - if kind == 'file': |
954 | + if not S_ISDIR(kind): |
955 | if perms is None: |
956 | perms = 0o644 |
957 | - self.st_mode = S_IFREG | perms |
958 | - elif kind == 'directory': |
959 | + self.st_mode = kind | perms |
960 | + else: |
961 | if perms is None: |
962 | perms = 0o755 |
963 | - self.st_mode = S_IFDIR | perms |
964 | - elif kind == 'symlink': |
965 | - self.st_mode = S_IFLNK | 0o644 |
966 | - else: |
967 | - raise AssertionError('unknown kind %r' % kind) |
968 | + self.st_mode = kind | perms |
969 | |
970 | |
971 | class MemoryTransport(transport.Transport): |
972 | @@ -111,7 +108,7 @@ |
973 | |
974 | def append_file(self, relpath, f, mode=None): |
975 | """See Transport.append_file().""" |
976 | - _abspath = self._abspath(relpath) |
977 | + _abspath = self._resolve_symlinks(relpath) |
978 | self._check_parent(_abspath) |
979 | orig_content, orig_mode = self._files.get(_abspath, (b"", None)) |
980 | if mode is None: |
981 | @@ -128,16 +125,20 @@ |
982 | def has(self, relpath): |
983 | """See Transport.has().""" |
984 | _abspath = self._abspath(relpath) |
985 | - return ((_abspath in self._files) |
986 | - or (_abspath in self._dirs) |
987 | - or (_abspath in self._symlinks)) |
988 | + for container in (self._files, self._dirs, self._symlinks): |
989 | + if _abspath in container.keys(): |
990 | + return True |
991 | + return False |
992 | |
993 | def delete(self, relpath): |
994 | """See Transport.delete().""" |
995 | _abspath = self._abspath(relpath) |
996 | - if _abspath not in self._files: |
997 | + if _abspath in self._files: |
998 | + del self._files[_abspath] |
999 | + elif _abspath in self._symlinks: |
1000 | + del self._symlinks[_abspath] |
1001 | + else: |
1002 | raise NoSuchFile(relpath) |
1003 | - del self._files[_abspath] |
1004 | |
1005 | def external_url(self): |
1006 | """See breezy.transport.Transport.external_url.""" |
1007 | @@ -147,7 +148,7 @@ |
1008 | |
1009 | def get(self, relpath): |
1010 | """See Transport.get().""" |
1011 | - _abspath = self._abspath(relpath) |
1012 | + _abspath = self._resolve_symlinks(relpath) |
1013 | if _abspath not in self._files: |
1014 | if _abspath in self._dirs: |
1015 | return LateReadError(relpath) |
1016 | @@ -157,15 +158,20 @@ |
1017 | |
1018 | def put_file(self, relpath, f, mode=None): |
1019 | """See Transport.put_file().""" |
1020 | - _abspath = self._abspath(relpath) |
1021 | + _abspath = self._resolve_symlinks(relpath) |
1022 | self._check_parent(_abspath) |
1023 | raw_bytes = f.read() |
1024 | self._files[_abspath] = (raw_bytes, mode) |
1025 | return len(raw_bytes) |
1026 | |
1027 | + def symlink(self, source, target): |
1028 | + _abspath = self._resolve_symlinks(target) |
1029 | + self._check_parent(_abspath) |
1030 | + self._symlinks[_abspath] = self._abspath(source) |
1031 | + |
1032 | def mkdir(self, relpath, mode=None): |
1033 | """See Transport.mkdir().""" |
1034 | - _abspath = self._abspath(relpath) |
1035 | + _abspath = self._resolve_symlinks(relpath) |
1036 | self._check_parent(_abspath) |
1037 | if _abspath in self._dirs: |
1038 | raise FileExists(relpath) |
1039 | @@ -183,13 +189,13 @@ |
1040 | return True |
1041 | |
1042 | def iter_files_recursive(self): |
1043 | - for file in self._files: |
1044 | + for file in itertools.chain(self._files, self._symlinks): |
1045 | if file.startswith(self._cwd): |
1046 | yield urlutils.escape(file[len(self._cwd):]) |
1047 | |
1048 | def list_dir(self, relpath): |
1049 | """See Transport.list_dir().""" |
1050 | - _abspath = self._abspath(relpath) |
1051 | + _abspath = self._resolve_symlinks(relpath) |
1052 | if _abspath != '/' and _abspath not in self._dirs: |
1053 | raise NoSuchFile(relpath) |
1054 | result = [] |
1055 | @@ -197,7 +203,7 @@ |
1056 | if not _abspath.endswith('/'): |
1057 | _abspath += '/' |
1058 | |
1059 | - for path_group in self._files, self._dirs: |
1060 | + for path_group in self._files, self._dirs, self._symlinks: |
1061 | for path in path_group: |
1062 | if path.startswith(_abspath): |
1063 | trailing = path[len(_abspath):] |
1064 | @@ -207,8 +213,8 @@ |
1065 | |
1066 | def rename(self, rel_from, rel_to): |
1067 | """Rename a file or directory; fail if the destination exists""" |
1068 | - abs_from = self._abspath(rel_from) |
1069 | - abs_to = self._abspath(rel_to) |
1070 | + abs_from = self._resolve_symlinks(rel_from) |
1071 | + abs_to = self._resolve_symlinks(rel_to) |
1072 | |
1073 | def replace(x): |
1074 | if x == abs_from: |
1075 | @@ -233,21 +239,25 @@ |
1076 | # fail differently depending on dict order. So work on copy, fail on |
1077 | # error on only replace dicts if all goes well. |
1078 | renamed_files = self._files.copy() |
1079 | + renamed_symlinks = self._symlinks.copy() |
1080 | renamed_dirs = self._dirs.copy() |
1081 | do_renames(renamed_files) |
1082 | + do_renames(renamed_symlinks) |
1083 | do_renames(renamed_dirs) |
1084 | # We may have been cloned so modify in place |
1085 | self._files.clear() |
1086 | self._files.update(renamed_files) |
1087 | + self._symlinks.clear() |
1088 | + self._symlinks.update(renamed_symlinks) |
1089 | self._dirs.clear() |
1090 | self._dirs.update(renamed_dirs) |
1091 | |
1092 | def rmdir(self, relpath): |
1093 | """See Transport.rmdir.""" |
1094 | - _abspath = self._abspath(relpath) |
1095 | + _abspath = self._resolve_symlinks(relpath) |
1096 | if _abspath in self._files: |
1097 | self._translate_error(IOError(errno.ENOTDIR, relpath), relpath) |
1098 | - for path in self._files: |
1099 | + for path in itertools.chain(self._files, self._symlinks): |
1100 | if path.startswith(_abspath + '/'): |
1101 | self._translate_error(IOError(errno.ENOTEMPTY, relpath), |
1102 | relpath) |
1103 | @@ -262,13 +272,13 @@ |
1104 | def stat(self, relpath): |
1105 | """See Transport.stat().""" |
1106 | _abspath = self._abspath(relpath) |
1107 | - if _abspath in self._files: |
1108 | - return MemoryStat(len(self._files[_abspath][0]), 'file', |
1109 | + if _abspath in self._files.keys(): |
1110 | + return MemoryStat(len(self._files[_abspath][0]), S_IFREG, |
1111 | self._files[_abspath][1]) |
1112 | - elif _abspath in self._dirs: |
1113 | - return MemoryStat(0, 'directory', self._dirs[_abspath]) |
1114 | - elif _abspath in self._symlinks: |
1115 | - return MemoryStat(0, 'symlink', 0) |
1116 | + elif _abspath in self._dirs.keys(): |
1117 | + return MemoryStat(0, S_IFDIR, self._dirs[_abspath]) |
1118 | + elif _abspath in self._symlinks.keys(): |
1119 | + return MemoryStat(0, S_IFLNK) |
1120 | else: |
1121 | raise NoSuchFile(_abspath) |
1122 | |
1123 | @@ -280,6 +290,12 @@ |
1124 | """See Transport.lock_write().""" |
1125 | return _MemoryLock(self._abspath(relpath), self) |
1126 | |
1127 | + def _resolve_symlinks(self, relpath): |
1128 | + path = self._abspath(relpath) |
1129 | + while path in self._symlinks.keys(): |
1130 | + path = self._symlinks[path] |
1131 | + return path |
1132 | + |
1133 | def _abspath(self, relpath): |
1134 | """Generate an internal absolute path.""" |
1135 | relpath = urlutils.unescape(relpath) |
1136 | @@ -336,6 +352,7 @@ |
1137 | def start_server(self): |
1138 | self._dirs = {'/': None} |
1139 | self._files = {} |
1140 | + self._symlinks = {} |
1141 | self._locks = {} |
1142 | self._scheme = "memory+%s:///" % id(self) |
1143 | |
1144 | @@ -344,6 +361,7 @@ |
1145 | result = memory.MemoryTransport(url) |
1146 | result._dirs = self._dirs |
1147 | result._files = self._files |
1148 | + result._symlinks = self._symlinks |
1149 | result._locks = self._locks |
1150 | return result |
1151 | self._memory_factory = memory_factory |
1152 | |
1153 | === modified file 'breezy/urlutils.py' |
1154 | --- breezy/urlutils.py 2018-11-16 23:19:12 +0000 |
1155 | +++ breezy/urlutils.py 2019-03-06 14:35:55 +0000 |
1156 | @@ -561,7 +561,10 @@ |
1157 | (base_url, subsegments) = split_segment_parameters_raw(url) |
1158 | parameters = {} |
1159 | for subsegment in subsegments: |
1160 | - (key, value) = subsegment.split("=", 1) |
1161 | + try: |
1162 | + (key, value) = subsegment.split("=", 1) |
1163 | + except ValueError: |
1164 | + raise InvalidURL(url, "missing = in subsegment") |
1165 | if not isinstance(key, str): |
1166 | raise TypeError(key) |
1167 | if not isinstance(value, str): |
1168 | |
1169 | === modified file 'brz' |
1170 | --- brz 2018-11-18 12:41:12 +0000 |
1171 | +++ brz 2019-03-06 14:35:55 +0000 |
1172 | @@ -25,7 +25,7 @@ |
1173 | import warnings |
1174 | |
1175 | # update this on each release |
1176 | -_script_version = (3, 0, 0) |
1177 | +_script_version = (3, 1, 0) |
1178 | |
1179 | NEED_VERS = (2, 7) |
1180 | |
1181 | |
1182 | === modified file 'byov.conf' |
1183 | --- byov.conf 2018-12-19 01:30:58 +0000 |
1184 | +++ byov.conf 2019-03-06 14:35:55 +0000 |
1185 | @@ -13,6 +13,8 @@ |
1186 | sphinx_epytext.install3 = (pip3 install sphinx_epytext) |
1187 | flake8.install = (pip install flake8) |
1188 | flake8.install3 = (pip3 install flake8) |
1189 | +cython.install = (pip install cython) |
1190 | +cython.install3 = (pip3 install cython) |
1191 | |
1192 | [brz] |
1193 | # FIXME: we're stuck on xenial |
1194 | @@ -25,12 +27,12 @@ |
1195 | |
1196 | # FIXME: Arguably this should be vm.build_deps=brz but it requires either an |
1197 | # available package or at least a debian/ dir ? -- vila 2018-02-23 |
1198 | -brz.build_deps = gcc, debhelper, python, python-all-dev, python3-all-dev, python-configobj, python3-configobj, python-docutils, python3-docutils, python-paramiko, python3-paramiko, python-subunit, python3-subunit, python-testtools, python3-testtools, subunit, cython, cython3, python-pip, python3-pip, python-setuptools, python3-setuptools, python-flake8, python3-flake8, python-sphinx, python3-sphinx, python-launchpadlib, python3-launchpadlib |
1199 | +brz.build_deps = gcc, debhelper, python, python-all-dev, python3-all-dev, python-configobj, python3-configobj, python-docutils, python3-docutils, python-paramiko, python3-paramiko, python-subunit, python3-subunit, python-testtools, python3-testtools, subunit, python-pip, python3-pip, python-setuptools, python3-setuptools, python-flake8, python3-flake8, python-sphinx, python3-sphinx, python-launchpadlib, python3-launchpadlib |
1200 | subunit.build_deps = python-testscenarios, python3-testscenarios, python-testtools, python3-testtools |
1201 | vm.packages = {brz.build_deps}, {subunit.build_deps}, bzr, git, python-junitxml |
1202 | [brz-xenial] |
1203 | vm.release = xenial |
1204 | -byoci.setup.command = ({dulwich.clone} && {dulwich.install} && {dulwich.install3} && {fastimport.clone} && {fastimport.install} && {fastimport.install3} && {subunit.clone} && {flake8.install} && {flake8.install3} && {sphinx_epytext.install} && {sphinx_epytext.install3}) |
1205 | +byoci.setup.command = ({dulwich.clone} && {dulwich.install} && {dulwich.install3} && {fastimport.clone} && {fastimport.install} && {fastimport.install3} && {subunit.clone} && {flake8.install} && {flake8.install3} && {sphinx_epytext.install} && {sphinx_epytext.install3} && {cython.install} && {cython.install3}) |
1206 | # FIXME: bzr log -l2 should be by default -- vila 2018-03-09 |
1207 | byoci.tests.command = bash -o pipefail -c "bzr log -l2 && PYTHONPATH=../subunit/python:$PYTHONPATH PATH=../subunit/filters:$PATH make check-ci | subunit2junitxml -o ../results.xml -f | subunit2pyunit" |
1208 | [brz-bionic] |
1209 | |
1210 | === modified file 'doc/developers/apport.txt' |
1211 | --- doc/developers/apport.txt 2009-12-02 20:34:07 +0000 |
1212 | +++ doc/developers/apport.txt 2019-03-06 14:35:55 +0000 |
1213 | @@ -41,7 +41,7 @@ |
1214 | |
1215 | #. An exception reaches the top-level handler. |
1216 | |
1217 | -#. We log it in apport-format to a file in ~/.bazaar/crash. |
1218 | +#. We log it in apport-format to a file in ~/.config/breezy/crash. |
1219 | |
1220 | #. We tell the user where that file is, and invite them to file a bug |
1221 | report. |
1222 | |
1223 | === modified file 'doc/developers/configuration.txt' |
1224 | --- doc/developers/configuration.txt 2017-07-30 16:59:50 +0000 |
1225 | +++ doc/developers/configuration.txt 2019-03-06 14:35:55 +0000 |
1226 | @@ -154,20 +154,6 @@ |
1227 | though). The ``bzr-bookmarks`` plugin defines a ``BOOKMARKS`` section there |
1228 | for example. |
1229 | |
1230 | -pkgimport.conf |
1231 | -============== |
1232 | - |
1233 | -The Ubuntu package importer defines a store and two stacks involving |
1234 | -``pkgimport.conf``. A no-name section contains the options common to all |
1235 | -packages and sections named after their corresponding package can also be |
1236 | -defined. |
1237 | - |
1238 | -The ``ImporterStack`` uses ``locations.conf`` and the no-name section in |
1239 | -``pkgimport.conf`` for the importer options. |
1240 | - |
1241 | -The ``PackageStack`` uses only ``pkgimport.conf`` and uses the section name |
1242 | -after the package followed by the no-name section. |
1243 | - |
1244 | location.conf |
1245 | ============= |
1246 | |
1247 | |
1248 | === modified file 'doc/developers/contribution-quickstart.txt' |
1249 | --- doc/developers/contribution-quickstart.txt 2019-01-01 21:38:07 +0000 |
1250 | +++ doc/developers/contribution-quickstart.txt 2019-03-06 14:35:55 +0000 |
1251 | @@ -46,7 +46,7 @@ |
1252 | closely-related cluster of bugs per branch, to make reviews and merges |
1253 | flow more smoothly. |
1254 | |
1255 | -You probably want this configuration in ``~/.bazaar/locations.conf``:: |
1256 | +You probably want this configuration in ``~/.config/breezy/locations.conf``:: |
1257 | |
1258 | [/home/USER/brz] |
1259 | push_location = lp:~LAUNCHPAD_USER/brz/{branchname} |
1260 | |
1261 | === modified file 'doc/developers/plugin-development.txt' |
1262 | --- doc/developers/plugin-development.txt 2018-11-22 02:23:26 +0000 |
1263 | +++ doc/developers/plugin-development.txt 2019-03-06 14:35:55 +0000 |
1264 | @@ -31,7 +31,7 @@ |
1265 | To ensure your plugin under development is available to Breezy, set |
1266 | the ``BRZ_PLUGIN_PATH`` environment variable to its parent directory. |
1267 | Alternatively, you may wish to develop your plugin within a directory |
1268 | -under your personal plugins area (``~/.bazaar/plugins`` on GNU/Linux) |
1269 | +under your personal plugins area (``~/.config/breezy/plugins`` on GNU/Linux) |
1270 | or put a symbolic link in that area pointing to your plugin under |
1271 | test. Finally you can use ``BRZ_PLUGINS_AT`` to point to a specific |
1272 | directory for a specific plugin (separated by your platform's value of |
1273 | |
1274 | === modified file 'doc/en/admin-guide/hooks-plugins.txt' |
1275 | --- doc/en/admin-guide/hooks-plugins.txt 2018-11-18 13:20:01 +0000 |
1276 | +++ doc/en/admin-guide/hooks-plugins.txt 2019-03-06 14:35:55 +0000 |
1277 | @@ -25,10 +25,10 @@ |
1278 | http://doc.bazaar.canonical.com/plugins/en/. For purposes of installation, |
1279 | plugins are simply python packages. They can be installed alongside Bazaar in |
1280 | the ``bzrlib.plugins`` package using each plugin's ``setup.py``. They can |
1281 | -also be installed in the plugin path which is the user's ``~/.bazaar/plugins`` |
1282 | -directory or can be specified with the ``BZR_PLUGIN_PATH`` environment |
1283 | -variable. See ``bzr help configuration`` for more on specifying the location |
1284 | -of plugins. |
1285 | +also be installed in the plugin path which is the user's |
1286 | +``~/.config/breezy/plugins`` directory or can be specified with the |
1287 | +``BZR_PLUGIN_PATH`` environment variable. See ``bzr help configuration`` for |
1288 | +more on specifying the location of plugins. |
1289 | |
1290 | |
1291 | Email Notification |
1292 | |
1293 | === modified file 'doc/en/admin-guide/migration.txt' |
1294 | --- doc/en/admin-guide/migration.txt 2018-11-18 13:20:01 +0000 |
1295 | +++ doc/en/admin-guide/migration.txt 2019-03-06 14:35:55 +0000 |
1296 | @@ -56,7 +56,7 @@ |
1297 | This command has flexible ways to specify what paths within the Subversion |
1298 | repository contain branches and which contain tags. For example, the |
1299 | recommended layout for Subversion projects (called ``trunk`` by the svn |
1300 | -plugin) could be specified in ``~/.bazaar/subversion.conf`` as |
1301 | +plugin) could be specified in ``~/.config/breezy/subversion.conf`` as |
1302 | |
1303 | :: |
1304 | |
1305 | |
1306 | === modified file 'doc/en/index.txt' |
1307 | --- doc/en/index.txt 2018-09-14 09:31:24 +0000 |
1308 | +++ doc/en/index.txt 2019-03-06 14:35:55 +0000 |
1309 | @@ -10,7 +10,7 @@ |
1310 | .. toctree:: |
1311 | :maxdepth: 1 |
1312 | |
1313 | - whats-new/whats-new-in-3.0 |
1314 | + whats-new/whats-new-in-3.1 |
1315 | user-guide/index |
1316 | tutorials/index |
1317 | quick-reference/index |
1318 | |
1319 | === modified file 'doc/en/release-notes/brz-3.0.txt' |
1320 | --- doc/en/release-notes/brz-3.0.txt 2019-03-02 22:31:28 +0000 |
1321 | +++ doc/en/release-notes/brz-3.0.txt 2019-03-06 14:35:55 +0000 |
1322 | @@ -5,16 +5,16 @@ |
1323 | .. toctree:: |
1324 | :maxdepth: 1 |
1325 | |
1326 | +brz 3.0.0 |
1327 | +######### |
1328 | + |
1329 | +:Codename: Pelican |
1330 | +:3.0.0: 2019-03-06 |
1331 | + |
1332 | brz 3.0.0 is the first release of ``Breezy``, a fork of Bazaar. For more |
1333 | information, see our release announcement on the Bazaar mailing list and |
1334 | README. |
1335 | |
1336 | -brz 3.0.0 |
1337 | -######### |
1338 | - |
1339 | -:Codename: Pelican |
1340 | -:3.0.0: NOT RELEASED YET |
1341 | - |
1342 | External Compatibility Breaks |
1343 | ***************************** |
1344 | |
1345 | @@ -85,6 +85,9 @@ |
1346 | longer performed, since there are no longer |
1347 | any automated imports. (Jelmer Vernooij) |
1348 | |
1349 | + * ``setuptools`` is now required to build and install Breezy. |
1350 | + (Jelmer Vernooij) |
1351 | + |
1352 | New Features |
1353 | ************ |
1354 | |
1355 | @@ -234,6 +237,13 @@ |
1356 | * Don't report .git files as unknown files. |
1357 | (Jelmer Vernooij, Debian Bug #921240) |
1358 | |
1359 | +* Raise better error when path subsegments lack =. |
1360 | + (Jelmer Vernooij, #891483) |
1361 | + |
1362 | +* Display correct pull location argument in |
1363 | + output of ``brz uncommit``. |
1364 | + (Jelmer Vernooij, #386577) |
1365 | + |
1366 | Documentation |
1367 | ************* |
1368 | |
1369 | |
1370 | === added file 'doc/en/release-notes/brz-3.1.txt' |
1371 | --- doc/en/release-notes/brz-3.1.txt 1970-01-01 00:00:00 +0000 |
1372 | +++ doc/en/release-notes/brz-3.1.txt 2019-03-06 14:35:55 +0000 |
1373 | @@ -0,0 +1,62 @@ |
1374 | +#################### |
1375 | +Breezy Release Notes |
1376 | +#################### |
1377 | + |
1378 | +.. toctree:: |
1379 | + :maxdepth: 1 |
1380 | + |
1381 | +brz 3.1.0 |
1382 | +######### |
1383 | + |
1384 | +:Codename: Nirvana |
1385 | +:3.1.0: NOT RELEASED YET |
1386 | + |
1387 | +External Compatibility Breaks |
1388 | +***************************** |
1389 | + |
1390 | +.. These may require users to change the way they use Breezy. |
1391 | + |
1392 | +New Features |
1393 | +************ |
1394 | + |
1395 | +.. New commands, options, etc that users may wish to try out. |
1396 | + |
1397 | +Improvements |
1398 | +************ |
1399 | + |
1400 | +.. Improvements to existing commands, especially improved performance |
1401 | + or memory usage, or better results. |
1402 | + |
1403 | +Bug Fixes |
1404 | +********* |
1405 | + |
1406 | +.. Fixes for situations where brz would previously crash or give incorrect |
1407 | + or undesirable results. |
1408 | + |
1409 | +Documentation |
1410 | +************* |
1411 | + |
1412 | +.. Improved or updated documentation. |
1413 | + |
1414 | +API Changes |
1415 | +*********** |
1416 | + |
1417 | +.. Changes that may require updates in plugins or other code that uses |
1418 | + breezy. |
1419 | + |
1420 | +Internals |
1421 | +********* |
1422 | + |
1423 | +.. Major internal changes, unlikely to be visible to users or plugin |
1424 | + developers, but interesting for brz developers. |
1425 | + |
1426 | +Testing |
1427 | +******* |
1428 | + |
1429 | +.. Fixes and changes that are only relevant to brz's test framework and |
1430 | + suite. This can include new facilities for writing tests, fixes to |
1431 | + spurious test failures and changes to the way things should be tested. |
1432 | + |
1433 | + |
1434 | +.. |
1435 | + vim: tw=74 ft=rst ff=unix |
1436 | |
1437 | === modified file 'doc/en/user-guide/controlling_registration.txt' |
1438 | --- doc/en/user-guide/controlling_registration.txt 2017-05-21 13:41:54 +0000 |
1439 | +++ doc/en/user-guide/controlling_registration.txt 2019-03-06 14:35:55 +0000 |
1440 | @@ -95,12 +95,12 @@ |
1441 | There are some ignored files which are not project specific, but more user |
1442 | specific. Things like editor temporary files, or personal temporary files. |
1443 | Rather than add these ignores to every project, brz supports a global |
1444 | -ignore file in ``~/.bazaar/ignore`` [#]_. It has the same syntax as the |
1445 | +ignore file in ``~/.config/breezy/ignore`` [#]_. It has the same syntax as the |
1446 | per-project ignore file. |
1447 | |
1448 | .. [#] On Windows, the users configuration files can be found in the |
1449 | - application data directory. So instead of ``~/.bazaar/branch.conf`` |
1450 | + application data directory. So instead of ``~/.config/breezy/branch.conf`` |
1451 | the configuration file can be found as: |
1452 | - ``C:\Documents and Settings\<username>\Application Data\Breezy\2.0\branch.conf``. |
1453 | + ``C:\Documents and Settings\<username>\Application Data\Breezy\3.0\branch.conf``. |
1454 | The same is true for ``locations.conf``, ``ignore``, and the |
1455 | ``plugins`` directory. |
1456 | |
1457 | === added file 'doc/en/user-guide/git_limitations.txt' |
1458 | --- doc/en/user-guide/git_limitations.txt 1970-01-01 00:00:00 +0000 |
1459 | +++ doc/en/user-guide/git_limitations.txt 2019-03-06 14:35:55 +0000 |
1460 | @@ -0,0 +1,18 @@ |
1461 | +Git Limitations |
1462 | +=============== |
1463 | + |
1464 | +Breezy's support for Git repositories currently has the following limitations: |
1465 | + |
1466 | +* No support for creating annotated tags. pad.lv/1758185 |
1467 | +* No support for gitattributes and the features that depend on it (lfs, eol, etc). pad.lv/1802797 |
1468 | +* Limited support for submodules. pad.lv/402814 |
1469 | +* No rename/copy inference. pad.lv/1760740 |
1470 | +* No support for creating shallow branches (pad.lv/1760151) |
1471 | +* No good way to refer to git remotes from the command-line (pad.lv/1702283) |
1472 | +* No mailmap support (pad.lv/544031) |
1473 | + |
1474 | +Functionality similar to git that's missing: |
1475 | + |
1476 | +* No rebase command. pad.lv/1708046 |
1477 | +* No --amend option for commit. pad.lv/507529 |
1478 | +* No clone/fetch commands. pad.lv/831939 |
1479 | |
1480 | === modified file 'doc/en/user-guide/index-plain.txt' |
1481 | --- doc/en/user-guide/index-plain.txt 2018-11-24 15:56:05 +0000 |
1482 | +++ doc/en/user-guide/index-plain.txt 2019-03-06 14:35:55 +0000 |
1483 | @@ -114,6 +114,7 @@ |
1484 | .. include:: setting_up_email.txt |
1485 | .. include:: http_smart_server.txt |
1486 | .. include:: writing_a_plugin.txt |
1487 | +.. include:: git_limitations.txt |
1488 | .. include:: licence.txt |
1489 | |
1490 | .. |--| unicode:: U+2014 |
1491 | |
1492 | === modified file 'doc/en/user-guide/installing_breezy.txt' |
1493 | --- doc/en/user-guide/installing_breezy.txt 2018-11-18 13:43:04 +0000 |
1494 | +++ doc/en/user-guide/installing_breezy.txt 2019-03-06 14:35:55 +0000 |
1495 | @@ -90,7 +90,7 @@ |
1496 | 3. Put the created directory on your PATH. |
1497 | |
1498 | Advanced users may also wish to build the optional C extensions for greater |
1499 | -speed. This can be done using ``make`` and requires ``pyrex`` and a C compiler. |
1500 | +speed. This can be done using ``make`` and requires ``cython`` and a C compiler. |
1501 | Please contact us on email or IRC if you need assistance with this. |
1502 | |
1503 | |
1504 | |
1505 | === modified file 'doc/en/user-guide/plugins.txt' |
1506 | --- doc/en/user-guide/plugins.txt 2017-05-21 13:41:54 +0000 |
1507 | +++ doc/en/user-guide/plugins.txt 2019-03-06 14:35:55 +0000 |
1508 | @@ -35,7 +35,7 @@ |
1509 | |
1510 | Installing a plugin is very easy! If not already created, create a |
1511 | ``plugins`` directory under your Breezy configuration directory, |
1512 | -``~/.bazaar/`` on Unix and |
1513 | +``~/.config/breezy/`` on Unix and |
1514 | ``C:\Documents and Settings\<username>\Application Data\Breezy\2.0\`` |
1515 | on Windows. Within this directory (referred to as $BZR_HOME below), |
1516 | each plugin is placed in its own subdirectory. |
1517 | @@ -45,7 +45,7 @@ |
1518 | one can perform the following:: |
1519 | |
1520 | brz branch http://panoramicfeedback.com/opensource/brz/brztools |
1521 | - ~/.bazaar/plugins/brztools |
1522 | + ~/.config/breezy/plugins/brztools |
1523 | |
1524 | When installing plugins, the directories that you install them in must |
1525 | be valid python identifiers. This means that they can only contain |
1526 | |
1527 | === modified file 'doc/en/whats-new/template.txt' |
1528 | --- doc/en/whats-new/template.txt 2011-07-18 15:58:50 +0000 |
1529 | +++ doc/en/whats-new/template.txt 2019-03-06 14:35:55 +0000 |
1530 | @@ -1,8 +1,8 @@ |
1531 | ************************* |
1532 | -What's New in Bazaar x.y? |
1533 | +What's New in Breezy x.y? |
1534 | ************************* |
1535 | |
1536 | -Bazaar x.y is still under development, and will be released in Month Year. |
1537 | +Breezy x.y is still under development, and will be released in Month Year. |
1538 | This document accumulates a high level summary of what's changed. See the |
1539 | :doc:`../release-notes/index` for a full list. |
1540 | |
1541 | @@ -14,7 +14,7 @@ |
1542 | For more detailed information on the changes made, see the the |
1543 | :doc:`../release-notes/index` for: |
1544 | |
1545 | -* the interim bzr `milestones <https://launchpad.net/bzr/x.y>`_ |
1546 | +* the interim brz `milestones <https://launchpad.net/bzr/x.y>`_ |
1547 | * the plugins you use. |
1548 | |
1549 | For a summary of changes made in earlier releases, see: |
1550 | |
1551 | === added file 'doc/en/whats-new/whats-new-in-3.1.txt' |
1552 | --- doc/en/whats-new/whats-new-in-3.1.txt 1970-01-01 00:00:00 +0000 |
1553 | +++ doc/en/whats-new/whats-new-in-3.1.txt 2019-03-06 14:35:55 +0000 |
1554 | @@ -0,0 +1,22 @@ |
1555 | +************************* |
1556 | +What's New in Breezy 3.1? |
1557 | +************************* |
1558 | + |
1559 | +Breezy 3.1 is still under development, and will be released when it is |
1560 | +ready. This document accumulates a high level summary of what's changed. |
1561 | +See the :doc:`../release-notes/index` for a full list. |
1562 | + |
1563 | +<topics of interest here> |
1564 | + |
1565 | +Further information |
1566 | +******************* |
1567 | + |
1568 | +For more detailed information on the changes made, see the the |
1569 | +:doc:`../release-notes/index` for: |
1570 | + |
1571 | +* the interim brz `milestones <https://launchpad.net/brz/3.1>`_ |
1572 | +* the plugins you use. |
1573 | + |
1574 | +For a summary of changes made in earlier releases, see: |
1575 | + |
1576 | +* :doc:`whats-new-in-3.0` |
1577 | |
1578 | === modified file 'setup.py' |
1579 | --- setup.py 2019-02-06 05:44:37 +0000 |
1580 | +++ setup.py 2019-03-06 14:35:55 +0000 |
1581 | @@ -16,6 +16,14 @@ |
1582 | sys.stderr.write("[ERROR] Not a supported Python version. Need 2.7+\n") |
1583 | sys.exit(1) |
1584 | |
1585 | + |
1586 | +try: |
1587 | + import setuptools |
1588 | +except ImportError: |
1589 | + sys.stderr.write("[ERROR] Please install setuptools\n") |
1590 | + sys.exit(1) |
1591 | + |
1592 | + |
1593 | # NOTE: The directory containing setup.py, whether run by 'python setup.py' or |
1594 | # './setup.py' or the equivalent with another path, should always be at the |
1595 | # start of the path, so this should find the right one... |
1596 | @@ -118,8 +126,7 @@ |
1597 | BREEZY['packages'] = get_breezy_packages() |
1598 | |
1599 | |
1600 | -from distutils import log |
1601 | -from distutils.core import setup |
1602 | +from setuptools import setup |
1603 | from distutils.version import LooseVersion |
1604 | from distutils.command.install_scripts import install_scripts |
1605 | from distutils.command.install_data import install_data |
1606 | @@ -211,8 +218,17 @@ |
1607 | print("") |
1608 | from distutils.command.build_ext import build_ext |
1609 | else: |
1610 | - have_cython = True |
1611 | + minimum_cython_version = '0.29' |
1612 | cython_version_info = LooseVersion(cython_version) |
1613 | + if cython_version_info < LooseVersion(minimum_cython_version): |
1614 | + print("Version of Cython is too old. " |
1615 | + "Current is %s, need at least %s." |
1616 | + % (cython_version, minimum_cython_version)) |
1617 | + print("If the .c files are available, they will be built," |
1618 | + " but modifying the .pyx files will not rebuild them.") |
1619 | + have_cython = False |
1620 | + else: |
1621 | + have_cython = True |
1622 | |
1623 | |
1624 | class build_ext_if_possible(build_ext): |
RM self-approval