/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1
# Copyright (C) 2006-2010 Canonical Ltd
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
2
# Authors:  Robert Collins <robert.collins@canonical.com>
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
17
18
import os
19
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
20
from breezy import (
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
21
    branch,
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
22
    conflicts,
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
23
    controldir,
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
24
    errors,
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
25
    mutabletree,
2922.2.1 by John Arbash Meinel
Add failing tests exposing part of bug #114615
26
    osutils,
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
27
    revision as _mod_revision,
5777.2.1 by Jelmer Vernooij
Skip commit exclude tests for repositories that don't support excludes.
28
    tests,
6437.70.1 by John Arbash Meinel
Set up the infrastructure to start testing a lightweight checkout of a remote repository.
29
    transport as _mod_transport,
2598.5.2 by Aaron Bentley
Got all tests passing with Branch returning 'null:' for null revision
30
    ui,
31
    )
6734.1.20 by Jelmer Vernooij
Move errors.
32
from breezy.commit import (
33
    CannotCommitSelectedFileMerge,
34
    PointlessCommit,
35
    )
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
36
from breezy.tests.matchers import HasPathRelations
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
37
from breezy.tests.per_workingtree import TestCaseWithWorkingTree
38
from breezy.tests.testui import ProgressRecordingUIFactory
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
39
40
41
class TestCommit(TestCaseWithWorkingTree):
42
2922.2.1 by John Arbash Meinel
Add failing tests exposing part of bug #114615
43
    def test_autodelete_renamed(self):
44
        tree_a = self.make_branch_and_tree('a')
45
        self.build_tree(['a/dir/', 'a/dir/f1', 'a/dir/f2'])
6745.1.1 by Jelmer Vernooij
Avoid explicitly setting file ids or guard it by checking
46
        tree_a.add(['dir', 'dir/f1', 'dir/f2'])
2922.2.1 by John Arbash Meinel
Add failing tests exposing part of bug #114615
47
        rev_id1 = tree_a.commit('init')
48
        # Start off by renaming entries,
49
        # but then actually auto delete the whole tree
50
        # https://bugs.launchpad.net/bzr/+bug/114615
51
        tree_a.rename_one('dir/f1', 'dir/a')
52
        tree_a.rename_one('dir/f2', 'dir/z')
53
        osutils.rmtree('a/dir')
54
        tree_a.commit('autoremoved')
55
56
        tree_a.lock_read()
57
        try:
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
58
            root_id = tree_a.get_root_id()
2922.2.1 by John Arbash Meinel
Add failing tests exposing part of bug #114615
59
            paths = [(path, ie.file_id)
60
                     for path, ie in tree_a.iter_entries_by_dir()]
61
        finally:
62
            tree_a.unlock()
63
        # The only paths left should be the root
64
        self.assertEqual([('', root_id)], paths)
65
2922.2.3 by John Arbash Meinel
Add a test which shows why the previous fix is broken.
66
    def test_no_autodelete_renamed_away(self):
67
        tree_a = self.make_branch_and_tree('a')
68
        self.build_tree(['a/dir/', 'a/dir/f1', 'a/dir/f2', 'a/dir2/'])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
69
        tree_a.add(['dir', 'dir/f1', 'dir/f2', 'dir2'])
2922.2.3 by John Arbash Meinel
Add a test which shows why the previous fix is broken.
70
        rev_id1 = tree_a.commit('init')
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
71
        revtree = tree_a.branch.repository.revision_tree(rev_id1)
2922.2.3 by John Arbash Meinel
Add a test which shows why the previous fix is broken.
72
        # Rename one entry out of this directory
73
        tree_a.rename_one('dir/f1', 'dir2/a')
74
        osutils.rmtree('a/dir')
75
        tree_a.commit('autoremoved')
76
77
        # The only paths left should be the root
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
78
        self.assertThat(
79
            tree_a, HasPathRelations(
80
                revtree,
81
                [('', ''), ('dir2/', 'dir2/'), ('dir2/a', 'dir/f1')]))
2922.2.3 by John Arbash Meinel
Add a test which shows why the previous fix is broken.
82
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
83
    def test_no_autodelete_alternate_renamed(self):
84
        # Test for bug #114615
85
        tree_a = self.make_branch_and_tree('A')
86
        self.build_tree(['A/a/', 'A/a/m', 'A/a/n'])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
87
        tree_a.add(['a', 'a/m', 'a/n'])
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
88
        tree_a.commit('init')
89
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
90
        tree_b = tree_a.controldir.sprout('B').open_workingtree()
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
91
        self.build_tree(['B/xyz/'])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
92
        tree_b.add(['xyz'])
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
93
        tree_b.rename_one('a/m', 'xyz/m')
94
        osutils.rmtree('B/a')
95
        tree_b.commit('delete in B')
