/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/blackbox/test_uncommit.py

  • Committer: Jelmer Vernooij
  • Date: 2019-01-01 21:08:01 UTC
  • mto: This revision was merged to the branch mainline in revision 7231.
  • Revision ID: jelmer@jelmer.uk-20190101210801-2dlsv7b1lvydmpkl
Fix tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2011, 2013, 2016 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Test the uncommit command."""
 
18
 
 
19
import os
 
20
 
 
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 (
 
27
    run_script,
 
28
    ScriptRunner,
 
29
    )
 
30
 
 
31
 
 
32
class TestUncommit(TestCaseWithTransport):
 
33
 
 
34
    def create_simple_tree(self):
 
35
        wt = self.make_branch_and_tree('tree')
 
36
        self.build_tree(['tree/a', 'tree/b', 'tree/c'])
 
37
        wt.add(['a', 'b', 'c'])
 
38
        wt.commit('initial commit', rev_id=b'a1')
 
39
 
 
40
        self.build_tree_contents([('tree/a', b'new contents of a\n')])
 
41
        wt.commit('second commit', rev_id=b'a2')
 
42
 
 
43
        return wt
 
44
 
 
45
    def test_uncommit(self):
 
46
        """Test uncommit functionality."""
 
47
        wt = self.create_simple_tree()
 
48
 
 
49
        os.chdir('tree')
 
50
        out, err = self.run_bzr('uncommit --dry-run --force')
 
51
        self.assertContainsRe(out, 'Dry-run')
 
52
        self.assertNotContainsRe(out, 'initial commit')
 
53
        self.assertContainsRe(out, 'second commit')
 
54
 
 
55
        # Nothing has changed
 
56
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
57
 
 
58
        # Uncommit, don't prompt
 
59
        out, err = self.run_bzr('uncommit --force')
 
60
        self.assertNotContainsRe(out, 'initial commit')
 
61
        self.assertContainsRe(out, 'second commit')
 
62
 
 
63
        # This should look like we are back in revno 1
 
64
        self.assertEqual([b'a1'], wt.get_parent_ids())
 
65
        out, err = self.run_bzr('status')
 
66
        self.assertEqual(out, 'modified:\n  a\n')
 
67
 
 
68
    def test_uncommit_interactive(self):
 
69
        """Uncommit seeks confirmation, and doesn't proceed without it."""
 
70
        wt = self.create_simple_tree()
 
71
        os.chdir('tree')
 
72
        run_script(self, """
 
73
        $ brz uncommit
 
74
        ...
 
75
        The above revision(s) will be removed.
 
76
        2>Uncommit these revisions? ([y]es, [n]o): no
 
77
        <n
 
78
        Canceled
 
79
        """)
 
80
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
81
 
 
82
    def test_uncommit_no_history(self):
 
83
        wt = self.make_branch_and_tree('tree')
 
84
        out, err = self.run_bzr('uncommit --force', retcode=1)
 
85
        self.assertEqual('', err)
 
86
        self.assertEqual('No revisions to uncommit.\n', out)
 
87
 
 
88
    def test_uncommit_checkout(self):
 
89
        wt = self.create_simple_tree()
 
90
        checkout_tree = wt.branch.create_checkout('checkout')
 
91
 
 
92
        self.assertEqual([b'a2'], checkout_tree.get_parent_ids())
 
93
 
 
94
        os.chdir('checkout')
 
95
        out, err = self.run_bzr('uncommit --dry-run --force')
 
96
        self.assertContainsRe(out, 'Dry-run')
 
97
        self.assertNotContainsRe(out, 'initial commit')
 
98
        self.assertContainsRe(out, 'second commit')
 
99
 
 
100
        self.assertEqual([b'a2'], checkout_tree.get_parent_ids())
 
101
 
 
102
        out, err = self.run_bzr('uncommit --force')
 
103
        self.assertNotContainsRe(out, 'initial commit')
 
104
        self.assertContainsRe(out, 'second commit')
 
105
 
 
106
        # uncommit in a checkout should uncommit the parent branch
 
107
        # (but doesn't effect the other working tree)
 
108
        self.assertEqual([b'a1'], checkout_tree.get_parent_ids())
 
109
        self.assertEqual(b'a1', wt.branch.last_revision())
 
110
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
111
 
 
112
    def test_uncommit_bound(self):
 
113
        os.mkdir('a')
 
114
        a = BzrDirMetaFormat1().initialize('a')
 
115
        a.create_repository()
 
116
        a.create_branch()
 
117
        t_a = a.create_workingtree()
 
118
        t_a.commit('commit 1')
 
119
        t_a.commit('commit 2')
 
120
        t_a.commit('commit 3')
 
121
        b = t_a.branch.create_checkout('b').branch
 
122
        uncommit.uncommit(b)
 
123
        self.assertEqual(b.last_revision_info()[0], 2)
 
124
        self.assertEqual(t_a.branch.last_revision_info()[0], 2)
 
