~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
 
 
 
2
#
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
12
 
 
 
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33
33
from bzrlib.osutils import (safe_unicode, rand_bytes, compact_date, 
34
34
                            local_time_offset)
35
35
from bzrlib.revision import NULL_REVISION, Revision
 
36
from bzrlib.revisiontree import RevisionTree
36
37
from bzrlib.store.versioned import VersionedFileStore, WeaveStore
37
38
from bzrlib.store.text import TextStore
38
39
from bzrlib.symbol_versioning import (deprecated_method,
39
40
        zero_nine, 
40
41
        )
 
42
from bzrlib.testament import Testament
41
43
from bzrlib.trace import mutter, note
42
 
from bzrlib.tree import RevisionTree, EmptyTree
43
44
from bzrlib.tsort import topo_sort
44
 
from bzrlib.testament import Testament
45
 
from bzrlib.tree import EmptyTree
46
45
from bzrlib.weave import WeaveFile
47
46
 
48
47
 
347
346
                     t in self.revision_trees(required_trees))
348
347
        for revision in revisions:
349
348
            if not revision.parent_ids:
350
 
                old_tree = EmptyTree()
 
349
                old_tree = self.revision_tree(None)
351
350
            else:
352
351
                old_tree = trees[revision.parent_ids[0]]
353
 
            yield delta.compare_trees(old_tree, trees[revision.revision_id])
 
352
            yield trees[revision.revision_id].changes_from(old_tree)
354
353
 
355
354
    @needs_read_lock
356
355
    def get_revision_delta(self, revision_id):
565
564
    def revision_tree(self, revision_id):
566
565
        """Return Tree for a revision on this branch.
567
566
 
568
 
        `revision_id` may be None for the null revision, in which case
569
 
        an `EmptyTree` is returned."""
 
567
        `revision_id` may be None for the empty tree revision.
 
568
        """
570
569
        # TODO: refactor this to use an existing revision object
571
570
        # so we don't need to read it in twice.
572
571
        if revision_id is None or revision_id == NULL_REVISION:
573
 
            return EmptyTree()
 
572
            return RevisionTree(self, Inventory(), NULL_REVISION)
574
573
        else:
575
574
            inv = self.get_revision_inventory(revision_id)
576
575
            return RevisionTree(self, inv, revision_id)
746
745
            present_parents.append(p_id)
747
746
            parent_trees[p_id] = repository.revision_tree(p_id)
748
747
        else:
749
 
            parent_trees[p_id] = EmptyTree()
 
748
            parent_trees[p_id] = repository.revision_tree(None)
750
749
 
751
750
    inv = revision_tree.inventory
752
751
    
 
752
    # backwards compatability hack: skip the root id.
 
753
    entries = inv.iter_entries()
 
754
    entries.next()
753
755
    # Add the texts that are not already present
754
 
    for path, ie in inv.iter_entries():
 
756
    for path, ie in entries:
755
757
        w = repository.weave_store.get_weave_or_empty(ie.file_id,
756
758
                repository.get_transaction())
757
759
        if ie.revision not in w:
1579
1581
            return
1580
1582
        self.target.fetch(self.source, revision_id=revision_id)
1581
1583
 
1582
 
    def _double_lock(self, lock_source, lock_target):
1583
 
        """Take out too locks, rolling back the first if the second throws."""
1584
 
        lock_source()
1585
 
        try:
1586
 
            lock_target()
1587
 
        except Exception:
1588
 
            # we want to ensure that we don't leave source locked by mistake.
1589
 
            # and any error on target should not confuse source.
1590
 
            self.source.unlock()
1591
 
            raise
1592
 
 
1593
1584
    @needs_write_lock
1594
1585
    def fetch(self, revision_id=None, pb=None):
1595
1586
        """Fetch the content required to construct revision_id.
1613
1604
                               pb=pb)
1614
1605
        return f.count_copied, f.failed_revisions
1615
1606
 
1616
 
    def lock_read(self):
1617
 
        """Take out a logical read lock.
1618
 
 
1619
 
        This will lock the source branch and the target branch. The source gets
1620
 
        a read lock and the target a read lock.
1621
 
        """
1622
 
        self._double_lock(self.source.lock_read, self.target.lock_read)
1623
 
 
1624
 
    def lock_write(self):
1625
 
        """Take out a logical write lock.
1626
 
 
1627
 
        This will lock the source branch and the target branch. The source gets
1628
 
        a read lock and the target a write lock.
1629
 
        """
1630
 
        self._double_lock(self.source.lock_read, self.target.lock_write)
1631
 
 
1632
1607
    @needs_read_lock
1633
1608
    def missing_revision_ids(self, revision_id=None):
1634
1609
        """Return the revision ids that source has that target does not.
1652
1627
        # that we've decided we need.
1653
1628
        return [rev_id for rev_id in source_ids if rev_id in result_set]
1654
1629
 
1655
 
    def unlock(self):
1656
 
        """Release the locks on source and target."""
1657
 
        try:
1658
 
            self.target.unlock()
1659
 
        finally:
1660
 
            self.source.unlock()
1661
 
 
1662
1630
 
1663
1631
class InterWeaveRepo(InterRepository):
1664
1632
    """Optimised code paths between Weave based repositories."""
2014
1982
            self._revprops.update(revprops)
2015
1983
 
2016
1984
        if timestamp is None:
2017
 
            self._timestamp = time.time()
2018
 
        else:
2019
 
            self._timestamp = long(timestamp)
 
1985
            timestamp = time.time()
 
1986
        # Restrict resolution to 1ms
 
1987
        self._timestamp = round(timestamp, 3)
2020
1988
 
2021
1989
        if timezone is None:
2022
1990
            self._timezone = local_time_offset()
2115
2083
        :param text_sha1: Optional SHA1 of the file contents.
2116
2084
        :param text_size: Optional size of the file contents.
2117
2085
        """
2118
 
        mutter('storing text of file {%s} in revision {%s} into %r',
2119
 
               file_id, self._new_revision_id, self.repository.weave_store)
 
2086
        # mutter('storing text of file {%s} in revision {%s} into %r',
 
2087
        #        file_id, self._new_revision_id, self.repository.weave_store)
2120
2088
        # special case to avoid diffing on renames or 
2121
2089
        # reparenting
2122
2090
        if (len(file_parents) == 1