~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Martin Pool
  • Date: 2010-04-01 04:41:18 UTC
  • mto: This revision was merged to the branch mainline in revision 5128.
  • Revision ID: mbp@sourcefrog.net-20100401044118-shyctqc02ob08ngz
ignore .testrepository

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2010 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 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
 
26
 
 
27
 
 
28
class TestUncommit(TestCaseWithTransport):
 
29
 
 
30
    def create_simple_tree(self):
 
31
        wt = self.make_branch_and_tree('tree')
 
32
        self.build_tree(['tree/a', 'tree/b', 'tree/c'])
 
33
        wt.add(['a', 'b', 'c'])
 
34
        wt.commit('initial commit', rev_id='a1')
 
35
 
 
36
        self.build_tree_contents([('tree/a', 'new contents of a\n')])
 
37
        wt.commit('second commit', rev_id='a2')
 
38
 
 
39
        return wt
 
40
 
 
41
    def test_uncommit(self):
 
42
        """Test uncommit functionality."""
 
43
        wt = self.create_simple_tree()
 
44
 
 
45
        os.chdir('tree')
 
46
        out, err = self.run_bzr('uncommit --dry-run --force')
 
47
        self.assertContainsRe(out, 'Dry-run')
 
48
        self.assertNotContainsRe(out, 'initial commit')
 
49
        self.assertContainsRe(out, 'second commit')
 
50
 
 
51
        # Nothing has changed
 
52
        self.assertEqual(['a2'], wt.get_parent_ids())
 
53
 
 
54
        # Uncommit, don't prompt
 
55
        out, err = self.run_bzr('uncommit --force')
 
56
        self.assertNotContainsRe(out, 'initial commit')
 
57
        self.assertContainsRe(out, 'second commit')
 
58
 
 
59
        # This should look like we are back in revno 1
 
60
        self.assertEqual(['a1'], wt.get_parent_ids())
 
61
        out, err = self.run_bzr('status')
 
62
        self.assertEquals(out, 'modified:\n  a\n')
 
63
 
 
64
    def test_uncommit_no_history(self):
 
65
        wt = self.make_branch_and_tree('tree')
 
66
        out, err = self.run_bzr('uncommit --force', retcode=1)
 
67
        self.assertEqual('', err)
 
68
        self.assertEqual('No revisions to uncommit.\n', out)
 
69
 
 
70
    def test_uncommit_checkout(self):
 
71
        wt = self.create_simple_tree()
 
72
        checkout_tree = wt.branch.create_checkout('checkout')
 
73
 
 
74
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
 
75
 
 
76
        os.chdir('checkout')
 
77
        out, err = self.run_bzr('uncommit --dry-run --force')
 
78
        self.assertContainsRe(out, 'Dry-run')
 
79
        self.assertNotContainsRe(out, 'initial commit')
 
80
        self.assertContainsRe(out, 'second commit')
 
81
 
 
82
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
 
83
 
 
84
        out, err = self.run_bzr('uncommit --force')
 
85
        self.assertNotContainsRe(out, 'initial commit')
 
86
        self.assertContainsRe(out, 'second commit')
 
87
 
 
88
        # uncommit in a checkout should uncommit the parent branch
 
89
        # (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())
 
93
 
 
94
    def test_uncommit_bound(self):
 
95
        os.mkdir('a')
 
96
        a = BzrDirMetaFormat1().initialize('a')
 
97
        a.create_repository()
 
98
        a.create_branch()
 
99
        t_a = a.create_workingtree()
 
100
        t_a.commit('commit 1')
 
101
        t_a.commit('commit 2')
 
102
        t_a.commit('commit 3')
 
103
        b = t_a.branch.create_checkout('b').branch
 
104
        uncommit.uncommit(b)
 
105
        self.assertEqual(len(b.revision_history()), 2)
 
106
        self.assertEqual(len(t_a.branch.revision_history()), 2)
 
107
        # update A's tree to not have the uncommitted revision referenced.
 
108
        t_a.update()
 
109
        t_a.commit('commit 3b')
 
110
        self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
 
111
        b.pull(t_a.branch)
 
112
        uncommit.uncommit(b)
 
113
 
 
114
    def test_uncommit_bound_local(self):
 
115
        t_a = self.make_branch_and_tree('a')
 
116
        rev_id1 = t_a.commit('commit 1')
 
117
        rev_id2 = t_a.commit('commit 2')
 
118
        rev_id3 = t_a.commit('commit 3')
 
119
        b = t_a.branch.create_checkout('b').branch
 
120
 
 
121
        out, err = self.run_bzr(['uncommit', '--local', 'b', '--force'])
 
122
        self.assertEqual(rev_id3, t_a.last_revision())
 
123
        self.assertEqual((3, rev_id3), t_a.branch.last_revision_info())
 
124
        self.assertEqual((2, rev_id2), b.last_revision_info())
 
125
 
 
126
    def test_uncommit_revision(self):
 
127
        wt = self.create_simple_tree()
 
128
 
 
129
        os.chdir('tree')
 
130
        out, err = self.run_bzr('uncommit -r1 --force')
 
131
 
 
132
        self.assertNotContainsRe(out, 'initial commit')
 
133
        self.assertContainsRe(out, 'second commit')
 
134
        self.assertEqual(['a1'], wt.get_parent_ids())
 
