~bzr-pqm/bzr/bzr.dev

3280.4.1 by John Arbash Meinel
Add uncommit --local.
1
# Copyright (C) 2005, 2006, 2008 Canonical Ltd
1850.3.4 by John Arbash Meinel
Add copyright to test_uncommit.py
2
#
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.
7
#
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.
12
#
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
16
17
"""Test the uncommit command."""
1558.1.12 by Aaron Bentley
Got uncommit working properly with checkouts
18
19
import os
20
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
21
from bzrlib import uncommit, workingtree
1558.9.1 by Aaron Bentley
Fix uncommit to handle bound branches, and to do locking
22
from bzrlib.bzrdir import BzrDirMetaFormat1
23
from bzrlib.errors import BzrError, BoundBranchOutOfDate
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
24
from bzrlib.tests import TestCaseWithTransport
25
26
27
class TestUncommit(TestCaseWithTransport):
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
28
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
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'])
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
33
        wt.commit('initial commit', rev_id='a1')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
34
3629.1.1 by John Arbash Meinel
Change 'bzr uncommit' to display the revision ids and log them.
35
        self.build_tree_contents([('tree/a', 'new contents of a\n')])
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
36
        wt.commit('second commit', rev_id='a2')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
37
38
        return wt
39
0.3.11 by John Arbash Meinel
Updated to latest bzr.dev code, and added tests.
40
    def test_uncommit(self):
41
        """Test uncommit functionality."""
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
42
        wt = self.create_simple_tree()
43
44
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
45
        out, err = self.run_bzr('uncommit --dry-run --force')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
46
        self.assertContainsRe(out, 'Dry-run')
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
47
        self.assertNotContainsRe(out, 'initial commit')
48
        self.assertContainsRe(out, 'second commit')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
49
50
        # Nothing has changed
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
51
        self.assertEqual(['a2'], wt.get_parent_ids())
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
52
53
        # Uncommit, don't prompt
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
54
        out, err = self.run_bzr('uncommit --force')
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
55
        self.assertNotContainsRe(out, 'initial commit')
56
        self.assertContainsRe(out, 'second commit')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
57
58
        # This should look like we are back in revno 1
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
59
        self.assertEqual(['a1'], wt.get_parent_ids())
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
60
        out, err = self.run_bzr('status')
61
        self.assertEquals(out, 'modified:\n  a\n')
62
2948.2.1 by John Arbash Meinel
Fix 'bzr uncommit' when there is no revision history.
63
    def test_uncommit_no_history(self):
64
        wt = self.make_branch_and_tree('tree')
65
        out, err = self.run_bzr('uncommit --force', retcode=1)
66
        self.assertEqual('', err)
67
        self.assertEqual('No revisions to uncommit.\n', out)
68
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
69
    def test_uncommit_checkout(self):
70
        wt = self.create_simple_tree()
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
71
        checkout_tree = wt.branch.create_checkout('checkout')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
72
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
73
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
74
75
        os.chdir('checkout')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
76
        out, err = self.run_bzr('uncommit --dry-run --force')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
77
        self.assertContainsRe(out, 'Dry-run')
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
78
        self.assertNotContainsRe(out, 'initial commit')
79
        self.assertContainsRe(out, 'second commit')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
80
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
81
        self.assertEqual(['a2'], checkout_tree.get_parent_ids())
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
82
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
83
        out, err = self.run_bzr('uncommit --force')
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
84
        self.assertNotContainsRe(out, 'initial commit')
85
        self.assertContainsRe(out, 'second commit')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
86
87
        # uncommit in a checkout should uncommit the parent branch
88
        # (but doesn't effect the other working tree)
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
89
        self.assertEquals(['a1'], checkout_tree.get_parent_ids())
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
90
        self.assertEquals('a1', wt.branch.last_revision())
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
91
        self.assertEquals(['a2'], wt.get_parent_ids())
1558.9.1 by Aaron Bentley
Fix uncommit to handle bound branches, and to do locking
92
93
    def test_uncommit_bound(self):
94
        os.mkdir('a')
95
        a = BzrDirMetaFormat1().initialize('a')
96
        a.create_repository()
97
        a.create_branch()
