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