13
13
# You should have received a copy of the GNU General Public License
14
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Test the uncommit command."""
21
from bzrlib import uncommit, workingtree
21
from bzrlib import uncommit
22
22
from bzrlib.bzrdir import BzrDirMetaFormat1
23
from bzrlib.errors import BzrError, BoundBranchOutOfDate
23
from bzrlib.errors import BoundBranchOutOfDate
24
24
from bzrlib.tests import TestCaseWithTransport
25
from bzrlib.tests.script import (
27
31
class TestUncommit(TestCaseWithTransport):
60
64
out, err = self.run_bzr('status')
61
65
self.assertEquals(out, 'modified:\n a\n')
67
def test_uncommit_interactive(self):
68
"""Uncommit seeks confirmation, and doesn't proceed without it."""
69
wt = self.create_simple_tree()
74
The above revision(s) will be removed.
75
2>Uncommit these revisions? [y/n]:
79
self.assertEqual(['a2'], wt.get_parent_ids())
81
def test_uncommit_no_history(self):
82
wt = self.make_branch_and_tree('tree')
83
out, err = self.run_bzr('uncommit --force', retcode=1)
84
self.assertEqual('', err)
85
self.assertEqual('No revisions to uncommit.\n', out)
63
87
def test_uncommit_checkout(self):
64
88
wt = self.create_simple_tree()
65
89
checkout_tree = wt.branch.create_checkout('checkout')
67
91
self.assertEqual(['a2'], checkout_tree.get_parent_ids())
69
93
os.chdir('checkout')
70
out, err = self.run_bzr('uncommit', '--dry-run', '--force')
94
out, err = self.run_bzr('uncommit --dry-run --force')
71
95
self.assertContainsRe(out, 'Dry-run')
72
96
self.assertNotContainsRe(out, 'initial commit')
73
97
self.assertContainsRe(out, 'second commit')
75
99
self.assertEqual(['a2'], checkout_tree.get_parent_ids())
77
out, err = self.run_bzr('uncommit', '--force')
101
out, err = self.run_bzr('uncommit --force')
78
102
self.assertNotContainsRe(out, 'initial commit')
79
103
self.assertContainsRe(out, 'second commit')
97
121
uncommit.uncommit(b)
98
122
self.assertEqual(len(b.revision_history()), 2)
99
123
self.assertEqual(len(t_a.branch.revision_history()), 2)
100
# update A's tree to not have the uncomitted revision referenced.
124
# update A's tree to not have the uncommitted revision referenced.
102
126
t_a.commit('commit 3b')
103
127
self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
104
128
b.pull(t_a.branch)
105
129
uncommit.uncommit(b)
131
def test_uncommit_bound_local(self):
132
t_a = self.make_branch_and_tree('a')
133
rev_id1 = t_a.commit('commit 1')
134
rev_id2 = t_a.commit('commit 2')
135
rev_id3 = t_a.commit('commit 3')
136
b = t_a.branch.create_checkout('b').branch
138
out, err = self.run_bzr(['uncommit', '--local', 'b', '--force'])
139
self.assertEqual(rev_id3, t_a.last_revision())
140
self.assertEqual((3, rev_id3), t_a.branch.last_revision_info())
141
self.assertEqual((2, rev_id2), b.last_revision_info())
107
143
def test_uncommit_revision(self):
108
144
wt = self.create_simple_tree()
111
out, err = self.run_bzr('uncommit', '-r1', '--force')
147
out, err = self.run_bzr('uncommit -r1 --force')
113
149
self.assertNotContainsRe(out, 'initial commit')
114
150
self.assertContainsRe(out, 'second commit')
148
184
wt.set_pending_merges(['b3'])
151
out, err = self.run_bzr('uncommit', '--force')
187
out, err = self.run_bzr('uncommit --force')
152
188
self.assertEqual(['a1', 'b3'], wt.get_parent_ids())
154
190
def test_uncommit_multiple_merge(self):
155
191
wt = self.create_simple_tree()
157
193
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
159
194
tree2.commit('unchanged', rev_id='b3')
196
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
197
tree3.commit('unchanged', rev_id='c3')
161
199
wt.merge_from_branch(tree2.branch)
162
200
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')
202
wt.merge_from_branch(tree3.branch)
203
wt.commit('merge c3', rev_id='a4')
169
205
self.assertEqual(['a4'], wt.get_parent_ids())
172
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
208
out, err = self.run_bzr('uncommit --force -r 2')
174
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
210
self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
176
212
def test_uncommit_merge_plus_pending(self):
177
213
wt = self.create_simple_tree()
179
215
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
181
216
tree2.commit('unchanged', rev_id='b3')
217
tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
218
tree3.commit('unchanged', rev_id='c3')
182
220
wt.branch.fetch(tree2.branch)
183
221
wt.set_pending_merges(['b3'])
184
222
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())
225
wt.merge_from_branch(tree3.branch)
227
self.assertEqual(['a3', 'c3'], wt.get_parent_ids())
193
out, err = self.run_bzr('uncommit', '--force', '-r', '2')
195
self.assertEqual(['a2', 'b3', 'b4'], wt.get_parent_ids())
230
out, err = self.run_bzr('uncommit --force -r 2')
232
self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
234
def test_uncommit_shows_log_with_revision_id(self):
235
wt = self.create_simple_tree()
237
script = ScriptRunner()
238
script.run_script(self, """
240
$ bzr uncommit --force
244
The above revision(s) will be removed.
245
You can restore the old tip by running:
246
bzr pull . -r revid:a2
197
249
def test_uncommit_octopus_merge(self):
198
250
# Check that uncommit keeps the pending merges in the same order
251
# though it will also filter out ones in the ancestry
199
252
wt = self.create_simple_tree()
201
254
tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
204
257
tree2.commit('unchanged', rev_id='b3')
205
258
tree3.commit('unchanged', rev_id='c3')
207
260
wt.merge_from_branch(tree2.branch)
208
wt.merge_from_branch(tree3.branch)
261
wt.merge_from_branch(tree3.branch, force=True)
209
262
wt.commit('merge b3, c3', rev_id='a3')
211
264
tree2.commit('unchanged', rev_id='b4')
212
265
tree3.commit('unchanged', rev_id='c4')
214
267
wt.merge_from_branch(tree3.branch)
215
wt.merge_from_branch(tree2.branch)
268
wt.merge_from_branch(tree2.branch, force=True)
216
269
wt.commit('merge b4, c4', rev_id='a4')
218
271
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())
274
out, err = self.run_bzr('uncommit --force -r 2')
276
self.assertEqual(['a2', 'c4', 'b4'], wt.get_parent_ids())
278
def test_uncommit_nonascii(self):
279
tree = self.make_branch_and_tree('tree')
280
tree.commit(u'\u1234 message')
281
out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
282
self.assertContainsRe(out, r'\? message')
284
def test_uncommit_removes_tags(self):
285
tree = self.make_branch_and_tree('tree')
286
revid = tree.commit('message')
287
tree.branch.tags.set_tag("atag", revid)
288
out, err = self.run_bzr('uncommit --force tree')
289
self.assertEquals({}, tree.branch.tags.get_tag_dict())
291
def test_uncommit_keep_tags(self):
292
tree = self.make_branch_and_tree('tree')
293
revid = tree.commit('message')
294
tree.branch.tags.set_tag("atag", revid)
295
out, err = self.run_bzr('uncommit --keep-tags --force tree')
296
self.assertEquals({"atag": revid}, tree.branch.tags.get_tag_dict())