135
        self.assertEqual('a1', wt.branch.last_revision())
 
136
 
 
137
    def test_uncommit_neg_1(self):
 
138
        wt = self.create_simple_tree()
 
139
        os.chdir('tree')
 
140
        out, err = self.run_bzr('uncommit -r -1', retcode=1)
 
141
        self.assertEqual('No revisions to uncommit.\n', out)
 
142
 
 
143
    def test_uncommit_merges(self):
 
144
        wt = self.create_simple_tree()
 
145
 
 
146
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
 
147
 
 
148
        tree2.commit('unchanged', rev_id='b3')
 
149
        tree2.commit('unchanged', rev_id='b4')
 
150
 
 
151
        wt.merge_from_branch(tree2.branch)
 
152
        wt.commit('merge b4', rev_id='a3')
 
153
 
 
154
        self.assertEqual(['a3'], wt.get_parent_ids())
 
155
 
 
156
        os.chdir('tree')
 
157
        out, err = self.run_bzr('uncommit --force')
 
158
 
 
159
        self.assertEqual(['a2', 'b4'], wt.get_parent_ids())
 
160
 
 
161
    def test_uncommit_pending_merge(self):
 
162
        wt = self.create_simple_tree()
 
163
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
 
164
        tree2.commit('unchanged', rev_id='b3')
 
165
 
 
166
        wt.branch.fetch(tree2.branch)
 
167
        wt.set_pending_merges(['b3'])
 
168
 
 
169
        os.chdir('tree')
 
170
        out, err = self.run_bzr('uncommit --force')
 
171
        self.assertEqual(['a1', 'b3'], wt.get_parent_ids())
 
172
 
 
173
    def test_uncommit_multiple_merge(self):
 
174
        wt = self.create_simple_tree()
 
175
 
 
176
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
 
177
        tree2.commit('unchanged', rev_id='b3')
 
178
 
 
179
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
 
180
        tree3.commit('unchanged', rev_id='c3')
 
181
 
 
182
        wt.merge_from_branch(tree2.branch)
 
183
        wt.commit('merge b3', rev_id='a3')
 
184
 
 
185
        wt.merge_from_branch(tree3.branch)
 
186
        wt.commit('merge c3', rev_id='a4')
 
187
 
 
188
        self.assertEqual(['a4'], wt.get_parent_ids())
 
189
 
 
190
        os.chdir('tree')
 
191
        out, err = self.run_bzr('uncommit --force -r 2')
 
192
 
 
193
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
 
194
 
 
195
    def test_uncommit_merge_plus_pending(self):
 
196
        wt = self.create_simple_tree()
 
197
 
 
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')
 
202
 
 
203
        wt.branch.fetch(tree2.branch)
 
204
        wt.set_pending_merges(['b3'])
 
205
        wt.commit('merge b3', rev_id='a3')
 
206
 
 
207
 
 
208
        wt.merge_from_branch(tree3.branch)
 
209
 
 
210
        self.assertEqual(['a3', 'c3'], wt.get_parent_ids())
 
211
 
 
212
        os.chdir('tree')
 
213
        out, err = self.run_bzr('uncommit --force -r 2')
 
214
 
 
215
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
 
216
 
 
217
    def test_uncommit_shows_log_with_revision_id(self):
 
218
        wt = self.create_simple_tree()
 
219
 
 
220
        script = ScriptRunner()
 
221
        script.run_script(self, """
 
222
$ cd tree
 
223
$ bzr uncommit --force 
 
224
    2 ...
 
225
      second commit
 
226
...
 
227
The above revision(s) will be removed.
 
228
You can restore the old tip by running:
 
229
  bzr pull . -r revid:a2
 
230
""")
 
231
 
 
232
    def test_uncommit_octopus_merge(self):
 
233
        # Check that uncommit keeps the pending merges in the same order
 
234
        # though it will also filter out ones in the ancestry
 
235
        wt = self.create_simple_tree()
 
236
 
 
237
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
 
238
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
 
239
 
 
240
        tree2.commit('unchanged', rev_id='b3')
 
241
        tree3.commit('unchanged', rev_id='c3')
 
242
 
 
243
        wt.merge_from_branch(tree2.branch)
 
244
        wt.merge_from_branch(tree3.branch, force=True)
 
245
        wt.commit('merge b3, c3', rev_id='a3')
 
246
 
 
247
        tree2.commit('unchanged', rev_id='b4')
 
248
        tree3.commit('unchanged', rev_id='c4')
 
249
 
 
250
        wt.merge_from_branch(tree3.branch)
 
251
        wt.merge_from_branch(tree2.branch, force=True)
 
252
        wt.commit('merge b4, c4', rev_id='a4')
 
253
 
 
254
        self.assertEqual(['a4'], wt.get_parent_ids())
 
255
 
 
256
        os.chdir('tree')
 
257
        out, err = self.run_bzr('uncommit --force -r 2')
 
258
 
 
259
        self.assertEqual(['a2', 'c4', 'b4'], wt.get_parent_ids())
 
260
 
 
261
    def test_uncommit_nonascii(self):
 
262
        tree = self.make_branch_and_tree('tree')
 
263
        tree.commit(u'\u1234 message')
 
264
        out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
 
265
        self.assertContainsRe(out, r'\? message')