/brz/remove-bazaar

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