96
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
97
        self.assertThat(
7143.15.2 by Jelmer Vernooij
Run autopep8.
98
            tree_b,
99
            HasPathRelations(
100
                tree_a, [('', ''), ('xyz/', None), ('xyz/m', 'a/m')]))
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
101
6855.4.1 by Jelmer Vernooij
Yet more bees.
102
        self.build_tree_contents([('A/a/n', b'new contents for n\n')])
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
103
        tree_a.commit('change n in A')
104
105
        # Merging from A should introduce conflicts because 'n' was modified
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
106
        # (in A) and removed (in B), so 'a' needs to be restored.
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
107
        num_conflicts = tree_b.merge_from_branch(tree_a.branch)
108
        self.assertEqual(3, num_conflicts)
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
109
110
        self.assertThat(
7143.15.2 by Jelmer Vernooij
Run autopep8.
111
            tree_b, HasPathRelations(
112
                tree_a,
113
                [('', ''), ('a/', 'a/'), ('xyz/', None),
114
                 ('a/n.OTHER', 'a/n'), ('xyz/m', 'a/m')]))
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
115
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
116
        osutils.rmtree('B/a')
117
        try:
118
            # bzr resolve --all
119
            tree_b.set_conflicts(conflicts.ConflictList())
120
        except errors.UnsupportedOperation:
121
            # On WT2, set_conflicts is unsupported, but the rmtree has the same
122
            # effect.
123
            pass
124
        tree_b.commit('autoremove a, without touching xyz/m')
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
125
126
        self.assertThat(
7143.15.2 by Jelmer Vernooij
Run autopep8.
127
            tree_b, HasPathRelations(
128
                tree_a,
129
                [('', ''), ('xyz/', None), ('xyz/m', 'a/m')]))
2922.2.4 by John Arbash Meinel
Fix bug #114615 by teaching unversion() to not touch renamed entries.
130
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
131
    def test_commit_exclude_pending_merge_fails(self):
132
        """Excludes are a form of partial commit."""
133
        wt = self.make_branch_and_tree('.')
134
        self.build_tree(['foo'])
135
        wt.add('foo')
136
        wt.commit('commit one')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
137
        wt2 = wt.controldir.sprout('to').open_workingtree()
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
138
        wt2.commit('change_right')
139
        wt.merge_from_branch(wt2.branch)
6747.1.1 by Jelmer Vernooij
Remove unnecessary ExcludesUnsupported exception.
140
        self.assertRaises(CannotCommitSelectedFileMerge,
7143.15.2 by Jelmer Vernooij
Run autopep8.
141
                          wt.commit, 'test', exclude=['foo'])
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
142
3602.1.2 by Robert Collins
Review feedback : test for PointlessCommit and that the example given in the help (excluding a subtree of a specified tree) does in fact work.
143
    def test_commit_exclude_exclude_changed_is_pointless(self):
144
        tree = self.make_branch_and_tree('.')
145
        self.build_tree(['a'])
146
        tree.smart_add(['.'])
147
        tree.commit('setup test')
6855.4.1 by Jelmer Vernooij
Yet more bees.
148
        self.build_tree_contents([('a', b'new contents for "a"\n')])
6747.1.1 by Jelmer Vernooij
Remove unnecessary ExcludesUnsupported exception.
149
        self.assertRaises(PointlessCommit, tree.commit, 'test',
7143.15.2 by Jelmer Vernooij
Run autopep8.
150
                          exclude=['a'], allow_pointless=False)
3602.1.2 by Robert Collins
Review feedback : test for PointlessCommit and that the example given in the help (excluding a subtree of a specified tree) does in fact work.
151
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
152
    def test_commit_exclude_excludes_modified_files(self):
153
        tree = self.make_branch_and_tree('.')
154
        self.build_tree(['a', 'b', 'c'])
155
        tree.smart_add(['.'])
6747.1.1 by Jelmer Vernooij
Remove unnecessary ExcludesUnsupported exception.
156
        tree.commit('test', exclude=['b', 'c'])
3602.1.4 by Robert Collins
Andrew's review feedback.
157
        # If b was excluded it will still be 'added' in status.
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
158
        tree.lock_read()
159
        self.addCleanup(tree.unlock)
160
        changes = list(tree.iter_changes(tree.basis_tree()))
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
161
        self.assertEqual([(None, 'b'), (None, 'c')], [c[1] for c in changes])
3602.1.1 by Robert Collins
Add support for -x or --exclude to bzr commit, fixing bug 3117. (Robert Collins)
162
3602.1.2 by Robert Collins
Review feedback : test for PointlessCommit and that the example given in the help (excluding a subtree of a specified tree) does in fact work.
163
    def test_commit_exclude_subtree_of_selected(self):
