~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Packman
  • Date: 2012-02-27 12:16:28 UTC
  • mto: (6437.23.25 2.5)
  • mto: This revision was merged to the branch mainline in revision 6499.
  • Revision ID: martin.packman@canonical.com-20120227121628-9q8krey0u73v56k3
Get default stream for help output via ui_factory instead of using stdout directly

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Test the uncommit command."""
18
18
 
19
19
import os
20
20
 
21
 
from bzrlib import uncommit, workingtree
 
21
from bzrlib import uncommit
22
22
from bzrlib.bzrdir import BzrDirMetaFormat1
23
 
from bzrlib.errors import BzrError, BoundBranchOutOfDate
 
23
from bzrlib.errors import BoundBranchOutOfDate
24
24
from bzrlib.tests import TestCaseWithTransport
 
25
from bzrlib.tests.matchers import ContainsNoVfsCalls
 
26
from bzrlib.tests.script import (
 
27
    run_script,
 
28
    ScriptRunner,
 
29
    )
25
30
 
26
31
 
27
32
class TestUncommit(TestCaseWithTransport):
32
37
        wt.add(['a', 'b', 'c'])
33
38
        wt.commit('initial commit', rev_id='a1')
34
39
 
35
 
        open('tree/a', 'wb').write('new contents of a\n')
 
40
        self.build_tree_contents([('tree/a', 'new contents of a\n')])
36
41
        wt.commit('second commit', rev_id='a2')
37
42
 
38
43
        return wt
42
47
        wt = self.create_simple_tree()
43
48
 
44
49
        os.chdir('tree')
45
 
        out, err = self.run_bzr('uncommit', '--dry-run', '--force')
 
50
        out, err = self.run_bzr('uncommit --dry-run --force')
46
51
        self.assertContainsRe(out, 'Dry-run')
47
52
        self.assertNotContainsRe(out, 'initial commit')
48
53
        self.assertContainsRe(out, 'second commit')
51
56
        self.assertEqual(['a2'], wt.get_parent_ids())
52
57
 
53
58
        # Uncommit, don't prompt
54
 
        out, err = self.run_bzr('uncommit', '--force')
 
59
        out, err = self.run_bzr('uncommit --force')
55
60
        self.assertNotContainsRe(out, 'initial commit')
56
61
        self.assertContainsRe(out, 'second commit')
57
62
 
60
65
        out, err = self.run_bzr('status')
61
66
        self.assertEquals(out, 'modified:\n  a\n')
62
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
        $ bzr 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(['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
 
63
88
    def test_uncommit_checkout(self):
64
89
        wt = self.create_simple_tree()
65
90
        checkout_tree = wt.branch.create_checkout('checkout')
67
92
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
68
93
 
69
94
        os.chdir('checkout')
70
 
        out, err = self.run_bzr('uncommit', '--dry-run', '--force')
 
95
        out, err = self.run_bzr('uncommit --dry-run --force')
71
96
        self.assertContainsRe(out, 'Dry-run')
72
97
        self.assertNotContainsRe(out, 'initial commit')
73
98
        self.assertContainsRe(out, 'second commit')
74
99
 
75
100
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
76
101
 
77
 
        out, err = self.run_bzr('uncommit', '--force')
 
102
        out, err = self.run_bzr('uncommit --force')
78
103
        self.assertNotContainsRe(out, 'initial commit')
79
104
        self.assertContainsRe(out, 'second commit')
80
105
 
95
120
        t_a.commit('commit 3')
96
121
        b = t_a.branch.create_checkout('b').branch
97
122
        uncommit.uncommit(b)
98
 
        self.assertEqual(len(b.revision_history()), 2)
99
 
        self.assertEqual(len(t_a.branch.revision_history()), 2)
100
 
        # update A's tree to not have the uncomitted revision referenced.
 
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.
101
126
        t_a.update()
102
127
        t_a.commit('commit 3b')
103
128
        self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
104
129
        b.pull(t_a.branch)
105
130
        uncommit.uncommit(b)
106
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
 
107
144
    def test_uncommit_revision(self):
108
145
        wt = self.create_simple_tree()
109
146
 
110
147
        os.chdir('tree')
111
 
        out, err = self.run_bzr('uncommit', '-r1', '--force')
 
148
        out, err = self.run_bzr('uncommit -r1 --force')
112
149
 
113
150
        self.assertNotContainsRe(out, 'initial commit')
114
151
        self.assertContainsRe(out, 'second commit')
118
155
    def test_uncommit_neg_1(self):
119
156
        wt = self.create_simple_tree()
120
157
        os.chdir('tree')
121
 
        out, err = self.run_bzr('uncommit', '-r', '-1', retcode=1)
 
158
        out, err = self.run_bzr('uncommit -r -1', retcode=1)
122
159
        self.assertEqual('No revisions to uncommit.\n', out)
123
160
 
124
161
    def test_uncommit_merges(self):
135
172
        self.assertEqual(['a3'], wt.get_parent_ids())
136
173
 
137
174
        os.chdir('tree')
138
 
        out, err = self.run_bzr('uncommit', '--force')
 
175
        out, err = self.run_bzr('uncommit --force')
139
176
 
140
177
        self.assertEqual(['a2', 'b4'], wt.get_parent_ids())
141
178
 
148
185
        wt.set_pending_merges(['b3'])
149
186
 
150
187
        os.chdir('tree')
151
 
        out, err = self.run_bzr('uncommit', '--force')
 
188
        out, err = self.run_bzr('uncommit --force')
152
189
        self.assertEqual(['a1', 'b3'], wt.get_parent_ids())
153
190
 
154
191
    def test_uncommit_multiple_merge(self):
155
192
        wt = self.create_simple_tree()
156
193
 
157
194
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
158
 
 
159
195
        tree2.commit('unchanged', rev_id='b3')
160
196
 
 
197
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
 
198
        tree3.commit('unchanged', rev_id='c3')
 
199
 
161
200
        wt.merge_from_branch(tree2.branch)
162
201
        wt.commit('merge b3', rev_id='a3')
163
202
 
164
 
        tree2.commit('unchanged', rev_id='b4')
165
 
 
166
 
        wt.merge_from_branch(tree2.branch)
167
 
        wt.commit('merge b4', rev_id='a4')
 
203
        wt.merge_from_branch(tree3.branch)
 
204
        wt.commit('merge c3', rev_id='a4')
168
205
 
169
206
        self.assertEqual(['a4'], wt.get_parent_ids())
170
207
 
171
208
        os.chdir('tree')
172
 
        out, err = self.run_bzr('uncommit', '--force', '-r', '2')
 
209
        out, err = self.run_bzr('uncommit --force -r 2')
173
210
 
174
 
        self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
 
211
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
175
212
 
176
213
    def test_uncommit_merge_plus_pending(self):
177
214
        wt = self.create_simple_tree()
178
215
 
179
216
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
180
 
 
181
217
        tree2.commit('unchanged', rev_id='b3')
 
218
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
 
219
        tree3.commit('unchanged', rev_id='c3')
 
220
 
182
221
        wt.branch.fetch(tree2.branch)
183
222
        wt.set_pending_merges(['b3'])
184
223
        wt.commit('merge b3', rev_id='a3')
185
224
 
186
 
        tree2.commit('unchanged', rev_id='b4')
187
 
        wt.branch.fetch(tree2.branch)
188
 
        wt.set_pending_merges(['b4'])
189
 
 
190
 
        self.assertEqual(['a3', 'b4'], wt.get_parent_ids())
 
225
 
 
226
        wt.merge_from_branch(tree3.branch)
 
227
 
 
228
        self.assertEqual(['a3', 'c3'], wt.get_parent_ids())
191
229
 
192
230
        os.chdir('tree')
193
 
        out, err = self.run_bzr('uncommit', '--force', '-r', '2')
194
 
 
195
 
        self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
 
231
        out, err = self.run_bzr('uncommit --force -r 2')
 
232
 
 
233
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
 
234
 
 
235
    def test_uncommit_shows_log_with_revision_id(self):
 
236
        wt = self.create_simple_tree()
 
237
 
 
238
        script = ScriptRunner()
 
239
        script.run_script(self, """
 
