21
from bzrlib import uncommit, workingtree
22
from bzrlib.bzrdir import BzrDirMetaFormat1
23
from bzrlib.errors import BzrError, BoundBranchOutOfDate
24
from bzrlib.tests import TestCaseWithTransport
25
from bzrlib.tests.script import ScriptRunner
21
from breezy import uncommit
22
from breezy.bzr.bzrdir import BzrDirMetaFormat1
23
from breezy.errors import BoundBranchOutOfDate
24
from breezy.tests import TestCaseWithTransport
25
from breezy.tests.matchers import ContainsNoVfsCalls
26
from breezy.tests.script import (
28
32
class TestUncommit(TestCaseWithTransport):
31
35
wt = self.make_branch_and_tree('tree')
32
36
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
33
37
wt.add(['a', 'b', 'c'])
34
wt.commit('initial commit', rev_id='a1')
38
wt.commit('initial commit', rev_id=b'a1')
36
self.build_tree_contents([('tree/a', 'new contents of a\n')])
37
wt.commit('second commit', rev_id='a2')
40
self.build_tree_contents([('tree/a', b'new contents of a\n')])
41
wt.commit('second commit', rev_id=b'a2')
59
63
# This should look like we are back in revno 1
60
64
self.assertEqual(['a1'], wt.get_parent_ids())
61
65
out, err = self.run_bzr('status')
62
self.assertEquals(out, 'modified:\n a\n')
66
self.assertEqual(out, 'modified:\n a\n')
68
def test_uncommit_interactive(self):
69
"""Uncommit seeks confirmation, and doesn't proceed without it."""
70
wt = self.create_simple_tree()
75
The above revision(s) will be removed.
76
2>Uncommit these revisions? ([y]es, [n]o): no
80
self.assertEqual(['a2'], wt.get_parent_ids())
64
82
def test_uncommit_no_history(self):
65
83
wt = self.make_branch_and_tree('tree')
88
106
# uncommit in a checkout should uncommit the parent branch
89
107
# (but doesn't effect the other working tree)
90
self.assertEquals(['a1'], checkout_tree.get_parent_ids())
91
self.assertEquals('a1', wt.branch.last_revision())
92
self.assertEquals(['a2'], wt.get_parent_ids())
108
self.assertEqual(['a1'], checkout_tree.get_parent_ids())
109
self.assertEqual('a1', wt.branch.last_revision())
110
self.assertEqual(['a2'], wt.get_parent_ids())
94
112
def test_uncommit_bound(self):
102
120
t_a.commit('commit 3')
103
121
b = t_a.branch.create_checkout('b').branch
104
122
uncommit.uncommit(b)
105
self.assertEqual(len(b.revision_history()), 2)
106
self.assertEqual(len(t_a.branch.revision_history()), 2)
123
self.assertEqual(b.last_revision_info()[0], 2)
124
self.assertEqual(t_a.branch.last_revision_info()[0], 2)
107
125
# update A's tree to not have the uncommitted revision referenced.
109
127
t_a.commit('commit 3b')
143
161
def test_uncommit_merges(self):
144
162
wt = self.create_simple_tree()
146
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
164
tree2 = wt.controldir.sprout('tree2').open_workingtree()
148
tree2.commit('unchanged', rev_id='b3')
149
tree2.commit('unchanged', rev_id='b4')
166
tree2.commit('unchanged', rev_id=b'b3')
167
tree2.commit('unchanged', rev_id=b'b4')
151
169
wt.merge_from_branch(tree2.branch)
152
wt.commit('merge b4', rev_id='a3')
170
wt.commit('merge b4', rev_id=b'a3')
154
172
self.assertEqual(['a3'], wt.get_parent_ids())
161
179
def test_uncommit_pending_merge(self):
162
180
wt = self.create_simple_tree()
163
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
164
tree2.commit('unchanged', rev_id='b3')
181
tree2 = wt.controldir.sprout('tree2').open_workingtree()
182
tree2.commit('unchanged', rev_id=b'b3')
166
184
wt.branch.fetch(tree2.branch)
167
185
wt.set_pending_merges(['b3'])
173
191
def test_uncommit_multiple_merge(self):
174
192
wt = self.create_simple_tree()
176
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
177
tree2.commit('unchanged', rev_id='b3')
194
tree2 = wt.controldir.sprout('tree2').open_workingtree()
195
tree2.commit('unchanged', rev_id=b'b3')
179
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
180
tree3.commit('unchanged', rev_id='c3')
197
tree3 = wt.controldir.sprout('tree3').open_workingtree()
198
tree3.commit('unchanged', rev_id=b'c3')
182
200
wt.merge_from_branch(tree2.branch)
183
wt.commit('merge b3', rev_id='a3')
201
wt.commit('merge b3', rev_id=b'a3')
185
203
wt.merge_from_branch(tree3.branch)
186
wt.commit('merge c3', rev_id='a4')
204
wt.commit('merge c3', rev_id=b'a4')
188
206
self.assertEqual(['a4'], wt.get_parent_ids())
195
213
def test_uncommit_merge_plus_pending(self):
196
214
wt = self.create_simple_tree()
198
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
199
tree2.commit('unchanged', rev_id='b3')
200
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
201
tree3.commit('unchanged', rev_id='c3')
216
tree2 = wt.controldir.sprout('tree2').open_workingtree()
217
tree2.commit('unchanged', rev_id=b'b3')
218
tree3 = wt.controldir.sprout('tree3').open_workingtree()
219
tree3.commit('unchanged', rev_id=b'c3')
203
221
wt.branch.fetch(tree2.branch)
204
222
wt.set_pending_merges(['b3'])
205
wt.commit('merge b3', rev_id='a3')
223
wt.commit('merge b3', rev_id=b'a3')
208
226
wt.merge_from_branch(tree3.branch)
234
252
# though it will also filter out ones in the ancestry
235
253
wt = self.create_simple_tree()
237
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
238
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
255
tree2 = wt.controldir.sprout('tree2').open_workingtree()
256
tree3 = wt.controldir.sprout('tree3').open_workingtree()
240
tree2.commit('unchanged', rev_id='b3')
241
tree3.commit('unchanged', rev_id='c3')
258
tree2.commit('unchanged', rev_id=b'b3')
259
tree3.commit('unchanged', rev_id=b'c3')
243
261
wt.merge_from_branch(tree2.branch)
244
262
wt.merge_from_branch(tree3.branch, force=True)
245
wt.commit('merge b3, c3', rev_id='a3')
263
wt.commit('merge b3, c3', rev_id=b'a3')
247
tree2.commit('unchanged', rev_id='b4')
248
tree3.commit('unchanged', rev_id='c4')
265
tree2.commit('unchanged', rev_id=b'b4')
266
tree3.commit('unchanged', rev_id=b'c4')
250
268
wt.merge_from_branch(tree3.branch)
251
269
wt.merge_from_branch(tree2.branch, force=True)
252
wt.commit('merge b4, c4', rev_id='a4')
270
wt.commit('merge b4, c4', rev_id=b'a4')
254
272
self.assertEqual(['a4'], wt.get_parent_ids())
263
281
tree.commit(u'\u1234 message')
264
282
out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
265
283
self.assertContainsRe(out, r'\? message')
285
def test_uncommit_removes_tags(self):
286
tree = self.make_branch_and_tree('tree')
287
revid = tree.commit('message')
288
tree.branch.tags.set_tag("atag", revid)
289
out, err = self.run_bzr('uncommit --force tree')
290
self.assertEqual({}, tree.branch.tags.get_tag_dict())
292
def test_uncommit_keep_tags(self):
293
tree = self.make_branch_and_tree('tree')
294
revid = tree.commit('message')
295
tree.branch.tags.set_tag("atag", revid)
296
out, err = self.run_bzr('uncommit --keep-tags --force tree')
297
self.assertEqual({"atag": revid}, tree.branch.tags.get_tag_dict())
300
class TestSmartServerUncommit(TestCaseWithTransport):
302
def test_uncommit(self):
303
self.setup_smart_server_with_call_log()
304
t = self.make_branch_and_tree('from')
305
for count in range(2):
306
t.commit(message='commit %d' % count)
307
self.reset_smart_call_log()
308
out, err = self.run_bzr(['uncommit', '--force', self.get_url('from')])
309
# This figure represent the amount of work to perform this use case. It
310
# is entirely ok to reduce this number if a test fails due to rpc_count
311
# being too low. If rpc_count increases, more network roundtrips have
312
# become necessary for this use case. Please do not adjust this number
313
# upwards without agreement from bzr's network support maintainers.
314
self.assertLength(14, self.hpss_calls)
315
self.assertLength(1, self.hpss_connections)
316
self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
319
class TestInconsistentDelta(TestCaseWithTransport):
320
# See https://bugs.launchpad.net/bzr/+bug/855155
321
# See https://bugs.launchpad.net/bzr/+bug/1100385
322
# brz uncommit may result in error
323
# 'An inconsistent delta was supplied involving'
325
def test_inconsistent_delta(self):
326
# Script taken from https://bugs.launchpad.net/bzr/+bug/855155/comments/26
327
wt = self.make_branch_and_tree('test')
328
self.build_tree(['test/a/', 'test/a/b', 'test/a/c'])
329
wt.add(['a', 'a/b', 'a/c'])
330
wt.commit('initial commit', rev_id=b'a1')
331
wt.remove(['a/b', 'a/c'])
332
wt.commit('remove b and c', rev_id=b'a2')
333
self.run_bzr("uncommit --force test")