83
86
from bzrlib.testament import Testament
84
87
from bzrlib.trace import mutter, note, warning
85
88
from bzrlib.xml5 import serializer_v5
86
from bzrlib.inventory import Inventory, ROOT_ID, InventoryEntry
89
from bzrlib.inventory import Inventory, InventoryEntry
87
90
from bzrlib import symbol_versioning
88
91
from bzrlib.symbol_versioning import (deprecated_passed,
89
92
deprecated_function,
123
126
def snapshot_change(self, change, path):
124
127
if change == 'unchanged':
129
if change == 'added' and path == '':
126
131
note("%s %s", change, path)
128
133
def completed(self, revno, rev_id):
277
282
self.work_inv = self.work_tree.inventory
278
283
self.basis_tree = self.work_tree.basis_tree()
279
284
self.basis_inv = self.basis_tree.inventory
285
if specific_files is not None:
286
# Ensure specified files are versioned
287
# (We don't actually need the ids here)
288
tree.find_ids_across_trees(specific_files,
289
[self.basis_tree, self.work_tree])
280
290
# one to finish, one for rev and inventory, and one for each
281
291
# inventory entry, and the same for the new inventory.
282
292
# note that this estimate is too long when we do a partial tree
324
334
# and now do the commit locally.
325
335
self.branch.append_revision(self.rev_id)
327
# if the builder gave us the revisiontree it created back, we
328
# could use it straight away here.
329
# TODO: implement this.
330
self.work_tree.set_parent_trees([(self.rev_id,
331
self.branch.repository.revision_tree(self.rev_id))])
337
rev_tree = self.builder.revision_tree()
338
self.work_tree.set_parent_trees([(self.rev_id, rev_tree)])
332
339
# now the work tree is up to date with the branch
334
341
self.reporter.completed(self.branch.revno(), self.rev_id)
346
353
return self.rev_id
355
def _any_real_changes(self):
356
"""Are there real changes between new_inventory and basis?
358
For trees without rich roots, inv.root.revision changes every commit.
359
But if that is the only change, we want to treat it as though there
362
new_entries = self.builder.new_inventory.iter_entries()
363
basis_entries = self.basis_inv.iter_entries()
364
new_path, new_root_ie = new_entries.next()
365
basis_path, basis_root_ie = basis_entries.next()
367
# This is a copy of InventoryEntry.__eq__ only leaving out .revision
368
def ie_equal_no_revision(this, other):
369
return ((this.file_id == other.file_id)
370
and (this.name == other.name)
371
and (this.symlink_target == other.symlink_target)
372
and (this.text_sha1 == other.text_sha1)
373
and (this.text_size == other.text_size)
374
and (this.text_id == other.text_id)
375
and (this.parent_id == other.parent_id)
376
and (this.kind == other.kind)
377
and (this.executable == other.executable)
379
if not ie_equal_no_revision(new_root_ie, basis_root_ie):
382
for new_ie, basis_ie in zip(new_entries, basis_entries):
383
if new_ie != basis_ie:
386
# No actual changes present
348
389
def _check_pointless(self):
349
390
if self.allow_pointless:
354
395
# work around the fact that a newly-initted tree does differ from its
397
if len(self.basis_inv) == 0 and len(self.builder.new_inventory) == 1:
398
raise PointlessCommit()
399
# Shortcut, if the number of entries changes, then we obviously have
356
401
if len(self.builder.new_inventory) != len(self.basis_inv):
358
if (len(self.builder.new_inventory) != 1 and
359
self.builder.new_inventory != self.basis_inv):
403
# If length == 1, then we only have the root entry. Which means
404
# that there is no real difference (only the root could be different)
405
if (len(self.builder.new_inventory) != 1 and self._any_real_changes()):
361
407
raise PointlessCommit()
510
556
# in bugs like #46635. Any reason not to use/enhance Tree.changes_from?
511
557
# ADHB 11-07-2006
512
558
mutter("Selecting files for commit with filter %s", self.specific_files)
559
assert self.work_inv.root is not None
513
560
entries = self.work_inv.iter_entries()
514
561
if not self.builder.record_root_entry:
515
562
symbol_versioning.warn('CommitBuilders should support recording'