240
$ cd tree
 
241
$ bzr uncommit --force 
 
242
    2 ...
 
243
      second commit
 
244
...
 
245
The above revision(s) will be removed.
 
246
You can restore the old tip by running:
 
247
  bzr pull . -r revid:a2
 
248
""")
196
249
 
197
250
    def test_uncommit_octopus_merge(self):
198
251
        # Check that uncommit keeps the pending merges in the same order
 
252
        # though it will also filter out ones in the ancestry
199
253
        wt = self.create_simple_tree()
200
254
 
201
255
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
203
257
 
204
258
        tree2.commit('unchanged', rev_id='b3')
205
259
        tree3.commit('unchanged', rev_id='c3')
206
 
        
 
260
 
207
261
        wt.merge_from_branch(tree2.branch)
208
 
        wt.merge_from_branch(tree3.branch)
 
262
        wt.merge_from_branch(tree3.branch, force=True)
209
263
        wt.commit('merge b3, c3', rev_id='a3')
210
264
 
211
265
        tree2.commit('unchanged', rev_id='b4')
212
266
        tree3.commit('unchanged', rev_id='c4')
213
267
 
214
268
        wt.merge_from_branch(tree3.branch)
215
 
        wt.merge_from_branch(tree2.branch)
 
269
        wt.merge_from_branch(tree2.branch, force=True)
216
270
        wt.commit('merge b4, c4', rev_id='a4')
217
271
 
218
272
        self.assertEqual(['a4'], wt.get_parent_ids())
219
273
 
220
274
        os.chdir('tree')
221
 
        out, err = self.run_bzr('uncommit', '--force', '-r', '2')
222
 
 
223
 
        self.assertEqual(['a2', 'b3', 'c3', 'c4', 'b4'], wt.get_parent_ids())
 
275
        out, err = self.run_bzr('uncommit --force -r 2')
 
276
 
 
277
        self.assertEqual(['a2', 'c4', 'b4'], wt.get_parent_ids())
 
278
 
 
279
    def test_uncommit_nonascii(self):
 
280
        tree = self.make_branch_and_tree('tree')
 
281
        tree.commit(u'\u1234 message')
 
282
        out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
 
283
        self.assertContainsRe(out, r'\? message')
 
284
 
 
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.assertEquals({}, tree.branch.tags.get_tag_dict())
 
291
 
 
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.assertEquals({"atag": revid}, tree.branch.tags.get_tag_dict())
 
298
 
 
299
 
 
300
class TestSmartServerUncommit(TestCaseWithTransport):
 
301
 
 
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)