125
        # update A's tree to not have the uncommitted revision referenced.
 
126
        t_a.update()
 
127
        t_a.commit('commit 3b')
 
128
        self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
 
129
        b.pull(t_a.branch)
 
130
        uncommit.uncommit(b)
 
131
 
 
132
    def test_uncommit_bound_local(self):
 
133
        t_a = self.make_branch_and_tree('a')
 
134
        rev_id1 = t_a.commit('commit 1')
 
135
        rev_id2 = t_a.commit('commit 2')
 
136
        rev_id3 = t_a.commit('commit 3')
 
137
        b = t_a.branch.create_checkout('b').branch
 
138
 
 
139
        out, err = self.run_bzr(['uncommit', '--local', 'b', '--force'])
 
140
        self.assertEqual(rev_id3, t_a.last_revision())
 
141
        self.assertEqual((3, rev_id3), t_a.branch.last_revision_info())
 
142
        self.assertEqual((2, rev_id2), b.last_revision_info())
 
143
 
 
144
    def test_uncommit_revision(self):
 
145
        wt = self.create_simple_tree()
 
146
 
 
147
        os.chdir('tree')
 
148
        out, err = self.run_bzr('uncommit -r1 --force')
 
149
 
 
150
        self.assertNotContainsRe(out, 'initial commit')
 
151
        self.assertContainsRe(out, 'second commit')
 
152
        self.assertEqual([b'a1'], wt.get_parent_ids())
 
153
        self.assertEqual(b'a1', wt.branch.last_revision())
 
154
 
 
155
    def test_uncommit_neg_1(self):
 
156
        wt = self.create_simple_tree()
 
157
        os.chdir('tree')
 
158
        out, err = self.run_bzr('uncommit -r -1', retcode=1)
 
159
        self.assertEqual('No revisions to uncommit.\n', out)
 
160
 
 
161
    def test_uncommit_merges(self):
 
162
        wt = self.create_simple_tree()
 
163
 
 
164
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
165
 
 
166
        tree2.commit('unchanged', rev_id=b'b3')
 
167
        tree2.commit('unchanged', rev_id=b'b4')
 
168
 
 
169
        wt.merge_from_branch(tree2.branch)
 
170
        wt.commit('merge b4', rev_id=b'a3')
 
171
 
 
172
        self.assertEqual([b'a3'], wt.get_parent_ids())
 
173
 
 
174
        os.chdir('tree')
 
175
        out, err = self.run_bzr('uncommit --force')
 
176
 
 
177
        self.assertEqual([b'a2', b'b4'], wt.get_parent_ids())
 
178
 
 
179
    def test_uncommit_pending_merge(self):
 
180
        wt = self.create_simple_tree()
 
181
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
182
        tree2.commit('unchanged', rev_id=b'b3')
 
183
 
 
184
        wt.branch.fetch(tree2.branch)
 
185
        wt.set_pending_merges([b'b3'])
 
186
 
 
187
        os.chdir('tree')
 
188
        out, err = self.run_bzr('uncommit --force')
 
189
        self.assertEqual([b'a1', b'b3'], wt.get_parent_ids())
 
190
 
 
191
    def test_uncommit_multiple_merge(self):
 
192
        wt = self.create_simple_tree()
 
193
 
 
194
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
195
        tree2.commit('unchanged', rev_id=b'b3')
 
196
 
 
197
        tree3 = wt.controldir.sprout('tree3').open_workingtree()
 
198
        tree3.commit('unchanged', rev_id=b'c3')
 
199
 
 
200
        wt.merge_from_branch(tree2.branch)
 
201
        wt.commit('merge b3', rev_id=b'a3')
 
202
 
 
203
        wt.merge_from_branch(tree3.branch)
 
204
        wt.commit('merge c3', rev_id=b'a4')
 
205
 
 
206
        self.assertEqual([b'a4'], wt.get_parent_ids())
 
207
 
 
208
        os.chdir('tree')
 
209
        out, err = self.run_bzr('uncommit --force -r 2')
 
210
 
 
211
        self.assertEqual([b'a2', b'b3', b'c3'], wt.get_parent_ids())
 
212
 
 
213
    def test_uncommit_merge_plus_pending(self):
 
214
        wt = self.create_simple_tree()
 
215
 
 
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')
 
220
 
 
221
        wt.branch.fetch(tree2.branch)
 
222
        wt.set_pending_merges([b'b3'])
 
223
        wt.commit('merge b3', rev_id=b'a3')
 
224
 
 
225
        wt.merge_from_branch(tree3.branch)
 
226
 
 
227
        self.assertEqual([b'a3', b'c3'], wt.get_parent_ids())
 
228
 
 
229
        os.chdir('tree')
 
230
        out, err = self.run_bzr('uncommit --force -r 2')
 
231
 
 
232
        self.assertEqual([b'a2', b'b3', b'c3'], wt.get_parent_ids())
 
233
 
 
234
    def test_uncommit_shows_log_with_revision_id(self):
 
