~bzr-pqm/bzr/bzr.dev

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