1908.6.1 by Robert Collins
Change all callers of set_last_revision to use set_parent_trees.
98
        t_a = a.create_workingtree()
99
        t_a.commit('commit 1')
100
        t_a.commit('commit 2')
101
        t_a.commit('commit 3')
1997.1.5 by Robert Collins
``Branch.bind(other_branch)`` no longer takes a write lock on the
102
        b = t_a.branch.create_checkout('b').branch
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
103
        uncommit.uncommit(b)
1558.9.1 by Aaron Bentley
Fix uncommit to handle bound branches, and to do locking
104
        self.assertEqual(len(b.revision_history()), 2)
1908.6.1 by Robert Collins
Change all callers of set_last_revision to use set_parent_trees.
105
        self.assertEqual(len(t_a.branch.revision_history()), 2)
106
        # update A's tree to not have the uncomitted revision referenced.
107
        t_a.update()
108
        t_a.commit('commit 3b')
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
109
        self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
1908.6.1 by Robert Collins
Change all callers of set_last_revision to use set_parent_trees.
110
        b.pull(t_a.branch)
1850.3.1 by John Arbash Meinel
cleanup the uncommit tests
111
        uncommit.uncommit(b)
1558.9.1 by Aaron Bentley
Fix uncommit to handle bound branches, and to do locking
112
3280.4.1 by John Arbash Meinel
Add uncommit --local.
113
    def test_uncommit_bound_local(self):
114
        t_a = self.make_branch_and_tree('a')
115
        rev_id1 = t_a.commit('commit 1')
116
        rev_id2 = t_a.commit('commit 2')
117
        rev_id3 = t_a.commit('commit 3')
118
        b = t_a.branch.create_checkout('b').branch
119
120
        out, err = self.run_bzr(['uncommit', '--local', 'b', '--force'])
121
        self.assertEqual(rev_id3, t_a.last_revision())
122
        self.assertEqual((3, rev_id3), t_a.branch.last_revision_info())
123
        self.assertEqual((2, rev_id2), b.last_revision_info())
124
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
125
    def test_uncommit_revision(self):
126
        wt = self.create_simple_tree()
127
128
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
129
        out, err = self.run_bzr('uncommit -r1 --force')
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
130
131
        self.assertNotContainsRe(out, 'initial commit')
132
        self.assertContainsRe(out, 'second commit')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
133
        self.assertEqual(['a1'], wt.get_parent_ids())
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
134
        self.assertEqual('a1', wt.branch.last_revision())
135
136
    def test_uncommit_neg_1(self):
137
        wt = self.create_simple_tree()
138
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
139
        out, err = self.run_bzr('uncommit -r -1', retcode=1)
1850.3.2 by John Arbash Meinel
Change uncommit -r 10 so that it uncommits *to* 10, rather than removing 10
140
        self.assertEqual('No revisions to uncommit.\n', out)
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
141
142
    def test_uncommit_merges(self):
143
        wt = self.create_simple_tree()
144
145
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
146
147
        tree2.commit('unchanged', rev_id='b3')
148
        tree2.commit('unchanged', rev_id='b4')
149
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
150
        wt.merge_from_branch(tree2.branch)
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
151
        wt.commit('merge b4', rev_id='a3')
152
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
153
        self.assertEqual(['a3'], wt.get_parent_ids())
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
154
155
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
156
        out, err = self.run_bzr('uncommit --force')
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
157
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
158
        self.assertEqual(['a2', 'b4'], wt.get_parent_ids())
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
159
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
160
    def test_uncommit_pending_merge(self):
161
        wt = self.create_simple_tree()
162
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
163
        tree2.commit('unchanged', rev_id='b3')
164
165
        wt.branch.fetch(tree2.branch)
166
        wt.set_pending_merges(['b3'])
167
168
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
169
        out, err = self.run_bzr('uncommit --force')
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
170
        self.assertEqual(['a1', 'b3'], wt.get_parent_ids())
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
171
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
172
    def test_uncommit_multiple_merge(self):
173
        wt = self.create_simple_tree()
174
175
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
176
        tree2.commit('unchanged', rev_id='b3')
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
177
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
178
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
179
        tree3.commit('unchanged', rev_id='c3')
180
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
181
        wt.merge_from_branch(tree2.branch)
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
182
        wt.commit('merge b3', rev_id='a3')
