/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1246 by Martin Pool
- add very simple commit tests
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1246 by Martin Pool
- add very simple commit tests
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1246 by Martin Pool
- add very simple commit tests
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1246 by Martin Pool
- add very simple commit tests
16
17
18
import os
19
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
20
import breezy
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
21
from .. import (
6351.3.12 by Vincent Ladeuil
Use simpler config stacks and use strings as inputs to better respect the API.
22
    config,
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
23
    controldir,
1957.1.17 by John Arbash Meinel
Change tests that expect locking to fail to timeout sooner.
24
    errors,
25
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
26
from ..branch import Branch
6670.4.1 by Jelmer Vernooij
Update imports.
27
from ..bzr.bzrdir import BzrDirMetaFormat1
6699.1.1 by Jelmer Vernooij
Support excludes with "bzr commit -x".
28
from ..commit import (
6734.1.20 by Jelmer Vernooij
Move errors.
29
    CannotCommitSelectedFileMerge,
6699.1.1 by Jelmer Vernooij
Support excludes with "bzr commit -x".
30
    Commit,
31
    NullCommitReporter,
6734.1.20 by Jelmer Vernooij
Move errors.
32
    PointlessCommit,
6699.1.1 by Jelmer Vernooij
Support excludes with "bzr commit -x".
33
    filter_excluded,
34
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
35
from ..errors import (
5972.3.15 by Jelmer Vernooij
Use matchers.
36
    BzrError,
37
    LockContention,
38
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
39
from . import (
6699.1.1 by Jelmer Vernooij
Support excludes with "bzr commit -x".
40
    TestCase,
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
41
    TestCaseWithTransport,
42
    test_foreign,
43
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
44
from .features import (
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
45
    SymlinkFeature,
46
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
47
from .matchers import MatchesAncestry
1246 by Martin Pool
- add very simple commit tests
48
49
1257 by Martin Pool
doc
50
# TODO: Test commit with some added, and added-but-missing files
51
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
52
class MustSignConfig(config.MemoryStack):
6351.3.12 by Vincent Ladeuil
Use simpler config stacks and use strings as inputs to better respect the API.
53
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
54
    def __init__(self):
55
        super(MustSignConfig, self).__init__('''
6351.3.12 by Vincent Ladeuil
Use simpler config stacks and use strings as inputs to better respect the API.
56
create_signatures=always
57
''')
1472 by Robert Collins
post commit hook, first pass implementation
58
59
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
60
class CapturingReporter(NullCommitReporter):
61
    """This reporter captures the calls made to it for evaluation later."""
62
63
    def __init__(self):
64
        # a list of the calls this received
65
        self.calls = []
66
67
    def snapshot_change(self, change, path):
68
        self.calls.append(('change', change, path))
69
70
    def deleted(self, file_id):
71
        self.calls.append(('deleted', file_id))
72
73
    def missing(self, path):
74
        self.calls.append(('missing', path))
75
76
    def renamed(self, change, old_path, new_path):
77
        self.calls.append(('renamed', change, old_path, new_path))
78
2789.2.1 by Ian Clatworthy
Make commit less verbose by default
79
    def is_verbose(self):
80
        return True
81
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
82
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
83
class TestCommit(TestCaseWithTransport):
1390 by Robert Collins
pair programming worx... merge integration and weave
84
1246 by Martin Pool
- add very simple commit tests
85
    def test_simple_commit(self):
86
        """Commit and check two versions of a single file."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
87
        wt = self.make_branch_and_tree('.')
88
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
89
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
90
        wt.add('hello')
6165.4.7 by Jelmer Vernooij
More fixes.
91
        rev1 = wt.commit(message='add hello')
1246 by Martin Pool
- add very simple commit tests
92
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
93
        with open('hello', 'w') as f: f.write('version 2')
6165.4.7 by Jelmer Vernooij
More fixes.
94
        rev2 = wt.commit(message='commit 2')
1246 by Martin Pool
- add very simple commit tests
95
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
96
        eq = self.assertEqual
1246 by Martin Pool
- add very simple commit tests
97
        eq(b.revno(), 2)
6165.4.7 by Jelmer Vernooij
More fixes.
98
        rev = b.repository.get_revision(rev1)
1246 by Martin Pool
- add very simple commit tests
99
        eq(rev.message, 'add hello')
100
6165.4.7 by Jelmer Vernooij
More fixes.
101
        tree1 = b.repository.revision_tree(rev1)
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
102
        tree1.lock_read()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
103
        text = tree1.get_file_text('hello')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
104
        tree1.unlock()
105
        self.assertEqual('hello world', text)
1246 by Martin Pool
- add very simple commit tests
106
6165.4.7 by Jelmer Vernooij
More fixes.
107
        tree2 = b.repository.revision_tree(rev2)
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
108
        tree2.lock_read()
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
109
        text = tree2.get_file_text('hello')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
110
        tree2.unlock()
111
        self.assertEqual('version 2', text)
1246 by Martin Pool
- add very simple commit tests
112
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
113
    def test_commit_lossy_native(self):
114
        """Attempt a lossy commit to a native branch."""
115
        wt = self.make_branch_and_tree('.')
116
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
117
        with open('hello', 'w') as f: f.write('hello world')
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
118
        wt.add('hello')
119
        revid = wt.commit(message='add hello', rev_id='revid', lossy=True)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
120
        self.assertEqual('revid', revid)
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
121
122
    def test_commit_lossy_foreign(self):
123
        """Attempt a lossy commit to a foreign branch."""
5777.6.6 by Jelmer Vernooij
Add lossy tests.
124
        test_foreign.register_dummy_foreign_for_test(self)
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
125
        wt = self.make_branch_and_tree('.',
126
            format=test_foreign.DummyForeignVcsDirFormat())
127
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
128
        with open('hello', 'w') as f: f.write('hello world')
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
129
        wt.add('hello')
5777.6.6 by Jelmer Vernooij
Add lossy tests.
130
        revid = wt.commit(message='add hello', lossy=True,
131
            timestamp=1302659388, timezone=0)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
132
        self.assertEqual('dummy-v1:1302659388.0-0-UNKNOWN', revid)
5777.6.5 by Jelmer Vernooij
Add tests for lossy commit.
133
5777.7.5 by Jelmer Vernooij
Add tests for committing to a branch bound to a foreign branch.
134
    def test_commit_bound_lossy_foreign(self):
135
        """Attempt a lossy commit to a bzr branch bound to a foreign branch."""
136
        test_foreign.register_dummy_foreign_for_test(self)
137
        foreign_branch = self.make_branch('foreign',
138
            format=test_foreign.DummyForeignVcsDirFormat())
139
        wt = foreign_branch.create_checkout("local")
140
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
141
        with open('local/hello', 'w') as f: f.write('hello world')
5777.7.5 by Jelmer Vernooij
Add tests for committing to a branch bound to a foreign branch.
142
        wt.add('hello')
143
        revid = wt.commit(message='add hello', lossy=True,
144
            timestamp=1302659388, timezone=0)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
145
        self.assertEqual('dummy-v1:1302659388.0-0-0', revid)
146
        self.assertEqual('dummy-v1:1302659388.0-0-0',
5777.7.5 by Jelmer Vernooij
Add tests for committing to a branch bound to a foreign branch.
147
            foreign_branch.last_revision())
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
148
        self.assertEqual('dummy-v1:1302659388.0-0-0',
5777.7.5 by Jelmer Vernooij
Add tests for committing to a branch bound to a foreign branch.
149
            wt.branch.last_revision())
150
4183.5.5 by Robert Collins
Enable record_iter_changes for cases where it can work.
151
    def test_missing_commit(self):
152
        """Test a commit with a missing file"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
153
        wt = self.make_branch_and_tree('.')
154
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
155
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
156
        wt.add(['hello'], ['hello-id'])
157
        wt.commit(message='add hello')
1247 by Martin Pool
- tests for deletion and removal of files in commits
158
159
        os.remove('hello')
6125.1.1 by Jelmer Vernooij
Report missing files as removed in 'bzr commit', rather than modified.
160
        reporter = CapturingReporter()
161
        wt.commit('removed hello', rev_id='rev2', reporter=reporter)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
162
        self.assertEqual(
6125.1.1 by Jelmer Vernooij
Report missing files as removed in 'bzr commit', rather than modified.
163
            [('missing', u'hello'), ('deleted', u'hello')],
164
            reporter.calls)
1247 by Martin Pool
- tests for deletion and removal of files in commits
165
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
166
        tree = b.repository.revision_tree('rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
167
        self.assertFalse(tree.has_id('hello-id'))
168
2258.4.1 by Jelmer Vernooij
Add test that demonstrates a corner case bug in commit.
169
    def test_partial_commit_move(self):
3373.4.1 by John Arbash Meinel
Merge in and clean up the test for bug #83039.
170
        """Test a partial commit where a file was renamed but not committed.
171
172
        https://bugs.launchpad.net/bzr/+bug/83039
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
173
2258.4.1 by Jelmer Vernooij
Add test that demonstrates a corner case bug in commit.
174
        If not handled properly, commit will try to snapshot
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
175
        dialog.py with olive/ as a parent, while
2258.4.1 by Jelmer Vernooij
Add test that demonstrates a corner case bug in commit.
176
        olive/ has not been snapshotted yet.
177
        """
178
        wt = self.make_branch_and_tree('.')
179
        b = wt.branch
3373.4.1 by John Arbash Meinel
Merge in and clean up the test for bug #83039.
180
        self.build_tree(['annotate/', 'annotate/foo.py',
181
                         'olive/', 'olive/dialog.py'
182
                        ])
2258.4.1 by Jelmer Vernooij
Add test that demonstrates a corner case bug in commit.
183
        wt.add(['annotate', 'olive', 'annotate/foo.py', 'olive/dialog.py'])
184
        wt.commit(message='add files')
3373.4.1 by John Arbash Meinel
Merge in and clean up the test for bug #83039.
185
        wt.rename_one("olive/dialog.py", "aaa")
186
        self.build_tree_contents([('annotate/foo.py', 'modified\n')])
2258.4.1 by Jelmer Vernooij
Add test that demonstrates a corner case bug in commit.
187
        wt.commit('renamed hello', specific_files=["annotate"])
188
1253 by Martin Pool
- test that pointless commits are trapped
189
    def test_pointless_commit(self):
190
        """Commit refuses unless there are changes or it's forced."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
191
        wt = self.make_branch_and_tree('.')
192
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
193
        with open('hello', 'w') as f: f.write('hello')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
194
        wt.add(['hello'])
195
        wt.commit(message='add hello')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
196
        self.assertEqual(b.revno(), 1)
1253 by Martin Pool
- test that pointless commits are trapped
197
        self.assertRaises(PointlessCommit,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
198
                          wt.commit,
1253 by Martin Pool
- test that pointless commits are trapped
199
                          message='fails',
200
                          allow_pointless=False)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
201
        self.assertEqual(b.revno(), 1)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
202
1252 by Martin Pool
- add test for commit of an empty tree
203
    def test_commit_empty(self):
1253 by Martin Pool
- test that pointless commits are trapped
204
        """Commiting an empty tree works."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
205
        wt = self.make_branch_and_tree('.')
206
        b = wt.branch
207
        wt.commit(message='empty tree', allow_pointless=True)
1253 by Martin Pool
- test that pointless commits are trapped
208
        self.assertRaises(PointlessCommit,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
209
                          wt.commit,
1253 by Martin Pool
- test that pointless commits are trapped
210
                          message='empty tree',
211
                          allow_pointless=False)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
212
        wt.commit(message='empty tree', allow_pointless=True)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
213
        self.assertEqual(b.revno(), 2)
1252 by Martin Pool
- add test for commit of an empty tree
214
215
    def test_selective_delete(self):
216
        """Selective commit in tree with deletions"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
217
        wt = self.make_branch_and_tree('.')
218
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
219
        with open('hello', 'w') as f: f.write('hello')
220
        with open('buongia', 'w') as f: f.write('buongia')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
221
        wt.add(['hello', 'buongia'],
1255 by Martin Pool
- more tests for selective commit of deletion
222
              ['hello-id', 'buongia-id'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
223
        wt.commit(message='add files',
1255 by Martin Pool
- more tests for selective commit of deletion
224
                 rev_id='test@rev-1')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
225
1254 by Martin Pool
- fix handling of selective commit with deleted files
226
        os.remove('hello')
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
227
        with open('buongia', 'w') as f: f.write('new text')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
228
        wt.commit(message='update text',
1254 by Martin Pool
- fix handling of selective commit with deleted files
229
                 specific_files=['buongia'],
1255 by Martin Pool
- more tests for selective commit of deletion
230
                 allow_pointless=False,
231
                 rev_id='test@rev-2')
1254 by Martin Pool
- fix handling of selective commit with deleted files
232
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
233
        wt.commit(message='remove hello',
1254 by Martin Pool
- fix handling of selective commit with deleted files
234
                 specific_files=['hello'],
1255 by Martin Pool
- more tests for selective commit of deletion
235
                 allow_pointless=False,
236
                 rev_id='test@rev-3')
1254 by Martin Pool
- fix handling of selective commit with deleted files
237
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
238
        eq = self.assertEqual
1254 by Martin Pool
- fix handling of selective commit with deleted files
239
        eq(b.revno(), 3)
1255 by Martin Pool
- more tests for selective commit of deletion
240
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
241
        tree2 = b.repository.revision_tree('test@rev-2')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
242
        tree2.lock_read()
243
        self.addCleanup(tree2.unlock)
1255 by Martin Pool
- more tests for selective commit of deletion
244
        self.assertTrue(tree2.has_filename('hello'))
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
245
        self.assertEqual(tree2.get_file_text('hello'), 'hello')
246
        self.assertEqual(tree2.get_file_text('buongia'), 'new text')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
247
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
248
        tree3 = b.repository.revision_tree('test@rev-3')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
249
        tree3.lock_read()
250
        self.addCleanup(tree3.unlock)
1255 by Martin Pool
- more tests for selective commit of deletion
251
        self.assertFalse(tree3.has_filename('hello'))
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
252
        self.assertEqual(tree3.get_file_text('buongia'), 'new text')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
253
254
    def test_commit_rename(self):
255
        """Test commit of a revision where a file is renamed."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
256
        tree = self.make_branch_and_tree('.')
257
        b = tree.branch
1185.38.7 by John Arbash Meinel
Updated build_tree to use fixed line-endings for tests which read the file contents and compare
258
        self.build_tree(['hello'], line_endings='binary')
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
259
        tree.add(['hello'], ['hello-id'])
260
        tree.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
261
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
262
        tree.rename_one('hello', 'fruity')
263
        tree.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
264
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
265
        eq = self.assertEqual
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
266
        tree1 = b.repository.revision_tree('test@rev-1')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
267
        tree1.lock_read()
268
        self.addCleanup(tree1.unlock)
1303 by Martin Pool
- commit updates entry_version
269
        eq(tree1.id2path('hello-id'), 'hello')
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
270
        eq(tree1.get_file_text('hello'), 'contents of hello\n')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
271
        self.assertFalse(tree1.has_filename('fruity'))
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
272
        self.check_tree_shape(tree1, ['hello'])
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
273
        eq(tree1.get_file_revision('hello'), 'test@rev-1')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
274
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
275
        tree2 = b.repository.revision_tree('test@rev-2')
3010.1.3 by Robert Collins
Lock RevisionTrees correctly in commit tests.
276
        tree2.lock_read()
277
        self.addCleanup(tree2.unlock)
1303 by Martin Pool
- commit updates entry_version
278
        eq(tree2.id2path('hello-id'), 'fruity')
6809.4.13 by Jelmer Vernooij
Fix tests.
279
        eq(tree2.get_file_text('fruity'), 'contents of hello\n')
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
280
        self.check_tree_shape(tree2, ['fruity'])
6809.4.13 by Jelmer Vernooij
Fix tests.
281
        eq(tree2.get_file_revision('fruity'), 'test@rev-2')
1291 by Martin Pool
- add test for moving files between directories
282
283
    def test_reused_rev_id(self):
1292 by Martin Pool
- add check that revision ids cannot be committed twice
284
        """Test that a revision id cannot be reused in a branch"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
285
        wt = self.make_branch_and_tree('.')
286
        b = wt.branch
287
        wt.commit('initial', rev_id='test@rev-1', allow_pointless=True)
1292 by Martin Pool
- add check that revision ids cannot be committed twice
288
        self.assertRaises(Exception,
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
289
                          wt.commit,
1292 by Martin Pool
- add check that revision ids cannot be committed twice
290
                          message='reused id',
291
                          rev_id='test@rev-1',
292
                          allow_pointless=True)
1291 by Martin Pool
- add test for moving files between directories
293
294
    def test_commit_move(self):
295
        """Test commit of revisions with moved files and directories"""
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
296
        eq = self.assertEqual
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
297
        wt = self.make_branch_and_tree('.')
298
        b = wt.branch
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
299
        r1 = 'test@rev-1'
1291 by Martin Pool
- add test for moving files between directories
300
        self.build_tree(['hello', 'a/', 'b/'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
301
        wt.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
302
        wt.commit('initial', rev_id=r1, allow_pointless=False)
303
        wt.move(['hello'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
304
        r2 = 'test@rev-2'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
305
        wt.commit('two', rev_id=r2, allow_pointless=False)
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
306
        wt.lock_read()
307
        try:
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
308
            self.check_tree_shape(wt, ['a/', 'a/hello', 'b/'])
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
309
        finally:
310
            wt.unlock()
1291 by Martin Pool
- add test for moving files between directories
311
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
312
        wt.move(['b'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
313
        r3 = 'test@rev-3'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
314
        wt.commit('three', rev_id=r3, allow_pointless=False)
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
315
        wt.lock_read()
316
        try:
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
317
            self.check_tree_shape(wt,
2545.3.2 by James Westby
Add a test for check_inventory_shape.
318
                                       ['a/', 'a/hello', 'a/b/'])
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
319
            self.check_tree_shape(b.repository.revision_tree(r3),
2545.3.2 by James Westby
Add a test for check_inventory_shape.
320
                                       ['a/', 'a/hello', 'a/b/'])
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
321
        finally:
322
            wt.unlock()
1291 by Martin Pool
- add test for moving files between directories
323
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
324
        wt.move(['a/hello'], 'a/b')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
325
        r4 = 'test@rev-4'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
326
        wt.commit('four', rev_id=r4, allow_pointless=False)
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
327
        wt.lock_read()
328
        try:
5807.1.5 by Jelmer Vernooij
Fix more things to use tree objects.
329
            self.check_tree_shape(wt, ['a/', 'a/b/hello', 'a/b/'])
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
330
        finally:
331
            wt.unlock()
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
332
5035.3.1 by Jelmer Vernooij
Remove Repository.get_revision_inventory.
333
        inv = b.repository.get_inventory(r4)
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
334
        eq(inv['hello-id'].revision, r4)
335
        eq(inv['a-id'].revision, r1)
336
        eq(inv['b-id'].revision, r3)
2255.2.136 by John Arbash Meinel
(James Westby) add read locks around read_working_inventory() in test_commit_move
337
1246 by Martin Pool
- add very simple commit tests
338
    def test_removed_commit(self):
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
339
        """Commit with a removed file"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
340
        wt = self.make_branch_and_tree('.')
341
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
342
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
343
        wt.add(['hello'], ['hello-id'])
344
        wt.commit(message='add hello')
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
345
        wt.remove('hello')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
346
        wt.commit('removed hello', rev_id='rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
347
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
348
        tree = b.repository.revision_tree('rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
349
        self.assertFalse(tree.has_id('hello-id'))
1246 by Martin Pool
- add very simple commit tests
350
1256 by Martin Pool
- test that commits append to the tree's ancestry
351
    def test_committed_ancestry(self):
352
        """Test commit appends revisions to ancestry."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
353
        wt = self.make_branch_and_tree('.')
354
        b = wt.branch
1256 by Martin Pool
- test that commits append to the tree's ancestry
355
        rev_ids = []
356
        for i in range(4):
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
357
            with open('hello', 'w') as f: f.write((str(i) * 4) + '\n')
1256 by Martin Pool
- test that commits append to the tree's ancestry
358
            if i == 0:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
359
                wt.add(['hello'], ['hello-id'])
1256 by Martin Pool
- test that commits append to the tree's ancestry
360
            rev_id = 'test@rev-%d' % (i+1)
361
            rev_ids.append(rev_id)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
362
            wt.commit(message='rev %d' % (i+1),
1256 by Martin Pool
- test that commits append to the tree's ancestry
363
                     rev_id=rev_id)
364
        for i in range(4):
5972.3.15 by Jelmer Vernooij
Use matchers.
365
            self.assertThat(rev_ids[:i+1],
366
                MatchesAncestry(b.repository, rev_ids[i]))
1416 by Robert Collins
when committing a specific file, include all its parents
367
368
    def test_commit_new_subdir_child_selective(self):
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
369
        wt = self.make_branch_and_tree('.')
370
        b = wt.branch
1416 by Robert Collins
when committing a specific file, include all its parents
371
        self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
372
        wt.add(['dir', 'dir/file1', 'dir/file2'],
1416 by Robert Collins
when committing a specific file, include all its parents
373
              ['dirid', 'file1id', 'file2id'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
374
        wt.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
375
        inv = b.repository.get_inventory('1')
1416 by Robert Collins
when committing a specific file, include all its parents
376
        self.assertEqual('1', inv['dirid'].revision)
377
        self.assertEqual('1', inv['file1id'].revision)
378
        # FIXME: This should raise a KeyError I think, rbc20051006
379
        self.assertRaises(BzrError, inv.__getitem__, 'file2id')
1185.16.65 by mbp at sourcefrog
- new commit --strict option
380
381
    def test_strict_commit(self):
382
        """Try and commit with unknown files and strict = True, should fail."""
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
383
        from ..errors import StrictCommitFailed
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
384
        wt = self.make_branch_and_tree('.')
385
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
386
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
387
        wt.add('hello')
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
388
        with open('goodbye', 'w') as f: f.write('goodbye cruel world!')
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
389
        self.assertRaises(StrictCommitFailed, wt.commit,
1185.16.65 by mbp at sourcefrog
- new commit --strict option
390
            message='add hello but not goodbye', strict=True)
391
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
392
    def test_strict_commit_without_unknowns(self):
393
        """Try and commit with no unknown files and strict = True,
394
        should work."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
395
        wt = self.make_branch_and_tree('.')
396
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
397
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
398
        wt.add('hello')
399
        wt.commit(message='add hello', strict=True)
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
400
1185.16.65 by mbp at sourcefrog
- new commit --strict option
401
    def test_nonstrict_commit(self):
402
        """Try and commit with unknown files and strict = False, should work."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
403
        wt = self.make_branch_and_tree('.')
404
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
405
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
406
        wt.add('hello')
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
407
        with open('goodbye', 'w') as f: f.write('goodbye cruel world!')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
408
        wt.commit(message='add hello but not goodbye', strict=False)
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
409
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
410
    def test_nonstrict_commit_without_unknowns(self):
411
        """Try and commit with no unknown files and strict = False,
412
        should work."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
413
        wt = self.make_branch_and_tree('.')
414
        b = wt.branch
6813.1.1 by Martin
Arbitrary small changes for saner Python 3 support
415
        with open('hello', 'w') as f: f.write('hello world')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
416
        wt.add('hello')
417
        wt.commit(message='add hello', strict=False)
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
418
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
419
    def test_signed_commit(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
420
        import breezy.gpg
421
        import breezy.commit as commit
422
        oldstrategy = breezy.gpg.GPGStrategy
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
423
        wt = self.make_branch_and_tree('.')
424
        branch = wt.branch
425
        wt.commit("base", allow_pointless=True, rev_id='A')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
426
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
427
        try:
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
428
            from ..testament import Testament
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
429
            # monkey patch gpg signing mechanism
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
430
            breezy.gpg.GPGStrategy = breezy.gpg.LoopbackGPGStrategy
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
431
            conf = config.MemoryStack('''
432
create_signatures=always
433
''')
434
            commit.Commit(config_stack=conf).commit(
435
                message="base", allow_pointless=True, rev_id='B',
436
                working_tree=wt)
1551.12.15 by Aaron Bentley
add header/trailer to fake clearsigned texts
437
            def sign(text):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
438
                return breezy.gpg.LoopbackGPGStrategy(None).sign(text)
1551.12.15 by Aaron Bentley
add header/trailer to fake clearsigned texts
439
            self.assertEqual(sign(Testament.from_revision(branch.repository,
6351.3.12 by Vincent Ladeuil
Use simpler config stacks and use strings as inputs to better respect the API.
440
                                                          'B').as_short_text()),
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
441
                             branch.repository.get_signature_text('B'))
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
442
        finally:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
443
            breezy.gpg.GPGStrategy = oldstrategy
1442.1.62 by Robert Collins
Allow creation of testaments from uncommitted data, and use that to get signatures before committing revisions.
444
445
    def test_commit_failed_signature(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
446
        import breezy.gpg
447
        import breezy.commit as commit
448
        oldstrategy = breezy.gpg.GPGStrategy
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
449
        wt = self.make_branch_and_tree('.')
450
        branch = wt.branch
451
        wt.commit("base", allow_pointless=True, rev_id='A')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
452
        self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
1442.1.62 by Robert Collins
Allow creation of testaments from uncommitted data, and use that to get signatures before committing revisions.
453
        try:
454
            # monkey patch gpg signing mechanism
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
455
            breezy.gpg.GPGStrategy = breezy.gpg.DisabledGPGStrategy
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
456
            conf = config.MemoryStack('''
457
create_signatures=always
458
''')
6728.1.2 by Jelmer Vernooij
Sign using python-gpg rather than command-line gpg.
459
            self.assertRaises(breezy.gpg.SigningFailed,
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
460
                              commit.Commit(config_stack=conf).commit,
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
461
                              message="base",
1442.1.62 by Robert Collins
Allow creation of testaments from uncommitted data, and use that to get signatures before committing revisions.
462
                              allow_pointless=True,
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
463
                              rev_id='B',
464
                              working_tree=wt)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
465
            branch = Branch.open(self.get_url('.'))
6165.4.7 by Jelmer Vernooij
More fixes.
466
            self.assertEqual(branch.last_revision(), 'A')
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
467
            self.assertFalse(branch.repository.has_revision('B'))
1442.1.62 by Robert Collins
Allow creation of testaments from uncommitted data, and use that to get signatures before committing revisions.
468
        finally:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
469
            breezy.gpg.GPGStrategy = oldstrategy
1472 by Robert Collins
post commit hook, first pass implementation
470
471
    def test_commit_invokes_hooks(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
472
        import breezy.commit as commit
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
473
        wt = self.make_branch_and_tree('.')
474
        branch = wt.branch
1472 by Robert Collins
post commit hook, first pass implementation
475
        calls = []
476
        def called(branch, rev_id):
477
            calls.append('called')
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
478
        breezy.ahook = called
1472 by Robert Collins
post commit hook, first pass implementation
479
        try:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
480
            conf = config.MemoryStack('post_commit=breezy.ahook breezy.ahook')
6393.1.1 by Vincent Ladeuil
Provides MemoryStack to simplify configuration setup in tests
481
            commit.Commit(config_stack=conf).commit(
482
                message = "base", allow_pointless=True, rev_id='A',
483
                working_tree = wt)
1472 by Robert Collins
post commit hook, first pass implementation
484
            self.assertEqual(['called', 'called'], calls)
485
        finally:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
486
            del breezy.ahook
1593.1.1 by Robert Collins
Move responsibility for setting branch nickname in commits to the WorkingTree convenience function.
487
488
    def test_commit_object_doesnt_set_nick(self):
489
        # using the Commit object directly does not set the branch nick.
490
        wt = self.make_branch_and_tree('.')
491
        c = Commit()
2149.1.3 by Aaron Bentley
Updates from review comments
492
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
493
        self.assertEqual(wt.branch.revno(), 1)
1593.1.1 by Robert Collins
Move responsibility for setting branch nickname in commits to the WorkingTree convenience function.
494
        self.assertEqual({},
495
                         wt.branch.repository.get_revision(
496
                            wt.branch.last_revision()).properties)
497
1614.1.1 by Aaron Bentley
Fixed master locking in commit
498
    def test_safe_master_lock(self):
499
        os.mkdir('master')
500
        master = BzrDirMetaFormat1().initialize('master')
501
        master.create_repository()
502
        master_branch = master.create_branch()
503
        master.create_workingtree()
504
        bound = master.sprout('bound')
505
        wt = bound.open_workingtree()
6404.6.7 by Vincent Ladeuil
Change set/remove to require a lock for the branch config files.
506
        wt.branch.set_bound_location(os.path.realpath('master'))
1614.1.1 by Aaron Bentley
Fixed master locking in commit
507
        master_branch.lock_write()
1658.1.5 by Martin Pool
Release more locks taken during test suite
508
        try:
509
            self.assertRaises(LockContention, wt.commit, 'silly')
510
        finally:
511
            master_branch.unlock()
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
512
513
    def test_commit_bound_merge(self):
514
        # see bug #43959; commit of a merge in a bound branch fails to push
515
        # the new commit into the master
516
        master_branch = self.make_branch('master')
517
        bound_tree = self.make_branch_and_tree('bound')
518
        bound_tree.branch.bind(master_branch)
519
520
        self.build_tree_contents([('bound/content_file', 'initial contents\n')])
521
        bound_tree.add(['content_file'])
522
        bound_tree.commit(message='woo!')
523
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
524
        other_bzrdir = master_branch.controldir.sprout('other')
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
525
        other_tree = other_bzrdir.open_workingtree()
526
4775.1.1 by Martin Pool
Remove several 'the the' typos
527
        # do a commit to the other branch changing the content file so
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
528
        # that our commit after merging will have a merged revision in the
529
        # content file history.
530
        self.build_tree_contents([('other/content_file', 'change in other\n')])
531
        other_tree.commit('change in other')
532
533
        # do a merge into the bound branch from other, and then change the
534
        # content file locally to force a new revision (rather than using the
535
        # revision from other). This forces extra processing in commit.
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
536
        bound_tree.merge_from_branch(other_tree.branch)
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
537
        self.build_tree_contents([('bound/content_file', 'change in bound\n')])
538
539
        # before #34959 was fixed, this failed with 'revision not present in
540
        # weave' when trying to implicitly push from the bound branch to the master
541
        bound_tree.commit(message='commit of merge in bound tree')
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
542
543
    def test_commit_reporting_after_merge(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
544
        # when doing a commit of a merge, the reporter needs to still
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
545
        # be called for each item that is added/removed/deleted.
546
        this_tree = self.make_branch_and_tree('this')
547
        # we need a bunch of files and dirs, to perform one action on each.
548
        self.build_tree([
549
            'this/dirtorename/',
550
            'this/dirtoreparent/',
551
            'this/dirtoleave/',
552
            'this/dirtoremove/',
553
            'this/filetoreparent',
554
            'this/filetorename',
555
            'this/filetomodify',
556
            'this/filetoremove',
557
            'this/filetoleave']
558
            )
559
        this_tree.add([
560
            'dirtorename',
561
            'dirtoreparent',
562
            'dirtoleave',
563
            'dirtoremove',
564
            'filetoreparent',
565
            'filetorename',
566
            'filetomodify',
567
            'filetoremove',
568
            'filetoleave']
569
            )
570
        this_tree.commit('create_files')
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
571
        other_dir = this_tree.controldir.sprout('other')
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
572
        other_tree = other_dir.open_workingtree()
573
        other_tree.lock_write()
574
        # perform the needed actions on the files and dirs.
575
        try:
576
            other_tree.rename_one('dirtorename', 'renameddir')
577
            other_tree.rename_one('dirtoreparent', 'renameddir/reparenteddir')
578
            other_tree.rename_one('filetorename', 'renamedfile')
579
            other_tree.rename_one('filetoreparent', 'renameddir/reparentedfile')
580
            other_tree.remove(['dirtoremove', 'filetoremove'])
581
            self.build_tree_contents([
582
                ('other/newdir/', ),
583
                ('other/filetomodify', 'new content'),
584
                ('other/newfile', 'new file content')])
585
            other_tree.add('newfile')
586
            other_tree.add('newdir/')
587
            other_tree.commit('modify all sample files and dirs.')
588
        finally:
589
            other_tree.unlock()
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
590
        this_tree.merge_from_branch(other_tree.branch)
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
591
        reporter = CapturingReporter()
592
        this_tree.commit('do the commit', reporter=reporter)
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
593
        expected = {
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
594
            ('change', 'modified', 'filetomodify'),
595
            ('change', 'added', 'newdir'),
596
            ('change', 'added', 'newfile'),
597
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
2829.1.1 by Ian Clatworthy
re-apply Aaron's fix for #94975 (Ian Clatworthy)
598
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
599
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
600
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
601
            ('deleted', 'dirtoremove'),
602
            ('deleted', 'filetoremove'),
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
603
            }
4183.5.5 by Robert Collins
Enable record_iter_changes for cases where it can work.
604
        result = set(reporter.calls)
605
        missing = expected - result
606
        new = result - expected
607
        self.assertEqual((set(), set()), (missing, new))
1551.7.24 by Aaron Bentley
Ensure commit respects file spec when committing removals
608
609
    def test_commit_removals_respects_filespec(self):
610
        """Commit respects the specified_files for removals."""
611
        tree = self.make_branch_and_tree('.')
612
        self.build_tree(['a', 'b'])
613
        tree.add(['a', 'b'])
614
        tree.commit('added a, b')
615
        tree.remove(['a', 'b'])
1906.1.1 by Robert Collins
(robertc) Trivial change to test_commit_removals_respects_filespec to be easir to read.
616
        tree.commit('removed a', specific_files='a')
2255.2.148 by John Arbash Meinel
lock a basis tree during a commit test.
617
        basis = tree.basis_tree()
6852.3.1 by Jelmer Vernooij
add Tree.is_versioned.
618
        with tree.lock_read():
619
            self.assertFalse(basis.is_versioned('a'))
620
            self.assertTrue(basis.is_versioned('b'))
1864.2.1 by John Arbash Meinel
Commit timestamp restricted to 1ms precision.
621
622
    def test_commit_saves_1ms_timestamp(self):
623
        """Passing in a timestamp is saved with 1ms resolution"""
624
        tree = self.make_branch_and_tree('.')
625
        self.build_tree(['a'])
626
        tree.add('a')
627
        tree.commit('added a', timestamp=1153248633.4186721, timezone=0,
628
                    rev_id='a1')
629
630
        rev = tree.branch.repository.get_revision('a1')
631
        self.assertEqual(1153248633.419, rev.timestamp)
632
633
    def test_commit_has_1ms_resolution(self):
634
        """Allowing commit to generate the timestamp also has 1ms resolution"""
635
        tree = self.make_branch_and_tree('.')
636
        self.build_tree(['a'])
637
        tree.add('a')
638
        tree.commit('added a', rev_id='a1')
639
640
        rev = tree.branch.repository.get_revision('a1')
641
        timestamp = rev.timestamp
642
        timestamp_1ms = round(timestamp, 3)
643
        self.assertEqual(timestamp_1ms, timestamp)
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
644
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
645
    def assertBasisTreeKind(self, kind, tree, path):
2255.2.135 by John Arbash Meinel
Add locking in the test_commit_kind_changes test.
646
        basis = tree.basis_tree()
647
        basis.lock_read()
648
        try:
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
649
            self.assertEqual(kind, basis.kind(path))
2255.2.135 by John Arbash Meinel
Add locking in the test_commit_kind_changes test.
650
        finally:
651
            basis.unlock()
652
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
653
    def test_commit_kind_changes(self):
2949.5.1 by Alexander Belchenko
selftest: use SymlinkFeature instead of TestSkipped where appropriate
654
        self.requireFeature(SymlinkFeature)
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
655
        tree = self.make_branch_and_tree('.')
656
        os.symlink('target', 'name')
657
        tree.add('name', 'a-file-id')
658
        tree.commit('Added a symlink')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
659
        self.assertBasisTreeKind('symlink', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
660
661
        os.unlink('name')
662
        self.build_tree(['name'])
663
        tree.commit('Changed symlink to file')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
664
        self.assertBasisTreeKind('file', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
665
666
        os.unlink('name')
667
        os.symlink('target', 'name')
668
        tree.commit('file to symlink')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
669
        self.assertBasisTreeKind('symlink', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
670
671
        os.unlink('name')
672
        os.mkdir('name')
673
        tree.commit('symlink to directory')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
674
        self.assertBasisTreeKind('directory', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
675
676
        os.rmdir('name')
677
        os.symlink('target', 'name')
678
        tree.commit('directory to symlink')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
679
        self.assertBasisTreeKind('symlink', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
680
681
        # prepare for directory <-> file tests
682
        os.unlink('name')
683
        os.mkdir('name')
684
        tree.commit('symlink to directory')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
685
        self.assertBasisTreeKind('directory', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
686
687
        os.rmdir('name')
688
        self.build_tree(['name'])
689
        tree.commit('Changed directory to file')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
690
        self.assertBasisTreeKind('file', tree, 'name')
1959.4.1 by Aaron Bentley
Correctly handle all file kind changes
691
692
        os.unlink('name')
693
        os.mkdir('name')
694
        tree.commit('file to directory')
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
695
        self.assertBasisTreeKind('directory', tree, 'name')
1959.4.2 by Aaron Bentley
Merge bzr.dev
696
1551.8.29 by Aaron Bentley
Stop accepting non-existant files in commit (#50793)
697
    def test_commit_unversioned_specified(self):
698
        """Commit should raise if specified files isn't in basis or worktree"""
699
        tree = self.make_branch_and_tree('.')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
700
        self.assertRaises(errors.PathsNotVersionedError, tree.commit,
1551.8.29 by Aaron Bentley
Stop accepting non-existant files in commit (#50793)
701
                          'message', specific_files=['bogus'])
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
702
703
    class Callback(object):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
704
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
705
        def __init__(self, message, testcase):
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
706
            self.called = False
707
            self.message = message
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
708
            self.testcase = testcase
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
709
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
710
        def __call__(self, commit_obj):
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
711
            self.called = True
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
712
            self.testcase.assertTrue(isinstance(commit_obj, Commit))
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
713
            return self.message
714
715
    def test_commit_callback(self):
716
        """Commit should invoke a callback to get the message"""
717
718
        tree = self.make_branch_and_tree('.')
719
        try:
720
            tree.commit()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
721
        except Exception as e:
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
722
            self.assertTrue(isinstance(e, BzrError))
2149.1.3 by Aaron Bentley
Updates from review comments
723
            self.assertEqual('The message or message_callback keyword'
724
                             ' parameter is required for commit().', str(e))
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
725
        else:
726
            self.fail('exception not raised')
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
727
        cb = self.Callback(u'commit 1', self)
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
728
        tree.commit(message_callback=cb)
729
        self.assertTrue(cb.called)
730
        repository = tree.branch.repository
731
        message = repository.get_revision(tree.last_revision()).message
732
        self.assertEqual('commit 1', message)
733
734
    def test_no_callback_pointless(self):
735
        """Callback should not be invoked for pointless commit"""
736
        tree = self.make_branch_and_tree('.')
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
737
        cb = self.Callback(u'commit 2', self)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
738
        self.assertRaises(PointlessCommit, tree.commit, message_callback=cb,
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
739
                          allow_pointless=False)
740
        self.assertFalse(cb.called)
741
742
    def test_no_callback_netfailure(self):
743
        """Callback should not be invoked if connectivity fails"""
2149.1.3 by Aaron Bentley
Updates from review comments
744
        tree = self.make_branch_and_tree('.')
2149.1.4 by Aaron Bentley
Add additional test that callback is called with a Commit instance
745
        cb = self.Callback(u'commit 2', self)
2149.1.3 by Aaron Bentley
Updates from review comments
746
        repository = tree.branch.repository
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
747
        # simulate network failure
4617.2.1 by Robert Collins
Fix test_commit for use with 2a as the default repository.
748
        def raise_(self, arg, arg2, arg3=None, arg4=None):
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
749
            raise errors.NoSuchFile('foo')
750
        repository.add_inventory = raise_
4617.2.1 by Robert Collins
Fix test_commit for use with 2a as the default repository.
751
        repository.add_inventory_by_delta = raise_
2149.1.1 by Aaron Bentley
Provide a message_callback parameter to tree.commit
752
        self.assertRaises(errors.NoSuchFile, tree.commit, message_callback=cb)
753
        self.assertFalse(cb.called)
1551.15.9 by Aaron Bentley
Better error for selected-file commit of merges
754
755
    def test_selected_file_merge_commit(self):
756
        """Ensure the correct error is raised"""
757
        tree = self.make_branch_and_tree('foo')
758
        # pending merge would turn into a left parent
759
        tree.commit('commit 1')
760
        tree.add_parent_tree_id('example')
761
        self.build_tree(['foo/bar', 'foo/baz'])
762
        tree.add(['bar', 'baz'])
6734.1.20 by Jelmer Vernooij
Move errors.
763
        err = self.assertRaises(CannotCommitSelectedFileMerge,
1551.15.9 by Aaron Bentley
Better error for selected-file commit of merges
764
            tree.commit, 'commit 2', specific_files=['bar', 'baz'])
765
        self.assertEqual(['bar', 'baz'], err.files)
766
        self.assertEqual('Selected-file commit of merges is not supported'
767
                         ' yet: files bar, baz', str(err))
2671.2.2 by Lukáš Lalinský
Move setting of the author revision property to MutableTree.commit. Don't use try/except KeyError in LongLogFormatter to display authors and branch-nicks. Removed warning about missing e-mail in the authors name.
768
2829.1.1 by Ian Clatworthy
re-apply Aaron's fix for #94975 (Ian Clatworthy)
769
    def test_commit_ordering(self):
770
        """Test of corner-case commit ordering error"""
771
        tree = self.make_branch_and_tree('.')
772
        self.build_tree(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
773
        tree.add(['a/', 'a/z/', 'a/c/', 'a/z/x', 'a/z/y'])
774
        tree.commit('setup')
775
        self.build_tree(['a/c/d/'])
776
        tree.add('a/c/d')
777
        tree.rename_one('a/z/x', 'a/c/d/x')
778
        tree.commit('test', specific_files=['a/z/y'])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
779
2671.2.2 by Lukáš Lalinský
Move setting of the author revision property to MutableTree.commit. Don't use try/except KeyError in LongLogFormatter to display authors and branch-nicks. Removed warning about missing e-mail in the authors name.
780
    def test_commit_no_author(self):
781
        """The default kwarg author in MutableTree.commit should not add
782
        the 'author' revision property.
783
        """
784
        tree = self.make_branch_and_tree('foo')
785
        rev_id = tree.commit('commit 1')
786
        rev = tree.branch.repository.get_revision(rev_id)
787
        self.assertFalse('author' in rev.properties)
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
788
        self.assertFalse('authors' in rev.properties)
2671.2.2 by Lukáš Lalinský
Move setting of the author revision property to MutableTree.commit. Don't use try/except KeyError in LongLogFormatter to display authors and branch-nicks. Removed warning about missing e-mail in the authors name.
789
790
    def test_commit_author(self):
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
791
        """Passing a non-empty authors kwarg to MutableTree.commit should add
2671.2.2 by Lukáš Lalinský
Move setting of the author revision property to MutableTree.commit. Don't use try/except KeyError in LongLogFormatter to display authors and branch-nicks. Removed warning about missing e-mail in the authors name.
792
        the 'author' revision property.
793
        """
794
        tree = self.make_branch_and_tree('foo')
6630.1.1 by Jelmer Vernooij
Remove deprecated functionality.
795
        rev_id = tree.commit(
796
            'commit 1',
797
            authors=['John Doe <jdoe@example.com>'])
2671.2.2 by Lukáš Lalinský
Move setting of the author revision property to MutableTree.commit. Don't use try/except KeyError in LongLogFormatter to display authors and branch-nicks. Removed warning about missing e-mail in the authors name.
798
        rev = tree.branch.repository.get_revision(rev_id)
799
        self.assertEqual('John Doe <jdoe@example.com>',
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
800
                         rev.properties['authors'])
801
        self.assertFalse('author' in rev.properties)
3113.6.7 by Aaron Bentley
Fix commit for a checkout sharing a repo with its branch (abentley, #177592)
802
4056.2.1 by James Westby
Allow specifying multiple authors for a revision.
803
    def test_commit_empty_authors_list(self):
804
        """Passing an empty list to authors shouldn't add the property."""
805
        tree = self.make_branch_and_tree('foo')
806
        rev_id = tree.commit('commit 1', authors=[])
807
        rev = tree.branch.repository.get_revision(rev_id)
808
        self.assertFalse('author' in rev.properties)
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
809
        self.assertFalse('authors' in rev.properties)
4056.2.1 by James Westby
Allow specifying multiple authors for a revision.
810
811
    def test_multiple_authors(self):
812
        tree = self.make_branch_and_tree('foo')
813
        rev_id = tree.commit('commit 1',
814
                authors=['John Doe <jdoe@example.com>',
815
                         'Jane Rey <jrey@example.com>'])
816
        rev = tree.branch.repository.get_revision(rev_id)
817
        self.assertEqual('John Doe <jdoe@example.com>\n'
4056.2.3 by James Westby
Use a new "authors" revision property to allow multiple authors
818
                'Jane Rey <jrey@example.com>', rev.properties['authors'])
819
        self.assertFalse('author' in rev.properties)
4056.2.1 by James Westby
Allow specifying multiple authors for a revision.
820
821
    def test_author_with_newline_rejected(self):
822
        tree = self.make_branch_and_tree('foo')
823
        self.assertRaises(AssertionError, tree.commit, 'commit 1',
824
                authors=['John\nDoe <jdoe@example.com>'])
825
3113.6.7 by Aaron Bentley
Fix commit for a checkout sharing a repo with its branch (abentley, #177592)
826
    def test_commit_with_checkout_and_branch_sharing_repo(self):
827
        repo = self.make_repository('repo', shared=True)
828
        # make_branch_and_tree ignores shared repos
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
829
        branch = controldir.ControlDir.create_branch_convenience('repo/branch')
3113.6.7 by Aaron Bentley
Fix commit for a checkout sharing a repo with its branch (abentley, #177592)
830
        tree2 = branch.create_checkout('repo/tree2')
831
        tree2.commit('message', rev_id='rev1')
832
        self.assertTrue(tree2.branch.repository.has_revision('rev1'))
6699.1.1 by Jelmer Vernooij
Support excludes with "bzr commit -x".
833
834
835
class FilterExcludedTests(TestCase):
836
837
    def test_add_file_not_excluded(self):
838
        changes = [
839
            ('fid', (None, 'newpath'),
840
             0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
841
             ('file', 'file'), (True, True))]
842
        self.assertEqual(changes, list(filter_excluded(changes, ['otherpath'])))
843
844
    def test_add_file_excluded(self):
845
        changes = [
846
            ('fid', (None, 'newpath'),
847
             0, (False, False), ('pid', 'pid'), ('newpath', 'newpath'),
848
             ('file', 'file'), (True, True))]
849
        self.assertEqual([], list(filter_excluded(changes, ['newpath'])))
850
851
    def test_delete_file_excluded(self):
852
        changes = [
853
            ('fid', ('somepath', None),
854
             0, (False, None), ('pid', None), ('newpath', None),
855
             ('file', None), (True, None))]
856
        self.assertEqual([], list(filter_excluded(changes, ['somepath'])))
857
858
    def test_move_from_or_to_excluded(self):
859
        changes = [
860
            ('fid', ('oldpath', 'newpath'),
861
             0, (False, False), ('pid', 'pid'), ('oldpath', 'newpath'),
862
             ('file', 'file'), (True, True))]
863
        self.assertEqual([], list(filter_excluded(changes, ['oldpath'])))
864
        self.assertEqual([], list(filter_excluded(changes, ['newpath'])))