Merge lp:~mbp/bzr/45719-update-r into lp:bzr
- 45719-update-r
- 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:~mbp/bzr/45719-update-r | ||||
Merge into: | lp:bzr | ||||
Diff against target: |
361 lines (+176/-37) 5 files modified
NEWS (+13/-5) bzrlib/builtins.py (+41/-15) bzrlib/tests/blackbox/test_update.py (+82/-6) bzrlib/tests/per_workingtree/test_workingtree.py (+14/-0) bzrlib/workingtree.py (+26/-11) |
||||
To merge this branch: | bzr merge lp:~mbp/bzr/45719-update-r | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel | Approve | ||
Review via email: mp+16476@code.launchpad.net |
Commit message
Description of the change
Martin Pool (mbp) wrote : | # |
John A Meinel (jameinel) wrote : | # |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Martin Pool wrote:
> Martin Pool has proposed merging lp:~mbp/bzr/45719-update-r into lp:bzr.
>
> Requested reviews:
> bzr-core (bzr-core)
> Related bugs:
> #45719 update command cannot take a revision number
> https:/
>
>
> This adds a 'bzr update -r' option. If the branch is bound to another, it always updates from the master branch first. This updated form of the patch addresses John's review comments in <https:/
>
> This is an updated version of what was one of the longest-standing merges, and it's for a five-digit bug too <https:/
>
v- does 'change_reporter' need to be inside the try/except ? I think it
just got refactored into there.
+ try:
+ change_reporter = delta._
+ unversioned_
+ view_info=
+ conflicts = tree.update(
+ change_reporter,
+ possible_
+ revision=rev,
+ old_tip=old_tip)
+ except errors.
+ raise errors.
+ "branch has no revision %s\n"
+ "bzr update --revision only works"
+ " for a revision in the branch
history"
+ % (e.revision))
+ if revision is not None:
+ rev = revision[
+ else:
+ rev = branch.
^- It might be clearer as 'rev_id' or 'revision_id = '. We have some
ambiguous naming (is it a Revision, revision_id, or RevSpec...) However,
this is really minor.
review: approve
merge: approve
John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://
iEYEARECAAYFAks
sdIAn3ABG2q0Rkq
=IrMf
-----END PGP SIGNATURE-----
Preview Diff
1 | === modified file 'NEWS' | |||
2 | --- NEWS 2009-12-23 05:04:12 +0000 | |||
3 | +++ NEWS 2009-12-23 06:33:19 +0000 | |||
4 | @@ -23,11 +23,10 @@ | |||
5 | 23 | ``locations.conf`` or ``branch.conf``. | 23 | ``locations.conf`` or ``branch.conf``. |
6 | 24 | (Ted Gould, Matthew Fuller, Vincent Ladeuil) | 24 | (Ted Gould, Matthew Fuller, Vincent Ladeuil) |
7 | 25 | 25 | ||
13 | 26 | * ``bzrlib.tests.permute_for_extension`` is a helper that simplifies | 26 | * ``bzr update`` now takes a ``--revision`` argument. This lets you |
14 | 27 | running all tests in the current module, once against a pure python | 27 | change the revision of the working tree to any revision in the |
15 | 28 | implementation, and once against an extension (pyrex/C) implementation. | 28 | ancestry of the current or master branch. (Matthieu Moy, Mark Hammond, |
16 | 29 | It can be used to dramatically simplify the implementation of | 29 | Martin Pool, #45719) |
12 | 30 | ``load_tests``. (John Arbash Meinel) | ||
17 | 31 | 30 | ||
18 | 32 | Bug Fixes | 31 | Bug Fixes |
19 | 33 | ********* | 32 | ********* |
20 | @@ -60,6 +59,9 @@ | |||
21 | 60 | CamelCase. For the features that were more likely to be used, we added a | 59 | CamelCase. For the features that were more likely to be used, we added a |
22 | 61 | deprecation thunk, but not all. (John Arbash Meinel) | 60 | deprecation thunk, but not all. (John Arbash Meinel) |
23 | 62 | 61 | ||
24 | 62 | * ``WorkingTree.update`` implementations must now accept a ``revision`` | ||
25 | 63 | parameter. | ||
26 | 64 | |||
27 | 63 | Internals | 65 | Internals |
28 | 64 | ********* | 66 | ********* |
29 | 65 | 67 | ||
30 | @@ -71,6 +73,12 @@ | |||
31 | 71 | Testing | 73 | Testing |
32 | 72 | ******* | 74 | ******* |
33 | 73 | 75 | ||
34 | 76 | * ``bzrlib.tests.permute_for_extension`` is a helper that simplifies | ||
35 | 77 | running all tests in the current module, once against a pure python | ||
36 | 78 | implementation, and once against an extension (pyrex/C) implementation. | ||
37 | 79 | It can be used to dramatically simplify the implementation of | ||
38 | 80 | ``load_tests``. (John Arbash Meinel) | ||
39 | 81 | |||
40 | 74 | * ``bzrlib.tests.TestCase`` now subclasses ``testtools.testcase.TestCase``. | 82 | * ``bzrlib.tests.TestCase`` now subclasses ``testtools.testcase.TestCase``. |
41 | 75 | This permits features in testtools such as getUniqueInteger and | 83 | This permits features in testtools such as getUniqueInteger and |
42 | 76 | getUniqueString to be used. Because of this, testtools version 0.9.2 or | 84 | getUniqueString to be used. Because of this, testtools version 0.9.2 or |
43 | 77 | 85 | ||
44 | === modified file 'bzrlib/builtins.py' | |||
45 | --- bzrlib/builtins.py 2009-12-21 17:24:22 +0000 | |||
46 | +++ bzrlib/builtins.py 2009-12-23 06:33:19 +0000 | |||
47 | @@ -1388,16 +1388,24 @@ | |||
48 | 1388 | 1388 | ||
49 | 1389 | If you want to discard your local changes, you can just do a | 1389 | If you want to discard your local changes, you can just do a |
50 | 1390 | 'bzr revert' instead of 'bzr commit' after the update. | 1390 | 'bzr revert' instead of 'bzr commit' after the update. |
51 | 1391 | |||
52 | 1392 | If the tree's branch is bound to a master branch, it will also update | ||
53 | 1393 | the branch from the master. | ||
54 | 1391 | """ | 1394 | """ |
55 | 1392 | 1395 | ||
56 | 1393 | _see_also = ['pull', 'working-trees', 'status-flags'] | 1396 | _see_also = ['pull', 'working-trees', 'status-flags'] |
57 | 1394 | takes_args = ['dir?'] | 1397 | takes_args = ['dir?'] |
58 | 1398 | takes_options = ['revision'] | ||
59 | 1395 | aliases = ['up'] | 1399 | aliases = ['up'] |
60 | 1396 | 1400 | ||
62 | 1397 | def run(self, dir='.'): | 1401 | def run(self, dir='.', revision=None): |
63 | 1402 | if revision is not None and len(revision) != 1: | ||
64 | 1403 | raise errors.BzrCommandError( | ||
65 | 1404 | "bzr update --revision takes exactly one revision") | ||
66 | 1398 | tree = WorkingTree.open_containing(dir)[0] | 1405 | tree = WorkingTree.open_containing(dir)[0] |
67 | 1406 | branch = tree.branch | ||
68 | 1399 | possible_transports = [] | 1407 | possible_transports = [] |
70 | 1400 | master = tree.branch.get_master_branch( | 1408 | master = branch.get_master_branch( |
71 | 1401 | possible_transports=possible_transports) | 1409 | possible_transports=possible_transports) |
72 | 1402 | if master is not None: | 1410 | if master is not None: |
73 | 1403 | tree.lock_write() | 1411 | tree.lock_write() |
74 | @@ -1410,20 +1418,38 @@ | |||
75 | 1410 | self.outf.encoding) | 1418 | self.outf.encoding) |
76 | 1411 | try: | 1419 | try: |
77 | 1412 | existing_pending_merges = tree.get_parent_ids()[1:] | 1420 | existing_pending_merges = tree.get_parent_ids()[1:] |
88 | 1413 | last_rev = _mod_revision.ensure_null(tree.last_revision()) | 1421 | if master is None: |
89 | 1414 | if last_rev == _mod_revision.ensure_null( | 1422 | old_tip = None |
90 | 1415 | tree.branch.last_revision()): | 1423 | else: |
91 | 1416 | # may be up to date, check master too. | 1424 | # may need to fetch data into a heavyweight checkout |
92 | 1417 | if master is None or last_rev == _mod_revision.ensure_null( | 1425 | # XXX: this may take some time, maybe we should display a |
93 | 1418 | master.last_revision()): | 1426 | # message |
94 | 1419 | revno = tree.branch.revision_id_to_revno(last_rev) | 1427 | old_tip = branch.update(possible_transports) |
95 | 1420 | note('Tree is up to date at revision %d of branch %s' | 1428 | if revision is not None: |
96 | 1421 | % (revno, branch_location)) | 1429 | revision_id = revision[0].as_revision_id(branch) |
97 | 1422 | return 0 | 1430 | else: |
98 | 1431 | revision_id = branch.last_revision() | ||
99 | 1432 | if revision_id == _mod_revision.ensure_null(tree.last_revision()): | ||
100 | 1433 | revno = branch.revision_id_to_revno(revision_id) | ||
101 | 1434 | note("Tree is up to date at revision %d of branch %s" % | ||
102 | 1435 | (revno, branch_location)) | ||
103 | 1436 | return 0 | ||
104 | 1423 | view_info = _get_view_info_for_change_reporter(tree) | 1437 | view_info = _get_view_info_for_change_reporter(tree) |
108 | 1424 | conflicts = tree.update( | 1438 | change_reporter = delta._ChangeReporter( |
109 | 1425 | delta._ChangeReporter(unversioned_filter=tree.is_ignored, | 1439 | unversioned_filter=tree.is_ignored, |
110 | 1426 | view_info=view_info), possible_transports=possible_transports) | 1440 | view_info=view_info) |
111 | 1441 | try: | ||
112 | 1442 | conflicts = tree.update( | ||
113 | 1443 | change_reporter, | ||
114 | 1444 | possible_transports=possible_transports, | ||
115 | 1445 | revision=revision_id, | ||
116 | 1446 | old_tip=old_tip) | ||
117 | 1447 | except errors.NoSuchRevision, e: | ||
118 | 1448 | raise errors.BzrCommandError( | ||
119 | 1449 | "branch has no revision %s\n" | ||
120 | 1450 | "bzr update --revision only works" | ||
121 | 1451 | " for a revision in the branch history" | ||
122 | 1452 | % (e.revision)) | ||
123 | 1427 | revno = tree.branch.revision_id_to_revno( | 1453 | revno = tree.branch.revision_id_to_revno( |
124 | 1428 | _mod_revision.ensure_null(tree.last_revision())) | 1454 | _mod_revision.ensure_null(tree.last_revision())) |
125 | 1429 | note('Updated to revision %d of branch %s' % | 1455 | note('Updated to revision %d of branch %s' % |
126 | 1430 | 1456 | ||
127 | === modified file 'bzrlib/tests/blackbox/test_update.py' | |||
128 | --- bzrlib/tests/blackbox/test_update.py 2009-12-14 15:51:36 +0000 | |||
129 | +++ bzrlib/tests/blackbox/test_update.py 2009-12-23 06:33:19 +0000 | |||
130 | @@ -1,4 +1,4 @@ | |||
132 | 1 | # Copyright (C) 2006 Canonical Ltd | 1 | # Copyright (C) 2006, 2009 Canonical Ltd |
133 | 2 | # -*- coding: utf-8 -*- | 2 | # -*- coding: utf-8 -*- |
134 | 3 | # | 3 | # |
135 | 4 | # This program is free software; you can redistribute it and/or modify | 4 | # This program is free software; you can redistribute it and/or modify |
136 | @@ -29,6 +29,7 @@ | |||
137 | 29 | urlutils, | 29 | urlutils, |
138 | 30 | workingtree, | 30 | workingtree, |
139 | 31 | ) | 31 | ) |
140 | 32 | from bzrlib.tests.script import ScriptRunner | ||
141 | 32 | 33 | ||
142 | 33 | 34 | ||
143 | 34 | class TestUpdate(tests.TestCaseWithTransport): | 35 | class TestUpdate(tests.TestCaseWithTransport): |
144 | @@ -67,11 +68,11 @@ | |||
145 | 67 | def test_update_up_to_date_checkout(self): | 68 | def test_update_up_to_date_checkout(self): |
146 | 68 | self.make_branch_and_tree('branch') | 69 | self.make_branch_and_tree('branch') |
147 | 69 | self.run_bzr('checkout branch checkout') | 70 | self.run_bzr('checkout branch checkout') |
153 | 70 | out, err = self.run_bzr('update checkout') | 71 | sr = ScriptRunner() |
154 | 71 | self.assertEqual('Tree is up to date at revision 0 of branch %s\n' | 72 | sr.run_script(self, ''' |
155 | 72 | % osutils.pathjoin(self.test_dir, 'branch'), | 73 | $ bzr update checkout |
156 | 73 | err) | 74 | 2>Tree is up to date at revision 0 of branch .../branch |
157 | 74 | self.assertEqual('', out) | 75 | ''') |
158 | 75 | 76 | ||
159 | 76 | def test_update_out_of_date_standalone_tree(self): | 77 | def test_update_out_of_date_standalone_tree(self): |
160 | 77 | # FIXME the default format has to change for this to pass | 78 | # FIXME the default format has to change for this to pass |
161 | @@ -239,3 +240,78 @@ | |||
162 | 239 | lightweight=True) | 240 | lightweight=True) |
163 | 240 | tree.commit('empty commit') | 241 | tree.commit('empty commit') |
164 | 241 | self.run_bzr('update checkout') | 242 | self.run_bzr('update checkout') |
165 | 243 | |||
166 | 244 | def test_update_dash_r(self): | ||
167 | 245 | # Test that 'bzr update' works correctly when you have | ||
168 | 246 | # an update in the master tree, and a lightweight checkout | ||
169 | 247 | # which has merged another branch | ||
170 | 248 | master = self.make_branch_and_tree('master') | ||
171 | 249 | os.chdir('master') | ||
172 | 250 | self.build_tree(['./file1']) | ||
173 | 251 | master.add(['file1']) | ||
174 | 252 | master.commit('one', rev_id='m1') | ||
175 | 253 | self.build_tree(['./file2']) | ||
176 | 254 | master.add(['file2']) | ||
177 | 255 | master.commit('two', rev_id='m2') | ||
178 | 256 | |||
179 | 257 | sr = ScriptRunner() | ||
180 | 258 | sr.run_script(self, ''' | ||
181 | 259 | $ bzr update -r 1 | ||
182 | 260 | 2>-D file2 | ||
183 | 261 | 2>All changes applied successfully. | ||
184 | 262 | 2>Updated to revision 1 of .../master | ||
185 | 263 | ''') | ||
186 | 264 | self.failUnlessExists('./file1') | ||
187 | 265 | self.failIfExists('./file2') | ||
188 | 266 | self.assertEquals(['m1'], master.get_parent_ids()) | ||
189 | 267 | |||
190 | 268 | def test_update_dash_r_outside_history(self): | ||
191 | 269 | # Test that 'bzr update' works correctly when you have | ||
192 | 270 | # an update in the master tree, and a lightweight checkout | ||
193 | 271 | # which has merged another branch | ||
194 | 272 | master = self.make_branch_and_tree('master') | ||
195 | 273 | self.build_tree(['master/file1']) | ||
196 | 274 | master.add(['file1']) | ||
197 | 275 | master.commit('one', rev_id='m1') | ||
198 | 276 | |||
199 | 277 | # Create a second branch, with an extra commit | ||
200 | 278 | other = master.bzrdir.sprout('other').open_workingtree() | ||
201 | 279 | self.build_tree(['other/file2']) | ||
202 | 280 | other.add(['file2']) | ||
203 | 281 | other.commit('other2', rev_id='o2') | ||
204 | 282 | |||
205 | 283 | os.chdir('master') | ||
206 | 284 | self.run_bzr('merge ../other') | ||
207 | 285 | master.commit('merge', rev_id='merge') | ||
208 | 286 | |||
209 | 287 | out, err = self.run_bzr('update -r revid:o2', | ||
210 | 288 | retcode=3) | ||
211 | 289 | self.assertEqual('', out) | ||
212 | 290 | self.assertEqual('bzr: ERROR: branch has no revision o2\n' | ||
213 | 291 | 'bzr update --revision only works' | ||
214 | 292 | ' for a revision in the branch history\n', | ||
215 | 293 | err) | ||
216 | 294 | |||
217 | 295 | def test_update_dash_r_in_master(self): | ||
218 | 296 | # Test that 'bzr update' works correctly when you have | ||
219 | 297 | # an update in the master tree, | ||
220 | 298 | master = self.make_branch_and_tree('master') | ||
221 | 299 | self.build_tree(['master/file1']) | ||
222 | 300 | master.add(['file1']) | ||
223 | 301 | master.commit('one', rev_id='m1') | ||
224 | 302 | |||
225 | 303 | self.run_bzr('checkout master checkout') | ||
226 | 304 | |||
227 | 305 | # add a revision in the master. | ||
228 | 306 | self.build_tree(['master/file2']) | ||
229 | 307 | master.add(['file2']) | ||
230 | 308 | master.commit('two', rev_id='m2') | ||
231 | 309 | |||
232 | 310 | os.chdir('checkout') | ||
233 | 311 | sr = ScriptRunner() | ||
234 | 312 | sr.run_script(self, ''' | ||
235 | 313 | $ bzr update -r revid:m2 | ||
236 | 314 | 2>+N file2 | ||
237 | 315 | 2>All changes applied successfully. | ||
238 | 316 | 2>Updated to revision 2 of branch .../master | ||
239 | 317 | ''') | ||
240 | 242 | 318 | ||
241 | === modified file 'bzrlib/tests/per_workingtree/test_workingtree.py' | |||
242 | --- bzrlib/tests/per_workingtree/test_workingtree.py 2009-11-08 05:28:57 +0000 | |||
243 | +++ bzrlib/tests/per_workingtree/test_workingtree.py 2009-12-23 06:33:19 +0000 | |||
244 | @@ -590,6 +590,20 @@ | |||
245 | 590 | self.assertEqual(master_tree.branch.revision_history(), | 590 | self.assertEqual(master_tree.branch.revision_history(), |
246 | 591 | tree.branch.revision_history()) | 591 | tree.branch.revision_history()) |
247 | 592 | 592 | ||
248 | 593 | def test_update_takes_revision_parameter(self): | ||
249 | 594 | wt = self.make_branch_and_tree('wt') | ||
250 | 595 | self.build_tree_contents([('wt/a', 'old content')]) | ||
251 | 596 | wt.add(['a']) | ||
252 | 597 | rev1 = wt.commit('first master commit') | ||
253 | 598 | self.build_tree_contents([('wt/a', 'new content')]) | ||
254 | 599 | rev2 = wt.commit('second master commit') | ||
255 | 600 | # https://bugs.edge.launchpad.net/bzr/+bug/45719/comments/20 | ||
256 | 601 | # when adding 'update -r' we should make sure all wt formats support | ||
257 | 602 | # it | ||
258 | 603 | conflicts = wt.update(revision=rev1) | ||
259 | 604 | self.assertFileEqual('old content', 'wt/a') | ||
260 | 605 | self.assertEqual([rev1], wt.get_parent_ids()) | ||
261 | 606 | |||
262 | 593 | def test_merge_modified_detects_corruption(self): | 607 | def test_merge_modified_detects_corruption(self): |
263 | 594 | # FIXME: This doesn't really test that it works; also this is not | 608 | # FIXME: This doesn't really test that it works; also this is not |
264 | 595 | # implementation-independent. mbp 20070226 | 609 | # implementation-independent. mbp 20070226 |
265 | 596 | 610 | ||
266 | === modified file 'bzrlib/workingtree.py' | |||
267 | --- bzrlib/workingtree.py 2009-12-02 18:15:55 +0000 | |||
268 | +++ bzrlib/workingtree.py 2009-12-23 06:33:19 +0000 | |||
269 | @@ -2191,7 +2191,10 @@ | |||
270 | 2191 | """ | 2191 | """ |
271 | 2192 | raise NotImplementedError(self.unlock) | 2192 | raise NotImplementedError(self.unlock) |
272 | 2193 | 2193 | ||
274 | 2194 | def update(self, change_reporter=None, possible_transports=None): | 2194 | _marker = object() |
275 | 2195 | |||
276 | 2196 | def update(self, change_reporter=None, possible_transports=None, | ||
277 | 2197 | revision=None, old_tip=_marker): | ||
278 | 2195 | """Update a working tree along its branch. | 2198 | """Update a working tree along its branch. |
279 | 2196 | 2199 | ||
280 | 2197 | This will update the branch if its bound too, which means we have | 2200 | This will update the branch if its bound too, which means we have |
281 | @@ -2215,10 +2218,16 @@ | |||
282 | 2215 | - Merge current state -> basis tree of the master w.r.t. the old tree | 2218 | - Merge current state -> basis tree of the master w.r.t. the old tree |
283 | 2216 | basis. | 2219 | basis. |
284 | 2217 | - Do a 'normal' merge of the old branch basis if it is relevant. | 2220 | - Do a 'normal' merge of the old branch basis if it is relevant. |
285 | 2221 | |||
286 | 2222 | :param revision: The target revision to update to. Must be in the | ||
287 | 2223 | revision history. | ||
288 | 2224 | :param old_tip: If branch.update() has already been run, the value it | ||
289 | 2225 | returned (old tip of the branch or None). _marker is used | ||
290 | 2226 | otherwise. | ||
291 | 2218 | """ | 2227 | """ |
292 | 2219 | if self.branch.get_bound_location() is not None: | 2228 | if self.branch.get_bound_location() is not None: |
293 | 2220 | self.lock_write() | 2229 | self.lock_write() |
295 | 2221 | update_branch = True | 2230 | update_branch = (old_tip is self._marker) |
296 | 2222 | else: | 2231 | else: |
297 | 2223 | self.lock_tree_write() | 2232 | self.lock_tree_write() |
298 | 2224 | update_branch = False | 2233 | update_branch = False |
299 | @@ -2226,13 +2235,14 @@ | |||
300 | 2226 | if update_branch: | 2235 | if update_branch: |
301 | 2227 | old_tip = self.branch.update(possible_transports) | 2236 | old_tip = self.branch.update(possible_transports) |
302 | 2228 | else: | 2237 | else: |
305 | 2229 | old_tip = None | 2238 | if old_tip is self._marker: |
306 | 2230 | return self._update_tree(old_tip, change_reporter) | 2239 | old_tip = None |
307 | 2240 | return self._update_tree(old_tip, change_reporter, revision) | ||
308 | 2231 | finally: | 2241 | finally: |
309 | 2232 | self.unlock() | 2242 | self.unlock() |
310 | 2233 | 2243 | ||
311 | 2234 | @needs_tree_write_lock | 2244 | @needs_tree_write_lock |
313 | 2235 | def _update_tree(self, old_tip=None, change_reporter=None): | 2245 | def _update_tree(self, old_tip=None, change_reporter=None, revision=None): |
314 | 2236 | """Update a tree to the master branch. | 2246 | """Update a tree to the master branch. |
315 | 2237 | 2247 | ||
316 | 2238 | :param old_tip: if supplied, the previous tip revision the branch, | 2248 | :param old_tip: if supplied, the previous tip revision the branch, |
317 | @@ -2253,12 +2263,17 @@ | |||
318 | 2253 | last_rev = self.get_parent_ids()[0] | 2263 | last_rev = self.get_parent_ids()[0] |
319 | 2254 | except IndexError: | 2264 | except IndexError: |
320 | 2255 | last_rev = _mod_revision.NULL_REVISION | 2265 | last_rev = _mod_revision.NULL_REVISION |
323 | 2256 | if last_rev != _mod_revision.ensure_null(self.branch.last_revision()): | 2266 | if revision is None: |
324 | 2257 | # merge tree state up to new branch tip. | 2267 | revision = self.branch.last_revision() |
325 | 2268 | else: | ||
326 | 2269 | if revision not in self.branch.revision_history(): | ||
327 | 2270 | raise errors.NoSuchRevision(self.branch, revision) | ||
328 | 2271 | if last_rev != _mod_revision.ensure_null(revision): | ||
329 | 2272 | # merge tree state up to specified revision. | ||
330 | 2258 | basis = self.basis_tree() | 2273 | basis = self.basis_tree() |
331 | 2259 | basis.lock_read() | 2274 | basis.lock_read() |
332 | 2260 | try: | 2275 | try: |
334 | 2261 | to_tree = self.branch.basis_tree() | 2276 | to_tree = self.branch.repository.revision_tree(revision) |
335 | 2262 | if basis.inventory.root is None: | 2277 | if basis.inventory.root is None: |
336 | 2263 | self.set_root_id(to_tree.get_root_id()) | 2278 | self.set_root_id(to_tree.get_root_id()) |
337 | 2264 | self.flush() | 2279 | self.flush() |
338 | @@ -2268,11 +2283,12 @@ | |||
339 | 2268 | basis, | 2283 | basis, |
340 | 2269 | this_tree=self, | 2284 | this_tree=self, |
341 | 2270 | change_reporter=change_reporter) | 2285 | change_reporter=change_reporter) |
342 | 2286 | self.set_last_revision(revision) | ||
343 | 2271 | finally: | 2287 | finally: |
344 | 2272 | basis.unlock() | 2288 | basis.unlock() |
345 | 2273 | # TODO - dedup parents list with things merged by pull ? | 2289 | # TODO - dedup parents list with things merged by pull ? |
346 | 2274 | # reuse the tree we've updated to to set the basis: | 2290 | # reuse the tree we've updated to to set the basis: |
348 | 2275 | parent_trees = [(self.branch.last_revision(), to_tree)] | 2291 | parent_trees = [(revision, to_tree)] |
349 | 2276 | merges = self.get_parent_ids()[1:] | 2292 | merges = self.get_parent_ids()[1:] |
350 | 2277 | # Ideally we ask the tree for the trees here, that way the working | 2293 | # Ideally we ask the tree for the trees here, that way the working |
351 | 2278 | # tree can decide whether to give us the entire tree or give us a | 2294 | # tree can decide whether to give us the entire tree or give us a |
352 | @@ -2308,8 +2324,7 @@ | |||
353 | 2308 | # should be able to remove this extra flush. | 2324 | # should be able to remove this extra flush. |
354 | 2309 | self.flush() | 2325 | self.flush() |
355 | 2310 | graph = self.branch.repository.get_graph() | 2326 | graph = self.branch.repository.get_graph() |
358 | 2311 | base_rev_id = graph.find_unique_lca(self.branch.last_revision(), | 2327 | base_rev_id = graph.find_unique_lca(revision, old_tip) |
357 | 2312 | old_tip) | ||
359 | 2313 | base_tree = self.branch.repository.revision_tree(base_rev_id) | 2328 | base_tree = self.branch.repository.revision_tree(base_rev_id) |
360 | 2314 | other_tree = self.branch.repository.revision_tree(old_tip) | 2329 | other_tree = self.branch.repository.revision_tree(old_tip) |
361 | 2315 | result += merge.merge_inner( | 2330 | result += merge.merge_inner( |
This adds a 'bzr update -r' option. If the branch is bound to another, it always updates from the master branch first. This updated form of the patch addresses John's review comments in <https:/ /bugs.edge. launchpad. net/bzr/ +bug/45719/ comments/ 20>.
This is an updated version of what was one of the longest-standing merges, and it's for a five-digit bug too <https:/ /bugs.edge. launchpad. net/bzr/ +bug/45719>.