2
Test the uncommit command.
4
from bzrlib.tests import TestCaseInTempDir
5
from bzrlib.errors import BzrError
7
class TestUncommit(TestCaseInTempDir):
1
# Copyright (C) 2005, 2006 by Canonical Ltd
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Test the uncommit command."""
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
27
class TestUncommit(TestCaseWithTransport):
29
def create_simple_tree(self):
30
wt = self.make_branch_and_tree('tree')
31
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
32
wt.add(['a', 'b', 'c'])
33
wt.commit('initial commit', rev_id='a1')
35
open('tree/a', 'wb').write('new contents of a\n')
36
wt.commit('second commit', rev_id='a2')
8
40
def test_uncommit(self):
9
41
"""Test uncommit functionality."""
13
self.build_tree(['a', 'b', 'c'])
16
bzr('commit -m initial')
18
self.assertEquals(bzr('revno'), '1\n')
20
open('a', 'wb').write('new contents of a\n')
21
self.assertEquals(bzr('status'), 'modified:\n a\n')
22
bzr('commit -m second')
24
self.assertEquals(bzr('status'), '')
25
self.assertEquals(bzr('revno'), '2\n')
27
txt = bzr('uncommit --dry-run --force')
28
self.failIfEqual(txt.find('Dry-run'), -1)
30
self.assertEquals(bzr('status'), '')
31
self.assertEquals(bzr('revno'), '2\n')
33
txt = bzr('uncommit --force')
35
self.assertEquals(bzr('revno'), '1\n')
36
self.assertEquals(bzr('status'), 'modified:\n a\n')
42
wt = self.create_simple_tree()
45
out, err = self.run_bzr('uncommit', '--dry-run', '--force')
46
self.assertContainsRe(out, 'Dry-run')
47
self.assertNotContainsRe(out, 'initial commit')
48
self.assertContainsRe(out, 'second commit')
51
self.assertEqual('a2', wt.last_revision())
53
# Uncommit, don't prompt
54
out, err = self.run_bzr('uncommit', '--force')
55
self.assertNotContainsRe(out, 'initial commit')
56
self.assertContainsRe(out, 'second commit')
58
# This should look like we are back in revno 1
59
self.assertEqual('a1', wt.last_revision())
60
out, err = self.run_bzr('status')
61
self.assertEquals(out, 'modified:\n a\n')
63
def test_uncommit_checkout(self):
64
wt = self.create_simple_tree()
66
checkout_tree = wt.bzrdir.sprout('checkout').open_workingtree()
67
checkout_tree.branch.bind(wt.branch)
69
self.assertEqual('a2', checkout_tree.last_revision())
72
out, err = self.run_bzr('uncommit', '--dry-run', '--force')
73
self.assertContainsRe(out, 'Dry-run')
74
self.assertNotContainsRe(out, 'initial commit')
75
self.assertContainsRe(out, 'second commit')
77
self.assertEqual('a2', checkout_tree.last_revision())
79
out, err = self.run_bzr('uncommit', '--force')
80
self.assertNotContainsRe(out, 'initial commit')
81
self.assertContainsRe(out, 'second commit')
83
# uncommit in a checkout should uncommit the parent branch
84
# (but doesn't effect the other working tree)
85
self.assertEquals('a1', checkout_tree.last_revision())
86
self.assertEquals('a1', wt.branch.last_revision())
87
self.assertEquals('a2', wt.last_revision())
89
def test_uncommit_bound(self):
91
a = BzrDirMetaFormat1().initialize('a')
94
t_a = a.create_workingtree()
95
t_a.commit('commit 1')
96
t_a.commit('commit 2')
97
t_a.commit('commit 3')
98
b = t_a.bzrdir.sprout('b').open_branch()
101
self.assertEqual(len(b.revision_history()), 2)
102
self.assertEqual(len(t_a.branch.revision_history()), 2)
103
# update A's tree to not have the uncomitted revision referenced.
105
t_a.commit('commit 3b')
106
self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
110
def test_uncommit_revision(self):
111
wt = self.create_simple_tree()
114
out, err = self.run_bzr('uncommit', '-r1', '--force')
116
self.assertNotContainsRe(out, 'initial commit')
117
self.assertContainsRe(out, 'second commit')
118
self.assertEqual('a1', wt.last_revision())
119
self.assertEqual('a1', wt.branch.last_revision())
121
def test_uncommit_neg_1(self):
122
wt = self.create_simple_tree()
124
out, err = self.run_bzr('uncommit', '-r', '-1', retcode=1)
125
self.assertEqual('No revisions to uncommit.\n', out)
127
def test_uncommit_merges(self):
128
wt = self.create_simple_tree()
130
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
132
tree2.commit('unchanged', rev_id='b3')
133
tree2.commit('unchanged', rev_id='b4')
135
self.merge(tree2.branch, wt)
136
wt.commit('merge b4', rev_id='a3')
138
self.assertEqual(['a3'], wt.get_parent_ids())
141
out, err = self.run_bzr('uncommit', '--force')
143
self.assertEqual(['a2', 'b4'], wt.get_parent_ids())
145
def test_uncommit_pending_merge(self):
146
wt = self.create_simple_tree()
147
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
148
tree2.commit('unchanged', rev_id='b3')
150
wt.branch.fetch(tree2.branch)
151
wt.set_pending_merges(['b3'])
154
out, err = self.run_bzr('uncommit', '--force')
155
self.assertEqual('a1', wt.last_revision())
156
self.assertEqual(['b3'], wt.pending_merges())
158
def test_uncommit_multiple_merge(self):
159
wt = self.create_simple_tree()
161
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
163
tree2.commit('unchanged', rev_id='b3')
165
self.merge(tree2.branch, wt)
166
wt.commit('merge b3', rev_id='a3')
168
tree2.commit('unchanged', rev_id='b4')
170
self.merge(tree2.branch, wt)
171
wt.commit('merge b4', rev_id='a4')
173
self.assertEqual(['a4'], wt.get_parent_ids())
176
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
178
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
180
def test_uncommit_merge_plus_pending(self):
181
wt = self.create_simple_tree()
183
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
185
tree2.commit('unchanged', rev_id='b3')
186
wt.branch.fetch(tree2.branch)
187
wt.set_pending_merges(['b3'])
188
wt.commit('merge b3', rev_id='a3')
190
tree2.commit('unchanged', rev_id='b4')
191
wt.branch.fetch(tree2.branch)
192
wt.set_pending_merges(['b4'])
194
self.assertEqual('a3', wt.last_revision())
195
self.assertEqual(['b4'], wt.pending_merges())
198
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
200
self.assertEqual('a2', wt.last_revision())
201
self.assertEqual(['b3', 'b4'], wt.pending_merges())
203
def test_uncommit_octopus_merge(self):
204
# Check that uncommit keeps the pending merges in the same order
205
wt = self.create_simple_tree()
207
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
208
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
210
tree2.commit('unchanged', rev_id='b3')
211
tree3.commit('unchanged', rev_id='c3')
213
self.merge(tree2.branch, wt)
214
self.merge(tree3.branch, wt)
215
wt.commit('merge b3, c3', rev_id='a3')
217
tree2.commit('unchanged', rev_id='b4')
218
tree3.commit('unchanged', rev_id='c4')
220
self.merge(tree3.branch, wt)
221
self.merge(tree2.branch, wt)
222
wt.commit('merge b4, c4', rev_id='a4')
224
self.assertEqual(['a4'], wt.get_parent_ids())
227
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
229
self.assertEqual(['a2', 'b3', 'c3', 'c4', 'b4'], wt.get_parent_ids())