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):
28
def create_simple_tree(self):
29
wt = self.make_branch_and_tree('tree')
30
self.build_tree(['tree/a', 'tree/b', 'tree/c'])
31
wt.add(['a', 'b', 'c'])
32
wt.commit('initial commit', rev_id='a1')
34
open('tree/a', 'wb').write('new contents of a\n')
35
wt.commit('second commit', rev_id='a2')
39
def test_uncommit(self):
40
"""Test uncommit functionality."""
41
wt = self.create_simple_tree()
44
out, err = self.run_bzr('uncommit', '--dry-run', '--force')
45
self.assertContainsRe(out, 'Dry-run')
46
self.assertNotContainsRe(out, 'initial commit')
47
self.assertContainsRe(out, 'second commit')
50
self.assertEqual('a2', wt.last_revision())
52
# Uncommit, don't prompt
53
out, err = self.run_bzr('uncommit', '--force')
54
self.assertNotContainsRe(out, 'initial commit')
55
self.assertContainsRe(out, 'second commit')
57
# This should look like we are back in revno 1
58
self.assertEqual('a1', wt.last_revision())
59
out, err = self.run_bzr('status')
60
self.assertEquals(out, 'modified:\n a\n')
62
def test_uncommit_checkout(self):
63
wt = self.create_simple_tree()
65
checkout_tree = wt.bzrdir.sprout('checkout').open_workingtree()
66
checkout_tree.branch.bind(wt.branch)
68
self.assertEqual('a2', checkout_tree.last_revision())
71
out, err = self.run_bzr('uncommit', '--dry-run', '--force')
72
self.assertContainsRe(out, 'Dry-run')
73
self.assertNotContainsRe(out, 'initial commit')
74
self.assertContainsRe(out, 'second commit')
76
self.assertEqual('a2', checkout_tree.last_revision())
78
out, err = self.run_bzr('uncommit', '--force')
79
self.assertNotContainsRe(out, 'initial commit')
80
self.assertContainsRe(out, 'second commit')
82
# uncommit in a checkout should uncommit the parent branch
83
# (but doesn't effect the other working tree)
84
self.assertEquals('a1', checkout_tree.last_revision())
85
self.assertEquals('a1', wt.branch.last_revision())
86
self.assertEquals('a2', wt.last_revision())
88
def test_uncommit_bound(self):
90
a = BzrDirMetaFormat1().initialize('a')
93
t = a.create_workingtree()
97
b = t.bzrdir.sprout('b').open_branch()
100
t.set_last_revision(t.branch.last_revision())
101
self.assertEqual(len(b.revision_history()), 2)
102
self.assertEqual(len(t.branch.revision_history()), 2)
103
t.commit('commit 3b')
104
self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
108
def test_uncommit_revision(self):
109
wt = self.create_simple_tree()
112
out, err = self.run_bzr('uncommit', '-r1', '--force')
114
self.assertNotContainsRe(out, 'initial commit')
115
self.assertContainsRe(out, 'second commit')
116
self.assertEqual('a1', wt.last_revision())
117
self.assertEqual('a1', wt.branch.last_revision())
119
def test_uncommit_neg_1(self):
120
wt = self.create_simple_tree()
122
out, err = self.run_bzr('uncommit', '-r', '-1', retcode=1)
123
self.assertEqual('No revisions to uncommit.\n', out)
125
def test_uncommit_merges(self):
126
wt = self.create_simple_tree()
128
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
130
tree2.commit('unchanged', rev_id='b3')
131
tree2.commit('unchanged', rev_id='b4')
133
wt.branch.fetch(tree2.branch)
134
wt.set_pending_merges(['b4'])
135
wt.commit('merge b4', rev_id='a3')
137
self.assertEqual('a3', wt.last_revision())
138
self.assertEqual([], wt.pending_merges())
141
out, err = self.run_bzr('uncommit', '--force')
143
self.assertEqual('a2', wt.last_revision())
144
self.assertEqual(['b4'], wt.pending_merges())
146
def test_uncommit_multiple_merge(self):
147
wt = self.create_simple_tree()
149
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
151
tree2.commit('unchanged', rev_id='b3')
152
wt.branch.fetch(tree2.branch)
153
wt.set_pending_merges(['b3'])
154
wt.commit('merge b3', rev_id='a3')
156
tree2.commit('unchanged', rev_id='b4')
157
wt.branch.fetch(tree2.branch)
158
wt.set_pending_merges(['b4'])
159
wt.commit('merge b4', rev_id='a4')
161
self.assertEqual('a4', wt.last_revision())
162
self.assertEqual([], wt.pending_merges())
165
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
167
self.assertEqual('a2', wt.last_revision())
168
self.assertEqual(['b3', 'b4'], wt.pending_merges())
170
def test_uncommit_octopus_merge(self):
171
# Check that uncommit keeps the pending merges in the same order
172
wt = self.create_simple_tree()
174
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
175
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
177
tree2.commit('unchanged', rev_id='b3')
178
tree3.commit('unchanged', rev_id='c3')
179
wt.branch.fetch(tree2.branch)
180
wt.branch.fetch(tree3.branch)
181
wt.set_pending_merges(['b3', 'c3'])
182
wt.commit('merge b3, c3', rev_id='a3')
184
tree2.commit('unchanged', rev_id='b4')
185
tree3.commit('unchanged', rev_id='c4')
186
wt.branch.fetch(tree2.branch)
187
wt.branch.fetch(tree3.branch)
188
wt.set_pending_merges(['c4', 'b4'])
189
wt.commit('merge b4, c4', rev_id='a4')
191
self.assertEqual('a4', wt.last_revision())
192
self.assertEqual([], wt.pending_merges())
195
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
197
self.assertEqual('a2', wt.last_revision())
198
self.assertEqual(['b3', 'c3', 'c4', 'b4'], wt.pending_merges())