183
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
184
        wt.merge_from_branch(tree3.branch)
185
        wt.commit('merge c3', rev_id='a4')
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
186
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
187
        self.assertEqual(['a4'], wt.get_parent_ids())
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
188
189
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
190
        out, err = self.run_bzr('uncommit --force -r 2')
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
191
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
192
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
193
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
194
    def test_uncommit_merge_plus_pending(self):
195
        wt = self.create_simple_tree()
196
197
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
198
        tree2.commit('unchanged', rev_id='b3')
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
199
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
200
        tree3.commit('unchanged', rev_id='c3')
201
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
202
        wt.branch.fetch(tree2.branch)
203
        wt.set_pending_merges(['b3'])
204
        wt.commit('merge b3', rev_id='a3')
205
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
206
207
        wt.merge_from_branch(tree3.branch)
208
209
        self.assertEqual(['a3', 'c3'], wt.get_parent_ids())
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
210
211
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
212
        out, err = self.run_bzr('uncommit --force -r 2')
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
213
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
214
        self.assertEqual(['a2', 'b3', 'c3'], wt.get_parent_ids())
1956.1.1 by John Arbash Meinel
Fix bug #57660: 'bzr uncommit' should preserve pending merges
215
3629.1.1 by John Arbash Meinel
Change 'bzr uncommit' to display the revision ids and log them.
216
    def test_uncommit_shows_log_with_revision_id(self):
217
        wt = self.create_simple_tree()
218
219
        out, err = self.run_bzr('uncommit --force', working_dir='tree')
220
        self.assertContainsRe(out, r'second commit')
3629.1.2 by John Arbash Meinel
Change to just display the command to restore the tip,
221
        self.assertContainsRe(err, r'You can restore the old tip by running')
222
        self.assertContainsRe(err, r'bzr pull . -r revid:a2')
3629.1.1 by John Arbash Meinel
Change 'bzr uncommit' to display the revision ids and log them.
223
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
224
    def test_uncommit_octopus_merge(self):
225
        # Check that uncommit keeps the pending merges in the same order
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
226
        # though it will also filter out ones in the ancestry
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
227
        wt = self.create_simple_tree()
228
229
        tree2 = wt.bzrdir.sprout('tree2').open_workingtree()
230
        tree3 = wt.bzrdir.sprout('tree3').open_workingtree()
231
232
        tree2.commit('unchanged', rev_id='b3')
233
        tree3.commit('unchanged', rev_id='c3')
3629.1.1 by John Arbash Meinel
Change 'bzr uncommit' to display the revision ids and log them.
234
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
235
        wt.merge_from_branch(tree2.branch)
236
        wt.merge_from_branch(tree3.branch)
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
237
        wt.commit('merge b3, c3', rev_id='a3')
238
239
        tree2.commit('unchanged', rev_id='b4')
240
        tree3.commit('unchanged', rev_id='c4')
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
241
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
242
        wt.merge_from_branch(tree3.branch)
243
        wt.merge_from_branch(tree2.branch)
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
244
        wt.commit('merge b4, c4', rev_id='a4')
245
1908.6.11 by Robert Collins
Remove usage of tree.pending_merges().
246
        self.assertEqual(['a4'], wt.get_parent_ids())
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
247
248
        os.chdir('tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
249
        out, err = self.run_bzr('uncommit --force -r 2')
1850.3.5 by John Arbash Meinel
Fix bug 31426, have uncommit keep track of pending merges.
250
3462.1.4 by John Arbash Meinel
fix up the uncommit tests now that set_parent_ids is filtering out ancestors.
251
        self.assertEqual(['a2', 'c4', 'b4'], wt.get_parent_ids())
3101.1.1 by Aaron Bentley
Uncommit doesn't throw when it encounters un-encodable characters
252
253
    def test_uncommit_nonascii(self):
254
        tree = self.make_branch_and_tree('tree')
255
        tree.commit(u'\u1234 message')
3101.1.2 by Aaron Bentley
Improve uncommit test
256
        out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
3101.1.1 by Aaron Bentley
Uncommit doesn't throw when it encounters un-encodable characters
257
        self.assertContainsRe(out, r'\? message')