164
        tree = self.make_branch_and_tree('.')
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
165
        self.build_tree(['a/', 'a/b', 'a/c'])
3602.1.2 by Robert Collins
Review feedback : test for PointlessCommit and that the example given in the help (excluding a subtree of a specified tree) does in fact work.
166
        tree.smart_add(['.'])
6913.5.2 by Jelmer Vernooij
Use HasPathRelations.
167
        tree.commit('test', specific_files=['a', 'a/c'], exclude=['a/b'])
3602.1.4 by Robert Collins
Andrew's review feedback.
168
        # If a/b was excluded it will still be 'added' in status.
3602.1.2 by Robert Collins
Review feedback : test for PointlessCommit and that the example given in the help (excluding a subtree of a specified tree) does in fact work.
169
        tree.lock_read()
170
        self.addCleanup(tree.unlock)
171
        changes = list(tree.iter_changes(tree.basis_tree()))
172
        self.assertEqual(1, len(changes))
173
        self.assertEqual((None, 'a/b'), changes[0][1])
174
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
175
    def test_commit_sets_last_revision(self):
176
        tree = self.make_branch_and_tree('tree')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
177
        if tree.branch.repository._format.supports_setting_revision_ids:
6855.4.1 by Jelmer Vernooij
Yet more bees.
178
            committed_id = tree.commit('foo', rev_id=b'foo')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
179
            # the commit should have returned the same id we asked for.
7045.1.14 by Jelmer Vernooij
More fixes.
180
            self.assertEqual(b'foo', committed_id)
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
181
        else:
182
            committed_id = tree.commit('foo')
183
        self.assertEqual([committed_id], tree.get_parent_ids())
1773.1.1 by Robert Collins
Teach WorkingTree.commit to return the committed revision id.
184
185
    def test_commit_returns_revision_id(self):
186
        tree = self.make_branch_and_tree('.')
2825.5.2 by Robert Collins
Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.
187
        committed_id = tree.commit('message')
1773.1.1 by Robert Collins
Teach WorkingTree.commit to return the committed revision id.
188
        self.assertTrue(tree.branch.repository.has_revision(committed_id))
