Merge lp:~jelmer/brz/git-switch into lp:brz

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/git-switch
Merge into: lp:brz
Diff against target: 218 lines (+98/-67)
3 files modified
breezy/git/tests/test_blackbox.py (+32/-0)
breezy/switch.py (+64/-65)
breezy/tests/blackbox/test_switch.py (+2/-2)
To merge this branch: bzr merge lp:~jelmer/brz/git-switch
Reviewer Review Type Date Requested Status
Martin Packman Approve
Review via email: mp+358603@code.launchpad.net

Commit message

Fix 'brz switch' in git repositories.

Description of the change

Fix 'brz switch' in git repositories.

To post a comment you must log in.
Revision history for this message
Martin Packman (gz) wrote :

Okay. This is pretty hairy but was previously as well.

review: Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'breezy/git/tests/test_blackbox.py'
--- breezy/git/tests/test_blackbox.py 2018-11-16 19:47:19 +0000
+++ breezy/git/tests/test_blackbox.py 2018-11-16 23:29:29 +0000
@@ -30,6 +30,7 @@
30 )30 )
3131
32from ...tests.blackbox import ExternalBase32from ...tests.blackbox import ExternalBase
33from ...workingtree import WorkingTree
3334
34from .. import (35from .. import (
35 tests,36 tests,
@@ -338,6 +339,37 @@
338 self.assertEqual(output, 'VERSION_INFO \n')339 self.assertEqual(output, 'VERSION_INFO \n')
339340
340341
342class SwitchTests(ExternalBase):
343
344 def test_switch_branch(self):
345 # Create a git repository with a revision.
346 repo = GitRepo.init(self.test_dir)
347 builder = tests.GitBranchBuilder()
348 builder.set_branch(b'refs/heads/oldbranch')
349 builder.set_file('a', b'text for a\n', False)
350 builder.commit(b'Joe Foo <joe@foo.com>', u'<The commit message>')
351 builder.set_branch(b'refs/heads/newbranch')
352 builder.reset()
353 builder.set_file('a', b'text for new a\n', False)
354 builder.commit(b'Joe Foo <joe@foo.com>', u'<The commit message>')
355 builder.finish()
356
357 repo.refs.set_symbolic_ref(b'HEAD', b'refs/heads/newbranch')
358
359 repo.reset_index()
360
361 output, error = self.run_bzr('switch oldbranch')
362 self.assertEqual(output, '')
363 self.assertTrue(error.startswith('Updated to revision 1.\n'), error)
364
365 self.assertFileEqual("text for a\n", 'a')
366 tree = WorkingTree.open('.')
367 with tree.lock_read():
368 basis_tree = tree.basis_tree()
369 with basis_tree.lock_read():
370 self.assertEqual([], list(tree.iter_changes(basis_tree)))
371
372
341class GrepTests(ExternalBase):373class GrepTests(ExternalBase):
342374
343 def test_simple_grep(self):375 def test_simple_grep(self):
344376
=== modified file 'breezy/switch.py'
--- breezy/switch.py 2018-11-12 01:41:38 +0000
+++ breezy/switch.py 2018-11-16 23:29:29 +0000
@@ -50,42 +50,74 @@
50 :param store_uncommitted: If True, store uncommitted changes in the50 :param store_uncommitted: If True, store uncommitted changes in the
51 branch.51 branch.
52 """52 """
53 _check_pending_merges(control_dir, force)53 try:
54 try:54 tree = control_dir.open_workingtree()
55 source_repository = control_dir.open_branch().repository55 except errors.NotBranchError as ex:
56 except errors.NotBranchError:56 # Lightweight checkout and branch is no longer there
57 source_repository = to_branch.repository57 if not force or store_uncommitted:
58 if store_uncommitted:58 raise ex
59 with lock.write_locked(control_dir.open_workingtree()) as tree:59 else:
60 tree = None
61 else:
62 if store_uncommitted or tree.branch.get_bound_location():
63 tree.lock_write()
64 else:
65 tree.lock_tree_write()
66 try:
67 if tree is not None:
68 parent_ids = tree.get_parent_ids()
69 if len(parent_ids) > 1:
70 raise errors.BzrCommandError(
71 gettext('Pending merges must be '
72 'committed or reverted before using switch.'))
73
74 if store_uncommitted:
60 tree.store_uncommitted()75 tree.store_uncommitted()
76 if tree is None:
77 source_repository = to_branch.repository
78 base_revision_id = None
79 else:
80 source_repository = tree.branch.repository
81 # Attempt to retrieve the base_revision_id now, since some
82 # working tree formats (i.e. git) don't have their own
83 # last_revision but just use that of the currently active branch.
84 base_revision_id = tree.last_revision()
85 finally:
86 if tree is not None:
87 tree.unlock()
61 with to_branch.lock_read():88 with to_branch.lock_read():
62 _set_branch_location(control_dir, to_branch, force)89 _set_branch_location(control_dir, to_branch, tree.branch if tree else None, force)
63 tree = control_dir.open_workingtree()90 tree = control_dir.open_workingtree()
64 _update(tree, source_repository, quiet, revision_id, store_uncommitted)91 if store_uncommitted:
65 _run_post_switch_hooks(control_dir, to_branch, force, revision_id)92 tree.lock_write()
6693 else:
6794 tree.lock_tree_write()
68def _check_pending_merges(control, force=False):
69 """Check that there are no outstanding pending merges before switching.
70
71 :param control: ControlDir of the branch to check
72 """
73 try:95 try:
74 tree = control.open_workingtree()96 if base_revision_id is None:
75 except errors.NotBranchError as ex:97 # If we couldn't get to the tree's last_revision earlier, perhaps
76 # Lightweight checkout and branch is no longer there98 # we can now.
77 if force:99 base_revision_id = tree.last_revision()
78 return100 if revision_id is None:
101 revision_id = to_branch.last_revision()
102 if base_revision_id == revision_id:
103 if not quiet:
104 note(gettext("Tree is up to date at revision %d."),
105 to_branch.revno())
79 else:106 else:
80 raise ex107 base_tree = source_repository.revision_tree(base_revision_id)
81 # XXX: Should the tree be locked for get_parent_ids?108 target_tree = to_branch.repository.revision_tree(revision_id)
82 existing_pending_merges = tree.get_parent_ids()[1:]109 merge.Merge3Merger(tree, tree, base_tree, target_tree)
83 if len(existing_pending_merges) > 0:110 tree.set_last_revision(revision_id)
84 raise errors.BzrCommandError(gettext('Pending merges must be '111 if not quiet:
85 'committed or reverted before using switch.'))112 note(gettext('Updated to revision %d.') % to_branch.revno())
86113 if store_uncommitted:
87114 tree.restore_uncommitted()
88def _set_branch_location(control, to_branch, force=False):115 _run_post_switch_hooks(control_dir, to_branch, force, revision_id)
116 finally:
117 tree.unlock()
118
119
120def _set_branch_location(control, to_branch, current_branch, force=False):
89 """Set location value of a branch reference.121 """Set location value of a branch reference.
90122
91 :param control: ControlDir of the checkout to change123 :param control: ControlDir of the checkout to change
@@ -97,7 +129,7 @@
97 # Lightweight checkout: update the branch reference129 # Lightweight checkout: update the branch reference
98 branch_format.set_reference(control, None, to_branch)130 branch_format.set_reference(control, None, to_branch)
99 else:131 else:
100 b = control.open_branch()132 b = current_branch
101 bound_branch = b.get_bound_location()133 bound_branch = b.get_bound_location()
102 if bound_branch is not None:134 if bound_branch is not None:
103 # Heavyweight checkout: check all local commits135 # Heavyweight checkout: check all local commits
@@ -152,36 +184,3 @@
152 if not graph.is_ancestor(last_rev, other_last_rev):184 if not graph.is_ancestor(last_rev, other_last_rev):
153 return True185 return True
154 return False186 return False
155
156
157def _update(tree, source_repository, quiet=False, revision_id=None,
158 restore_uncommitted=False):
159 """Update a working tree to the latest revision of its branch.
160
161 :param tree: the working tree
162 :param source_repository: repository holding the revisions
163 :param restore_uncommitted: restore any uncommitted changes in the branch.
164 """
165 if restore_uncommitted:
166 tree.lock_write()
167 else:
168 tree.lock_tree_write()
169 try:
170 to_branch = tree.branch
171 if revision_id is None:
172 revision_id = to_branch.last_revision()
173 if tree.last_revision() == revision_id:
174 if not quiet:
175 note(gettext("Tree is up to date at revision %d."),
176 to_branch.revno())
177 else:
178 base_tree = source_repository.revision_tree(tree.last_revision())
179 merge.Merge3Merger(tree, tree, base_tree,
180 to_branch.repository.revision_tree(revision_id))
181 tree.set_last_revision(to_branch.last_revision())
182 if not quiet:
183 note(gettext('Updated to revision %d.') % to_branch.revno())
184 if restore_uncommitted:
185 tree.restore_uncommitted()
186 finally:
187 tree.unlock()
188187
=== modified file 'breezy/tests/blackbox/test_switch.py'
--- breezy/tests/blackbox/test_switch.py 2018-11-16 11:37:47 +0000
+++ breezy/tests/blackbox/test_switch.py 2018-11-16 23:29:29 +0000
@@ -492,8 +492,8 @@
492 # being too low. If rpc_count increases, more network roundtrips have492 # being too low. If rpc_count increases, more network roundtrips have
493 # become necessary for this use case. Please do not adjust this number493 # become necessary for this use case. Please do not adjust this number
494 # upwards without agreement from bzr's network support maintainers.494 # upwards without agreement from bzr's network support maintainers.
495 self.assertLength(24, self.hpss_calls)495 self.assertLength(21, self.hpss_calls)
496 self.assertLength(4, self.hpss_connections)496 self.assertLength(3, self.hpss_connections)
497 self.assertThat(self.hpss_calls, ContainsNoVfsCalls)497 self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
498498
499499

Subscribers

People subscribed via source and target branches