1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
78
79
from bzrlib.testament import Testament
79
80
from bzrlib.trace import mutter, note, warning, is_quiet
80
from bzrlib.inventory import InventoryEntry, make_entry
81
from bzrlib.inventory import Inventory, InventoryEntry, make_entry
81
82
from bzrlib import symbol_versioning
82
83
from bzrlib.symbol_versioning import (deprecated_passed,
83
84
deprecated_function,
283
285
self.committer = committer
284
286
self.strict = strict
285
287
self.verbose = verbose
286
# accumulates an inventory delta to the basis entry, so we can make
287
# just the necessary updates to the workingtree's cached basis.
288
self._basis_delta = []
290
289
self.work_tree.lock_write()
291
290
self.pb = bzrlib.ui.ui_factory.nested_progress_bar()
298
297
raise ConflictsInTree
300
299
# Setup the bound branch variables as needed.
301
self._check_bound_branch()
300
self._check_bound_branch(possible_master_transports)
303
302
# Check that the working tree is up to date
304
303
old_revno, new_revno = self._check_out_of_date_tree()
353
352
entries_title="Directory")
354
353
self.builder = self.branch.get_commit_builder(self.parents,
355
354
self.config, timestamp, timezone, committer, revprops, rev_id)
357
self.builder.will_record_deletes()
358
358
# find the location being committed to
359
359
if self.bound_branch:
360
360
master_location = self.master_branch.base
383
383
# Add revision data to the local branch
384
384
self.rev_id = self.builder.commit(self.message)
387
mutter("aborting commit write group because of exception:")
388
trace.log_exception_quietly()
389
note("aborting commit write group: %r" % (e,))
387
390
self.builder.abort()
409
412
# Make the working tree up to date with the branch
410
413
self._set_progress_stage("Updating the working tree")
411
414
self.work_tree.update_basis_by_delta(self.rev_id,
415
self.builder.get_basis_delta())
413
416
self.reporter.completed(new_revno, self.rev_id)
414
417
self._process_post_hooks(old_revno, new_revno)
428
431
# A merge with no effect on files
429
432
if len(self.parents) > 1:
431
# TODO: we could simplify this by using self._basis_delta.
434
# TODO: we could simplify this by using self.builder.basis_delta.
433
436
# The initial commit adds a root directory, but this in itself is not
434
437
# a worthwhile commit.
445
448
raise PointlessCommit()
447
def _check_bound_branch(self):
450
def _check_bound_branch(self, possible_master_transports=None):
448
451
"""Check to see if the local branch is bound.
450
453
If it is bound, then most of the commit will actually be
455
458
raise errors.LocalRequiresBoundBranch()
457
460
if not self.local:
458
self.master_branch = self.branch.get_master_branch()
461
self.master_branch = self.branch.get_master_branch(
462
possible_master_transports)
460
464
if not self.master_branch:
461
465
# make this branch the reference branch for out of date checks.
690
694
# required after that changes.
691
695
if len(self.parents) > 1:
692
696
ie.revision = None
693
delta, version_recorded, _ = self.builder.record_entry_contents(
697
_, version_recorded, _ = self.builder.record_entry_contents(
694
698
ie, self.parent_invs, path, self.basis_tree, None)
695
699
if version_recorded:
696
700
self.any_entries_changed = True
698
self._basis_delta.append(delta)
700
702
def _report_and_accumulate_deletes(self):
701
703
# XXX: Could the list of deleted paths and ids be instead taken from
702
704
# _populate_from_inventory?
703
deleted_ids = set(self.basis_inv._byid.keys()) - \
704
set(self.builder.new_inventory._byid.keys())
705
if (isinstance(self.basis_inv, Inventory)
706
and isinstance(self.builder.new_inventory, Inventory)):
707
# the older Inventory classes provide a _byid dict, and building a
708
# set from the keys of this dict is substantially faster than even
709
# getting a set of ids from the inventory
711
# <lifeless> set(dict) is roughly the same speed as
712
# set(iter(dict)) and both are significantly slower than
714
deleted_ids = set(self.basis_inv._byid.keys()) - \
715
set(self.builder.new_inventory._byid.keys())
717
deleted_ids = set(self.basis_inv) - set(self.builder.new_inventory)
706
719
self.any_entries_deleted = True
707
720
deleted = [(self.basis_tree.id2path(file_id), file_id)
710
723
# XXX: this is not quite directory-order sorting
711
724
for path, file_id in deleted:
712
self._basis_delta.append((path, None, file_id, None))
725
self.builder.record_delete(path, file_id)
713
726
self.reporter.deleted(path)
715
728
def _populate_from_inventory(self):
846
859
ie.revision = None
847
860
# For carried over entries we don't care about the fs hash - the repo
848
861
# isn't generating a sha, so we're not saving computation time.
849
delta, version_recorded, fs_hash = self.builder.record_entry_contents(
862
_, version_recorded, fs_hash = self.builder.record_entry_contents(
850
863
ie, self.parent_invs, path, self.work_tree, content_summary)
852
self._basis_delta.append(delta)
853
864
if version_recorded:
854
865
self.any_entries_changed = True
855
866
if report_changes: