/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/blackbox/test_uncommit.py

  • Committer: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2011, 2013, 2016 Canonical Ltd
 
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Test the uncommit command."""
 
18
 
 
19
import os
 
20
 
 
21
from breezy import uncommit
 
22
from breezy.bzr.bzrdir import BzrDirMetaFormat1
 
23
from breezy.errors import BoundBranchOutOfDate
 
24
from breezy.tests import TestCaseWithTransport
 
25
from breezy.tests.script import (
 
26
    run_script,
 
27
    ScriptRunner,
 
28
    )
 
29
 
 
30
 
 
31
class TestUncommit(TestCaseWithTransport):
 
32
 
 
33
    def create_simple_tree(self):
 
34
        wt = self.make_branch_and_tree('tree')
 
35
        self.build_tree(['tree/a', 'tree/b', 'tree/c'])
 
36
        wt.add(['a', 'b', 'c'])
 
37
        wt.commit('initial commit', rev_id=b'a1')
 
38
 
 
39
        self.build_tree_contents([('tree/a', b'new contents of a\n')])
 
40
        wt.commit('second commit', rev_id=b'a2')
 
41
 
 
42
        return wt
 
43
 
 
44
    def test_uncommit(self):
 
45
        """Test uncommit functionality."""
 
46
        wt = self.create_simple_tree()
 
47
 
 
48
        os.chdir('tree')
 
49
        out, err = self.run_bzr('uncommit --dry-run --force')
 
50
        self.assertContainsRe(out, 'Dry-run')
 
51
        self.assertNotContainsRe(out, 'initial commit')
 
52
        self.assertContainsRe(out, 'second commit')
 
53
 
 
54
        # Nothing has changed
 
55
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
56
 
 
57
        # Uncommit, don't prompt
 
58
        out, err = self.run_bzr('uncommit --force')
 
59
        self.assertNotContainsRe(out, 'initial commit')
 
60
        self.assertContainsRe(out, 'second commit')
 
61
 
 
62
        # This should look like we are back in revno 1
 
63
        self.assertEqual([b'a1'], wt.get_parent_ids())
 
64
        out, err = self.run_bzr('status')
 
65
        self.assertEqual(out, 'modified:\n  a\n')
 
66
 
 
67
    def test_uncommit_interactive(self):
 
68
        """Uncommit seeks confirmation, and doesn't proceed without it."""
 
69
        wt = self.create_simple_tree()
 
70
        os.chdir('tree')
 
71
        run_script(self, """
 
72
        $ brz uncommit
 
73
        ...
 
74
        The above revision(s) will be removed.
 
75
        2>Uncommit these revisions? ([y]es, [n]o): no
 
76
        <n
 
77
        Canceled
 
78
        """)
 
79
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
80
 
 
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)
 
86
 
 
87
    def test_uncommit_checkout(self):
 
88
        wt = self.create_simple_tree()
 
89
        checkout_tree = wt.branch.create_checkout('checkout')
 
90
 
 
91
        self.assertEqual([b'a2'], checkout_tree.get_parent_ids())
 
92
 
 
93
        os.chdir('checkout')
 
94
        out, err = self.run_bzr('uncommit --dry-run --force')
 
95
        self.assertContainsRe(out, 'Dry-run')
 
96
        self.assertNotContainsRe(out, 'initial commit')
 
97
        self.assertContainsRe(out, 'second commit')
 
98
 
 
99
        self.assertEqual([b'a2'], checkout_tree.get_parent_ids())
 
100
 
 
101
        out, err = self.run_bzr('uncommit --force')
 
102
        self.assertNotContainsRe(out, 'initial commit')
 
103
        self.assertContainsRe(out, 'second commit')
 
104
 
 
105
        # uncommit in a checkout should uncommit the parent branch
 
106
        # (but doesn't effect the other working tree)
 
107
        self.assertEqual([b'a1'], checkout_tree.get_parent_ids())
 
108
        self.assertEqual(b'a1', wt.branch.last_revision())
 
109
        self.assertEqual([b'a2'], wt.get_parent_ids())
 
110
 
 
111
    def test_uncommit_bound(self):
 
112
        os.mkdir('a')
 
113
        a = BzrDirMetaFormat1().initialize('a')
 
114
        a.create_repository()
 
115
        a.create_branch()
 
116
        t_a = a.create_workingtree()
 
117
        t_a.commit('commit 1')
 
118
        t_a.commit('commit 2')
 
119
        t_a.commit('commit 3')
 
120
        b = t_a.branch.create_checkout('b').branch
 
121
        uncommit.uncommit(b)
 
122
        self.assertEqual(b.last_revision_info()[0], 2)
 
123
        self.assertEqual(t_a.branch.last_revision_info()[0], 2)
 
124
        # update A's tree to not have the uncommitted revision referenced.
 
125
        t_a.update()
 
126
        t_a.commit('commit 3b')
 
127
        self.assertRaises(BoundBranchOutOfDate, uncommit.uncommit, b)
 
128
        b.pull(t_a.branch)
 
129
        uncommit.uncommit(b)
 
130
 
 
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
 
137
 
 
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())
 
142
 
 
143
    def test_uncommit_revision(self):
 
144
        wt = self.create_simple_tree()
 
145
 
 
146
        os.chdir('tree')
 
147
        out, err = self.run_bzr('uncommit -r1 --force')
 
148
 
 
149
        self.assertNotContainsRe(out, 'initial commit')
 
150
        self.assertContainsRe(out, 'second commit')
 
151
        self.assertEqual([b'a1'], wt.get_parent_ids())
 
152
        self.assertEqual(b'a1', wt.branch.last_revision())
 
153
 
 
154
    def test_uncommit_neg_1(self):
 
155
        wt = self.create_simple_tree()
 
156
        os.chdir('tree')
 
157
        out, err = self.run_bzr('uncommit -r -1', retcode=1)
 
158
        self.assertEqual('No revisions to uncommit.\n', out)
 
159
 
 
160
    def test_uncommit_merges(self):
 
161
        wt = self.create_simple_tree()
 
162
 
 
163
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
164
 
 
165
        tree2.commit('unchanged', rev_id=b'b3')
 
166
        tree2.commit('unchanged', rev_id=b'b4')
 
167
 
 
168
        wt.merge_from_branch(tree2.branch)
 
169
        wt.commit('merge b4', rev_id=b'a3')
 
170
 
 
171
        self.assertEqual([b'a3'], wt.get_parent_ids())
 
172
 
 
173
        os.chdir('tree')
 
174
        out, err = self.run_bzr('uncommit --force')
 
175
 
 
176
        self.assertEqual([b'a2', b'b4'], wt.get_parent_ids())
 
177
 
 
178
    def test_uncommit_pending_merge(self):
 
179
        wt = self.create_simple_tree()
 
180
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
181
        tree2.commit('unchanged', rev_id=b'b3')
 
182
 
 
183
        wt.branch.fetch(tree2.branch)
 
184
        wt.set_pending_merges([b'b3'])
 
185
 
 
186
        os.chdir('tree')
 
187
        out, err = self.run_bzr('uncommit --force')
 
188
        self.assertEqual([b'a1', b'b3'], wt.get_parent_ids())
 
189
 
 
190
    def test_uncommit_multiple_merge(self):
 
191
        wt = self.create_simple_tree()
 
192
 
 
193
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
194
        tree2.commit('unchanged', rev_id=b'b3')
 
195
 
 
196
        tree3 = wt.controldir.sprout('tree3').open_workingtree()
 
197
        tree3.commit('unchanged', rev_id=b'c3')
 
198
 
 
199
        wt.merge_from_branch(tree2.branch)
 
200
        wt.commit('merge b3', rev_id=b'a3')
 
201
 
 
202
        wt.merge_from_branch(tree3.branch)
 
203
        wt.commit('merge c3', rev_id=b'a4')
 
204
 
 
205
        self.assertEqual([b'a4'], wt.get_parent_ids())
 
206
 
 
207
        os.chdir('tree')
 
208
        out, err = self.run_bzr('uncommit --force -r 2')
 
209
 
 
210
        self.assertEqual([b'a2', b'b3', b'c3'], wt.get_parent_ids())
 
211
 
 
212
    def test_uncommit_merge_plus_pending(self):
 
213
        wt = self.create_simple_tree()
 
214
 
 
215
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
216
        tree2.commit('unchanged', rev_id=b'b3')
 
217
        tree3 = wt.controldir.sprout('tree3').open_workingtree()
 
218
        tree3.commit('unchanged', rev_id=b'c3')
 
219
 
 
220
        wt.branch.fetch(tree2.branch)
 
221
        wt.set_pending_merges([b'b3'])
 
222
        wt.commit('merge b3', rev_id=b'a3')
 
223
 
 
224
        wt.merge_from_branch(tree3.branch)
 
225
 
 
226
        self.assertEqual([b'a3', b'c3'], wt.get_parent_ids())
 
227
 
 
228
        os.chdir('tree')
 
229
        out, err = self.run_bzr('uncommit --force -r 2')
 
230
 
 
231
        self.assertEqual([b'a2', b'b3', b'c3'], wt.get_parent_ids())
 
