~bzr-pqm/bzr/bzr.dev

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