235
        wt = self.create_simple_tree()
 
236
 
 
237
        script = ScriptRunner()
 
238
        script.run_script(self, """
 
239
$ cd tree
 
240
$ brz uncommit --force
 
241
    2 ...
 
242
      second commit
 
243
...
 
244
The above revision(s) will be removed.
 
245
You can restore the old tip by running:
 
246
  brz pull . -r revid:a2
 
247
""")
 
248
 
 
249
    def test_uncommit_octopus_merge(self):
 
250
        # Check that uncommit keeps the pending merges in the same order
 
251
        # though it will also filter out ones in the ancestry
 
252
        wt = self.create_simple_tree()
 
253
 
 
254
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
255
        tree3 = wt.controldir.sprout('tree3').open_workingtree()
 
256
 
 
257
        tree2.commit('unchanged', rev_id=b'b3')
 
258
        tree3.commit('unchanged', rev_id=b'c3')
 
259
 
 
260
        wt.merge_from_branch(tree2.branch)
 
261
        wt.merge_from_branch(tree3.branch, force=True)
 
262
        wt.commit('merge b3, c3', rev_id=b'a3')
 
263
 
 
264
        tree2.commit('unchanged', rev_id=b'b4')
 
265
        tree3.commit('unchanged', rev_id=b'c4')
 
266
 
 
267
        wt.merge_from_branch(tree3.branch)
 
268
        wt.merge_from_branch(tree2.branch, force=True)
 
269
        wt.commit('merge b4, c4', rev_id=b'a4')
 
270
 
 
271
        self.assertEqual([b'a4'], wt.get_parent_ids())
 
272
 
 
273
        os.chdir('tree')
 
274
        out, err = self.run_bzr('uncommit --force -r 2')
 
275
 
 
276
        self.assertEqual([b'a2', b'c4', b'b4'], wt.get_parent_ids())
 
277
 
 
278
    def test_uncommit_nonascii(self):
 
279
        tree = self.make_branch_and_tree('tree')
 
280
        tree.commit(u'\u1234 message')
 
281
        out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
 
282
        self.assertContainsRe(out, r'\? message')
 
283
 
 
284
    def test_uncommit_removes_tags(self):
 
285
        tree = self.make_branch_and_tree('tree')
 
286
        revid = tree.commit('message')
 
287
        tree.branch.tags.set_tag("atag", revid)
 
288
        out, err = self.run_bzr('uncommit --force tree')
 
289
        self.assertEqual({}, tree.branch.tags.get_tag_dict())
 
290
 
 
291
    def test_uncommit_keep_tags(self):
 
292
        tree = self.make_branch_and_tree('tree')
 
293
        revid = tree.commit('message')
 
294
        tree.branch.tags.set_tag("atag", revid)
 
295
        out, err = self.run_bzr('uncommit --keep-tags --force tree')
 
296
        self.assertEqual({"atag": revid}, tree.branch.tags.get_tag_dict())
 
297
 
 
298
 
 
299
class TestSmartServerUncommit(TestCaseWithTransport):
 
300
 
 
301
    def test_uncommit(self):
 
302
        self.setup_smart_server_with_call_log()
 
303
        t = self.make_branch_and_tree('from')
 
304
        for count in range(2):
 
305
            t.commit(message='commit %d' % count)
 
306
        self.reset_smart_call_log()
 
307
        out, err = self.run_bzr(['uncommit', '--force', self.get_url('from')])
 
308
        # This figure represent the amount of work to perform this use case. It
 
309
        # is entirely ok to reduce this number if a test fails due to rpc_count
 
310
        # being too low. If rpc_count increases, more network roundtrips have
 
311
        # become necessary for this use case. Please do not adjust this number
 
312
        # upwards without agreement from bzr's network support maintainers.
 
313
        self.assertLength(14, self.hpss_calls)
 
314
        self.assertLength(1, self.hpss_connections)
 
315
        self.assertThat(self.hpss_calls, ContainsNoVfsCalls)
 
316
 
 
317
 
 
318
class TestInconsistentDelta(TestCaseWithTransport):
 
319
    # See https://bugs.launchpad.net/bzr/+bug/855155
 
320
    # See https://bugs.launchpad.net/bzr/+bug/1100385
 
321
    # brz uncommit may result in error
 
322
    # 'An inconsistent delta was supplied involving'
 
323
 
 
324
    def test_inconsistent_delta(self):
 
325
        # Script taken from https://bugs.launchpad.net/bzr/+bug/855155/comments/26
 
326
        wt = self.make_branch_and_tree('test')
 
327
        self.build_tree(['test/a/', 'test/a/b', 'test/a/c'])
 
328
        wt.add(['a', 'a/b', 'a/c'])
 
329
        wt.commit('initial commit', rev_id=b'a1')
 
330
        wt.remove(['a/b', 'a/c'])
 
331
        wt.commit('remove b and c', rev_id=b'a2')
 
332
        self.run_bzr("uncommit --force test")