189
        self.assertNotEqual(None, committed_id)
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
190
191
    def test_commit_local_unbound(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
192
        # using the library api to do a local commit on unbound branches is
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
193
        # also an error
194
        tree = self.make_branch_and_tree('tree')
195
        self.assertRaises(errors.LocalRequiresBoundBranch,
196
                          tree.commit,
197
                          'foo',
198
                          local=True)
2374.2.1 by John Arbash Meinel
(broken) merge a test case showing that commiting a merge of a kind change fails.
199
200
    def test_commit_merged_kind_change(self):
201
        """Test merging a kind change.
202
203
        Test making a kind change in a working tree, and then merging that
204
        from another. When committed it should commit the new kind.
205
        """
206
        wt = self.make_branch_and_tree('.')
207
        self.build_tree(['a'])
208
        wt.add(['a'])
209
        wt.commit('commit one')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
210
        wt2 = wt.controldir.sprout('to').open_workingtree()
2374.2.1 by John Arbash Meinel
(broken) merge a test case showing that commiting a merge of a kind change fails.
211
        os.remove('a')
212
        os.mkdir('a')
213
        wt.commit('changed kind')
214
        wt2.merge_from_branch(wt.branch)
215
        wt2.commit('merged kind change')
216
4536.3.1 by Robert Collins
Defer doing unversioning of file ids during commit to after completing branch operations. (Robert Collins, bug 282402)
217
    def test_commit_aborted_does_not_apply_automatic_changes_bug_282402(self):
218
        wt = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
219
        wt.add(['a'], None, ['file'])
220
        a_id = wt.path2id('a')
6861.1.1 by Jelmer Vernooij
More foreign branch test fixes.
221
        self.assertEqual('a', wt.id2path(a_id))
7143.15.2 by Jelmer Vernooij
Run autopep8.
222
4536.3.1 by Robert Collins
Defer doing unversioning of file ids during commit to after completing branch operations. (Robert Collins, bug 282402)
223
        def fail_message(obj):
224
            raise errors.BzrCommandError("empty commit message")
225
        self.assertRaises(errors.BzrCommandError, wt.commit,
7143.15.2 by Jelmer Vernooij
Run autopep8.
226
                          message_callback=fail_message)
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
227
        self.assertEqual('a', wt.id2path(a_id))
4536.3.1 by Robert Collins
Defer doing unversioning of file ids during commit to after completing branch operations. (Robert Collins, bug 282402)
228
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
229
    def test_local_commit_ignores_master(self):
230
        # a --local commit does not require access to the master branch
231
        # at all, or even for it to exist.
232
        # we test this by setting up a bound branch and then corrupting
233
        # the master.
234
        master = self.make_branch('master')
235
        tree = self.make_branch_and_tree('tree')
236
        try:
237
            tree.branch.bind(master)
238
        except errors.UpgradeRequired:
239
            # older format.
240
            return
7027.3.3 by Jelmer Vernooij
Add some more bees; support writing both bytes and unicode strings in build_tree_contents.
241
        master.controldir.transport.put_bytes('branch-format', b'garbage')
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
242
        del master
243
        # check its corrupted.
244
        self.assertRaises(errors.UnknownFormatError,
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
245
                          controldir.ControlDir.open,
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
246
                          'master')
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
247
        tree.commit('foo', local=True)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
248
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
249
    def test_local_commit_does_not_push_to_master(self):
250
        # a --local commit does not require access to the master branch
251
        # at all, or even for it to exist.
252
        # we test that even when its available it does not push to it.
253
        master = self.make_branch('master')
254
        tree = self.make_branch_and_tree('tree')
255
        try:
256
            tree.branch.bind(master)
257
        except errors.UpgradeRequired:
258
            # older format.
259
            return
6747.3.1 by Jelmer Vernooij
Avoid more uses of revision_id.
260
        committed_id = tree.commit('foo', local=True)
261
        self.assertFalse(master.repository.has_revision(committed_id))
2598.5.7 by Aaron Bentley
Updates from review
262
        self.assertEqual(_mod_revision.NULL_REVISION,
263
                         (_mod_revision.ensure_null(master.last_revision())))
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
264
265
    def test_record_initial_ghost(self):
266
        """The working tree needs to record ghosts during commit."""
267
        wt = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
268
        if not wt.branch.repository._format.supports_ghosts:
269
            raise tests.TestNotApplicable(
270
                'format does not support ghosts')
6973.10.6 by Jelmer Vernooij
Fix tests.
271
        wt.set_parent_ids([b'non:existent@rev--ision--0--2'],
7143.15.2 by Jelmer Vernooij
Run autopep8.
272
                          allow_leftmost_as_ghost=True)
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
273
        rev_id = wt.commit('commit against a ghost first parent.')
274
        rev = wt.branch.repository.get_revision(rev_id)
6973.10.6 by Jelmer Vernooij
Fix tests.
275
        self.assertEqual(rev.parent_ids, [b'non:existent@rev--ision--0--2'])
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
276
        # parent_sha1s is not populated now, WTF. rbc 20051003
277
        self.assertEqual(len(rev.parent_sha1s), 0)
278
279
    def test_record_two_ghosts(self):
280
        """The working tree should preserve all the parents during commit."""
281
        wt = self.make_branch_and_tree('.')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
282
        if not wt.branch.repository._format.supports_ghosts:
283
            raise tests.TestNotApplicable(
284
                'format does not support ghosts')
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
285
        wt.set_parent_ids([
7143.15.2 by Jelmer Vernooij
Run autopep8.
286
            b'foo@azkhazan-123123-abcabc',
287
            b'wibble@fofof--20050401--1928390812',
1908.6.7 by Robert Collins
Remove all users of set_pending_merges and add_pending_merge except tests that they work correctly.
288
            ],
289
            allow_leftmost_as_ghost=True)
1927.2.1 by Robert Collins
Alter set_pending_merges to shove the left most merge into the trees last-revision if that is not set. Related bugfixes include basis_tree handling ghosts, de-duping the merges with the last-revision and update changing where and how it adds its pending merge.
290
        rev_id = wt.commit("commit from ghost base with one merge")
291
        # the revision should have been committed with two parents
292
        rev = wt.branch.repository.get_revision(rev_id)
6973.10.6 by Jelmer Vernooij
Fix tests.
293
        self.assertEqual([b'foo@azkhazan-123123-abcabc',
7143.15.2 by Jelmer Vernooij
Run autopep8.
294
                          b'wibble@fofof--20050401--1928390812'],
295
                         rev.parent_ids)
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
296
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
297
    def test_commit_deleted_subtree_and_files_updates_workingtree(self):
298
        """The working trees inventory may be adjusted by commit."""
299
        wt = self.make_branch_and_tree('.')
300
        wt.lock_write()
301
        self.build_tree(['a', 'b/', 'b/c', 'd'])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
302
        wt.add(['a', 'b', 'b/c', 'd'])
303
        a_id = wt.path2id('a')
304
        b_id = wt.path2id('b')
305
        c_id = wt.path2id('b/c')
306
        d_id = wt.path2id('d')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
307
        this_dir = wt.controldir.root_transport
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
308
        this_dir.delete_tree('b')
309
        this_dir.delete('d')
310
        # now we have a tree with a through d in the inventory, but only
311
        # a present on disk. After commit b-id, c-id and d-id should be
312
        # missing from the inventory, within the same tree transaction.
313
        wt.commit('commit stuff')
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
314
        self.assertTrue(wt.has_id(a_id))
315
        self.assertFalse(wt.has_or_had_id(b_id))
316
        self.assertFalse(wt.has_or_had_id(c_id))
317
        self.assertFalse(wt.has_or_had_id(d_id))
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
318
        self.assertTrue(wt.has_filename('a'))
319
        self.assertFalse(wt.has_filename('b'))
320
        self.assertFalse(wt.has_filename('b/c'))
321
        self.assertFalse(wt.has_filename('d'))
322
        wt.unlock()
323
        # the changes should have persisted to disk - reopen the workingtree
324
        # to be sure.
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
325
        wt = wt.controldir.open_workingtree()
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
326
        wt.lock_read()
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
327
        self.assertTrue(wt.has_id(a_id))
328
        self.assertFalse(wt.has_or_had_id(b_id))
329
        self.assertFalse(wt.has_or_had_id(c_id))
330
        self.assertFalse(wt.has_or_had_id(d_id))
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
331
        self.assertTrue(wt.has_filename('a'))
332
        self.assertFalse(wt.has_filename('b'))
333
        self.assertFalse(wt.has_filename('b/c'))
334
        self.assertFalse(wt.has_filename('d'))
335
        wt.unlock()
1731.2.4 by Aaron Bentley
Ensure subsume works with Knit2 repos
336
2363.2.2 by John Arbash Meinel
Simplify the test even further....
337
    def test_commit_deleted_subtree_with_removed(self):
2363.2.1 by John Arbash Meinel
(broken) Add a simplified test which exposes the bug.
338
        wt = self.make_branch_and_tree('.')
339
        self.build_tree(['a', 'b/', 'b/c', 'd'])
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
340
        wt.add(['a', 'b', 'b/c'])
341
        a_id = wt.path2id('a')
342
        b_id = wt.path2id('b')
343
        c_id = wt.path2id('b/c')
2363.2.1 by John Arbash Meinel
(broken) Add a simplified test which exposes the bug.
344
        wt.commit('first')
2363.2.2 by John Arbash Meinel
Simplify the test even further....
345
        wt.remove('b/c')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
346
        this_dir = wt.controldir.root_transport
2363.2.1 by John Arbash Meinel
(broken) Add a simplified test which exposes the bug.
347
        this_dir.delete_tree('b')
348
        wt.lock_write()
349
        wt.commit('commit deleted rename')
6883.7.12 by Jelmer Vernooij
avoid has_id.
350
        self.assertTrue(wt.is_versioned('a'))
6844.1.1 by Jelmer Vernooij
Many more foreign branch fixes.
351
        self.assertFalse(wt.has_or_had_id(b_id))
352
        self.assertFalse(wt.has_or_had_id(c_id))
2363.2.1 by John Arbash Meinel
(broken) Add a simplified test which exposes the bug.
353
        self.assertTrue(wt.has_filename('a'))
354
        self.assertFalse(wt.has_filename('b'))
355
        self.assertFalse(wt.has_filename('b/c'))
356
        wt.unlock()
357
1731.2.4 by Aaron Bentley
Ensure subsume works with Knit2 repos
358
    def test_commit_move_new(self):
359
        wt = self.make_branch_and_tree('first')
360
        wt.commit('first')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
361
        wt2 = wt.controldir.sprout('second').open_workingtree()
1731.2.4 by Aaron Bentley
Ensure subsume works with Knit2 repos
362
        self.build_tree(['second/name1'])
6745.1.1 by Jelmer Vernooij
Avoid explicitly setting file ids or guard it by checking
363
        wt2.add('name1')
1731.2.4 by Aaron Bentley
Ensure subsume works with Knit2 repos
364
        wt2.commit('second')
365
        wt.merge_from_branch(wt2.branch)
366
        wt.rename_one('name1', 'name2')
367
        wt.commit('third')
6745.1.1 by Jelmer Vernooij
Avoid explicitly setting file ids or guard it by checking
368
        wt.path2id('name1')
2255.2.218 by Robert Collins
Make the nested tree commit smoke test be more rigourous.
369
370
    def test_nested_commit(self):
371
        """Commit in multiply-nested trees"""
372
        tree = self.make_branch_and_tree('.')
373
        if not tree.supports_tree_reference():
374
            # inapplicable test.
375
            return
376
        subtree = self.make_branch_and_tree('subtree')
377
        subsubtree = self.make_branch_and_tree('subtree/subtree')
6926.2.8 by Jelmer Vernooij
Fix some more tests.
378
        subsub_revid = subsubtree.commit('subsubtree')
379
        subtree.commit('subtree')
2255.2.218 by Robert Collins
Make the nested tree commit smoke test be more rigourous.
380
        subtree.add(['subtree'])
381
        tree.add(['subtree'])
382
        # use allow_pointless=False to ensure that the deepest tree, which
383
        # has no commits made to it, does not get a pointless commit.
384
        rev_id = tree.commit('added reference', allow_pointless=False)
385
        tree.lock_read()
386
        self.addCleanup(tree.unlock)
387
        # the deepest subtree has not changed, so no commit should take place.
6926.2.8 by Jelmer Vernooij
Fix some more tests.
388
        self.assertEqual(subsub_revid, subsubtree.last_revision())
2255.2.218 by Robert Collins
Make the nested tree commit smoke test be more rigourous.
389
        # the intermediate tree should have committed a pointer to the current
390
        # subtree revision.
391
        sub_basis = subtree.basis_tree()
392
        sub_basis.lock_read()
393
        self.addCleanup(sub_basis.unlock)
6809.4.1 by Jelmer Vernooij
Swap file_id and path arguments for get_reference_revision and get_nested_tree.
394
        self.assertEqual(
7143.15.2 by Jelmer Vernooij
Run autopep8.
395
            subsubtree.last_revision(),
396
            sub_basis.get_reference_revision('subtree'))
2255.2.218 by Robert Collins
Make the nested tree commit smoke test be more rigourous.
397
        # the intermediate tree has changed, so should have had a commit
398
        # take place.
399
        self.assertNotEqual(None, subtree.last_revision())
400
        # the outer tree should have committed a pointer to the current
401
        # subtree revision.
402
        basis = tree.basis_tree()
403
        basis.lock_read()
404
        self.addCleanup(basis.unlock)
405
        self.assertEqual(subtree.last_revision(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
406
                         basis.get_reference_revision('subtree'))
2255.2.218 by Robert Collins
Make the nested tree commit smoke test be more rigourous.
407
        # the outer tree must have have changed too.
408
        self.assertNotEqual(None, rev_id)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
409
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
410
    def test_nested_commit_second_commit_detects_changes(self):
411
        """Commit with a nested tree picks up the correct child revid."""
412
        tree = self.make_branch_and_tree('.')
413
        if not tree.supports_tree_reference():
414
            # inapplicable test.
415
            return
6700.1.3 by Jelmer Vernooij
Drop support for committing using record_entr_contents.
416
        self.knownFailure('nested trees don\'t work well with iter_changes')
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
417
        subtree = self.make_branch_and_tree('subtree')
418
        tree.add(['subtree'])
419
        self.build_tree(['subtree/file'])
6745.1.1 by Jelmer Vernooij
Avoid explicitly setting file ids or guard it by checking
420
        subtree.add(['file'])
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
421
        rev_id = tree.commit('added reference', allow_pointless=False)
6809.4.1 by Jelmer Vernooij
Swap file_id and path arguments for get_reference_revision and get_nested_tree.
422
        tree.get_reference_revision('subtree')
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
423
        child_revid = subtree.last_revision()
424
        # now change the child tree
6855.4.1 by Jelmer Vernooij
Yet more bees.
425
        self.build_tree_contents([('subtree/file', b'new-content')])
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
426
        # and commit in the parent should commit the child and grab its revid,
427
        # we test with allow_pointless=False here so that we are simulating
428
        # what users will see.
429
        rev_id2 = tree.commit('changed subtree only', allow_pointless=False)
430
        # the child tree has changed, so should have had a commit
431
        # take place.
432
        self.assertNotEqual(None, subtree.last_revision())
433
        self.assertNotEqual(child_revid, subtree.last_revision())
434
        # the outer tree should have committed a pointer to the current
435
        # subtree revision.
436
        basis = tree.basis_tree()
437
        basis.lock_read()
438
        self.addCleanup(basis.unlock)
439
        self.assertEqual(subtree.last_revision(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
440
                         basis.get_reference_revision('subtree'))
2255.2.220 by Robert Collins
Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.
441
        self.assertNotEqual(rev_id, rev_id2)
442
2825.5.2 by Robert Collins
Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.
443
    def test_nested_pointless_commits_are_pointless(self):
444
        tree = self.make_branch_and_tree('.')
445
        if not tree.supports_tree_reference():
446
            # inapplicable test.
447
            return
448
        subtree = self.make_branch_and_tree('subtree')
6926.2.8 by Jelmer Vernooij
Fix some more tests.
449
        subtree.commit('')
2825.5.2 by Robert Collins
Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.
450
        tree.add(['subtree'])
451
        # record the reference.
452
        rev_id = tree.commit('added reference')
453
        child_revid = subtree.last_revision()
454
        # now do a no-op commit with allow_pointless=False
6734.1.20 by Jelmer Vernooij
Move errors.
455
        self.assertRaises(PointlessCommit, tree.commit, '',
7143.15.2 by Jelmer Vernooij
Run autopep8.
456
                          allow_pointless=False)
2825.5.2 by Robert Collins
Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.
457
        self.assertEqual(child_revid, subtree.last_revision())
458
        self.assertEqual(rev_id, tree.last_revision())
459
1988.3.1 by Robert Collins
Add test case to ensure that the working tree inventory and disk state is correctly update when commit is removing directory entries.
460
1740.3.10 by Jelmer Vernooij
Fix some minor issues pointed out by j-a-m.
461
class TestCommitProgress(TestCaseWithWorkingTree):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
462
4985.2.1 by Vincent Ladeuil
Deploy addAttrCleanup on the whole test suite.
463
    def setUp(self):
464
        super(TestCommitProgress, self).setUp()
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
465
        ui.ui_factory = ProgressRecordingUIFactory()
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
466
467
    def test_commit_progress_steps(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
468
        # during commit we one progress update for every entry in the
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
469
        # inventory, and then one for the inventory, and one for the
470
        # inventory, and one for the revision insertions.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
471
        # first we need a test commit to do. Lets setup a branch with
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
472
        # 3 files, and alter one in a selected-file commit. This exercises
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
473
        # a number of cases quickly. We should also test things like
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
474
        # selective commits which excludes newly added files.
475
        tree = self.make_branch_and_tree('.')
476
        self.build_tree(['a', 'b', 'c'])
477
        tree.add(['a', 'b', 'c'])
478
        tree.commit('first post')
6973.7.5 by Jelmer Vernooij
s/file/open.
479
        with open('b', 'wt') as f:
480
            f.write('new content')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
481
        # set a progress bar that captures the calls so we can see what is
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
482
        # emitted
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
483
        factory = ProgressRecordingUIFactory()
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
484
        ui.ui_factory = factory
485
        # TODO RBC 20060421 it would be nice to merge the reporter output
486
        # into the factory for this test - just make the test ui factory
487
        # pun as a reporter. Then we can check the ordering is right.
488
        tree.commit('second post', specific_files=['b'])
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
489
        # 5 steps, the first of which is reported 2 times, once per dir
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
490
        self.assertEqual(
4183.5.5 by Robert Collins
Enable record_iter_changes for cases where it can work.
491
            [('update', 1, 5, 'Collecting changes [0] - Stage'),
492
             ('update', 1, 5, 'Collecting changes [1] - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
493
             ('update', 2, 5, 'Saving data locally - Stage'),
2659.3.9 by NamNguyen
branch.py:
494
             ('update', 3, 5, 'Running pre_commit hooks - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
495
             ('update', 4, 5, 'Updating the working tree - Stage'),
2659.3.9 by NamNguyen
branch.py:
496
             ('update', 5, 5, 'Running post_commit hooks - Stage')],
1666.1.19 by Robert Collins
Introduce a progress bar during commit.
497
            factory._calls
7143.15.2 by Jelmer Vernooij
Run autopep8.
498
            )
2553.1.2 by Robert Collins
Show hook names during commit.
499
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
500
    def test_commit_progress_shows_post_hook_names(self):
2553.1.2 by Robert Collins
Show hook names during commit.
501
        tree = self.make_branch_and_tree('.')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
502
        # set a progress bar that captures the calls so we can see what is
2553.1.2 by Robert Collins
Show hook names during commit.
503
        # emitted
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
504
        factory = ProgressRecordingUIFactory()
2553.1.2 by Robert Collins
Show hook names during commit.
505
        ui.ui_factory = factory
7143.15.2 by Jelmer Vernooij
Run autopep8.
506
2553.1.2 by Robert Collins
Show hook names during commit.
507
        def a_hook(_, _2, _3, _4, _5, _6):
508
            pass
3256.2.19 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.workingtree_implementations.test_commit.
509
        branch.Branch.hooks.install_named_hook('post_commit', a_hook,
510
                                               'hook name')
2553.1.2 by Robert Collins
Show hook names during commit.
511
        tree.commit('first post')
512
        self.assertEqual(
4183.5.5 by Robert Collins
Enable record_iter_changes for cases where it can work.
513
            [('update', 1, 5, 'Collecting changes [0] - Stage'),
514
             ('update', 1, 5, 'Collecting changes [1] - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
515
             ('update', 2, 5, 'Saving data locally - Stage'),
2659.3.9 by NamNguyen
branch.py:
516
             ('update', 3, 5, 'Running pre_commit hooks - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
517
             ('update', 4, 5, 'Updating the working tree - Stage'),
2659.3.9 by NamNguyen
branch.py:
518
             ('update', 5, 5, 'Running post_commit hooks - Stage'),
519
             ('update', 5, 5, 'Running post_commit hooks [hook name] - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
520
             ],
521
            factory._calls
7143.15.2 by Jelmer Vernooij
Run autopep8.
522
            )
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
523
524
    def test_commit_progress_shows_pre_hook_names(self):
525
        tree = self.make_branch_and_tree('.')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
526
        # set a progress bar that captures the calls so we can see what is
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
527
        # emitted
5422.1.4 by Martin Pool
Rename CapturingUIFactory to ProgressRecordingUIFactory
528
        factory = ProgressRecordingUIFactory()
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
529
        ui.ui_factory = factory
7143.15.2 by Jelmer Vernooij
Run autopep8.
530
2659.3.3 by NamNguyen
Changed ``pre_commit`` hook signature.
531
        def a_hook(_, _2, _3, _4, _5, _6, _7, _8):
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
532
            pass
3256.2.19 by Daniel Watkins
Updated uses of Hooks.install_hook to Hooks.install_named_hook in tests.workingtree_implementations.test_commit.
533
        branch.Branch.hooks.install_named_hook('pre_commit', a_hook,
534
                                               'hook name')
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
535
        tree.commit('first post')
536
        self.assertEqual(
4183.5.5 by Robert Collins
Enable record_iter_changes for cases where it can work.
537
            [('update', 1, 5, 'Collecting changes [0] - Stage'),
538
             ('update', 1, 5, 'Collecting changes [1] - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
539
             ('update', 2, 5, 'Saving data locally - Stage'),
2659.3.9 by NamNguyen
branch.py:
540
             ('update', 3, 5, 'Running pre_commit hooks - Stage'),
541
             ('update', 3, 5, 'Running pre_commit hooks [hook name] - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
542
             ('update', 4, 5, 'Updating the working tree - Stage'),
2659.3.9 by NamNguyen
branch.py:
543
             ('update', 5, 5, 'Running post_commit hooks - Stage'),
2659.3.1 by NamNguyen
``Branch.hooks`` now supports ``pre_commit`` hook.
544
             ],
545
            factory._calls
7143.15.2 by Jelmer Vernooij
Run autopep8.
546
            )
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
547
548
    def test_start_commit_hook(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
549
        """Make sure a start commit hook can modify the tree that is
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
550
        committed."""
551
        def start_commit_hook_adds_file(tree):
7143.15.2 by Jelmer Vernooij
Run autopep8.
552
            with open(tree.abspath("newfile"), 'w') as f:
553
                f.write("data")
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
554
            tree.add(["newfile"])
7143.15.2 by Jelmer Vernooij
Run autopep8.
555
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
556
        def restoreDefaults():
557
            mutabletree.MutableTree.hooks['start_commit'] = []
558
        self.addCleanup(restoreDefaults)
559
        tree = self.make_branch_and_tree('.')
3256.2.26 by Daniel Watkins
Updated tests to use install_named_hook.
560
        mutabletree.MutableTree.hooks.install_named_hook(
561
            'start_commit',
562
            start_commit_hook_adds_file,
563
            None)
3335.1.3 by Jelmer Vernooij
Add tests for start_commit hook.
564
        revid = tree.commit('first post')
565
        committed_tree = tree.basis_tree()
566
        self.assertTrue(committed_tree.has_filename("newfile"))
4634.33.1 by Ian Clatworthy
original finish_commit hook patch
567
4634.33.3 by Ian Clatworthy
review feedback from Robert: rename finish_commit to post_commit
568
    def test_post_commit_hook(self):
569
        """Make sure a post_commit hook is called after a commit."""
570
        def post_commit_hook_test_params(params):
4634.33.2 by Ian Clatworthy
review feedback from jam
571
            self.assertTrue(isinstance(params,
7143.15.2 by Jelmer Vernooij
Run autopep8.
572
                                       mutabletree.PostCommitHookParams))
4634.33.2 by Ian Clatworthy
review feedback from jam
573
            self.assertTrue(isinstance(params.mutable_tree,
7143.15.2 by Jelmer Vernooij
Run autopep8.
574
                                       mutabletree.MutableTree))
575
            with open(tree.abspath("newfile"), 'w') as f:
576
                f.write("data")
4634.33.2 by Ian Clatworthy
review feedback from jam
577
            params.mutable_tree.add(["newfile"])
4634.33.1 by Ian Clatworthy
original finish_commit hook patch
578
        tree = self.make_branch_and_tree('.')
579
        mutabletree.MutableTree.hooks.install_named_hook(
4634.33.3 by Ian Clatworthy
review feedback from Robert: rename finish_commit to post_commit
580
            'post_commit',
581
            post_commit_hook_test_params,
4634.33.1 by Ian Clatworthy
original finish_commit hook patch
582
            None)
583
        self.assertFalse(tree.has_filename("newfile"))
584
        revid = tree.commit('first post')
585
        self.assertTrue(tree.has_filename("newfile"))
586
        committed_tree = tree.basis_tree()
587
        self.assertFalse(committed_tree.has_filename("newfile"))