/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
1
# Copyright (C) 2005, 2006 by 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
import os
19
1472 by Robert Collins
post commit hook, first pass implementation
20
import bzrlib
1551.8.29 by Aaron Bentley
Stop accepting non-existant files in commit (#50793)
21
from bzrlib import errors
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
22
from bzrlib.tests import TestCaseWithTransport
1246 by Martin Pool
- add very simple commit tests
23
from bzrlib.branch import Branch
1614.1.1 by Aaron Bentley
Fixed master locking in commit
24
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
25
from bzrlib.workingtree import WorkingTree
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
26
from bzrlib.commit import Commit, NullCommitReporter
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
27
from bzrlib.config import BranchConfig
1614.1.1 by Aaron Bentley
Fixed master locking in commit
28
from bzrlib.errors import (PointlessCommit, BzrError, SigningFailed, 
29
                           LockContention)
1246 by Martin Pool
- add very simple commit tests
30
31
1257 by Martin Pool
doc
32
# TODO: Test commit with some added, and added-but-missing files
33
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
34
class MustSignConfig(BranchConfig):
35
36
    def signature_needed(self):
37
        return True
38
39
    def gpg_signing_command(self):
40
        return ['cat', '-']
41
42
1472 by Robert Collins
post commit hook, first pass implementation
43
class BranchWithHooks(BranchConfig):
44
45
    def post_commit(self):
46
        return "bzrlib.ahook bzrlib.ahook"
47
48
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
49
class CapturingReporter(NullCommitReporter):
50
    """This reporter captures the calls made to it for evaluation later."""
51
52
    def __init__(self):
53
        # a list of the calls this received
54
        self.calls = []
55
56
    def snapshot_change(self, change, path):
57
        self.calls.append(('change', change, path))
58
59
    def deleted(self, file_id):
60
        self.calls.append(('deleted', file_id))
61
62
    def missing(self, path):
63
        self.calls.append(('missing', path))
64
65
    def renamed(self, change, old_path, new_path):
66
        self.calls.append(('renamed', change, old_path, new_path))
67
68
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
69
class TestCommit(TestCaseWithTransport):
1390 by Robert Collins
pair programming worx... merge integration and weave
70
1246 by Martin Pool
- add very simple commit tests
71
    def test_simple_commit(self):
72
        """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.
73
        wt = self.make_branch_and_tree('.')
74
        b = wt.branch
1246 by Martin Pool
- add very simple commit tests
75
        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.
76
        wt.add('hello')
77
        wt.commit(message='add hello')
78
        file_id = wt.path2id('hello')
1246 by Martin Pool
- add very simple commit tests
79
80
        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.
81
        wt.commit(message='commit 2')
1246 by Martin Pool
- add very simple commit tests
82
83
        eq = self.assertEquals
84
        eq(b.revno(), 2)
85
        rh = b.revision_history()
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
86
        rev = b.repository.get_revision(rh[0])
1246 by Martin Pool
- add very simple commit tests
87
        eq(rev.message, 'add hello')
88
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
89
        tree1 = b.repository.revision_tree(rh[0])
1246 by Martin Pool
- add very simple commit tests
90
        text = tree1.get_file_text(file_id)
91
        eq(text, 'hello world')
92
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
93
        tree2 = b.repository.revision_tree(rh[1])
1246 by Martin Pool
- add very simple commit tests
94
        eq(tree2.get_file_text(file_id), 'version 2')
95
96
    def test_delete_commit(self):
97
        """Test a commit with a deleted file"""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
98
        wt = self.make_branch_and_tree('.')
99
        b = wt.branch
1247 by Martin Pool
- tests for deletion and removal of files in commits
100
        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.
101
        wt.add(['hello'], ['hello-id'])
102
        wt.commit(message='add hello')
1247 by Martin Pool
- tests for deletion and removal of files in commits
103
104
        os.remove('hello')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
105
        wt.commit('removed hello', rev_id='rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
106
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
107
        tree = b.repository.revision_tree('rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
108
        self.assertFalse(tree.has_id('hello-id'))
109
1253 by Martin Pool
- test that pointless commits are trapped
110
    def test_pointless_commit(self):
111
        """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.
112
        wt = self.make_branch_and_tree('.')
113
        b = wt.branch
1253 by Martin Pool
- test that pointless commits are trapped
114
        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.
115
        wt.add(['hello'])
116
        wt.commit(message='add hello')
1253 by Martin Pool
- test that pointless commits are trapped
117
        self.assertEquals(b.revno(), 1)
118
        self.assertRaises(PointlessCommit,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
119
                          wt.commit,
1253 by Martin Pool
- test that pointless commits are trapped
120
                          message='fails',
121
                          allow_pointless=False)
122
        self.assertEquals(b.revno(), 1)
123
        
1252 by Martin Pool
- add test for commit of an empty tree
124
    def test_commit_empty(self):
1253 by Martin Pool
- test that pointless commits are trapped
125
        """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.
126
        wt = self.make_branch_and_tree('.')
127
        b = wt.branch
128
        wt.commit(message='empty tree', allow_pointless=True)
1253 by Martin Pool
- test that pointless commits are trapped
129
        self.assertRaises(PointlessCommit,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
130
                          wt.commit,
1253 by Martin Pool
- test that pointless commits are trapped
131
                          message='empty tree',
132
                          allow_pointless=False)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
133
        wt.commit(message='empty tree', allow_pointless=True)
1252 by Martin Pool
- add test for commit of an empty tree
134
        self.assertEquals(b.revno(), 2)
135
136
    def test_selective_delete(self):
137
        """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.
138
        wt = self.make_branch_and_tree('.')
139
        b = wt.branch
1254 by Martin Pool
- fix handling of selective commit with deleted files
140
        file('hello', 'w').write('hello')
141
        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.
142
        wt.add(['hello', 'buongia'],
1255 by Martin Pool
- more tests for selective commit of deletion
143
              ['hello-id', 'buongia-id'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
144
        wt.commit(message='add files',
1255 by Martin Pool
- more tests for selective commit of deletion
145
                 rev_id='test@rev-1')
1254 by Martin Pool
- fix handling of selective commit with deleted files
146
        
147
        os.remove('hello')
148
        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.
149
        wt.commit(message='update text',
1254 by Martin Pool
- fix handling of selective commit with deleted files
150
                 specific_files=['buongia'],
1255 by Martin Pool
- more tests for selective commit of deletion
151
                 allow_pointless=False,
152
                 rev_id='test@rev-2')
1254 by Martin Pool
- fix handling of selective commit with deleted files
153
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
154
        wt.commit(message='remove hello',
1254 by Martin Pool
- fix handling of selective commit with deleted files
155
                 specific_files=['hello'],
1255 by Martin Pool
- more tests for selective commit of deletion
156
                 allow_pointless=False,
157
                 rev_id='test@rev-3')
1254 by Martin Pool
- fix handling of selective commit with deleted files
158
159
        eq = self.assertEquals
160
        eq(b.revno(), 3)
1255 by Martin Pool
- more tests for selective commit of deletion
161
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
162
        tree2 = b.repository.revision_tree('test@rev-2')
1255 by Martin Pool
- more tests for selective commit of deletion
163
        self.assertTrue(tree2.has_filename('hello'))
164
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
165
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
166
        
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
167
        tree3 = b.repository.revision_tree('test@rev-3')
1255 by Martin Pool
- more tests for selective commit of deletion
168
        self.assertFalse(tree3.has_filename('hello'))
169
        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
170
171
    def test_commit_rename(self):
172
        """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.
173
        tree = self.make_branch_and_tree('.')
174
        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
175
        self.build_tree(['hello'], line_endings='binary')
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
176
        tree.add(['hello'], ['hello-id'])
177
        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
178
1508.1.7 by Robert Collins
Move rename_one from Branch to WorkingTree. (Robert Collins).
179
        tree.rename_one('hello', 'fruity')
180
        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
181
1303 by Martin Pool
- commit updates entry_version
182
        eq = self.assertEquals
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
183
        tree1 = b.repository.revision_tree('test@rev-1')
1303 by Martin Pool
- commit updates entry_version
184
        eq(tree1.id2path('hello-id'), 'hello')
185
        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
186
        self.assertFalse(tree1.has_filename('fruity'))
1291 by Martin Pool
- add test for moving files between directories
187
        self.check_inventory_shape(tree1.inventory, ['hello'])
1303 by Martin Pool
- commit updates entry_version
188
        ie = tree1.inventory['hello-id']
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
189
        eq(ie.revision, 'test@rev-1')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
190
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
191
        tree2 = b.repository.revision_tree('test@rev-2')
1303 by Martin Pool
- commit updates entry_version
192
        eq(tree2.id2path('hello-id'), 'fruity')
193
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
1291 by Martin Pool
- add test for moving files between directories
194
        self.check_inventory_shape(tree2.inventory, ['fruity'])
1303 by Martin Pool
- commit updates entry_version
195
        ie = tree2.inventory['hello-id']
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
196
        eq(ie.revision, 'test@rev-2')
1291 by Martin Pool
- add test for moving files between directories
197
198
    def test_reused_rev_id(self):
1292 by Martin Pool
- add check that revision ids cannot be committed twice
199
        """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.
200
        wt = self.make_branch_and_tree('.')
201
        b = wt.branch
202
        wt.commit('initial', rev_id='test@rev-1', allow_pointless=True)
1292 by Martin Pool
- add check that revision ids cannot be committed twice
203
        self.assertRaises(Exception,
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
204
                          wt.commit,
1292 by Martin Pool
- add check that revision ids cannot be committed twice
205
                          message='reused id',
206
                          rev_id='test@rev-1',
207
                          allow_pointless=True)
1291 by Martin Pool
- add test for moving files between directories
208
209
    def test_commit_move(self):
210
        """Test commit of revisions with moved files and directories"""
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
211
        eq = self.assertEquals
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
212
        wt = self.make_branch_and_tree('.')
213
        b = wt.branch
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
214
        r1 = 'test@rev-1'
1291 by Martin Pool
- add test for moving files between directories
215
        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.
216
        wt.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
217
        wt.commit('initial', rev_id=r1, allow_pointless=False)
218
        wt.move(['hello'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
219
        r2 = 'test@rev-2'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
220
        wt.commit('two', rev_id=r2, allow_pointless=False)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
221
        self.check_inventory_shape(wt.read_working_inventory(),
1291 by Martin Pool
- add test for moving files between directories
222
                                   ['a', 'a/hello', 'b'])
223
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
224
        wt.move(['b'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
225
        r3 = 'test@rev-3'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
226
        wt.commit('three', rev_id=r3, allow_pointless=False)
227
        self.check_inventory_shape(wt.read_working_inventory(),
1291 by Martin Pool
- add test for moving files between directories
228
                                   ['a', 'a/hello', 'a/b'])
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
229
        self.check_inventory_shape(b.repository.get_revision_inventory(r3),
1291 by Martin Pool
- add test for moving files between directories
230
                                   ['a', 'a/hello', 'a/b'])
231
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
232
        wt.move(['a/hello'], 'a/b')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
233
        r4 = 'test@rev-4'
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
234
        wt.commit('four', rev_id=r4, allow_pointless=False)
235
        self.check_inventory_shape(wt.read_working_inventory(),
1291 by Martin Pool
- add test for moving files between directories
236
                                   ['a', 'a/b/hello', 'a/b'])
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
237
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
238
        inv = b.repository.get_revision_inventory(r4)
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
239
        eq(inv['hello-id'].revision, r4)
240
        eq(inv['a-id'].revision, r1)
241
        eq(inv['b-id'].revision, r3)
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
242
        
1246 by Martin Pool
- add very simple commit tests
243
    def test_removed_commit(self):
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
244
        """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.
245
        wt = self.make_branch_and_tree('.')
246
        b = wt.branch
1247 by Martin Pool
- tests for deletion and removal of files in commits
247
        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.
248
        wt.add(['hello'], ['hello-id'])
249
        wt.commit(message='add hello')
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
250
        wt.remove('hello')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
251
        wt.commit('removed hello', rev_id='rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
252
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
253
        tree = b.repository.revision_tree('rev2')
1247 by Martin Pool
- tests for deletion and removal of files in commits
254
        self.assertFalse(tree.has_id('hello-id'))
1246 by Martin Pool
- add very simple commit tests
255
1256 by Martin Pool
- test that commits append to the tree's ancestry
256
    def test_committed_ancestry(self):
257
        """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.
258
        wt = self.make_branch_and_tree('.')
259
        b = wt.branch
1256 by Martin Pool
- test that commits append to the tree's ancestry
260
        rev_ids = []
261
        for i in range(4):
262
            file('hello', 'w').write((str(i) * 4) + '\n')
263
            if i == 0:
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
264
                wt.add(['hello'], ['hello-id'])
1256 by Martin Pool
- test that commits append to the tree's ancestry
265
            rev_id = 'test@rev-%d' % (i+1)
266
            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.
267
            wt.commit(message='rev %d' % (i+1),
1256 by Martin Pool
- test that commits append to the tree's ancestry
268
                     rev_id=rev_id)
269
        eq = self.assertEquals
270
        eq(b.revision_history(), rev_ids)
271
        for i in range(4):
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
272
            anc = b.repository.get_ancestry(rev_ids[i])
1390 by Robert Collins
pair programming worx... merge integration and weave
273
            eq(anc, [None] + rev_ids[:i+1])
1416 by Robert Collins
when committing a specific file, include all its parents
274
275
    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.
276
        wt = self.make_branch_and_tree('.')
277
        b = wt.branch
1416 by Robert Collins
when committing a specific file, include all its parents
278
        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.
279
        wt.add(['dir', 'dir/file1', 'dir/file2'],
1416 by Robert Collins
when committing a specific file, include all its parents
280
              ['dirid', 'file1id', 'file2id'])
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
281
        wt.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
282
        inv = b.repository.get_inventory('1')
1416 by Robert Collins
when committing a specific file, include all its parents
283
        self.assertEqual('1', inv['dirid'].revision)
284
        self.assertEqual('1', inv['file1id'].revision)
285
        # FIXME: This should raise a KeyError I think, rbc20051006
286
        self.assertRaises(BzrError, inv.__getitem__, 'file2id')
1185.16.65 by mbp at sourcefrog
- new commit --strict option
287
288
    def test_strict_commit(self):
289
        """Try and commit with unknown files and strict = True, should fail."""
290
        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.
291
        wt = self.make_branch_and_tree('.')
292
        b = wt.branch
1185.16.65 by mbp at sourcefrog
- new commit --strict option
293
        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.
294
        wt.add('hello')
1185.16.65 by mbp at sourcefrog
- new commit --strict option
295
        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()
296
        self.assertRaises(StrictCommitFailed, wt.commit,
1185.16.65 by mbp at sourcefrog
- new commit --strict option
297
            message='add hello but not goodbye', strict=True)
298
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
299
    def test_strict_commit_without_unknowns(self):
300
        """Try and commit with no unknown files and strict = True,
301
        should work."""
302
        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.
303
        wt = self.make_branch_and_tree('.')
304
        b = wt.branch
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
305
        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.
306
        wt.add('hello')
307
        wt.commit(message='add hello', strict=True)
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
308
1185.16.65 by mbp at sourcefrog
- new commit --strict option
309
    def test_nonstrict_commit(self):
310
        """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.
311
        wt = self.make_branch_and_tree('.')
312
        b = wt.branch
1185.16.65 by mbp at sourcefrog
- new commit --strict option
313
        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.
314
        wt.add('hello')
1185.16.65 by mbp at sourcefrog
- new commit --strict option
315
        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.
316
        wt.commit(message='add hello but not goodbye', strict=False)
1185.16.72 by Martin Pool
[merge] from robert and fix up tests
317
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
318
    def test_nonstrict_commit_without_unknowns(self):
319
        """Try and commit with no unknown files and strict = False,
320
        should work."""
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
321
        wt = self.make_branch_and_tree('.')
322
        b = wt.branch
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
323
        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.
324
        wt.add('hello')
325
        wt.commit(message='add hello', strict=False)
1185.22.4 by Michael Ellerman
Strict commit was a little .. ah .. too strict, oops :}
326
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
327
    def test_signed_commit(self):
328
        import bzrlib.gpg
329
        import bzrlib.commit as commit
330
        oldstrategy = bzrlib.gpg.GPGStrategy
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
331
        wt = self.make_branch_and_tree('.')
332
        branch = wt.branch
333
        wt.commit("base", allow_pointless=True, rev_id='A')
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
334
        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
335
        try:
336
            from bzrlib.testament import Testament
337
            # monkey patch gpg signing mechanism
338
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
339
            commit.Commit(config=MustSignConfig(branch)).commit(message="base",
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
340
                                                      allow_pointless=True,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
341
                                                      rev_id='B',
342
                                                      working_tree=wt)
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
343
            self.assertEqual(Testament.from_revision(branch.repository,
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
344
                             'B').as_short_text(),
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
345
                             branch.repository.get_signature_text('B'))
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
346
        finally:
347
            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.
348
349
    def test_commit_failed_signature(self):
350
        import bzrlib.gpg
351
        import bzrlib.commit as commit
352
        oldstrategy = bzrlib.gpg.GPGStrategy
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
        branch = wt.branch
355
        wt.commit("base", allow_pointless=True, rev_id='A')
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
356
        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.
357
        try:
358
            from bzrlib.testament import Testament
359
            # monkey patch gpg signing mechanism
360
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.DisabledGPGStrategy
361
            config = MustSignConfig(branch)
362
            self.assertRaises(SigningFailed,
363
                              commit.Commit(config=config).commit,
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
364
                              message="base",
1442.1.62 by Robert Collins
Allow creation of testaments from uncommitted data, and use that to get signatures before committing revisions.
365
                              allow_pointless=True,
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
366
                              rev_id='B',
367
                              working_tree=wt)
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
368
            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.
369
            self.assertEqual(branch.revision_history(), ['A'])
1563.2.31 by Robert Collins
Convert Knit repositories to use knits.
370
            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.
371
        finally:
372
            bzrlib.gpg.GPGStrategy = oldstrategy
1472 by Robert Collins
post commit hook, first pass implementation
373
374
    def test_commit_invokes_hooks(self):
375
        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.
376
        wt = self.make_branch_and_tree('.')
377
        branch = wt.branch
1472 by Robert Collins
post commit hook, first pass implementation
378
        calls = []
379
        def called(branch, rev_id):
380
            calls.append('called')
381
        bzrlib.ahook = called
382
        try:
383
            config = BranchWithHooks(branch)
384
            commit.Commit(config=config).commit(
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
385
                            message = "base",
1472 by Robert Collins
post commit hook, first pass implementation
386
                            allow_pointless=True,
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
387
                            rev_id='A', working_tree = wt)
1472 by Robert Collins
post commit hook, first pass implementation
388
            self.assertEqual(['called', 'called'], calls)
389
        finally:
390
            del bzrlib.ahook
1593.1.1 by Robert Collins
Move responsibility for setting branch nickname in commits to the WorkingTree convenience function.
391
392
    def test_commit_object_doesnt_set_nick(self):
393
        # using the Commit object directly does not set the branch nick.
394
        wt = self.make_branch_and_tree('.')
395
        c = Commit()
396
        c.commit(working_tree=wt, message='empty tree', allow_pointless=True)
397
        self.assertEquals(wt.branch.revno(), 1)
398
        self.assertEqual({},
399
                         wt.branch.repository.get_revision(
400
                            wt.branch.last_revision()).properties)
401
1614.1.1 by Aaron Bentley
Fixed master locking in commit
402
    def test_safe_master_lock(self):
403
        os.mkdir('master')
404
        master = BzrDirMetaFormat1().initialize('master')
405
        master.create_repository()
406
        master_branch = master.create_branch()
407
        master.create_workingtree()
408
        bound = master.sprout('bound')
409
        wt = bound.open_workingtree()
410
        wt.branch.set_bound_location(os.path.realpath('master'))
411
        master_branch.lock_write()
1658.1.5 by Martin Pool
Release more locks taken during test suite
412
        try:
413
            self.assertRaises(LockContention, wt.commit, 'silly')
414
        finally:
415
            master_branch.unlock()
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
416
417
    def test_commit_bound_merge(self):
418
        # see bug #43959; commit of a merge in a bound branch fails to push
419
        # the new commit into the master
420
        master_branch = self.make_branch('master')
421
        bound_tree = self.make_branch_and_tree('bound')
422
        bound_tree.branch.bind(master_branch)
423
424
        self.build_tree_contents([('bound/content_file', 'initial contents\n')])
425
        bound_tree.add(['content_file'])
426
        bound_tree.commit(message='woo!')
427
428
        other_bzrdir = master_branch.bzrdir.sprout('other')
429
        other_tree = other_bzrdir.open_workingtree()
430
431
        # do a commit to the the other branch changing the content file so
432
        # that our commit after merging will have a merged revision in the
433
        # content file history.
434
        self.build_tree_contents([('other/content_file', 'change in other\n')])
435
        other_tree.commit('change in other')
436
437
        # do a merge into the bound branch from other, and then change the
438
        # content file locally to force a new revision (rather than using the
439
        # 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.
440
        bound_tree.merge_from_branch(other_tree.branch)
1668.1.3 by Martin Pool
[patch] use the correct transaction when committing snapshot (Malone: #43959)
441
        self.build_tree_contents([('bound/content_file', 'change in bound\n')])
442
443
        # before #34959 was fixed, this failed with 'revision not present in
444
        # weave' when trying to implicitly push from the bound branch to the master
445
        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
446
447
    def test_commit_reporting_after_merge(self):
448
        # when doing a commit of a merge, the reporter needs to still 
449
        # be called for each item that is added/removed/deleted.
450
        this_tree = self.make_branch_and_tree('this')
451
        # we need a bunch of files and dirs, to perform one action on each.
452
        self.build_tree([
453
            'this/dirtorename/',
454
            'this/dirtoreparent/',
455
            'this/dirtoleave/',
456
            'this/dirtoremove/',
457
            'this/filetoreparent',
458
            'this/filetorename',
459
            'this/filetomodify',
460
            'this/filetoremove',
461
            'this/filetoleave']
462
            )
463
        this_tree.add([
464
            'dirtorename',
465
            'dirtoreparent',
466
            'dirtoleave',
467
            'dirtoremove',
468
            'filetoreparent',
469
            'filetorename',
470
            'filetomodify',
471
            'filetoremove',
472
            'filetoleave']
473
            )
474
        this_tree.commit('create_files')
475
        other_dir = this_tree.bzrdir.sprout('other')
476
        other_tree = other_dir.open_workingtree()
477
        other_tree.lock_write()
478
        # perform the needed actions on the files and dirs.
479
        try:
480
            other_tree.rename_one('dirtorename', 'renameddir')
481
            other_tree.rename_one('dirtoreparent', 'renameddir/reparenteddir')
482
            other_tree.rename_one('filetorename', 'renamedfile')
483
            other_tree.rename_one('filetoreparent', 'renameddir/reparentedfile')
484
            other_tree.remove(['dirtoremove', 'filetoremove'])
485
            self.build_tree_contents([
486
                ('other/newdir/', ),
487
                ('other/filetomodify', 'new content'),
488
                ('other/newfile', 'new file content')])
489
            other_tree.add('newfile')
490
            other_tree.add('newdir/')
491
            other_tree.commit('modify all sample files and dirs.')
492
        finally:
493
            other_tree.unlock()
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
494
        this_tree.merge_from_branch(other_tree.branch)
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
495
        reporter = CapturingReporter()
496
        this_tree.commit('do the commit', reporter=reporter)
497
        self.assertEqual([
1910.2.3 by Aaron Bentley
All tests pass
498
            ('change', 'unchanged', ''),
1668.1.5 by Martin Pool
[broken] fix up display of files changed by a commit
499
            ('change', 'unchanged', 'dirtoleave'),
500
            ('change', 'unchanged', 'filetoleave'),
501
            ('change', 'modified', 'filetomodify'),
502
            ('change', 'added', 'newdir'),
503
            ('change', 'added', 'newfile'),
504
            ('renamed', 'renamed', 'dirtorename', 'renameddir'),
505
            ('renamed', 'renamed', 'dirtoreparent', 'renameddir/reparenteddir'),
506
            ('renamed', 'renamed', 'filetoreparent', 'renameddir/reparentedfile'),
507
            ('renamed', 'renamed', 'filetorename', 'renamedfile'),
508
            ('deleted', 'dirtoremove'),
509
            ('deleted', 'filetoremove'),
510
            ],
511
            reporter.calls)
1551.7.24 by Aaron Bentley
Ensure commit respects file spec when committing removals
512
513
    def test_commit_removals_respects_filespec(self):
514
        """Commit respects the specified_files for removals."""
515
        tree = self.make_branch_and_tree('.')
516
        self.build_tree(['a', 'b'])
517
        tree.add(['a', 'b'])
518
        tree.commit('added a, b')
519
        tree.remove(['a', 'b'])
1906.1.1 by Robert Collins
(robertc) Trivial change to test_commit_removals_respects_filespec to be easir to read.
520
        tree.commit('removed a', specific_files='a')
1551.7.24 by Aaron Bentley
Ensure commit respects file spec when committing removals
521
        basis = tree.basis_tree().inventory
522
        self.assertIs(None, basis.path2id('a'))
523
        self.assertFalse(basis.path2id('b') is None)
1864.2.1 by John Arbash Meinel
Commit timestamp restricted to 1ms precision.
524
525
    def test_commit_saves_1ms_timestamp(self):
526
        """Passing in a timestamp is saved with 1ms resolution"""
527
        tree = self.make_branch_and_tree('.')
528
        self.build_tree(['a'])
529
        tree.add('a')
530
        tree.commit('added a', timestamp=1153248633.4186721, timezone=0,
531
                    rev_id='a1')
532
533
        rev = tree.branch.repository.get_revision('a1')
534
        self.assertEqual(1153248633.419, rev.timestamp)
535
536
    def test_commit_has_1ms_resolution(self):
537
        """Allowing commit to generate the timestamp also has 1ms resolution"""
538
        tree = self.make_branch_and_tree('.')
539
        self.build_tree(['a'])
540
        tree.add('a')
541
        tree.commit('added a', rev_id='a1')
542
543
        rev = tree.branch.repository.get_revision('a1')
544
        timestamp = rev.timestamp
545
        timestamp_1ms = round(timestamp, 3)
546
        self.assertEqual(timestamp_1ms, timestamp)
1551.8.29 by Aaron Bentley
Stop accepting non-existant files in commit (#50793)
547
548
    def test_commit_unversioned_specified(self):
549
        """Commit should raise if specified files isn't in basis or worktree"""
550
        tree = self.make_branch_and_tree('.')
551
        self.assertRaises(errors.PathsNotVersionedError, tree.commit, 
552
                          'message', specific_files=['bogus'])