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')
40
def test_uncommit(self):
41
"""Test uncommit functionality."""
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.get_parent_ids())
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.get_parent_ids())
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.get_parent_ids())
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.get_parent_ids())
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.get_parent_ids())
86
self.assertEquals('a1', wt.branch.last_revision())
87
self.assertEquals(['a2'], wt.get_parent_ids())
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.get_parent_ids())
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
wt.merge_from_branch(tree2.branch)
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', 'b3'], wt.get_parent_ids())
157
def test_uncommit_multiple_merge(self):
158
wt = self.create_simple_tree()
160
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
162
tree2.commit('unchanged', rev_id='b3')
164
wt.merge_from_branch(tree2.branch)
165
wt.commit('merge b3', rev_id='a3')
167
tree2.commit('unchanged', rev_id='b4')
169
wt.merge_from_branch(tree2.branch)
170
wt.commit('merge b4', rev_id='a4')
172
self.assertEqual(['a4'], wt.get_parent_ids())
175
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
177
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
179
def test_uncommit_merge_plus_pending(self):
180
wt = self.create_simple_tree()
182
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
184
tree2.commit('unchanged', rev_id='b3')
185
wt.branch.fetch(tree2.branch)
186
wt.set_pending_merges(['b3'])
187
wt.commit('merge b3', rev_id='a3')
189
tree2.commit('unchanged', rev_id='b4')
190
wt.branch.fetch(tree2.branch)
191
wt.set_pending_merges(['b4'])
193
self.assertEqual(['a3', 'b4'], wt.get_parent_ids())
196
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
198
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
200
def test_uncommit_octopus_merge(self):
201
# Check that uncommit keeps the pending merges in the same order
202
wt = self.create_simple_tree()
204
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
205
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
207
tree2.commit('unchanged', rev_id='b3')
208
tree3.commit('unchanged', rev_id='c3')
210
wt.merge_from_branch(tree2.branch)
211
wt.merge_from_branch(tree3.branch)
212
wt.commit('merge b3, c3', rev_id='a3')
214
tree2.commit('unchanged', rev_id='b4')
215
tree3.commit('unchanged', rev_id='c4')
217
wt.merge_from_branch(tree3.branch)
218
wt.merge_from_branch(tree2.branch)
219
wt.commit('merge b4, c4', rev_id='a4')
221
self.assertEqual(['a4'], wt.get_parent_ids())
224
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
226
self.assertEqual(['a2', 'b3', 'c3', 'c4', 'b4'], wt.get_parent_ids())