Merge lp:~vila/bzr/440631-has-changes-no-param into lp:bzr
- 440631-has-changes-no-param
- Merge into bzr.dev
Status: | Merged |
---|---|
Approved by: | John A Meinel |
Approved revision: | no longer in the source branch. |
Merged at revision: | not available |
Proposed branch: | lp:~vila/bzr/440631-has-changes-no-param |
Merge into: | lp:bzr |
Diff against target: |
399 lines 15 files modified
NEWS (+11/-3) bzrlib/builtins.py (+7/-6) bzrlib/bundle/apply_bundle.py (+2/-1) bzrlib/foreign.py (+1/-2) bzrlib/merge.py (+10/-1) bzrlib/mutabletree.py (+11/-3) bzrlib/reconfigure.py (+1/-3) bzrlib/send.py (+2/-3) bzrlib/tests/blackbox/test_merge.py (+1/-1) bzrlib/tests/blackbox/test_uncommit.py (+2/-2) bzrlib/tests/test_msgeditor.py (+1/-1) bzrlib/tests/test_mutabletree.py (+30/-9) bzrlib/tests/test_reconfigure.py (+14/-1) bzrlib/tests/test_status.py (+1/-1) bzrlib/workingtree.py (+4/-4) |
To merge this branch: | bzr merge lp:~vila/bzr/440631-has-changes-no-param |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel | Approve | ||
Review via email: mp+12924@code.launchpad.net |
Commit message
Description of the change
Vincent Ladeuil (vila) wrote : | # |
John A Meinel (jameinel) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Vincent Ladeuil wrote:
> Vincent Ladeuil has proposed merging lp:~vila/bzr/440631-has-changes-no-param into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
> Related bugs:
> #440631 mutable_
> https:/
>
>
> This patch changes MutableTree.
> to the basis tree instead. It also add a check for pending merges.
>
> I've made the '_from_tree' parameter to keep the existing tests or I would have need to rewrite
> them all (~20, none of them trivial).
>
> I've updated all the call sites and fixed the test failures.
> The later led to a discussion with John and Aaron that prompted the deprecations
> of check_basis() and friends since they are not used anymore (and sometimes not tested).
>
> I've also used has_changes() for reconfigure where the pending merges weren't checked,
> and added the corresponding test.
>
Everything looks good, except I don't see any new tests that *don't*
pass the parameter to "has_changes()". It is certainly tested indirectly
via the blackbox tests. So certainly don't change all 20, but maybe 1
or 2 to get a simple unit test of it? Up to you.
review: approve
merge: approve
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAkr
+O8AnipiyUVF4S0
=WI34
-----END PGP SIGNATURE-----
Preview Diff
1 | === modified file 'NEWS' |
2 | --- NEWS 2009-10-06 02:38:44 +0000 |
3 | +++ NEWS 2009-10-06 16:40:25 +0000 |
4 | @@ -160,9 +160,6 @@ |
5 | API Changes |
6 | *********** |
7 | |
8 | -* ``ProgressTask.note`` is deprecated. |
9 | - (Martin Pool) |
10 | - |
11 | * ``bzrlib.user_encoding`` has been removed; use |
12 | ``bzrlib.osutils.get_user_encoding`` instead. (Martin Pool) |
13 | |
14 | @@ -172,6 +169,17 @@ |
15 | * ``bzrlib.trace.log_error``, ``error`` and ``info`` have been deprecated. |
16 | (Martin Pool) |
17 | |
18 | +* ``MutableTree.has_changes()`` does not require a tree parameter anymore. It |
19 | + now defaults to comparing to the basis tree. It now checks for pending |
20 | + merges too. ``Merger.check_basis`` has been deprecated and replaced by the |
21 | + corresponding has_changes() calls. ``Merge.compare_basis``, |
22 | + ``Merger.file_revisions`` and ``Merger.ensure_revision_trees`` have also |
23 | + been deprecated. |
24 | + (Vincent Ladeuil, #440631) |
25 | + |
26 | +* ``ProgressTask.note`` is deprecated. |
27 | + (Martin Pool) |
28 | + |
29 | Internals |
30 | ********* |
31 | |
32 | |
33 | === modified file 'bzrlib/builtins.py' |
34 | --- bzrlib/builtins.py 2009-09-24 19:51:37 +0000 |
35 | +++ bzrlib/builtins.py 2009-10-06 16:40:25 +0000 |
36 | @@ -461,8 +461,7 @@ |
37 | raise errors.BzrCommandError("You cannot remove the working tree" |
38 | " of a remote path") |
39 | if not force: |
40 | - if (working.has_changes(working.basis_tree()) |
41 | - or len(working.get_parent_ids()) > 1): |
42 | + if (working.has_changes()): |
43 | raise errors.UncommittedChanges(working) |
44 | |
45 | working_path = working.bzrdir.root_transport.base |
46 | @@ -1109,8 +1108,7 @@ |
47 | else: |
48 | revision_id = None |
49 | if strict and tree is not None and revision_id is None: |
50 | - if (tree.has_changes(tree.basis_tree()) |
51 | - or len(tree.get_parent_ids()) > 1): |
52 | + if (tree.has_changes()): |
53 | raise errors.UncommittedChanges( |
54 | tree, more='Use --no-strict to force the push.') |
55 | if tree.last_revision() != tree.branch.last_revision(): |
56 | @@ -3663,7 +3661,7 @@ |
57 | |
58 | # die as quickly as possible if there are uncommitted changes |
59 | if not force: |
60 | - if tree.has_changes(basis_tree) or len(tree.get_parent_ids()) > 1: |
61 | + if tree.has_changes(): |
62 | raise errors.UncommittedChanges(tree) |
63 | |
64 | view_info = _get_view_info_for_change_reporter(tree) |
65 | @@ -3720,7 +3718,10 @@ |
66 | merger.other_rev_id) |
67 | result.report(self.outf) |
68 | return 0 |
69 | - merger.check_basis(False) |
70 | + if merger.this_basis is None: |
71 | + raise errors.BzrCommandError( |
72 | + "This branch has no commits." |
73 | + " (perhaps you would prefer 'bzr pull')") |
74 | if preview: |
75 | return self._do_preview(merger, cleanups) |
76 | elif interactive: |
77 | |
78 | === modified file 'bzrlib/bundle/apply_bundle.py' |
79 | --- bzrlib/bundle/apply_bundle.py 2009-03-23 14:59:43 +0000 |
80 | +++ bzrlib/bundle/apply_bundle.py 2009-10-06 16:40:25 +0000 |
81 | @@ -56,7 +56,8 @@ |
82 | change_reporter=change_reporter) |
83 | merger.pp = pp |
84 | merger.pp.next_phase() |
85 | - merger.check_basis(check_clean, require_commits=False) |
86 | + if check_clean and tree.has_changes(): |
87 | + raise errors.UncommittedChanges(self) |
88 | merger.other_rev_id = reader.target |
89 | merger.other_tree = merger.revision_tree(reader.target) |
90 | merger.other_basis = reader.target |
91 | |
92 | === modified file 'bzrlib/foreign.py' |
93 | --- bzrlib/foreign.py 2009-10-02 09:11:43 +0000 |
94 | +++ bzrlib/foreign.py 2009-10-06 16:40:24 +0000 |
95 | @@ -305,8 +305,7 @@ |
96 | ).get_user_option_as_bool('dpush_strict') |
97 | if strict is None: strict = True # default value |
98 | if strict and source_wt is not None: |
99 | - if (source_wt.has_changes(source_wt.basis_tree()) |
100 | - or len(source_wt.get_parent_ids()) > 1): |
101 | + if (source_wt.has_changes()): |
102 | raise errors.UncommittedChanges( |
103 | source_wt, more='Use --no-strict to force the push.') |
104 | if source_wt.last_revision() != source_wt.branch.last_revision(): |
105 | |
106 | === modified file 'bzrlib/merge.py' |
107 | --- bzrlib/merge.py 2009-10-06 12:25:59 +0000 |
108 | +++ bzrlib/merge.py 2009-10-06 16:40:25 +0000 |
109 | @@ -35,6 +35,10 @@ |
110 | ui, |
111 | versionedfile |
112 | ) |
113 | +from bzrlib.symbol_versioning import ( |
114 | + deprecated_in, |
115 | + deprecated_method, |
116 | + ) |
117 | # TODO: Report back as changes are merged in |
118 | |
119 | |
120 | @@ -226,6 +230,7 @@ |
121 | revision_id = _mod_revision.ensure_null(revision_id) |
122 | return branch, self.revision_tree(revision_id, branch) |
123 | |
124 | + @deprecated_method(deprecated_in((2, 1, 0))) |
125 | def ensure_revision_trees(self): |
126 | if self.this_revision_tree is None: |
127 | self.this_basis_tree = self.revision_tree(self.this_basis) |
128 | @@ -239,6 +244,7 @@ |
129 | other_rev_id = self.other_basis |
130 | self.other_tree = other_basis_tree |
131 | |
132 | + @deprecated_method(deprecated_in((2, 1, 0))) |
133 | def file_revisions(self, file_id): |
134 | self.ensure_revision_trees() |
135 | def get_id(tree, file_id): |
136 | @@ -252,6 +258,7 @@ |
137 | trees = (self.this_basis_tree, self.other_tree) |
138 | return [get_id(tree, file_id) for tree in trees] |
139 | |
140 | + @deprecated_method(deprecated_in((2, 1, 0))) |
141 | def check_basis(self, check_clean, require_commits=True): |
142 | if self.this_basis is None and require_commits is True: |
143 | raise errors.BzrCommandError( |
144 | @@ -262,6 +269,7 @@ |
145 | if self.this_basis != self.this_rev_id: |
146 | raise errors.UncommittedChanges(self.this_tree) |
147 | |
148 | + @deprecated_method(deprecated_in((2, 1, 0))) |
149 | def compare_basis(self): |
150 | try: |
151 | basis_tree = self.revision_tree(self.this_tree.last_revision()) |
152 | @@ -274,7 +282,8 @@ |
153 | self.interesting_files = file_list |
154 | |
155 | def set_pending(self): |
156 | - if not self.base_is_ancestor or not self.base_is_other_ancestor or self.other_rev_id is None: |
157 | + if (not self.base_is_ancestor or not self.base_is_other_ancestor |
158 | + or self.other_rev_id is None): |
159 | return |
160 | self._add_parent() |
161 | |
162 | |
163 | === modified file 'bzrlib/mutabletree.py' |
164 | --- bzrlib/mutabletree.py 2009-10-06 12:25:59 +0000 |
165 | +++ bzrlib/mutabletree.py 2009-10-06 16:40:24 +0000 |
166 | @@ -233,12 +233,20 @@ |
167 | raise NotImplementedError(self._gather_kinds) |
168 | |
169 | @needs_read_lock |
170 | - def has_changes(self, from_tree): |
171 | - """Quickly check that the tree contains at least one change. |
172 | + def has_changes(self, _from_tree=None): |
173 | + """Quickly check that the tree contains at least one commitable change. |
174 | + |
175 | + :param _from_tree: tree to compare against to find changes (default to |
176 | + the basis tree and is intended to be used by tests). |
177 | |
178 | :return: True if a change is found. False otherwise |
179 | """ |
180 | - changes = self.iter_changes(from_tree) |
181 | + # Check pending merges |
182 | + if len(self.get_parent_ids()) > 1: |
183 | + return True |
184 | + if _from_tree is None: |
185 | + _from_tree = self.basis_tree() |
186 | + changes = self.iter_changes(_from_tree) |
187 | try: |
188 | change = changes.next() |
189 | # Exclude root (talk about black magic... --vila 20090629) |
190 | |
191 | === modified file 'bzrlib/reconfigure.py' |
192 | --- bzrlib/reconfigure.py 2009-07-24 03:15:56 +0000 |
193 | +++ bzrlib/reconfigure.py 2009-10-06 16:40:25 +0000 |
194 | @@ -265,9 +265,7 @@ |
195 | |
196 | def _check(self): |
197 | """Raise if reconfiguration would destroy local changes""" |
198 | - if self._destroy_tree: |
199 | - # XXX: What about pending merges ? -- vila 20090629 |
200 | - if self.tree.has_changes(self.tree.basis_tree()): |
201 | + if self._destroy_tree and self.tree.has_changes(): |
202 | raise errors.UncommittedChanges(self.tree) |
203 | if self._create_reference and self.local_branch is not None: |
204 | reference_branch = branch.Branch.open(self._select_bind_location()) |
205 | |
206 | === modified file 'bzrlib/send.py' |
207 | --- bzrlib/send.py 2009-07-17 14:41:02 +0000 |
208 | +++ bzrlib/send.py 2009-10-06 16:40:24 +0000 |
209 | @@ -115,14 +115,13 @@ |
210 | ).get_user_option_as_bool('send_strict') |
211 | if strict is None: strict = True # default value |
212 | if strict and tree is not None: |
213 | - if (tree.has_changes(tree.basis_tree()) |
214 | - or len(tree.get_parent_ids()) > 1): |
215 | + if (tree.has_changes()): |
216 | raise errors.UncommittedChanges( |
217 | tree, more='Use --no-strict to force the send.') |
218 | if tree.last_revision() != tree.branch.last_revision(): |
219 | # The tree has lost sync with its branch, there is little |
220 | # chance that the user is aware of it but he can still force |
221 | - # the push with --no-strict |
222 | + # the send with --no-strict |
223 | raise errors.OutOfDateTree( |
224 | tree, more='Use --no-strict to force the send.') |
225 | revision_id = branch.last_revision() |
226 | |
227 | === modified file 'bzrlib/tests/blackbox/test_merge.py' |
228 | --- bzrlib/tests/blackbox/test_merge.py 2009-09-09 15:43:52 +0000 |
229 | +++ bzrlib/tests/blackbox/test_merge.py 2009-10-06 16:40:24 +0000 |
230 | @@ -605,7 +605,7 @@ |
231 | |
232 | def test_merge_force(self): |
233 | self.tree_a.commit('empty change to allow merge to run') |
234 | - # Second merge on top if the uncommitted one |
235 | + # Second merge on top of the uncommitted one |
236 | self.run_bzr(['merge', '../a', '--force'], working_dir='b') |
237 | |
238 | |
239 | |
240 | === modified file 'bzrlib/tests/blackbox/test_uncommit.py' |
241 | --- bzrlib/tests/blackbox/test_uncommit.py 2009-04-04 02:50:01 +0000 |
242 | +++ bzrlib/tests/blackbox/test_uncommit.py 2009-10-06 16:40:24 +0000 |
243 | @@ -233,14 +233,14 @@ |
244 | tree3.commit('unchanged', rev_id='c3') |
245 | |
246 | wt.merge_from_branch(tree2.branch) |
247 | - wt.merge_from_branch(tree3.branch) |
248 | + wt.merge_from_branch(tree3.branch, force=True) |
249 | wt.commit('merge b3, c3', rev_id='a3') |
250 | |
251 | tree2.commit('unchanged', rev_id='b4') |
252 | tree3.commit('unchanged', rev_id='c4') |
253 | |
254 | wt.merge_from_branch(tree3.branch) |
255 | - wt.merge_from_branch(tree2.branch) |
256 | + wt.merge_from_branch(tree2.branch, force=True) |
257 | wt.commit('merge b4, c4', rev_id='a4') |
258 | |
259 | self.assertEqual(['a4'], wt.get_parent_ids()) |
260 | |
261 | === modified file 'bzrlib/tests/test_msgeditor.py' |
262 | --- bzrlib/tests/test_msgeditor.py 2009-08-20 04:09:58 +0000 |
263 | +++ bzrlib/tests/test_msgeditor.py 2009-10-06 16:40:24 +0000 |
264 | @@ -93,7 +93,7 @@ |
265 | tree3.commit('Feature Y, based on initial X work.', |
266 | timestamp=1233285960, timezone=0) |
267 | tree.merge_from_branch(tree2.branch) |
268 | - tree.merge_from_branch(tree3.branch) |
269 | + tree.merge_from_branch(tree3.branch, force=True) |
270 | return tree |
271 | |
272 | def test_commit_template_pending_merges(self): |
273 | |
274 | === modified file 'bzrlib/tests/test_mutabletree.py' |
275 | --- bzrlib/tests/test_mutabletree.py 2009-09-07 23:14:05 +0000 |
276 | +++ bzrlib/tests/test_mutabletree.py 2009-10-06 16:40:24 +0000 |
277 | @@ -19,15 +19,18 @@ |
278 | Most functionality of MutableTree is tested as part of WorkingTree. |
279 | """ |
280 | |
281 | -from bzrlib.tests import TestCase |
282 | -from bzrlib.mutabletree import MutableTree, MutableTreeHooks |
283 | - |
284 | -class TestHooks(TestCase): |
285 | +from bzrlib import ( |
286 | + mutabletree, |
287 | + tests, |
288 | + ) |
289 | + |
290 | + |
291 | +class TestHooks(tests.TestCase): |
292 | |
293 | def test_constructor(self): |
294 | """Check that creating a MutableTreeHooks instance has the right |
295 | defaults.""" |
296 | - hooks = MutableTreeHooks() |
297 | + hooks = mutabletree.MutableTreeHooks() |
298 | self.assertTrue("start_commit" in hooks, |
299 | "start_commit not in %s" % hooks) |
300 | self.assertTrue("post_commit" in hooks, |
301 | @@ -36,7 +39,25 @@ |
302 | def test_installed_hooks_are_MutableTreeHooks(self): |
303 | """The installed hooks object should be a MutableTreeHooks.""" |
304 | # the installed hooks are saved in self._preserved_hooks. |
305 | - self.assertIsInstance(self._preserved_hooks[MutableTree][1], |
306 | - MutableTreeHooks) |
307 | - |
308 | - |
309 | + self.assertIsInstance(self._preserved_hooks[mutabletree.MutableTree][1], |
310 | + mutabletree.MutableTreeHooks) |
311 | + |
312 | + |
313 | +class TestHasChanges(tests.TestCaseWithTransport): |
314 | + |
315 | + def setUp(self): |
316 | + super(TestHasChanges, self).setUp() |
317 | + self.tree = self.make_branch_and_tree('tree') |
318 | + |
319 | + def test_with_uncommitted_changes(self): |
320 | + self.build_tree(['tree/file']) |
321 | + self.tree.add('file') |
322 | + self.assertTrue(self.tree.has_changes()) |
323 | + |
324 | + def test_with_pending_merges(self): |
325 | + other_tree = self.tree.bzrdir.sprout('other').open_workingtree() |
326 | + self.build_tree(['other/file']) |
327 | + other_tree.add('file') |
328 | + other_tree.commit('added file') |
329 | + self.tree.merge_from_branch(other_tree.branch) |
330 | + self.assertTrue(self.tree.has_changes()) |
331 | |
332 | === modified file 'bzrlib/tests/test_reconfigure.py' |
333 | --- bzrlib/tests/test_reconfigure.py 2009-04-28 20:12:44 +0000 |
334 | +++ bzrlib/tests/test_reconfigure.py 2009-10-06 16:40:25 +0000 |
335 | @@ -1,4 +1,4 @@ |
336 | -# Copyright (C) 2007 Canonical Ltd |
337 | +# Copyright (C) 2007, 2008, 2009 Canonical Ltd |
338 | # |
339 | # This program is free software; you can redistribute it and/or modify |
340 | # it under the terms of the GNU General Public License as published by |
341 | @@ -44,6 +44,19 @@ |
342 | self.assertRaises(errors.NoWorkingTree, workingtree.WorkingTree.open, |
343 | 'tree') |
344 | |
345 | + def test_tree_with_pending_merge_to_branch(self): |
346 | + tree = self.make_branch_and_tree('tree') |
347 | + other_tree = tree.bzrdir.sprout('other').open_workingtree() |
348 | + self.build_tree(['other/file']) |
349 | + other_tree.add('file') |
350 | + other_tree.commit('file added') |
351 | + tree.merge_from_branch(other_tree.branch) |
352 | + reconfiguration = reconfigure.Reconfigure.to_branch(tree.bzrdir) |
353 | + self.assertRaises(errors.UncommittedChanges, reconfiguration.apply) |
354 | + reconfiguration.apply(force=True) |
355 | + self.assertRaises(errors.NoWorkingTree, workingtree.WorkingTree.open, |
356 | + 'tree') |
357 | + |
358 | def test_branch_to_branch(self): |
359 | branch = self.make_branch('branch') |
360 | self.assertRaises(errors.AlreadyBranch, |
361 | |
362 | === modified file 'bzrlib/tests/test_status.py' |
363 | --- bzrlib/tests/test_status.py 2009-08-20 04:09:58 +0000 |
364 | +++ bzrlib/tests/test_status.py 2009-10-06 16:40:24 +0000 |
365 | @@ -53,7 +53,7 @@ |
366 | tree2.commit('commit 3b', timestamp=1196796819, timezone=0) |
367 | tree3.commit('commit 3c', timestamp=1196796819, timezone=0) |
368 | tree.merge_from_branch(tree2.branch) |
369 | - tree.merge_from_branch(tree3.branch) |
370 | + tree.merge_from_branch(tree3.branch, force=True) |
371 | return tree |
372 | |
373 | def test_multiple_pending(self): |
374 | |
375 | === modified file 'bzrlib/workingtree.py' |
376 | --- bzrlib/workingtree.py 2009-08-26 05:38:16 +0000 |
377 | +++ bzrlib/workingtree.py 2009-10-06 16:40:25 +0000 |
378 | @@ -896,7 +896,7 @@ |
379 | |
380 | @needs_write_lock # because merge pulls data into the branch. |
381 | def merge_from_branch(self, branch, to_revision=None, from_revision=None, |
382 | - merge_type=None): |
383 | + merge_type=None, force=False): |
384 | """Merge from a branch into this working tree. |
385 | |
386 | :param branch: The branch to merge from. |
387 | @@ -911,9 +911,9 @@ |
388 | merger = Merger(self.branch, this_tree=self, pb=pb) |
389 | merger.pp = ProgressPhase("Merge phase", 5, pb) |
390 | merger.pp.next_phase() |
391 | - # check that there are no |
392 | - # local alterations |
393 | - merger.check_basis(check_clean=True, require_commits=False) |
394 | + # check that there are no local alterations |
395 | + if not force and self.has_changes(): |
396 | + raise errors.UncommittedChanges(self) |
397 | if to_revision is None: |
398 | to_revision = _mod_revision.ensure_null(branch.last_revision()) |
399 | merger.other_rev_id = to_revision |
This patch changes MutableTree. has_changes( ) to stop requiring a tree parameter and default
to the basis tree instead. It also add a check for pending merges.
I've made the '_from_tree' parameter to keep the existing tests or I would have need to rewrite
them all (~20, none of them trivial).
I've updated all the call sites and fixed the test failures.
The later led to a discussion with John and Aaron that prompted the deprecations
of check_basis() and friends since they are not used anymore (and sometimes not tested).
I've also used has_changes() for reconfigure where the pending merges weren't checked,
and added the corresponding test.