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