~bzr-pqm/bzr/bzr.dev

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