232
 
 
233
    def test_uncommit_shows_log_with_revision_id(self):
 
234
        wt = self.create_simple_tree()
 
235
 
 
236
        script = ScriptRunner()
 
237
        script.run_script(self, """
 
238
$ cd tree
 
239
$ brz uncommit --force
 
240
    2 ...
 
241
      second commit
 
242
...
 
243
The above revision(s) will be removed.
 
244
You can restore the old tip by running:
 
245
  brz pull . -r revid:a2
 
246
""")
 
247
 
 
248
    def test_uncommit_shows_pull_with_location(self):
 
249
        wt = self.create_simple_tree()
 
250
 
 
251
        script = ScriptRunner()
 
252
        script.run_script(self, """
 
253
$ brz uncommit --force tree
 
254
    2 ...
 
255
      second commit
 
256
...
 
257
The above revision(s) will be removed.
 
258
You can restore the old tip by running:
 
259
  brz pull -d tree tree -r revid:a2
 
260
""")
 
261
 
 
262
    def test_uncommit_octopus_merge(self):
 
263
        # Check that uncommit keeps the pending merges in the same order
 
264
        # though it will also filter out ones in the ancestry
 
265
        wt = self.create_simple_tree()
 
266
 
 
267
        tree2 = wt.controldir.sprout('tree2').open_workingtree()
 
268
        tree3 = wt.controldir.sprout('tree3').open_workingtree()
 
269
 
 
270
        tree2.commit('unchanged', rev_id=b'b3')
 
271
        tree3.commit('unchanged', rev_id=b'c3')
 
272
 
 
273
        wt.merge_from_branch(tree2.branch)
 
274
        wt.merge_from_branch(tree3.branch, force=True)
 
275
        wt.commit('merge b3, c3', rev_id=b'a3')
 
276
 
 
277
        tree2.commit('unchanged', rev_id=b'b4')
 
278
        tree3.commit('unchanged', rev_id=b'c4')
 
279
 
 
280
        wt.merge_from_branch(tree3.branch)
 
281
        wt.merge_from_branch(tree2.branch, force=True)
 
282
        wt.commit('merge b4, c4', rev_id=b'a4')
 
283
 
 
284
        self.assertEqual([b'a4'], wt.get_parent_ids())
 
285
 
 
286
        os.chdir('tree')
 
287
        out, err = self.run_bzr('uncommit --force -r 2')
 
288
 
 
289
        self.assertEqual([b'a2', b'c4', b'b4'], wt.get_parent_ids())
 
290
 
 
291
    def test_uncommit_nonascii(self):
 
292
        tree = self.make_branch_and_tree('tree')
 
293
        tree.commit(u'\u1234 message')
 
294
        out, err = self.run_bzr('uncommit --force tree', encoding='ascii')
 
295
        self.assertContainsRe(out, r'\? message')
 
296
 
 
297
    def test_uncommit_removes_tags(self):
 
298
        tree = self.make_branch_and_tree('tree')
 
299
        revid = tree.commit('message')
 
300
        tree.branch.tags.set_tag("atag", revid)
 
301
        out, err = self.run_bzr('uncommit --force tree')
 
302
        self.assertEqual({}, tree.branch.tags.get_tag_dict())
 
303
 
 
304
    def test_uncommit_keep_tags(self):
 
305
        tree = self.make_branch_and_tree('tree')
 
306
        revid = tree.commit('message')
 
307
        tree.branch.tags.set_tag("atag", revid)
 
308
        out, err = self.run_bzr('uncommit --keep-tags --force tree')
 
309
        self.assertEqual({"atag": revid}, tree.branch.tags.get_tag_dict())
 
310
 
 
311
 
 
312
class TestInconsistentDelta(TestCaseWithTransport):
 
313
    # See https://bugs.launchpad.net/bzr/+bug/855155
 
314
    # See https://bugs.launchpad.net/bzr/+bug/1100385
 
315
    # brz uncommit may result in error
 
316
    # 'An inconsistent delta was supplied involving'
 
317
 
 
318
    def test_inconsistent_delta(self):
 
319
        # Script taken from https://bugs.launchpad.net/bzr/+bug/855155/comments/26
 
320
        wt = self.make_branch_and_tree('test')
 
321
        self.build_tree(['test/a/', 'test/a/b', 'test/a/c'])
 
322
        wt.add(['a', 'a/b', 'a/c'])
 
323
        wt.commit('initial commit', rev_id=b'a1')
 
324
        wt.remove(['a/b', 'a/c'])
 
325
        wt.commit('remove b and c', rev_id=b'a2')
 
326
        self.run_bzr("uncommit --force test")