1
# Copyright (C) 2005, 2006 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()
65
checkout_tree = wt.branch.create_checkout('checkout')
67
self.assertEqual(['a2'], checkout_tree.get_parent_ids())
70
out, err = self.run_bzr('uncommit --dry-run --force')
71
self.assertContainsRe(out, 'Dry-run')
72
self.assertNotContainsRe(out, 'initial commit')
73
self.assertContainsRe(out, 'second commit')
75
self.assertEqual(['a2'], checkout_tree.get_parent_ids())
77
out, err = self.run_bzr('uncommit --force')
78
self.assertNotContainsRe(out, 'initial commit')
79
self.assertContainsRe(out, 'second commit')
81
# uncommit in a checkout should uncommit the parent branch
82
# (but doesn't effect the other working tree)
83
self.assertEquals(['a1'], checkout_tree.get_parent_ids())
84
self.assertEquals('a1', wt.branch.last_revision())
85
self.assertEquals(['a2'], wt.get_parent_ids())
87
def test_uncommit_bound(self):
89
a = BzrDirMetaFormat1().initialize('a')
92
t_a = a.create_workingtree()
93
t_a.commit('commit 1')
94
t_a.commit('commit 2')
95
t_a.commit('commit 3')
96
b = t_a.branch.create_checkout('b').branch
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.
102
t_a.commit('commit 3b')
103
self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
107
def test_uncommit_revision(self):
108
wt = self.create_simple_tree()
111
out, err = self.run_bzr('uncommit -r1 --force')
113
self.assertNotContainsRe(out, 'initial commit')
114
self.assertContainsRe(out, 'second commit')
115
self.assertEqual(['a1'], wt.get_parent_ids())
116
self.assertEqual('a1', wt.branch.last_revision())
118
def test_uncommit_neg_1(self):
119
wt = self.create_simple_tree()
121
out, err = self.run_bzr('uncommit -r -1', retcode=1)
122
self.assertEqual('No revisions to uncommit.\n', out)
124
def test_uncommit_merges(self):
125
wt = self.create_simple_tree()
127
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
129
tree2.commit('unchanged', rev_id='b3')
130
tree2.commit('unchanged', rev_id='b4')
132
wt.merge_from_branch(tree2.branch)
133
wt.commit('merge b4', rev_id='a3')
135
self.assertEqual(['a3'], wt.get_parent_ids())
138
out, err = self.run_bzr('uncommit --force')
140
self.assertEqual(['a2', 'b4'], wt.get_parent_ids())
142
def test_uncommit_pending_merge(self):
143
wt = self.create_simple_tree()
144
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
145
tree2.commit('unchanged', rev_id='b3')
147
wt.branch.fetch(tree2.branch)
148
wt.set_pending_merges(['b3'])
151
out, err = self.run_bzr('uncommit --force')
152
self.assertEqual(['a1', 'b3'], wt.get_parent_ids())
154
def test_uncommit_multiple_merge(self):
155
wt = self.create_simple_tree()
157
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
159
tree2.commit('unchanged', rev_id='b3')
161
wt.merge_from_branch(tree2.branch)
162
wt.commit('merge b3', rev_id='a3')
164
tree2.commit('unchanged', rev_id='b4')
166
wt.merge_from_branch(tree2.branch)
167
wt.commit('merge b4', rev_id='a4')
169
self.assertEqual(['a4'], wt.get_parent_ids())
172
out, err = self.run_bzr('uncommit --force -r 2')
174
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
176
def test_uncommit_merge_plus_pending(self):
177
wt = self.create_simple_tree()
179
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
181
tree2.commit('unchanged', rev_id='b3')
182
wt.branch.fetch(tree2.branch)
183
wt.set_pending_merges(['b3'])
184
wt.commit('merge b3', rev_id='a3')
186
tree2.commit('unchanged', rev_id='b4')
187
wt.branch.fetch(tree2.branch)
188
wt.set_pending_merges(['b4'])
190
self.assertEqual(['a3', 'b4'], wt.get_parent_ids())
193
out, err = self.run_bzr('uncommit --force -r 2')
195
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
197
def test_uncommit_octopus_merge(self):
198
# Check that uncommit keeps the pending merges in the same order
199
wt = self.create_simple_tree()
201
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
202
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
204
tree2.commit('unchanged', rev_id='b3')
205
tree3.commit('unchanged', rev_id='c3')
207
wt.merge_from_branch(tree2.branch)
208
wt.merge_from_branch(tree3.branch)
209
wt.commit('merge b3, c3', rev_id='a3')
211
tree2.commit('unchanged', rev_id='b4')
212
tree3.commit('unchanged', rev_id='c4')
214
wt.merge_from_branch(tree3.branch)
215
wt.merge_from_branch(tree2.branch)
216
wt.commit('merge b4, c4', rev_id='a4')
218
self.assertEqual(['a4'], wt.get_parent_ids())
221
out, err = self.run_bzr('uncommit --force -r 2')
223
self.assertEqual(['a2', 'b3', 'c3', 'c4', 'b4'], wt.get_parent_ids())