bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
1553.5.56
by Martin Pool
 Format 7 repo now uses LockDir!  | 
1  | 
# Copyright (C) 2005, 2006 Canonical Ltd
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
2  | 
|
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.
 | 
|
7  | 
||
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.
 | 
|
12  | 
||
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
 | 
|
| 
1185.65.10
by Robert Collins
 Rename Controlfiles to LockableFiles.  | 
16  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
17  | 
from copy import deepcopy  | 
| 
1185.65.10
by Robert Collins
 Rename Controlfiles to LockableFiles.  | 
18  | 
from cStringIO import StringIO  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
19  | 
from unittest import TestSuite  | 
| 
1553.5.70
by Martin Pool
 doc  | 
20  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
21  | 
import bzrlib.bzrdir as bzrdir  | 
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
22  | 
from bzrlib.decorators import needs_read_lock, needs_write_lock  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
23  | 
import bzrlib.errors as errors  | 
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
24  | 
from bzrlib.errors import InvalidRevisionId  | 
| 
1570.1.2
by Robert Collins
 Import bzrtools' 'fix' command as 'bzr reconcile.'  | 
25  | 
import bzrlib.gpg as gpg  | 
| 
1594.2.3
by Robert Collins
 bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.  | 
26  | 
from bzrlib.graph import Graph  | 
| 
1563.2.12
by Robert Collins
 Checkpointing: created InterObject to factor out common inter object worker code, added InterVersionedFile and tests to allow making join work between any versionedfile.  | 
27  | 
from bzrlib.inter import InterObject  | 
| 
1628.1.4
by Robert Collins
 Change knit format to use non-delta, non-annotated revisions and signatures.  | 
28  | 
from bzrlib.knit import KnitVersionedFile, KnitPlainFactory  | 
| 
1553.5.56
by Martin Pool
 Format 7 repo now uses LockDir!  | 
29  | 
from bzrlib.lockable_files import LockableFiles, TransportLock  | 
| 
1553.5.49
by Martin Pool
 Use LockDirs for repo format 7  | 
30  | 
from bzrlib.lockdir import LockDir  | 
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
31  | 
from bzrlib.osutils import safe_unicode  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
32  | 
from bzrlib.revision import NULL_REVISION  | 
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
33  | 
from bzrlib.store.versioned import VersionedFileStore, WeaveStore  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
34  | 
from bzrlib.store.text import TextStore  | 
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
35  | 
from bzrlib.symbol_versioning import *  | 
| 
1608.2.1
by Martin Pool
 [merge] Storage filename escaping  | 
36  | 
from bzrlib.trace import mutter, note  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
37  | 
from bzrlib.tree import RevisionTree  | 
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
38  | 
from bzrlib.tsort import topo_sort  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
39  | 
from bzrlib.testament import Testament  | 
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
40  | 
from bzrlib.tree import EmptyTree  | 
| 
1185.79.2
by John Arbash Meinel
 Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves.  | 
41  | 
import bzrlib.ui  | 
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
42  | 
from bzrlib.weave import WeaveFile  | 
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
43  | 
import bzrlib.xml5  | 
| 
1185.70.3
by Martin Pool
 Various updates to make storage branch mergeable:  | 
44  | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
45  | 
|
| 
1185.66.5
by Aaron Bentley
 Renamed RevisionStorage to Repository  | 
46  | 
class Repository(object):  | 
| 
1185.70.3
by Martin Pool
 Various updates to make storage branch mergeable:  | 
47  | 
"""Repository holding history for one or more branches.  | 
48  | 
||
49  | 
    The repository holds and retrieves historical information including
 | 
|
50  | 
    revisions and file history.  It's normally accessed only by the Branch,
 | 
|
51  | 
    which views a particular line of development through that history.
 | 
|
52  | 
||
53  | 
    The Repository builds on top of Stores and a Transport, which respectively 
 | 
|
54  | 
    describe the disk data format and the way of accessing the (possibly 
 | 
|
55  | 
    remote) disk.
 | 
|
56  | 
    """
 | 
|
| 
1185.65.17
by Robert Collins
 Merge from integration, mode-changes are broken.  | 
57  | 
|
| 
1570.1.2
by Robert Collins
 Import bzrtools' 'fix' command as 'bzr reconcile.'  | 
58  | 
    @needs_write_lock
 | 
59  | 
def add_inventory(self, revid, inv, parents):  | 
|
60  | 
"""Add the inventory inv to the repository as revid.  | 
|
61  | 
        
 | 
|
62  | 
        :param parents: The revision ids of the parents that revid
 | 
|
63  | 
                        is known to have and are in the repository already.
 | 
|
64  | 
||
65  | 
        returns the sha1 of the serialized inventory.
 | 
|
66  | 
        """
 | 
|
67  | 
inv_text = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)  | 
|
68  | 
inv_sha1 = bzrlib.osutils.sha_string(inv_text)  | 
|
| 
1563.2.25
by Robert Collins
 Merge in upstream.  | 
69  | 
inv_vf = self.control_weaves.get_weave('inventory',  | 
70  | 
self.get_transaction())  | 
|
71  | 
inv_vf.add_lines(revid, parents, bzrlib.osutils.split_lines(inv_text))  | 
|
| 
1570.1.2
by Robert Collins
 Import bzrtools' 'fix' command as 'bzr reconcile.'  | 
72  | 
return inv_sha1  | 
73  | 
||
74  | 
    @needs_write_lock
 | 
|
75  | 
def add_revision(self, rev_id, rev, inv=None, config=None):  | 
|
76  | 
"""Add rev to the revision store as rev_id.  | 
|
77  | 
||
78  | 
        :param rev_id: the revision id to use.
 | 
|
79  | 
        :param rev: The revision object.
 | 
|
80  | 
        :param inv: The inventory for the revision. if None, it will be looked
 | 
|
81  | 
                    up in the inventory storer
 | 
|
82  | 
        :param config: If None no digital signature will be created.
 | 
|
83  | 
                       If supplied its signature_needed method will be used
 | 
|
84  | 
                       to determine if a signature should be made.
 | 
|
85  | 
        """
 | 
|
86  | 
if config is not None and config.signature_needed():  | 
|
87  | 
if inv is None:  | 
|
88  | 
inv = self.get_inventory(rev_id)  | 
|
89  | 
plaintext = Testament(rev, inv).as_short_text()  | 
|
90  | 
self.store_revision_signature(  | 
|
91  | 
gpg.GPGStrategy(config), plaintext, rev_id)  | 
|
92  | 
if not rev_id in self.get_inventory_weave():  | 
|
93  | 
if inv is None:  | 
|
94  | 
raise errors.WeaveRevisionNotPresent(rev_id,  | 
|
95  | 
self.get_inventory_weave())  | 
|
96  | 
else:  | 
|
97  | 
                # yes, this is not suitable for adding with ghosts.
 | 
|
98  | 
self.add_inventory(rev_id, inv, rev.parent_ids)  | 
|
| 
1608.2.1
by Martin Pool
 [merge] Storage filename escaping  | 
99  | 
self._revision_store.add_revision(rev, self.get_transaction())  | 
| 
1570.1.2
by Robert Collins
 Import bzrtools' 'fix' command as 'bzr reconcile.'  | 
100  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
101  | 
    @needs_read_lock
 | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
102  | 
def _all_possible_ids(self):  | 
103  | 
"""Return all the possible revisions that we could find."""  | 
|
| 
1563.2.4
by Robert Collins
 First cut at including the knit implementation of versioned_file.  | 
104  | 
return self.get_inventory_weave().versions()  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
105  | 
|
106  | 
    @needs_read_lock
 | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
107  | 
def all_revision_ids(self):  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
108  | 
"""Returns a list of all the revision ids in the repository.  | 
109  | 
||
110  | 
        These are in as much topological order as the underlying store can 
 | 
|
111  | 
        present: for weaves ghosts may lead to a lack of correctness until
 | 
|
112  | 
        the reweave updates the parents list.
 | 
|
113  | 
        """
 | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
114  | 
if self._revision_store.text_store.listable():  | 
115  | 
return self._revision_store.all_revision_ids(self.get_transaction())  | 
|
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
116  | 
result = self._all_possible_ids()  | 
117  | 
return self._eliminate_revisions_not_present(result)  | 
|
118  | 
||
119  | 
    @needs_read_lock
 | 
|
120  | 
def _eliminate_revisions_not_present(self, revision_ids):  | 
|
121  | 
"""Check every revision id in revision_ids to see if we have it.  | 
|
122  | 
||
123  | 
        Returns a set of the present revisions.
 | 
|
124  | 
        """
 | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
125  | 
result = []  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
126  | 
for id in revision_ids:  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
127  | 
if self.has_revision(id):  | 
128  | 
result.append(id)  | 
|
129  | 
return result  | 
|
130  | 
||
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
131  | 
    @staticmethod
 | 
132  | 
def create(a_bzrdir):  | 
|
133  | 
"""Construct the current default format repository in a_bzrdir."""  | 
|
134  | 
return RepositoryFormat.get_default_format().initialize(a_bzrdir)  | 
|
135  | 
||
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
136  | 
def __init__(self, _format, a_bzrdir, control_files, _revision_store, control_store, text_store):  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
137  | 
"""instantiate a Repository.  | 
138  | 
||
139  | 
        :param _format: The format of the repository on disk.
 | 
|
140  | 
        :param a_bzrdir: The BzrDir of the repository.
 | 
|
141  | 
||
142  | 
        In the future we will have a single api for all stores for
 | 
|
143  | 
        getting file texts, inventories and revisions, then
 | 
|
144  | 
        this construct will accept instances of those things.
 | 
|
145  | 
        """
 | 
|
| 
1608.2.1
by Martin Pool
 [merge] Storage filename escaping  | 
146  | 
super(Repository, self).__init__()  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
147  | 
self._format = _format  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
148  | 
        # the following are part of the public API for Repository:
 | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
149  | 
self.bzrdir = a_bzrdir  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
150  | 
self.control_files = control_files  | 
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
151  | 
self._revision_store = _revision_store  | 
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
152  | 
self.text_store = text_store  | 
153  | 
        # backwards compatability
 | 
|
154  | 
self.weave_store = text_store  | 
|
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
155  | 
        # not right yet - should be more semantically clear ? 
 | 
156  | 
        # 
 | 
|
157  | 
self.control_store = control_store  | 
|
158  | 
self.control_weaves = control_store  | 
|
| 
1608.2.1
by Martin Pool
 [merge] Storage filename escaping  | 
159  | 
        # TODO: make sure to construct the right store classes, etc, depending
 | 
160  | 
        # on whether escaping is required.
 | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
161  | 
|
162  | 
def lock_write(self):  | 
|
163  | 
self.control_files.lock_write()  | 
|
164  | 
||
165  | 
def lock_read(self):  | 
|
| 
1553.5.55
by Martin Pool
 [revert] broken changes  | 
166  | 
self.control_files.lock_read()  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
167  | 
|
| 
1553.5.35
by Martin Pool
 Start break-lock --show  | 
168  | 
def is_locked(self):  | 
169  | 
return self.control_files.is_locked()  | 
|
170  | 
||
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
171  | 
    @needs_read_lock
 | 
172  | 
def missing_revision_ids(self, other, revision_id=None):  | 
|
173  | 
"""Return the revision ids that other has that this does not.  | 
|
174  | 
        
 | 
|
175  | 
        These are returned in topological order.
 | 
|
176  | 
||
177  | 
        revision_id: only return revision ids included by revision_id.
 | 
|
178  | 
        """
 | 
|
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
179  | 
return InterRepository.get(other, self).missing_revision_ids(revision_id)  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
180  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
181  | 
    @staticmethod
 | 
182  | 
def open(base):  | 
|
183  | 
"""Open the repository rooted at base.  | 
|
184  | 
||
185  | 
        For instance, if the repository is at URL/.bzr/repository,
 | 
|
186  | 
        Repository.open(URL) -> a Repository instance.
 | 
|
187  | 
        """
 | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
188  | 
control = bzrlib.bzrdir.BzrDir.open(base)  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
189  | 
return control.open_repository()  | 
190  | 
||
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
191  | 
def copy_content_into(self, destination, revision_id=None, basis=None):  | 
| 
1534.6.6
by Robert Collins
 Move find_repository to bzrdir, its not quite ideal there but its simpler and until someone chooses to vary the search by branch type its completely sufficient.  | 
192  | 
"""Make a complete copy of the content in self into destination.  | 
193  | 
        
 | 
|
194  | 
        This is a destructive operation! Do not use it on existing 
 | 
|
195  | 
        repositories.
 | 
|
196  | 
        """
 | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
197  | 
return InterRepository.get(self, destination).copy_content(revision_id, basis)  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
198  | 
|
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
199  | 
def fetch(self, source, revision_id=None, pb=None):  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
200  | 
"""Fetch the content required to construct revision_id from source.  | 
201  | 
||
202  | 
        If revision_id is None all content is copied.
 | 
|
203  | 
        """
 | 
|
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
204  | 
return InterRepository.get(source, self).fetch(revision_id=revision_id,  | 
205  | 
pb=pb)  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
206  | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
207  | 
def unlock(self):  | 
208  | 
self.control_files.unlock()  | 
|
209  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
210  | 
    @needs_read_lock
 | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
211  | 
def clone(self, a_bzrdir, revision_id=None, basis=None):  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
212  | 
"""Clone this repository into a_bzrdir using the current format.  | 
213  | 
||
214  | 
        Currently no check is made that the format of this repository and
 | 
|
215  | 
        the bzrdir format are compatible. FIXME RBC 20060201.
 | 
|
216  | 
        """
 | 
|
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
217  | 
if not isinstance(a_bzrdir._format, self.bzrdir._format.__class__):  | 
218  | 
            # use target default format.
 | 
|
219  | 
result = a_bzrdir.create_repository()  | 
|
220  | 
        # FIXME RBC 20060209 split out the repository type to avoid this check ?
 | 
|
221  | 
elif isinstance(a_bzrdir._format,  | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
222  | 
(bzrlib.bzrdir.BzrDirFormat4,  | 
223  | 
bzrlib.bzrdir.BzrDirFormat5,  | 
|
224  | 
bzrlib.bzrdir.BzrDirFormat6)):  | 
|
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
225  | 
result = a_bzrdir.open_repository()  | 
226  | 
else:  | 
|
| 
1534.6.5
by Robert Collins
 Cloning of repos preserves shared and make-working-tree attributes.  | 
227  | 
result = self._format.initialize(a_bzrdir, shared=self.is_shared())  | 
| 
1534.4.50
by Robert Collins
 Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.  | 
228  | 
self.copy_content_into(result, revision_id, basis)  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
229  | 
return result  | 
230  | 
||
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
231  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
232  | 
def has_revision(self, revision_id):  | 
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
233  | 
"""True if this repository has a copy of the revision."""  | 
234  | 
return self._revision_store.has_revision_id(revision_id,  | 
|
235  | 
self.get_transaction())  | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
236  | 
|
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
237  | 
    @needs_read_lock
 | 
| 
1570.1.13
by Robert Collins
 Check for incorrect revision parentage in the weave during revision access.  | 
238  | 
def get_revision_reconcile(self, revision_id):  | 
239  | 
"""'reconcile' helper routine that allows access to a revision always.  | 
|
240  | 
        
 | 
|
241  | 
        This variant of get_revision does not cross check the weave graph
 | 
|
242  | 
        against the revision one as get_revision does: but it should only
 | 
|
243  | 
        be used by reconcile, or reconcile-alike commands that are correcting
 | 
|
244  | 
        or testing the revision graph.
 | 
|
245  | 
        """
 | 
|
| 
1563.2.25
by Robert Collins
 Merge in upstream.  | 
246  | 
if not revision_id or not isinstance(revision_id, basestring):  | 
247  | 
raise InvalidRevisionId(revision_id=revision_id, branch=self)  | 
|
248  | 
return self._revision_store.get_revision(revision_id,  | 
|
249  | 
self.get_transaction())  | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
250  | 
|
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
251  | 
    @needs_read_lock
 | 
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
252  | 
def get_revision_xml(self, revision_id):  | 
253  | 
rev = self.get_revision(revision_id)  | 
|
254  | 
rev_tmp = StringIO()  | 
|
255  | 
        # the current serializer..
 | 
|
256  | 
self._revision_store._serializer.write_revision(rev, rev_tmp)  | 
|
257  | 
rev_tmp.seek(0)  | 
|
258  | 
return rev_tmp.getvalue()  | 
|
259  | 
||
260  | 
    @needs_read_lock
 | 
|
| 
1570.1.13
by Robert Collins
 Check for incorrect revision parentage in the weave during revision access.  | 
261  | 
def get_revision(self, revision_id):  | 
262  | 
"""Return the Revision object for a named revision"""  | 
|
263  | 
r = self.get_revision_reconcile(revision_id)  | 
|
264  | 
        # weave corruption can lead to absent revision markers that should be
 | 
|
265  | 
        # present.
 | 
|
266  | 
        # the following test is reasonably cheap (it needs a single weave read)
 | 
|
267  | 
        # and the weave is cached in read transactions. In write transactions
 | 
|
268  | 
        # it is not cached but typically we only read a small number of
 | 
|
269  | 
        # revisions. For knits when they are introduced we will probably want
 | 
|
270  | 
        # to ensure that caching write transactions are in use.
 | 
|
271  | 
inv = self.get_inventory_weave()  | 
|
| 
1570.1.14
by Robert Collins
 Enforce repository consistency during 'fetch' operations.  | 
272  | 
self._check_revision_parents(r, inv)  | 
273  | 
return r  | 
|
274  | 
||
275  | 
def _check_revision_parents(self, revision, inventory):  | 
|
276  | 
"""Private to Repository and Fetch.  | 
|
277  | 
        
 | 
|
278  | 
        This checks the parentage of revision in an inventory weave for 
 | 
|
279  | 
        consistency and is only applicable to inventory-weave-for-ancestry
 | 
|
280  | 
        using repository formats & fetchers.
 | 
|
281  | 
        """
 | 
|
| 
1563.2.25
by Robert Collins
 Merge in upstream.  | 
282  | 
weave_parents = inventory.get_parents(revision.revision_id)  | 
283  | 
weave_names = inventory.versions()  | 
|
| 
1570.1.14
by Robert Collins
 Enforce repository consistency during 'fetch' operations.  | 
284  | 
for parent_id in revision.parent_ids:  | 
| 
1570.1.13
by Robert Collins
 Check for incorrect revision parentage in the weave during revision access.  | 
285  | 
if parent_id in weave_names:  | 
286  | 
                # this parent must not be a ghost.
 | 
|
287  | 
if not parent_id in weave_parents:  | 
|
288  | 
                    # but it is a ghost
 | 
|
289  | 
raise errors.CorruptRepository(self)  | 
|
290  | 
||
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
291  | 
    @needs_write_lock
 | 
292  | 
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
293  | 
signature = gpg_strategy.sign(plaintext)  | 
294  | 
self._revision_store.add_revision_signature_text(revision_id,  | 
|
295  | 
signature,  | 
|
296  | 
self.get_transaction())  | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
297  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
298  | 
def fileid_involved_between_revs(self, from_revid, to_revid):  | 
299  | 
"""Find file_id(s) which are involved in the changes between revisions.  | 
|
300  | 
||
301  | 
        This determines the set of revisions which are involved, and then
 | 
|
302  | 
        finds all file ids affected by those revisions.
 | 
|
303  | 
        """
 | 
|
304  | 
w = self.get_inventory_weave()  | 
|
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
305  | 
from_set = set(w.get_ancestry(from_revid))  | 
306  | 
to_set = set(w.get_ancestry(to_revid))  | 
|
307  | 
changed = to_set.difference(from_set)  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
308  | 
return self._fileid_involved_by_set(changed)  | 
309  | 
||
310  | 
def fileid_involved(self, last_revid=None):  | 
|
311  | 
"""Find all file_ids modified in the ancestry of last_revid.  | 
|
312  | 
||
313  | 
        :param last_revid: If None, last_revision() will be used.
 | 
|
314  | 
        """
 | 
|
315  | 
w = self.get_inventory_weave()  | 
|
316  | 
if not last_revid:  | 
|
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
317  | 
changed = set(w.versions())  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
318  | 
else:  | 
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
319  | 
changed = set(w.get_ancestry(last_revid))  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
320  | 
return self._fileid_involved_by_set(changed)  | 
321  | 
||
322  | 
def fileid_involved_by_set(self, changes):  | 
|
323  | 
"""Find all file_ids modified by the set of revisions passed in.  | 
|
324  | 
||
325  | 
        :param changes: A set() of revision ids
 | 
|
326  | 
        """
 | 
|
327  | 
        # TODO: jam 20060119 This line does *nothing*, remove it.
 | 
|
328  | 
        #       or better yet, change _fileid_involved_by_set so
 | 
|
329  | 
        #       that it takes the inventory weave, rather than
 | 
|
330  | 
        #       pulling it out by itself.
 | 
|
331  | 
return self._fileid_involved_by_set(changes)  | 
|
332  | 
||
333  | 
def _fileid_involved_by_set(self, changes):  | 
|
334  | 
"""Find the set of file-ids affected by the set of revisions.  | 
|
335  | 
||
336  | 
        :param changes: A set() of revision ids.
 | 
|
337  | 
        :return: A set() of file ids.
 | 
|
338  | 
        
 | 
|
339  | 
        This peaks at the Weave, interpreting each line, looking to
 | 
|
340  | 
        see if it mentions one of the revisions. And if so, includes
 | 
|
341  | 
        the file id mentioned.
 | 
|
342  | 
        This expects both the Weave format, and the serialization
 | 
|
343  | 
        to have a single line per file/directory, and to have
 | 
|
344  | 
        fileid="" and revision="" on that line.
 | 
|
345  | 
        """
 | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
346  | 
assert isinstance(self._format, (RepositoryFormat5,  | 
347  | 
RepositoryFormat6,  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
348  | 
RepositoryFormat7,  | 
349  | 
RepositoryFormatKnit1)), \  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
350  | 
            "fileid_involved only supported for branches which store inventory as unnested xml"
 | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
351  | 
|
352  | 
w = self.get_inventory_weave()  | 
|
353  | 
file_ids = set()  | 
|
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
354  | 
|
| 
1594.2.6
by Robert Collins
 Introduce a api specifically for looking at lines in some versions of the inventory, for fileid_involved.  | 
355  | 
        # this code needs to read every line in every inventory for the
 | 
356  | 
        # inventories [changes]. Seeing a line twice is ok. Seeing a line
 | 
|
357  | 
        # not pesent in one of those inventories is unnecessary and not 
 | 
|
358  | 
        # harmful because we are filtering by the revision id marker in the
 | 
|
359  | 
        # inventory lines to only select file ids altered in one of those  
 | 
|
360  | 
        # revisions. We dont need to see all lines in the inventory because
 | 
|
361  | 
        # only those added in an inventory in rev X can contain a revision=X
 | 
|
362  | 
        # line.
 | 
|
363  | 
for line in w.iter_lines_added_or_present_in_versions(changes):  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
364  | 
start = line.find('file_id="')+9  | 
365  | 
if start < 9: continue  | 
|
366  | 
end = line.find('"', start)  | 
|
367  | 
assert end>= 0  | 
|
| 
1596.1.1
by Martin Pool
 Use simple xml unescaping rather than importing xml.sax  | 
368  | 
file_id = _unescape_xml(line[start:end])  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
369  | 
|
370  | 
            # check if file_id is already present
 | 
|
371  | 
if file_id in file_ids: continue  | 
|
372  | 
||
373  | 
start = line.find('revision="')+10  | 
|
374  | 
if start < 10: continue  | 
|
375  | 
end = line.find('"', start)  | 
|
376  | 
assert end>= 0  | 
|
| 
1596.1.1
by Martin Pool
 Use simple xml unescaping rather than importing xml.sax  | 
377  | 
revision_id = _unescape_xml(line[start:end])  | 
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
378  | 
if revision_id in changes:  | 
379  | 
file_ids.add(file_id)  | 
|
380  | 
return file_ids  | 
|
381  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
382  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
383  | 
def get_inventory_weave(self):  | 
384  | 
return self.control_weaves.get_weave('inventory',  | 
|
385  | 
self.get_transaction())  | 
|
386  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
387  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
388  | 
def get_inventory(self, revision_id):  | 
389  | 
"""Get Inventory object by hash."""  | 
|
390  | 
xml = self.get_inventory_xml(revision_id)  | 
|
391  | 
return bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)  | 
|
392  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
393  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
394  | 
def get_inventory_xml(self, revision_id):  | 
395  | 
"""Get inventory XML as a file object."""  | 
|
396  | 
try:  | 
|
397  | 
assert isinstance(revision_id, basestring), type(revision_id)  | 
|
398  | 
iw = self.get_inventory_weave()  | 
|
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
399  | 
return iw.get_text(revision_id)  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
400  | 
except IndexError:  | 
401  | 
raise bzrlib.errors.HistoryMissing(self, 'inventory', revision_id)  | 
|
402  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
403  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
404  | 
def get_inventory_sha1(self, revision_id):  | 
405  | 
"""Return the sha1 hash of the inventory entry  | 
|
406  | 
        """
 | 
|
407  | 
return self.get_revision(revision_id).inventory_sha1  | 
|
408  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
409  | 
    @needs_read_lock
 | 
| 
1590.1.1
by Robert Collins
 Improve common_ancestor performance.  | 
410  | 
def get_revision_graph(self, revision_id=None):  | 
411  | 
"""Return a dictionary containing the revision graph.  | 
|
412  | 
        
 | 
|
413  | 
        :return: a dictionary of revision_id->revision_parents_list.
 | 
|
414  | 
        """
 | 
|
415  | 
weave = self.get_inventory_weave()  | 
|
| 
1563.2.34
by Robert Collins
 Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction  | 
416  | 
all_revisions = self._eliminate_revisions_not_present(weave.versions())  | 
417  | 
entire_graph = dict([(node, weave.get_parents(node)) for  | 
|
| 
1590.1.1
by Robert Collins
 Improve common_ancestor performance.  | 
418  | 
node in all_revisions])  | 
419  | 
if revision_id is None:  | 
|
420  | 
return entire_graph  | 
|
421  | 
elif revision_id not in entire_graph:  | 
|
422  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
423  | 
else:  | 
|
424  | 
            # add what can be reached from revision_id
 | 
|
425  | 
result = {}  | 
|
426  | 
pending = set([revision_id])  | 
|
427  | 
while len(pending) > 0:  | 
|
428  | 
node = pending.pop()  | 
|
429  | 
result[node] = entire_graph[node]  | 
|
430  | 
for revision_id in result[node]:  | 
|
431  | 
if revision_id not in result:  | 
|
432  | 
pending.add(revision_id)  | 
|
433  | 
return result  | 
|
434  | 
||
435  | 
    @needs_read_lock
 | 
|
| 
1594.2.3
by Robert Collins
 bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.  | 
436  | 
def get_revision_graph_with_ghosts(self, revision_ids=None):  | 
437  | 
"""Return a graph of the revisions with ghosts marked as applicable.  | 
|
438  | 
||
439  | 
        :param revision_ids: an iterable of revisions to graph or None for all.
 | 
|
440  | 
        :return: a Graph object with the graph reachable from revision_ids.
 | 
|
441  | 
        """
 | 
|
442  | 
result = Graph()  | 
|
443  | 
if not revision_ids:  | 
|
444  | 
pending = set(self.all_revision_ids())  | 
|
445  | 
required = set([])  | 
|
446  | 
else:  | 
|
447  | 
pending = set(revision_ids)  | 
|
448  | 
required = set(revision_ids)  | 
|
449  | 
done = set([])  | 
|
450  | 
while len(pending):  | 
|
451  | 
revision_id = pending.pop()  | 
|
452  | 
try:  | 
|
453  | 
rev = self.get_revision(revision_id)  | 
|
454  | 
except errors.NoSuchRevision:  | 
|
455  | 
if revision_id in required:  | 
|
456  | 
                    raise
 | 
|
457  | 
                # a ghost
 | 
|
458  | 
result.add_ghost(revision_id)  | 
|
459  | 
                continue
 | 
|
460  | 
for parent_id in rev.parent_ids:  | 
|
461  | 
                # is this queued or done ?
 | 
|
462  | 
if (parent_id not in pending and  | 
|
463  | 
parent_id not in done):  | 
|
464  | 
                    # no, queue it.
 | 
|
465  | 
pending.add(parent_id)  | 
|
466  | 
result.add_node(revision_id, rev.parent_ids)  | 
|
| 
1594.2.15
by Robert Collins
 Unfuck performance.  | 
467  | 
done.add(revision_id)  | 
| 
1594.2.3
by Robert Collins
 bugfix revision.MultipleRevisionSources.get_revision_graph to integrate ghosts between sources. [slow on weaves, fast on knits.  | 
468  | 
return result  | 
469  | 
||
470  | 
    @needs_read_lock
 | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
471  | 
def get_revision_inventory(self, revision_id):  | 
472  | 
"""Return inventory of a past revision."""  | 
|
473  | 
        # TODO: Unify this with get_inventory()
 | 
|
474  | 
        # bzr 0.0.6 and later imposes the constraint that the inventory_id
 | 
|
475  | 
        # must be the same as its revision, so this is trivial.
 | 
|
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
476  | 
if revision_id is None:  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
477  | 
            # This does not make sense: if there is no revision,
 | 
478  | 
            # then it is the current tree inventory surely ?!
 | 
|
479  | 
            # and thus get_root_id() is something that looks at the last
 | 
|
480  | 
            # commit on the branch, and the get_root_id is an inventory check.
 | 
|
481  | 
raise NotImplementedError  | 
|
482  | 
            # return Inventory(self.get_root_id())
 | 
|
483  | 
else:  | 
|
484  | 
return self.get_inventory(revision_id)  | 
|
485  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
486  | 
    @needs_read_lock
 | 
| 
1534.6.3
by Robert Collins
 find_repository sufficiently robust.  | 
487  | 
def is_shared(self):  | 
488  | 
"""Return True if this repository is flagged as a shared repository."""  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
489  | 
raise NotImplementedError(self.is_shared)  | 
| 
1534.6.3
by Robert Collins
 find_repository sufficiently robust.  | 
490  | 
|
| 
1594.2.7
by Robert Collins
 Add versionedfile.fix_parents api for correcting data post hoc.  | 
491  | 
    @needs_write_lock
 | 
492  | 
def reconcile(self):  | 
|
493  | 
"""Reconcile this repository."""  | 
|
494  | 
from bzrlib.reconcile import RepoReconciler  | 
|
495  | 
reconciler = RepoReconciler(self)  | 
|
496  | 
reconciler.reconcile()  | 
|
497  | 
return reconciler  | 
|
498  | 
||
| 
1534.6.3
by Robert Collins
 find_repository sufficiently robust.  | 
499  | 
    @needs_read_lock
 | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
500  | 
def revision_tree(self, revision_id):  | 
501  | 
"""Return Tree for a revision on this branch.  | 
|
502  | 
||
503  | 
        `revision_id` may be None for the null revision, in which case
 | 
|
504  | 
        an `EmptyTree` is returned."""
 | 
|
505  | 
        # TODO: refactor this to use an existing revision object
 | 
|
506  | 
        # so we don't need to read it in twice.
 | 
|
| 
1534.4.28
by Robert Collins
 first cut at merge from integration.  | 
507  | 
if revision_id is None or revision_id == NULL_REVISION:  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
508  | 
return EmptyTree()  | 
509  | 
else:  | 
|
510  | 
inv = self.get_revision_inventory(revision_id)  | 
|
| 
1185.65.17
by Robert Collins
 Merge from integration, mode-changes are broken.  | 
511  | 
return RevisionTree(self, inv, revision_id)  | 
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
512  | 
|
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
513  | 
    @needs_read_lock
 | 
| 
1185.66.2
by Aaron Bentley
 Moved get_ancestry to RevisionStorage  | 
514  | 
def get_ancestry(self, revision_id):  | 
515  | 
"""Return a list of revision-ids integrated by a revision.  | 
|
516  | 
        
 | 
|
517  | 
        This is topologically sorted.
 | 
|
518  | 
        """
 | 
|
519  | 
if revision_id is None:  | 
|
520  | 
return [None]  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
521  | 
if not self.has_revision(revision_id):  | 
522  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
| 
1185.66.2
by Aaron Bentley
 Moved get_ancestry to RevisionStorage  | 
523  | 
w = self.get_inventory_weave()  | 
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
524  | 
candidates = w.get_ancestry(revision_id)  | 
525  | 
return [None] + candidates # self._eliminate_revisions_not_present(candidates)  | 
|
| 
1185.66.2
by Aaron Bentley
 Moved get_ancestry to RevisionStorage  | 
526  | 
|
| 
1185.65.4
by Aaron Bentley
 Fixed cat command  | 
527  | 
    @needs_read_lock
 | 
528  | 
def print_file(self, file, revision_id):  | 
|
| 
1185.65.29
by Robert Collins
 Implement final review suggestions.  | 
529  | 
"""Print `file` to stdout.  | 
530  | 
        
 | 
|
531  | 
        FIXME RBC 20060125 as John Meinel points out this is a bad api
 | 
|
532  | 
        - it writes to stdout, it assumes that that is valid etc. Fix
 | 
|
533  | 
        by creating a new more flexible convenience function.
 | 
|
534  | 
        """
 | 
|
| 
1185.65.4
by Aaron Bentley
 Fixed cat command  | 
535  | 
tree = self.revision_tree(revision_id)  | 
536  | 
        # use inventory as it was in that revision
 | 
|
537  | 
file_id = tree.inventory.path2id(file)  | 
|
538  | 
if not file_id:  | 
|
539  | 
raise BzrError("%r is not present in revision %s" % (file, revno))  | 
|
| 
1185.65.15
by Robert Collins
 Merge from integration.  | 
540  | 
try:  | 
541  | 
revno = self.revision_id_to_revno(revision_id)  | 
|
542  | 
except errors.NoSuchRevision:  | 
|
543  | 
                # TODO: This should not be BzrError,
 | 
|
544  | 
                # but NoSuchFile doesn't fit either
 | 
|
545  | 
raise BzrError('%r is not present in revision %s'  | 
|
546  | 
% (file, revision_id))  | 
|
547  | 
else:  | 
|
548  | 
raise BzrError('%r is not present in revision %s'  | 
|
549  | 
% (file, revno))  | 
|
| 
1185.65.4
by Aaron Bentley
 Fixed cat command  | 
550  | 
tree.print_file(file_id)  | 
551  | 
||
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
552  | 
def get_transaction(self):  | 
553  | 
return self.control_files.get_transaction()  | 
|
554  | 
||
| 
1590.1.1
by Robert Collins
 Improve common_ancestor performance.  | 
555  | 
def revision_parents(self, revid):  | 
556  | 
return self.get_inventory_weave().parent_names(revid)  | 
|
557  | 
||
| 
1185.65.27
by Robert Collins
 Tweak storage towards mergability.  | 
558  | 
    @needs_write_lock
 | 
| 
1534.6.5
by Robert Collins
 Cloning of repos preserves shared and make-working-tree attributes.  | 
559  | 
def set_make_working_trees(self, new_value):  | 
560  | 
"""Set the policy flag for making working trees when creating branches.  | 
|
561  | 
||
562  | 
        This only applies to branches that use this repository.
 | 
|
563  | 
||
564  | 
        The default is 'True'.
 | 
|
565  | 
        :param new_value: True to restore the default, False to disable making
 | 
|
566  | 
                          working trees.
 | 
|
567  | 
        """
 | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
568  | 
raise NotImplementedError(self.set_make_working_trees)  | 
| 
1534.6.5
by Robert Collins
 Cloning of repos preserves shared and make-working-tree attributes.  | 
569  | 
|
570  | 
def make_working_trees(self):  | 
|
571  | 
"""Returns the policy for making working trees on new branches."""  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
572  | 
raise NotImplementedError(self.make_working_trees)  | 
| 
1534.6.5
by Robert Collins
 Cloning of repos preserves shared and make-working-tree attributes.  | 
573  | 
|
574  | 
    @needs_write_lock
 | 
|
| 
1185.65.1
by Aaron Bentley
 Refactored out ControlFiles and RevisionStore from _Branch  | 
575  | 
def sign_revision(self, revision_id, gpg_strategy):  | 
576  | 
plaintext = Testament.from_revision(self, revision_id).as_short_text()  | 
|
577  | 
self.store_revision_signature(gpg_strategy, plaintext, revision_id)  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
578  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
579  | 
    @needs_read_lock
 | 
580  | 
def has_signature_for_revision_id(self, revision_id):  | 
|
581  | 
"""Query for a revision signature for revision_id in the repository."""  | 
|
582  | 
return self._revision_store.has_signature(revision_id,  | 
|
583  | 
self.get_transaction())  | 
|
584  | 
||
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
585  | 
    @needs_read_lock
 | 
586  | 
def get_signature_text(self, revision_id):  | 
|
587  | 
"""Return the text for a signature."""  | 
|
588  | 
return self._revision_store.get_signature_text(revision_id,  | 
|
589  | 
self.get_transaction())  | 
|
590  | 
||
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
591  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
592  | 
class AllInOneRepository(Repository):  | 
593  | 
"""Legacy support - the repository behaviour for all-in-one branches."""  | 
|
594  | 
||
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
595  | 
def __init__(self, _format, a_bzrdir, _revision_store, control_store, text_store):  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
596  | 
        # we reuse one control files instance.
 | 
597  | 
dir_mode = a_bzrdir._control_files._dir_mode  | 
|
598  | 
file_mode = a_bzrdir._control_files._file_mode  | 
|
599  | 
||
600  | 
def get_store(name, compressed=True, prefixed=False):  | 
|
601  | 
            # FIXME: This approach of assuming stores are all entirely compressed
 | 
|
602  | 
            # or entirely uncompressed is tidy, but breaks upgrade from 
 | 
|
603  | 
            # some existing branches where there's a mixture; we probably 
 | 
|
604  | 
            # still want the option to look for both.
 | 
|
605  | 
relpath = a_bzrdir._control_files._escape(name)  | 
|
606  | 
store = TextStore(a_bzrdir._control_files._transport.clone(relpath),  | 
|
607  | 
prefixed=prefixed, compressed=compressed,  | 
|
608  | 
dir_mode=dir_mode,  | 
|
609  | 
file_mode=file_mode)  | 
|
610  | 
            #if self._transport.should_cache():
 | 
|
611  | 
            #    cache_path = os.path.join(self.cache_root, name)
 | 
|
612  | 
            #    os.mkdir(cache_path)
 | 
|
613  | 
            #    store = bzrlib.store.CachedStore(store, cache_path)
 | 
|
614  | 
return store  | 
|
615  | 
||
616  | 
        # not broken out yet because the controlweaves|inventory_store
 | 
|
617  | 
        # and text_store | weave_store bits are still different.
 | 
|
618  | 
if isinstance(_format, RepositoryFormat4):  | 
|
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
619  | 
            # cannot remove these - there is still no consistent api 
 | 
620  | 
            # which allows access to this old info.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
621  | 
self.inventory_store = get_store('inventory-store')  | 
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
622  | 
text_store = get_store('text-store')  | 
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
623  | 
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files, _revision_store, control_store, text_store)  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
624  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
625  | 
    @needs_read_lock
 | 
626  | 
def is_shared(self):  | 
|
627  | 
"""AllInOne repositories cannot be shared."""  | 
|
628  | 
return False  | 
|
629  | 
||
630  | 
    @needs_write_lock
 | 
|
631  | 
def set_make_working_trees(self, new_value):  | 
|
632  | 
"""Set the policy flag for making working trees when creating branches.  | 
|
633  | 
||
634  | 
        This only applies to branches that use this repository.
 | 
|
635  | 
||
636  | 
        The default is 'True'.
 | 
|
637  | 
        :param new_value: True to restore the default, False to disable making
 | 
|
638  | 
                          working trees.
 | 
|
639  | 
        """
 | 
|
640  | 
raise NotImplementedError(self.set_make_working_trees)  | 
|
641  | 
||
642  | 
def make_working_trees(self):  | 
|
643  | 
"""Returns the policy for making working trees on new branches."""  | 
|
644  | 
return True  | 
|
645  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
646  | 
|
647  | 
class MetaDirRepository(Repository):  | 
|
648  | 
"""Repositories in the new meta-dir layout."""  | 
|
649  | 
||
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
650  | 
def __init__(self, _format, a_bzrdir, control_files, _revision_store, control_store, text_store):  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
651  | 
super(MetaDirRepository, self).__init__(_format,  | 
652  | 
a_bzrdir,  | 
|
653  | 
control_files,  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
654  | 
_revision_store,  | 
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
655  | 
control_store,  | 
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
656  | 
text_store)  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
657  | 
|
658  | 
dir_mode = self.control_files._dir_mode  | 
|
659  | 
file_mode = self.control_files._file_mode  | 
|
660  | 
||
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
661  | 
    @needs_read_lock
 | 
662  | 
def is_shared(self):  | 
|
663  | 
"""Return True if this repository is flagged as a shared repository."""  | 
|
664  | 
return self.control_files._transport.has('shared-storage')  | 
|
665  | 
||
666  | 
    @needs_write_lock
 | 
|
667  | 
def set_make_working_trees(self, new_value):  | 
|
668  | 
"""Set the policy flag for making working trees when creating branches.  | 
|
669  | 
||
670  | 
        This only applies to branches that use this repository.
 | 
|
671  | 
||
672  | 
        The default is 'True'.
 | 
|
673  | 
        :param new_value: True to restore the default, False to disable making
 | 
|
674  | 
                          working trees.
 | 
|
675  | 
        """
 | 
|
676  | 
if new_value:  | 
|
677  | 
try:  | 
|
678  | 
self.control_files._transport.delete('no-working-trees')  | 
|
679  | 
except errors.NoSuchFile:  | 
|
680  | 
                pass
 | 
|
681  | 
else:  | 
|
682  | 
self.control_files.put_utf8('no-working-trees', '')  | 
|
683  | 
||
684  | 
def make_working_trees(self):  | 
|
685  | 
"""Returns the policy for making working trees on new branches."""  | 
|
686  | 
return not self.control_files._transport.has('no-working-trees')  | 
|
687  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
688  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
689  | 
class KnitRepository(MetaDirRepository):  | 
690  | 
"""Knit format repository."""  | 
|
691  | 
||
692  | 
    @needs_read_lock
 | 
|
693  | 
def all_revision_ids(self):  | 
|
694  | 
"""See Repository.all_revision_ids()."""  | 
|
695  | 
return self._revision_store.all_revision_ids(self.get_transaction())  | 
|
696  | 
||
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
697  | 
def fileid_involved_between_revs(self, from_revid, to_revid):  | 
698  | 
"""Find file_id(s) which are involved in the changes between revisions.  | 
|
699  | 
||
700  | 
        This determines the set of revisions which are involved, and then
 | 
|
701  | 
        finds all file ids affected by those revisions.
 | 
|
702  | 
        """
 | 
|
703  | 
vf = self._get_revision_vf()  | 
|
704  | 
from_set = set(vf.get_ancestry(from_revid))  | 
|
705  | 
to_set = set(vf.get_ancestry(to_revid))  | 
|
706  | 
changed = to_set.difference(from_set)  | 
|
707  | 
return self._fileid_involved_by_set(changed)  | 
|
708  | 
||
709  | 
def fileid_involved(self, last_revid=None):  | 
|
710  | 
"""Find all file_ids modified in the ancestry of last_revid.  | 
|
711  | 
||
712  | 
        :param last_revid: If None, last_revision() will be used.
 | 
|
713  | 
        """
 | 
|
714  | 
if not last_revid:  | 
|
715  | 
changed = set(self.all_revision_ids())  | 
|
716  | 
else:  | 
|
717  | 
changed = set(self.get_ancestry(last_revid))  | 
|
718  | 
if None in changed:  | 
|
719  | 
changed.remove(None)  | 
|
720  | 
return self._fileid_involved_by_set(changed)  | 
|
721  | 
||
| 
1594.2.7
by Robert Collins
 Add versionedfile.fix_parents api for correcting data post hoc.  | 
722  | 
    @needs_read_lock
 | 
723  | 
def get_ancestry(self, revision_id):  | 
|
724  | 
"""Return a list of revision-ids integrated by a revision.  | 
|
725  | 
        
 | 
|
726  | 
        This is topologically sorted.
 | 
|
727  | 
        """
 | 
|
728  | 
if revision_id is None:  | 
|
729  | 
return [None]  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
730  | 
vf = self._get_revision_vf()  | 
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
731  | 
try:  | 
732  | 
return [None] + vf.get_ancestry(revision_id)  | 
|
733  | 
except errors.RevisionNotPresent:  | 
|
734  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
735  | 
||
736  | 
    @needs_read_lock
 | 
|
| 
1594.2.10
by Robert Collins
 Teach knit fetching and branching to only duplicate relevant data avoiding unnecessary reconciles.  | 
737  | 
def get_revision(self, revision_id):  | 
738  | 
"""Return the Revision object for a named revision"""  | 
|
739  | 
return self.get_revision_reconcile(revision_id)  | 
|
740  | 
||
741  | 
    @needs_read_lock
 | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
742  | 
def get_revision_graph(self, revision_id=None):  | 
743  | 
"""Return a dictionary containing the revision graph.  | 
|
744  | 
        
 | 
|
745  | 
        :return: a dictionary of revision_id->revision_parents_list.
 | 
|
746  | 
        """
 | 
|
747  | 
weave = self._get_revision_vf()  | 
|
748  | 
entire_graph = weave.get_graph()  | 
|
749  | 
if revision_id is None:  | 
|
750  | 
return weave.get_graph()  | 
|
751  | 
elif revision_id not in weave:  | 
|
752  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
753  | 
else:  | 
|
754  | 
            # add what can be reached from revision_id
 | 
|
755  | 
result = {}  | 
|
756  | 
pending = set([revision_id])  | 
|
757  | 
while len(pending) > 0:  | 
|
758  | 
node = pending.pop()  | 
|
759  | 
result[node] = weave.get_parents(node)  | 
|
760  | 
for revision_id in result[node]:  | 
|
761  | 
if revision_id not in result:  | 
|
762  | 
pending.add(revision_id)  | 
|
763  | 
return result  | 
|
764  | 
||
765  | 
    @needs_read_lock
 | 
|
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
766  | 
def get_revision_graph_with_ghosts(self, revision_ids=None):  | 
767  | 
"""Return a graph of the revisions with ghosts marked as applicable.  | 
|
768  | 
||
769  | 
        :param revision_ids: an iterable of revisions to graph or None for all.
 | 
|
770  | 
        :return: a Graph object with the graph reachable from revision_ids.
 | 
|
771  | 
        """
 | 
|
772  | 
result = Graph()  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
773  | 
vf = self._get_revision_vf()  | 
| 
1628.1.7
by Robert Collins
 Tune get_revision_graph_with_ghosts for Knit repositories.  | 
774  | 
versions = set(vf.versions())  | 
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
775  | 
if not revision_ids:  | 
776  | 
pending = set(self.all_revision_ids())  | 
|
777  | 
required = set([])  | 
|
778  | 
else:  | 
|
779  | 
pending = set(revision_ids)  | 
|
780  | 
required = set(revision_ids)  | 
|
781  | 
done = set([])  | 
|
782  | 
while len(pending):  | 
|
783  | 
revision_id = pending.pop()  | 
|
784  | 
if not revision_id in versions:  | 
|
785  | 
if revision_id in required:  | 
|
786  | 
raise errors.NoSuchRevision(self, revision_id)  | 
|
787  | 
                # a ghost
 | 
|
788  | 
result.add_ghost(revision_id)  | 
|
| 
1628.1.7
by Robert Collins
 Tune get_revision_graph_with_ghosts for Knit repositories.  | 
789  | 
                # mark it as done so we dont try for it again.
 | 
790  | 
done.add(revision_id)  | 
|
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
791  | 
                continue
 | 
792  | 
parent_ids = vf.get_parents_with_ghosts(revision_id)  | 
|
793  | 
for parent_id in parent_ids:  | 
|
794  | 
                # is this queued or done ?
 | 
|
795  | 
if (parent_id not in pending and  | 
|
796  | 
parent_id not in done):  | 
|
797  | 
                    # no, queue it.
 | 
|
798  | 
pending.add(parent_id)  | 
|
799  | 
result.add_node(revision_id, parent_ids)  | 
|
| 
1628.1.7
by Robert Collins
 Tune get_revision_graph_with_ghosts for Knit repositories.  | 
800  | 
done.add(revision_id)  | 
| 
1594.2.9
by Robert Collins
 Teach Knit repositories how to handle ghosts without corrupting at all.  | 
801  | 
return result  | 
| 
1594.2.7
by Robert Collins
 Add versionedfile.fix_parents api for correcting data post hoc.  | 
802  | 
|
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
803  | 
def _get_revision_vf(self):  | 
| 
1607.1.2
by Robert Collins
 Merge in knit-using-revision-versioned-file-graph tuning work.  | 
804  | 
""":return: a versioned file containing the revisions."""  | 
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
805  | 
vf = self._revision_store.get_revision_file(self.get_transaction())  | 
806  | 
return vf  | 
|
807  | 
||
| 
1594.2.7
by Robert Collins
 Add versionedfile.fix_parents api for correcting data post hoc.  | 
808  | 
    @needs_write_lock
 | 
809  | 
def reconcile(self):  | 
|
810  | 
"""Reconcile this repository."""  | 
|
811  | 
from bzrlib.reconcile import KnitReconciler  | 
|
812  | 
reconciler = KnitReconciler(self)  | 
|
813  | 
reconciler.reconcile()  | 
|
814  | 
return reconciler  | 
|
815  | 
||
| 
1596.2.12
by Robert Collins
 Merge and make Knit Repository use the revision store for all possible queries.  | 
816  | 
def revision_parents(self, revid):  | 
817  | 
return self._get_revision_vf().get_parents(rev_id)  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
818  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
819  | 
class RepositoryFormat(object):  | 
820  | 
"""A repository format.  | 
|
821  | 
||
822  | 
    Formats provide three things:
 | 
|
823  | 
     * An initialization routine to construct repository data on disk.
 | 
|
824  | 
     * a format string which is used when the BzrDir supports versioned
 | 
|
825  | 
       children.
 | 
|
826  | 
     * an open routine which returns a Repository instance.
 | 
|
827  | 
||
828  | 
    Formats are placed in an dict by their format string for reference 
 | 
|
829  | 
    during opening. These should be subclasses of RepositoryFormat
 | 
|
830  | 
    for consistency.
 | 
|
831  | 
||
832  | 
    Once a format is deprecated, just deprecate the initialize and open
 | 
|
833  | 
    methods on the format class. Do not deprecate the object, as the 
 | 
|
834  | 
    object will be created every system load.
 | 
|
835  | 
||
836  | 
    Common instance attributes:
 | 
|
837  | 
    _matchingbzrdir - the bzrdir format that the repository format was
 | 
|
838  | 
    originally written to work with. This can be used if manually
 | 
|
839  | 
    constructing a bzrdir and repository, or more commonly for test suite
 | 
|
840  | 
    parameterisation.
 | 
|
841  | 
    """
 | 
|
842  | 
||
843  | 
_default_format = None  | 
|
| 
1534.4.41
by Robert Collins
 Branch now uses BzrDir reasonably sanely.  | 
844  | 
"""The default format used for new repositories."""  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
845  | 
|
846  | 
_formats = {}  | 
|
847  | 
"""The known formats."""  | 
|
848  | 
||
849  | 
    @classmethod
 | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
850  | 
def find_format(klass, a_bzrdir):  | 
851  | 
"""Return the format for the repository object in a_bzrdir."""  | 
|
852  | 
try:  | 
|
853  | 
transport = a_bzrdir.get_repository_transport(None)  | 
|
854  | 
format_string = transport.get("format").read()  | 
|
855  | 
return klass._formats[format_string]  | 
|
856  | 
except errors.NoSuchFile:  | 
|
857  | 
raise errors.NoRepositoryPresent(a_bzrdir)  | 
|
858  | 
except KeyError:  | 
|
859  | 
raise errors.UnknownFormatError(format_string)  | 
|
860  | 
||
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
861  | 
def _get_control_store(self, repo_transport, control_files):  | 
862  | 
"""Return the control store for this repository."""  | 
|
863  | 
raise NotImplementedError(self._get_control_store)  | 
|
864  | 
||
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
865  | 
    @classmethod
 | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
866  | 
def get_default_format(klass):  | 
867  | 
"""Return the current default format."""  | 
|
868  | 
return klass._default_format  | 
|
869  | 
||
870  | 
def get_format_string(self):  | 
|
871  | 
"""Return the ASCII format string that identifies this format.  | 
|
872  | 
        
 | 
|
873  | 
        Note that in pre format ?? repositories the format string is 
 | 
|
874  | 
        not permitted nor written to disk.
 | 
|
875  | 
        """
 | 
|
876  | 
raise NotImplementedError(self.get_format_string)  | 
|
877  | 
||
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
878  | 
def get_format_description(self):  | 
879  | 
"""Return the short desciption for this format."""  | 
|
880  | 
raise NotImplementedError(self.get_format_description)  | 
|
881  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
882  | 
def _get_revision_store(self, repo_transport, control_files):  | 
883  | 
"""Return the revision store object for this a_bzrdir."""  | 
|
| 
1556.1.5
by Robert Collins
 Review feedback.  | 
884  | 
raise NotImplementedError(self._get_revision_store)  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
885  | 
|
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
886  | 
def _get_text_rev_store(self,  | 
887  | 
transport,  | 
|
888  | 
control_files,  | 
|
889  | 
name,  | 
|
890  | 
compressed=True,  | 
|
| 
1563.2.28
by Robert Collins
 Add total_size to the revision_store api.  | 
891  | 
prefixed=False,  | 
892  | 
serializer=None):  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
893  | 
"""Common logic for getting a revision store for a repository.  | 
894  | 
        
 | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
895  | 
        see self._get_revision_store for the subclass-overridable method to 
 | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
896  | 
        get the store for a repository.
 | 
897  | 
        """
 | 
|
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
898  | 
from bzrlib.store.revision.text import TextRevisionStore  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
899  | 
dir_mode = control_files._dir_mode  | 
900  | 
file_mode = control_files._file_mode  | 
|
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
901  | 
text_store =TextStore(transport.clone(name),  | 
902  | 
prefixed=prefixed,  | 
|
903  | 
compressed=compressed,  | 
|
904  | 
dir_mode=dir_mode,  | 
|
905  | 
file_mode=file_mode)  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
906  | 
_revision_store = TextRevisionStore(text_store, serializer)  | 
907  | 
return _revision_store  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
908  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
909  | 
def _get_versioned_file_store(self,  | 
910  | 
name,  | 
|
911  | 
transport,  | 
|
912  | 
control_files,  | 
|
913  | 
prefixed=True,  | 
|
| 
1608.2.12
by Martin Pool
 Store-escaping must quote uppercase characters too, so that they're safely  | 
914  | 
versionedfile_class=WeaveFile,  | 
915  | 
escaped=False):  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
916  | 
weave_transport = control_files._transport.clone(name)  | 
917  | 
dir_mode = control_files._dir_mode  | 
|
918  | 
file_mode = control_files._file_mode  | 
|
919  | 
return VersionedFileStore(weave_transport, prefixed=prefixed,  | 
|
| 
1608.2.12
by Martin Pool
 Store-escaping must quote uppercase characters too, so that they're safely  | 
920  | 
dir_mode=dir_mode,  | 
921  | 
file_mode=file_mode,  | 
|
922  | 
versionedfile_class=versionedfile_class,  | 
|
923  | 
escaped=escaped)  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
924  | 
|
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
925  | 
def initialize(self, a_bzrdir, shared=False):  | 
926  | 
"""Initialize a repository of this format in a_bzrdir.  | 
|
927  | 
||
928  | 
        :param a_bzrdir: The bzrdir to put the new repository in it.
 | 
|
929  | 
        :param shared: The repository should be initialized as a sharable one.
 | 
|
930  | 
||
931  | 
        This may raise UninitializableFormat if shared repository are not
 | 
|
932  | 
        compatible the a_bzrdir.
 | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
933  | 
        """
 | 
934  | 
||
935  | 
def is_supported(self):  | 
|
936  | 
"""Is this format supported?  | 
|
937  | 
||
938  | 
        Supported formats must be initializable and openable.
 | 
|
939  | 
        Unsupported formats may not support initialization or committing or 
 | 
|
940  | 
        some other features depending on the reason for not being supported.
 | 
|
941  | 
        """
 | 
|
942  | 
return True  | 
|
943  | 
||
944  | 
def open(self, a_bzrdir, _found=False):  | 
|
945  | 
"""Return an instance of this format for the bzrdir a_bzrdir.  | 
|
946  | 
        
 | 
|
947  | 
        _found is a private parameter, do not use it.
 | 
|
948  | 
        """
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
949  | 
raise NotImplementedError(self.open)  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
950  | 
|
951  | 
    @classmethod
 | 
|
952  | 
def register_format(klass, format):  | 
|
953  | 
klass._formats[format.get_format_string()] = format  | 
|
954  | 
||
955  | 
    @classmethod
 | 
|
956  | 
def set_default_format(klass, format):  | 
|
957  | 
klass._default_format = format  | 
|
958  | 
||
959  | 
    @classmethod
 | 
|
960  | 
def unregister_format(klass, format):  | 
|
961  | 
assert klass._formats[format.get_format_string()] is format  | 
|
962  | 
del klass._formats[format.get_format_string()]  | 
|
963  | 
||
964  | 
||
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
965  | 
class PreSplitOutRepositoryFormat(RepositoryFormat):  | 
966  | 
"""Base class for the pre split out repository formats."""  | 
|
967  | 
||
968  | 
def initialize(self, a_bzrdir, shared=False, _internal=False):  | 
|
969  | 
"""Create a weave repository.  | 
|
970  | 
        
 | 
|
971  | 
        TODO: when creating split out bzr branch formats, move this to a common
 | 
|
972  | 
        base for Format5, Format6. or something like that.
 | 
|
973  | 
        """
 | 
|
974  | 
from bzrlib.weavefile import write_weave_v5  | 
|
975  | 
from bzrlib.weave import Weave  | 
|
976  | 
||
977  | 
if shared:  | 
|
978  | 
raise errors.IncompatibleFormat(self, a_bzrdir._format)  | 
|
979  | 
||
980  | 
if not _internal:  | 
|
981  | 
            # always initialized when the bzrdir is.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
982  | 
return self.open(a_bzrdir, _found=True)  | 
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
983  | 
|
984  | 
        # Create an empty weave
 | 
|
985  | 
sio = StringIO()  | 
|
986  | 
bzrlib.weavefile.write_weave_v5(Weave(), sio)  | 
|
987  | 
empty_weave = sio.getvalue()  | 
|
988  | 
||
989  | 
mutter('creating repository in %s.', a_bzrdir.transport.base)  | 
|
990  | 
dirs = ['revision-store', 'weaves']  | 
|
| 
1553.5.56
by Martin Pool
 Format 7 repo now uses LockDir!  | 
991  | 
files = [('inventory.weave', StringIO(empty_weave)),  | 
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
992  | 
                 ]
 | 
993  | 
||
994  | 
        # FIXME: RBC 20060125 dont peek under the covers
 | 
|
995  | 
        # NB: no need to escape relative paths that are url safe.
 | 
|
| 
1553.5.56
by Martin Pool
 Format 7 repo now uses LockDir!  | 
996  | 
control_files = LockableFiles(a_bzrdir.transport, 'branch-lock',  | 
997  | 
TransportLock)  | 
|
| 
1553.5.63
by Martin Pool
 Lock type is now mandatory for LockableFiles constructor  | 
998  | 
control_files.create_lock()  | 
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
999  | 
control_files.lock_write()  | 
1000  | 
control_files._transport.mkdir_multi(dirs,  | 
|
1001  | 
mode=control_files._dir_mode)  | 
|
1002  | 
try:  | 
|
1003  | 
for file, content in files:  | 
|
1004  | 
control_files.put(file, content)  | 
|
1005  | 
finally:  | 
|
1006  | 
control_files.unlock()  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1007  | 
return self.open(a_bzrdir, _found=True)  | 
1008  | 
||
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
1009  | 
def _get_control_store(self, repo_transport, control_files):  | 
1010  | 
"""Return the control store for this repository."""  | 
|
1011  | 
return self._get_versioned_file_store('',  | 
|
1012  | 
repo_transport,  | 
|
1013  | 
control_files,  | 
|
1014  | 
prefixed=False)  | 
|
1015  | 
||
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1016  | 
def _get_text_store(self, transport, control_files):  | 
1017  | 
"""Get a store for file texts for this format."""  | 
|
1018  | 
raise NotImplementedError(self._get_text_store)  | 
|
1019  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1020  | 
def open(self, a_bzrdir, _found=False):  | 
1021  | 
"""See RepositoryFormat.open()."""  | 
|
1022  | 
if not _found:  | 
|
1023  | 
            # we are being called directly and must probe.
 | 
|
1024  | 
raise NotImplementedError  | 
|
1025  | 
||
1026  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
|
1027  | 
control_files = a_bzrdir._control_files  | 
|
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
1028  | 
text_store = self._get_text_store(repo_transport, control_files)  | 
1029  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
1030  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1031  | 
return AllInOneRepository(_format=self,  | 
1032  | 
a_bzrdir=a_bzrdir,  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
1033  | 
_revision_store=_revision_store,  | 
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
1034  | 
control_store=control_store,  | 
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1035  | 
text_store=text_store)  | 
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
1036  | 
|
1037  | 
||
1038  | 
class RepositoryFormat4(PreSplitOutRepositoryFormat):  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1039  | 
"""Bzr repository format 4.  | 
1040  | 
||
1041  | 
    This repository format has:
 | 
|
1042  | 
     - flat stores
 | 
|
1043  | 
     - TextStores for texts, inventories,revisions.
 | 
|
1044  | 
||
1045  | 
    This format is deprecated: it indexes texts using a text id which is
 | 
|
1046  | 
    removed in format 5; initializationa and write support for this format
 | 
|
1047  | 
    has been removed.
 | 
|
1048  | 
    """
 | 
|
1049  | 
||
1050  | 
def __init__(self):  | 
|
1051  | 
super(RepositoryFormat4, self).__init__()  | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1052  | 
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat4()  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1053  | 
|
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
1054  | 
def get_format_description(self):  | 
1055  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
1056  | 
return "Repository format 4"  | 
|
1057  | 
||
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
1058  | 
def initialize(self, url, shared=False, _internal=False):  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1059  | 
"""Format 4 branches cannot be created."""  | 
1060  | 
raise errors.UninitializableFormat(self)  | 
|
1061  | 
||
1062  | 
def is_supported(self):  | 
|
1063  | 
"""Format 4 is not supported.  | 
|
1064  | 
||
1065  | 
        It is not supported because the model changed from 4 to 5 and the
 | 
|
1066  | 
        conversion logic is expensive - so doing it on the fly was not 
 | 
|
1067  | 
        feasible.
 | 
|
1068  | 
        """
 | 
|
1069  | 
return False  | 
|
1070  | 
||
| 
1563.2.23
by Robert Collins
 Add add_revision and get_revision methods to RevisionStore  | 
1071  | 
def _get_control_store(self, repo_transport, control_files):  | 
1072  | 
"""Format 4 repositories have no formal control store at this point.  | 
|
1073  | 
        
 | 
|
1074  | 
        This will cause any control-file-needing apis to fail - this is desired.
 | 
|
1075  | 
        """
 | 
|
1076  | 
return None  | 
|
1077  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1078  | 
def _get_revision_store(self, repo_transport, control_files):  | 
1079  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
| 
1563.2.28
by Robert Collins
 Add total_size to the revision_store api.  | 
1080  | 
from bzrlib.xml4 import serializer_v4  | 
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
1081  | 
return self._get_text_rev_store(repo_transport,  | 
1082  | 
control_files,  | 
|
| 
1563.2.28
by Robert Collins
 Add total_size to the revision_store api.  | 
1083  | 
'revision-store',  | 
1084  | 
serializer=serializer_v4)  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1085  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1086  | 
def _get_text_store(self, transport, control_files):  | 
1087  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
1088  | 
||
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1089  | 
|
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
1090  | 
class RepositoryFormat5(PreSplitOutRepositoryFormat):  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1091  | 
"""Bzr control format 5.  | 
1092  | 
||
1093  | 
    This repository format has:
 | 
|
1094  | 
     - weaves for file texts and inventory
 | 
|
1095  | 
     - flat stores
 | 
|
1096  | 
     - TextStores for revisions and signatures.
 | 
|
1097  | 
    """
 | 
|
1098  | 
||
1099  | 
def __init__(self):  | 
|
1100  | 
super(RepositoryFormat5, self).__init__()  | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1101  | 
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat5()  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1102  | 
|
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
1103  | 
def get_format_description(self):  | 
1104  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
1105  | 
return "Weave repository format 5"  | 
|
1106  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1107  | 
def _get_revision_store(self, repo_transport, control_files):  | 
1108  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
1109  | 
"""Return the revision store object for this a_bzrdir."""  | 
|
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
1110  | 
return self._get_text_rev_store(repo_transport,  | 
1111  | 
control_files,  | 
|
1112  | 
'revision-store',  | 
|
1113  | 
compressed=False)  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1114  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1115  | 
def _get_text_store(self, transport, control_files):  | 
1116  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
1117  | 
return self._get_versioned_file_store('weaves', transport, control_files, prefixed=False)  | 
|
1118  | 
||
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1119  | 
|
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
1120  | 
class RepositoryFormat6(PreSplitOutRepositoryFormat):  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1121  | 
"""Bzr control format 6.  | 
1122  | 
||
1123  | 
    This repository format has:
 | 
|
1124  | 
     - weaves for file texts and inventory
 | 
|
1125  | 
     - hash subdirectory based stores.
 | 
|
1126  | 
     - TextStores for revisions and signatures.
 | 
|
1127  | 
    """
 | 
|
1128  | 
||
1129  | 
def __init__(self):  | 
|
1130  | 
super(RepositoryFormat6, self).__init__()  | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1131  | 
self._matchingbzrdir = bzrlib.bzrdir.BzrDirFormat6()  | 
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1132  | 
|
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
1133  | 
def get_format_description(self):  | 
1134  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
1135  | 
return "Weave repository format 6"  | 
|
1136  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1137  | 
def _get_revision_store(self, repo_transport, control_files):  | 
1138  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
| 
1563.2.22
by Robert Collins
 Move responsibility for repository.has_revision into RevisionStore  | 
1139  | 
return self._get_text_rev_store(repo_transport,  | 
1140  | 
control_files,  | 
|
1141  | 
'revision-store',  | 
|
1142  | 
compressed=False,  | 
|
1143  | 
prefixed=True)  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1144  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1145  | 
def _get_text_store(self, transport, control_files):  | 
1146  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
1147  | 
return self._get_versioned_file_store('weaves', transport, control_files)  | 
|
1148  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1149  | 
|
1150  | 
class MetaDirRepositoryFormat(RepositoryFormat):  | 
|
1151  | 
"""Common base class for the new repositories using the metadir layour."""  | 
|
1152  | 
||
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1153  | 
def __init__(self):  | 
1154  | 
super(MetaDirRepositoryFormat, self).__init__()  | 
|
1155  | 
self._matchingbzrdir = bzrlib.bzrdir.BzrDirMetaFormat1()  | 
|
1156  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1157  | 
def _create_control_files(self, a_bzrdir):  | 
1158  | 
"""Create the required files and the initial control_files object."""  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1159  | 
        # FIXME: RBC 20060125 dont peek under the covers
 | 
1160  | 
        # NB: no need to escape relative paths that are url safe.
 | 
|
1161  | 
repository_transport = a_bzrdir.get_repository_transport(self)  | 
|
| 
1553.5.57
by Martin Pool
 [merge] sync from bzr.dev  | 
1162  | 
control_files = LockableFiles(repository_transport, 'lock', LockDir)  | 
| 
1553.5.61
by Martin Pool
 Locks protecting LockableFiles must now be explicitly created before use.  | 
1163  | 
control_files.create_lock()  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1164  | 
return control_files  | 
1165  | 
||
1166  | 
def _upload_blank_content(self, a_bzrdir, dirs, files, utf8_files, shared):  | 
|
1167  | 
"""Upload the initial blank content."""  | 
|
1168  | 
control_files = self._create_control_files(a_bzrdir)  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1169  | 
control_files.lock_write()  | 
1170  | 
try:  | 
|
| 
1553.5.49
by Martin Pool
 Use LockDirs for repo format 7  | 
1171  | 
control_files._transport.mkdir_multi(dirs,  | 
1172  | 
mode=control_files._dir_mode)  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1173  | 
for file, content in files:  | 
1174  | 
control_files.put(file, content)  | 
|
1175  | 
for file, content in utf8_files:  | 
|
1176  | 
control_files.put_utf8(file, content)  | 
|
| 
1534.6.1
by Robert Collins
 allow API creation of shared repositories  | 
1177  | 
if shared == True:  | 
1178  | 
control_files.put_utf8('shared-storage', '')  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1179  | 
finally:  | 
1180  | 
control_files.unlock()  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1181  | 
|
1182  | 
||
1183  | 
class RepositoryFormat7(MetaDirRepositoryFormat):  | 
|
1184  | 
"""Bzr repository 7.  | 
|
1185  | 
||
1186  | 
    This repository format has:
 | 
|
1187  | 
     - weaves for file texts and inventory
 | 
|
1188  | 
     - hash subdirectory based stores.
 | 
|
1189  | 
     - TextStores for revisions and signatures.
 | 
|
1190  | 
     - a format marker of its own
 | 
|
1191  | 
     - an optional 'shared-storage' flag
 | 
|
1192  | 
     - an optional 'no-working-trees' flag
 | 
|
1193  | 
    """
 | 
|
1194  | 
||
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
1195  | 
def _get_control_store(self, repo_transport, control_files):  | 
1196  | 
"""Return the control store for this repository."""  | 
|
1197  | 
return self._get_versioned_file_store('',  | 
|
1198  | 
repo_transport,  | 
|
1199  | 
control_files,  | 
|
1200  | 
prefixed=False)  | 
|
1201  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1202  | 
def get_format_string(self):  | 
1203  | 
"""See RepositoryFormat.get_format_string()."""  | 
|
1204  | 
return "Bazaar-NG Repository format 7"  | 
|
1205  | 
||
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
1206  | 
def get_format_description(self):  | 
1207  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
1208  | 
return "Weave repository format 7"  | 
|
1209  | 
||
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1210  | 
def _get_revision_store(self, repo_transport, control_files):  | 
1211  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
1212  | 
return self._get_text_rev_store(repo_transport,  | 
|
1213  | 
control_files,  | 
|
1214  | 
'revision-store',  | 
|
1215  | 
compressed=False,  | 
|
1216  | 
prefixed=True,  | 
|
1217  | 
                                        )
 | 
|
1218  | 
||
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1219  | 
def _get_text_store(self, transport, control_files):  | 
1220  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
1221  | 
return self._get_versioned_file_store('weaves',  | 
|
1222  | 
transport,  | 
|
1223  | 
control_files)  | 
|
1224  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1225  | 
def initialize(self, a_bzrdir, shared=False):  | 
1226  | 
"""Create a weave repository.  | 
|
1227  | 
||
1228  | 
        :param shared: If true the repository will be initialized as a shared
 | 
|
1229  | 
                       repository.
 | 
|
1230  | 
        """
 | 
|
1231  | 
from bzrlib.weavefile import write_weave_v5  | 
|
1232  | 
from bzrlib.weave import Weave  | 
|
1233  | 
||
1234  | 
        # Create an empty weave
 | 
|
1235  | 
sio = StringIO()  | 
|
1236  | 
bzrlib.weavefile.write_weave_v5(Weave(), sio)  | 
|
1237  | 
empty_weave = sio.getvalue()  | 
|
1238  | 
||
1239  | 
mutter('creating repository in %s.', a_bzrdir.transport.base)  | 
|
1240  | 
dirs = ['revision-store', 'weaves']  | 
|
1241  | 
files = [('inventory.weave', StringIO(empty_weave)),  | 
|
1242  | 
                 ]
 | 
|
1243  | 
utf8_files = [('format', self.get_format_string())]  | 
|
1244  | 
||
1245  | 
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)  | 
|
1246  | 
return self.open(a_bzrdir=a_bzrdir, _found=True)  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1247  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
1248  | 
def open(self, a_bzrdir, _found=False, _override_transport=None):  | 
1249  | 
"""See RepositoryFormat.open().  | 
|
1250  | 
        
 | 
|
1251  | 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
 | 
|
1252  | 
                                    repository at a slightly different url
 | 
|
1253  | 
                                    than normal. I.e. during 'upgrade'.
 | 
|
1254  | 
        """
 | 
|
1255  | 
if not _found:  | 
|
1256  | 
format = RepositoryFormat.find_format(a_bzrdir)  | 
|
1257  | 
assert format.__class__ == self.__class__  | 
|
1258  | 
if _override_transport is not None:  | 
|
1259  | 
repo_transport = _override_transport  | 
|
1260  | 
else:  | 
|
1261  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
|
| 
1563.2.36
by Robert Collins
 Merge in bzr.dev  | 
1262  | 
control_files = LockableFiles(repo_transport, 'lock', LockDir)  | 
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
1263  | 
text_store = self._get_text_store(repo_transport, control_files)  | 
1264  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
|
1265  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1266  | 
return MetaDirRepository(_format=self,  | 
1267  | 
a_bzrdir=a_bzrdir,  | 
|
1268  | 
control_files=control_files,  | 
|
1269  | 
_revision_store=_revision_store,  | 
|
1270  | 
control_store=control_store,  | 
|
1271  | 
text_store=text_store)  | 
|
| 
1563.2.29
by Robert Collins
 Remove all but fetch references to repository.revision_store.  | 
1272  | 
|
| 
1534.4.47
by Robert Collins
 Split out repository into .bzr/repository  | 
1273  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1274  | 
class RepositoryFormatKnit1(MetaDirRepositoryFormat):  | 
1275  | 
"""Bzr repository knit format 1.  | 
|
1276  | 
||
1277  | 
    This repository format has:
 | 
|
1278  | 
     - knits for file texts and inventory
 | 
|
1279  | 
     - hash subdirectory based stores.
 | 
|
1280  | 
     - knits for revisions and signatures
 | 
|
1281  | 
     - TextStores for revisions and signatures.
 | 
|
1282  | 
     - a format marker of its own
 | 
|
1283  | 
     - an optional 'shared-storage' flag
 | 
|
1284  | 
     - an optional 'no-working-trees' flag
 | 
|
| 
1553.5.62
by Martin Pool
 Add tests that MetaDir repositories use LockDirs  | 
1285  | 
     - a LockDir lock
 | 
| 
1608.2.12
by Martin Pool
 Store-escaping must quote uppercase characters too, so that they're safely  | 
1286  | 
|
1287  | 
    This format was introduced in bzr 0.8.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1288  | 
    """
 | 
1289  | 
||
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
1290  | 
def _get_control_store(self, repo_transport, control_files):  | 
1291  | 
"""Return the control store for this repository."""  | 
|
| 
1628.1.5
by Robert Collins
 Make inventory knits not annotated, only delta compressed.  | 
1292  | 
return VersionedFileStore(  | 
1293  | 
repo_transport,  | 
|
1294  | 
prefixed=False,  | 
|
1295  | 
file_mode=control_files._file_mode,  | 
|
1296  | 
versionedfile_class=KnitVersionedFile,  | 
|
1297  | 
versionedfile_kwargs={'factory':KnitPlainFactory()},  | 
|
1298  | 
            )
 | 
|
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
1299  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1300  | 
def get_format_string(self):  | 
1301  | 
"""See RepositoryFormat.get_format_string()."""  | 
|
1302  | 
return "Bazaar-NG Knit Repository Format 1"  | 
|
1303  | 
||
| 
1624.3.19
by Olaf Conradi
 New call get_format_description to give a user-friendly description of a  | 
1304  | 
def get_format_description(self):  | 
1305  | 
"""See RepositoryFormat.get_format_description()."""  | 
|
1306  | 
return "Knit repository format 1"  | 
|
1307  | 
||
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1308  | 
def _get_revision_store(self, repo_transport, control_files):  | 
1309  | 
"""See RepositoryFormat._get_revision_store()."""  | 
|
1310  | 
from bzrlib.store.revision.knit import KnitRevisionStore  | 
|
1311  | 
versioned_file_store = VersionedFileStore(  | 
|
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
1312  | 
repo_transport,  | 
| 
1651.1.1
by Martin Pool
 [merge][wip] Storage escaping  | 
1313  | 
file_mode=control_files._file_mode,  | 
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1314  | 
prefixed=False,  | 
| 
1563.2.34
by Robert Collins
 Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction  | 
1315  | 
precious=True,  | 
| 
1628.1.4
by Robert Collins
 Change knit format to use non-delta, non-annotated revisions and signatures.  | 
1316  | 
versionedfile_class=KnitVersionedFile,  | 
| 
1651.1.1
by Martin Pool
 [merge][wip] Storage escaping  | 
1317  | 
versionedfile_kwargs={'delta':False, 'factory':KnitPlainFactory()},  | 
| 
1608.2.12
by Martin Pool
 Store-escaping must quote uppercase characters too, so that they're safely  | 
1318  | 
escaped=True,  | 
| 
1651.1.1
by Martin Pool
 [merge][wip] Storage escaping  | 
1319  | 
            )
 | 
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1320  | 
return KnitRevisionStore(versioned_file_store)  | 
1321  | 
||
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1322  | 
def _get_text_store(self, transport, control_files):  | 
1323  | 
"""See RepositoryFormat._get_text_store()."""  | 
|
1324  | 
return self._get_versioned_file_store('knits',  | 
|
1325  | 
transport,  | 
|
1326  | 
control_files,  | 
|
| 
1608.2.12
by Martin Pool
 Store-escaping must quote uppercase characters too, so that they're safely  | 
1327  | 
versionedfile_class=KnitVersionedFile,  | 
1328  | 
escaped=True)  | 
|
| 
1563.2.17
by Robert Collins
 Change knits repositories to use a knit versioned file store for file texts.  | 
1329  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1330  | 
def initialize(self, a_bzrdir, shared=False):  | 
1331  | 
"""Create a knit format 1 repository.  | 
|
1332  | 
||
| 
1658.1.7
by Martin Pool
 (RepositoryFormatKnit1.initialize) remove dead code that constructs weaves  | 
1333  | 
        :param a_bzrdir: bzrdir to contain the new repository; must already
 | 
1334  | 
            be initialized.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1335  | 
        :param shared: If true the repository will be initialized as a shared
 | 
1336  | 
                       repository.
 | 
|
1337  | 
        """
 | 
|
1338  | 
mutter('creating repository in %s.', a_bzrdir.transport.base)  | 
|
| 
1658.1.7
by Martin Pool
 (RepositoryFormatKnit1.initialize) remove dead code that constructs weaves  | 
1339  | 
dirs = ['revision-store', 'knits']  | 
1340  | 
files = []  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1341  | 
utf8_files = [('format', self.get_format_string())]  | 
1342  | 
||
1343  | 
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)  | 
|
| 
1563.2.25
by Robert Collins
 Merge in upstream.  | 
1344  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
| 
1563.2.36
by Robert Collins
 Merge in bzr.dev  | 
1345  | 
control_files = LockableFiles(repo_transport, 'lock', LockDir)  | 
| 
1563.2.25
by Robert Collins
 Merge in upstream.  | 
1346  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
| 
1594.2.20
by Robert Collins
 Add finished() notifications to transactions.  | 
1347  | 
transaction = bzrlib.transactions.WriteTransaction()  | 
| 
1563.2.34
by Robert Collins
 Remove the commit and rollback transaction methods as misleading, and implement a WriteTransaction  | 
1348  | 
        # trigger a write of the inventory store.
 | 
| 
1563.2.35
by Robert Collins
 cleanup deprecation warnings and finish conversion so the inventory is knit based too.  | 
1349  | 
control_store.get_weave_or_empty('inventory', transaction)  | 
1350  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
|
1351  | 
_revision_store.has_revision_id('A', transaction)  | 
|
1352  | 
_revision_store.get_signature_file(transaction)  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1353  | 
return self.open(a_bzrdir=a_bzrdir, _found=True)  | 
1354  | 
||
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1355  | 
def open(self, a_bzrdir, _found=False, _override_transport=None):  | 
1356  | 
"""See RepositoryFormat.open().  | 
|
1357  | 
        
 | 
|
1358  | 
        :param _override_transport: INTERNAL USE ONLY. Allows opening the
 | 
|
1359  | 
                                    repository at a slightly different url
 | 
|
1360  | 
                                    than normal. I.e. during 'upgrade'.
 | 
|
1361  | 
        """
 | 
|
1362  | 
if not _found:  | 
|
1363  | 
format = RepositoryFormat.find_format(a_bzrdir)  | 
|
1364  | 
assert format.__class__ == self.__class__  | 
|
1365  | 
if _override_transport is not None:  | 
|
1366  | 
repo_transport = _override_transport  | 
|
1367  | 
else:  | 
|
1368  | 
repo_transport = a_bzrdir.get_repository_transport(None)  | 
|
| 
1563.2.36
by Robert Collins
 Merge in bzr.dev  | 
1369  | 
control_files = LockableFiles(repo_transport, 'lock', LockDir)  | 
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1370  | 
text_store = self._get_text_store(repo_transport, control_files)  | 
1371  | 
control_store = self._get_control_store(repo_transport, control_files)  | 
|
1372  | 
_revision_store = self._get_revision_store(repo_transport, control_files)  | 
|
1373  | 
return KnitRepository(_format=self,  | 
|
1374  | 
a_bzrdir=a_bzrdir,  | 
|
1375  | 
control_files=control_files,  | 
|
1376  | 
_revision_store=_revision_store,  | 
|
1377  | 
control_store=control_store,  | 
|
1378  | 
text_store=text_store)  | 
|
1379  | 
||
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1380  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1381  | 
# formats which have no format string are not discoverable
 | 
1382  | 
# and not independently creatable, so are not registered.
 | 
|
| 
1666.1.6
by Robert Collins
 Make knit the default format.  | 
1383  | 
RepositoryFormat.register_format(RepositoryFormat7())  | 
1384  | 
_default_format = RepositoryFormatKnit1()  | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1385  | 
RepositoryFormat.register_format(_default_format)  | 
1386  | 
RepositoryFormat.set_default_format(_default_format)  | 
|
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1387  | 
_legacy_formats = [RepositoryFormat4(),  | 
1388  | 
RepositoryFormat5(),  | 
|
1389  | 
RepositoryFormat6()]  | 
|
1390  | 
||
1391  | 
||
| 
1563.2.12
by Robert Collins
 Checkpointing: created InterObject to factor out common inter object worker code, added InterVersionedFile and tests to allow making join work between any versionedfile.  | 
1392  | 
class InterRepository(InterObject):  | 
| 
1534.1.27
by Robert Collins
 Start InterRepository with InterRepository.get.  | 
1393  | 
"""This class represents operations taking place between two repositories.  | 
1394  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1395  | 
    Its instances have methods like copy_content and fetch, and contain
 | 
| 
1534.1.27
by Robert Collins
 Start InterRepository with InterRepository.get.  | 
1396  | 
    references to the source and target repositories these operations can be 
 | 
1397  | 
    carried out on.
 | 
|
1398  | 
||
1399  | 
    Often we will provide convenience methods on 'repository' which carry out
 | 
|
1400  | 
    operations with another repository - they will always forward to
 | 
|
1401  | 
    InterRepository.get(other).method_name(parameters).
 | 
|
1402  | 
    """
 | 
|
1403  | 
||
| 
1534.1.28
by Robert Collins
 Allow for optimised InterRepository selection.  | 
1404  | 
_optimisers = set()  | 
1405  | 
"""The available optimised InterRepository types."""  | 
|
1406  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1407  | 
    @needs_write_lock
 | 
1408  | 
def copy_content(self, revision_id=None, basis=None):  | 
|
1409  | 
"""Make a complete copy of the content in self into destination.  | 
|
1410  | 
        
 | 
|
1411  | 
        This is a destructive operation! Do not use it on existing 
 | 
|
1412  | 
        repositories.
 | 
|
1413  | 
||
1414  | 
        :param revision_id: Only copy the content needed to construct
 | 
|
1415  | 
                            revision_id and its parents.
 | 
|
1416  | 
        :param basis: Copy the needed data preferentially from basis.
 | 
|
1417  | 
        """
 | 
|
1418  | 
try:  | 
|
1419  | 
self.target.set_make_working_trees(self.source.make_working_trees())  | 
|
1420  | 
except NotImplementedError:  | 
|
1421  | 
            pass
 | 
|
1422  | 
        # grab the basis available data
 | 
|
1423  | 
if basis is not None:  | 
|
1424  | 
self.target.fetch(basis, revision_id=revision_id)  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1425  | 
        # but dont bother fetching if we have the needed data now.
 | 
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1426  | 
if (revision_id not in (None, NULL_REVISION) and  | 
1427  | 
self.target.has_revision(revision_id)):  | 
|
1428  | 
            return
 | 
|
1429  | 
self.target.fetch(self.source, revision_id=revision_id)  | 
|
1430  | 
||
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1431  | 
def _double_lock(self, lock_source, lock_target):  | 
1432  | 
"""Take out too locks, rolling back the first if the second throws."""  | 
|
1433  | 
lock_source()  | 
|
1434  | 
try:  | 
|
1435  | 
lock_target()  | 
|
1436  | 
except Exception:  | 
|
1437  | 
            # we want to ensure that we don't leave source locked by mistake.
 | 
|
1438  | 
            # and any error on target should not confuse source.
 | 
|
1439  | 
self.source.unlock()  | 
|
1440  | 
            raise
 | 
|
1441  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1442  | 
    @needs_write_lock
 | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1443  | 
def fetch(self, revision_id=None, pb=None):  | 
1444  | 
"""Fetch the content required to construct revision_id.  | 
|
1445  | 
||
1446  | 
        The content is copied from source to target.
 | 
|
1447  | 
||
1448  | 
        :param revision_id: if None all content is copied, if NULL_REVISION no
 | 
|
1449  | 
                            content is copied.
 | 
|
1450  | 
        :param pb: optional progress bar to use for progress reports. If not
 | 
|
1451  | 
                   provided a default one will be created.
 | 
|
1452  | 
||
1453  | 
        Returns the copied revision count and the failed revisions in a tuple:
 | 
|
1454  | 
        (copied, failures).
 | 
|
1455  | 
        """
 | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1456  | 
from bzrlib.fetch import GenericRepoFetcher  | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1457  | 
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",  | 
1458  | 
self.source, self.source._format, self.target, self.target._format)  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1459  | 
f = GenericRepoFetcher(to_repository=self.target,  | 
1460  | 
from_repository=self.source,  | 
|
1461  | 
last_revision=revision_id,  | 
|
1462  | 
pb=pb)  | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1463  | 
return f.count_copied, f.failed_revisions  | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1464  | 
|
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1465  | 
def lock_read(self):  | 
1466  | 
"""Take out a logical read lock.  | 
|
1467  | 
||
1468  | 
        This will lock the source branch and the target branch. The source gets
 | 
|
1469  | 
        a read lock and the target a read lock.
 | 
|
1470  | 
        """
 | 
|
1471  | 
self._double_lock(self.source.lock_read, self.target.lock_read)  | 
|
1472  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1473  | 
def lock_write(self):  | 
1474  | 
"""Take out a logical write lock.  | 
|
1475  | 
||
1476  | 
        This will lock the source branch and the target branch. The source gets
 | 
|
1477  | 
        a read lock and the target a write lock.
 | 
|
1478  | 
        """
 | 
|
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1479  | 
self._double_lock(self.source.lock_read, self.target.lock_write)  | 
1480  | 
||
1481  | 
    @needs_read_lock
 | 
|
1482  | 
def missing_revision_ids(self, revision_id=None):  | 
|
1483  | 
"""Return the revision ids that source has that target does not.  | 
|
1484  | 
        
 | 
|
1485  | 
        These are returned in topological order.
 | 
|
1486  | 
||
1487  | 
        :param revision_id: only return revision ids included by this
 | 
|
1488  | 
                            revision_id.
 | 
|
1489  | 
        """
 | 
|
1490  | 
        # generic, possibly worst case, slow code path.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1491  | 
target_ids = set(self.target.all_revision_ids())  | 
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1492  | 
if revision_id is not None:  | 
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1493  | 
source_ids = self.source.get_ancestry(revision_id)  | 
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1494  | 
assert source_ids.pop(0) == None  | 
1495  | 
else:  | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1496  | 
source_ids = self.source.all_revision_ids()  | 
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1497  | 
result_set = set(source_ids).difference(target_ids)  | 
1498  | 
        # this may look like a no-op: its not. It preserves the ordering
 | 
|
1499  | 
        # other_ids had while only returning the members from other_ids
 | 
|
1500  | 
        # that we've decided we need.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1501  | 
return [rev_id for rev_id in source_ids if rev_id in result_set]  | 
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1502  | 
|
1503  | 
def unlock(self):  | 
|
1504  | 
"""Release the locks on source and target."""  | 
|
1505  | 
try:  | 
|
1506  | 
self.target.unlock()  | 
|
1507  | 
finally:  | 
|
1508  | 
self.source.unlock()  | 
|
1509  | 
||
| 
1534.1.27
by Robert Collins
 Start InterRepository with InterRepository.get.  | 
1510  | 
|
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1511  | 
class InterWeaveRepo(InterRepository):  | 
1512  | 
"""Optimised code paths between Weave based repositories."""  | 
|
1513  | 
||
| 
1666.1.6
by Robert Collins
 Make knit the default format.  | 
1514  | 
_matching_repo_format = RepositoryFormat7()  | 
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1515  | 
"""Repository format for testing with."""  | 
1516  | 
||
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1517  | 
    @staticmethod
 | 
1518  | 
def is_compatible(source, target):  | 
|
1519  | 
"""Be compatible with known Weave formats.  | 
|
1520  | 
        
 | 
|
1521  | 
        We dont test for the stores being of specific types becase that
 | 
|
1522  | 
        could lead to confusing results, and there is no need to be 
 | 
|
1523  | 
        overly general.
 | 
|
1524  | 
        """
 | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1525  | 
try:  | 
1526  | 
return (isinstance(source._format, (RepositoryFormat5,  | 
|
1527  | 
RepositoryFormat6,  | 
|
1528  | 
RepositoryFormat7)) and  | 
|
1529  | 
isinstance(target._format, (RepositoryFormat5,  | 
|
1530  | 
RepositoryFormat6,  | 
|
1531  | 
RepositoryFormat7)))  | 
|
1532  | 
except AttributeError:  | 
|
1533  | 
return False  | 
|
1534  | 
||
1535  | 
    @needs_write_lock
 | 
|
1536  | 
def copy_content(self, revision_id=None, basis=None):  | 
|
1537  | 
"""See InterRepository.copy_content()."""  | 
|
1538  | 
        # weave specific optimised path:
 | 
|
1539  | 
if basis is not None:  | 
|
1540  | 
            # copy the basis in, then fetch remaining data.
 | 
|
1541  | 
basis.copy_content_into(self.target, revision_id)  | 
|
1542  | 
            # the basis copy_content_into could misset this.
 | 
|
1543  | 
try:  | 
|
1544  | 
self.target.set_make_working_trees(self.source.make_working_trees())  | 
|
1545  | 
except NotImplementedError:  | 
|
1546  | 
                pass
 | 
|
1547  | 
self.target.fetch(self.source, revision_id=revision_id)  | 
|
1548  | 
else:  | 
|
1549  | 
try:  | 
|
1550  | 
self.target.set_make_working_trees(self.source.make_working_trees())  | 
|
1551  | 
except NotImplementedError:  | 
|
1552  | 
                pass
 | 
|
1553  | 
            # FIXME do not peek!
 | 
|
1554  | 
if self.source.control_files._transport.listable():  | 
|
| 
1594.1.3
by Robert Collins
 Fixup pb usage to use nested_progress_bar.  | 
1555  | 
pb = bzrlib.ui.ui_factory.nested_progress_bar()  | 
1556  | 
try:  | 
|
| 
1563.2.37
by Robert Collins
 Merge in nested progress bars  | 
1557  | 
self.target.weave_store.copy_all_ids(  | 
1558  | 
self.source.weave_store,  | 
|
1559  | 
pb=pb,  | 
|
1560  | 
from_transaction=self.source.get_transaction(),  | 
|
1561  | 
to_transaction=self.target.get_transaction())  | 
|
| 
1594.1.3
by Robert Collins
 Fixup pb usage to use nested_progress_bar.  | 
1562  | 
pb.update('copying inventory', 0, 1)  | 
1563  | 
self.target.control_weaves.copy_multi(  | 
|
| 
1563.2.37
by Robert Collins
 Merge in nested progress bars  | 
1564  | 
self.source.control_weaves, ['inventory'],  | 
1565  | 
from_transaction=self.source.get_transaction(),  | 
|
1566  | 
to_transaction=self.target.get_transaction())  | 
|
1567  | 
self.target._revision_store.text_store.copy_all_ids(  | 
|
1568  | 
self.source._revision_store.text_store,  | 
|
1569  | 
pb=pb)  | 
|
| 
1594.1.3
by Robert Collins
 Fixup pb usage to use nested_progress_bar.  | 
1570  | 
finally:  | 
1571  | 
pb.finished()  | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1572  | 
else:  | 
1573  | 
self.target.fetch(self.source, revision_id=revision_id)  | 
|
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1574  | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1575  | 
    @needs_write_lock
 | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1576  | 
def fetch(self, revision_id=None, pb=None):  | 
1577  | 
"""See InterRepository.fetch()."""  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1578  | 
from bzrlib.fetch import GenericRepoFetcher  | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1579  | 
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",  | 
1580  | 
self.source, self.source._format, self.target, self.target._format)  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1581  | 
f = GenericRepoFetcher(to_repository=self.target,  | 
1582  | 
from_repository=self.source,  | 
|
1583  | 
last_revision=revision_id,  | 
|
1584  | 
pb=pb)  | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1585  | 
return f.count_copied, f.failed_revisions  | 
1586  | 
||
| 
1534.1.34
by Robert Collins
 Move missing_revision_ids from Repository to InterRepository, and eliminate the now unused Repository._compatible_formats method.  | 
1587  | 
    @needs_read_lock
 | 
1588  | 
def missing_revision_ids(self, revision_id=None):  | 
|
1589  | 
"""See InterRepository.missing_revision_ids()."""  | 
|
1590  | 
        # we want all revisions to satisfy revision_id in source.
 | 
|
1591  | 
        # but we dont want to stat every file here and there.
 | 
|
1592  | 
        # we want then, all revisions other needs to satisfy revision_id 
 | 
|
1593  | 
        # checked, but not those that we have locally.
 | 
|
1594  | 
        # so the first thing is to get a subset of the revisions to 
 | 
|
1595  | 
        # satisfy revision_id in source, and then eliminate those that
 | 
|
1596  | 
        # we do already have. 
 | 
|
1597  | 
        # this is slow on high latency connection to self, but as as this
 | 
|
1598  | 
        # disk format scales terribly for push anyway due to rewriting 
 | 
|
1599  | 
        # inventory.weave, this is considered acceptable.
 | 
|
1600  | 
        # - RBC 20060209
 | 
|
1601  | 
if revision_id is not None:  | 
|
1602  | 
source_ids = self.source.get_ancestry(revision_id)  | 
|
1603  | 
assert source_ids.pop(0) == None  | 
|
1604  | 
else:  | 
|
1605  | 
source_ids = self.source._all_possible_ids()  | 
|
1606  | 
source_ids_set = set(source_ids)  | 
|
1607  | 
        # source_ids is the worst possible case we may need to pull.
 | 
|
1608  | 
        # now we want to filter source_ids against what we actually
 | 
|
1609  | 
        # have in target, but dont try to check for existence where we know
 | 
|
1610  | 
        # we do not have a revision as that would be pointless.
 | 
|
1611  | 
target_ids = set(self.target._all_possible_ids())  | 
|
1612  | 
possibly_present_revisions = target_ids.intersection(source_ids_set)  | 
|
1613  | 
actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))  | 
|
1614  | 
required_revisions = source_ids_set.difference(actually_present_revisions)  | 
|
1615  | 
required_topo_revisions = [rev_id for rev_id in source_ids if rev_id in required_revisions]  | 
|
1616  | 
if revision_id is not None:  | 
|
1617  | 
            # we used get_ancestry to determine source_ids then we are assured all
 | 
|
1618  | 
            # revisions referenced are present as they are installed in topological order.
 | 
|
1619  | 
            # and the tip revision was validated by get_ancestry.
 | 
|
1620  | 
return required_topo_revisions  | 
|
1621  | 
else:  | 
|
1622  | 
            # if we just grabbed the possibly available ids, then 
 | 
|
1623  | 
            # we only have an estimate of whats available and need to validate
 | 
|
1624  | 
            # that against the revision records.
 | 
|
1625  | 
return self.source._eliminate_revisions_not_present(required_topo_revisions)  | 
|
1626  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1627  | 
|
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1628  | 
class InterKnitRepo(InterRepository):  | 
1629  | 
"""Optimised code paths between Knit based repositories."""  | 
|
1630  | 
||
1631  | 
_matching_repo_format = RepositoryFormatKnit1()  | 
|
1632  | 
"""Repository format for testing with."""  | 
|
1633  | 
||
1634  | 
    @staticmethod
 | 
|
1635  | 
def is_compatible(source, target):  | 
|
1636  | 
"""Be compatible with known Knit formats.  | 
|
1637  | 
        
 | 
|
1638  | 
        We dont test for the stores being of specific types becase that
 | 
|
1639  | 
        could lead to confusing results, and there is no need to be 
 | 
|
1640  | 
        overly general.
 | 
|
1641  | 
        """
 | 
|
1642  | 
try:  | 
|
1643  | 
return (isinstance(source._format, (RepositoryFormatKnit1)) and  | 
|
1644  | 
isinstance(target._format, (RepositoryFormatKnit1)))  | 
|
1645  | 
except AttributeError:  | 
|
1646  | 
return False  | 
|
1647  | 
||
1648  | 
    @needs_write_lock
 | 
|
1649  | 
def fetch(self, revision_id=None, pb=None):  | 
|
1650  | 
"""See InterRepository.fetch()."""  | 
|
1651  | 
from bzrlib.fetch import KnitRepoFetcher  | 
|
1652  | 
mutter("Using fetch logic to copy between %s(%s) and %s(%s)",  | 
|
1653  | 
self.source, self.source._format, self.target, self.target._format)  | 
|
1654  | 
f = KnitRepoFetcher(to_repository=self.target,  | 
|
1655  | 
from_repository=self.source,  | 
|
1656  | 
last_revision=revision_id,  | 
|
1657  | 
pb=pb)  | 
|
1658  | 
return f.count_copied, f.failed_revisions  | 
|
1659  | 
||
1660  | 
    @needs_read_lock
 | 
|
1661  | 
def missing_revision_ids(self, revision_id=None):  | 
|
1662  | 
"""See InterRepository.missing_revision_ids()."""  | 
|
1663  | 
if revision_id is not None:  | 
|
1664  | 
source_ids = self.source.get_ancestry(revision_id)  | 
|
1665  | 
assert source_ids.pop(0) == None  | 
|
1666  | 
else:  | 
|
1667  | 
source_ids = self.source._all_possible_ids()  | 
|
1668  | 
source_ids_set = set(source_ids)  | 
|
1669  | 
        # source_ids is the worst possible case we may need to pull.
 | 
|
1670  | 
        # now we want to filter source_ids against what we actually
 | 
|
1671  | 
        # have in target, but dont try to check for existence where we know
 | 
|
1672  | 
        # we do not have a revision as that would be pointless.
 | 
|
1673  | 
target_ids = set(self.target._all_possible_ids())  | 
|
1674  | 
possibly_present_revisions = target_ids.intersection(source_ids_set)  | 
|
1675  | 
actually_present_revisions = set(self.target._eliminate_revisions_not_present(possibly_present_revisions))  | 
|
1676  | 
required_revisions = source_ids_set.difference(actually_present_revisions)  | 
|
1677  | 
required_topo_revisions = [rev_id for rev_id in source_ids if rev_id in required_revisions]  | 
|
1678  | 
if revision_id is not None:  | 
|
1679  | 
            # we used get_ancestry to determine source_ids then we are assured all
 | 
|
1680  | 
            # revisions referenced are present as they are installed in topological order.
 | 
|
1681  | 
            # and the tip revision was validated by get_ancestry.
 | 
|
1682  | 
return required_topo_revisions  | 
|
1683  | 
else:  | 
|
1684  | 
            # if we just grabbed the possibly available ids, then 
 | 
|
1685  | 
            # we only have an estimate of whats available and need to validate
 | 
|
1686  | 
            # that against the revision records.
 | 
|
1687  | 
return self.source._eliminate_revisions_not_present(required_topo_revisions)  | 
|
1688  | 
||
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1689  | 
InterRepository.register_optimiser(InterWeaveRepo)  | 
| 
1563.2.31
by Robert Collins
 Convert Knit repositories to use knits.  | 
1690  | 
InterRepository.register_optimiser(InterKnitRepo)  | 
| 
1534.1.31
by Robert Collins
 Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo.  | 
1691  | 
|
1692  | 
||
| 
1534.4.40
by Robert Collins
 Add RepositoryFormats and allow bzrdir.open or create _repository to be used.  | 
1693  | 
class RepositoryTestProviderAdapter(object):  | 
1694  | 
"""A tool to generate a suite testing multiple repository formats at once.  | 
|
1695  | 
||
1696  | 
    This is done by copying the test once for each transport and injecting
 | 
|
1697  | 
    the transport_server, transport_readonly_server, and bzrdir_format and
 | 
|
1698  | 
    repository_format classes into each copy. Each copy is also given a new id()
 | 
|
1699  | 
    to make it easy to identify.
 | 
|
1700  | 
    """
 | 
|
1701  | 
||
1702  | 
def __init__(self, transport_server, transport_readonly_server, formats):  | 
|
1703  | 
self._transport_server = transport_server  | 
|
1704  | 
self._transport_readonly_server = transport_readonly_server  | 
|
1705  | 
self._formats = formats  | 
|
1706  | 
||
1707  | 
def adapt(self, test):  | 
|
1708  | 
result = TestSuite()  | 
|
1709  | 
for repository_format, bzrdir_format in self._formats:  | 
|
1710  | 
new_test = deepcopy(test)  | 
|
1711  | 
new_test.transport_server = self._transport_server  | 
|
1712  | 
new_test.transport_readonly_server = self._transport_readonly_server  | 
|
1713  | 
new_test.bzrdir_format = bzrdir_format  | 
|
1714  | 
new_test.repository_format = repository_format  | 
|
1715  | 
def make_new_test_id():  | 
|
1716  | 
new_id = "%s(%s)" % (new_test.id(), repository_format.__class__.__name__)  | 
|
1717  | 
return lambda: new_id  | 
|
1718  | 
new_test.id = make_new_test_id()  | 
|
1719  | 
result.addTest(new_test)  | 
|
1720  | 
return result  | 
|
| 
1534.1.29
by Robert Collins
 Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.  | 
1721  | 
|
1722  | 
||
1723  | 
class InterRepositoryTestProviderAdapter(object):  | 
|
1724  | 
"""A tool to generate a suite testing multiple inter repository formats.  | 
|
1725  | 
||
1726  | 
    This is done by copying the test once for each interrepo provider and injecting
 | 
|
1727  | 
    the transport_server, transport_readonly_server, repository_format and 
 | 
|
1728  | 
    repository_to_format classes into each copy.
 | 
|
1729  | 
    Each copy is also given a new id() to make it easy to identify.
 | 
|
1730  | 
    """
 | 
|
1731  | 
||
1732  | 
def __init__(self, transport_server, transport_readonly_server, formats):  | 
|
1733  | 
self._transport_server = transport_server  | 
|
1734  | 
self._transport_readonly_server = transport_readonly_server  | 
|
1735  | 
self._formats = formats  | 
|
1736  | 
||
1737  | 
def adapt(self, test):  | 
|
1738  | 
result = TestSuite()  | 
|
1739  | 
for interrepo_class, repository_format, repository_format_to in self._formats:  | 
|
1740  | 
new_test = deepcopy(test)  | 
|
1741  | 
new_test.transport_server = self._transport_server  | 
|
1742  | 
new_test.transport_readonly_server = self._transport_readonly_server  | 
|
1743  | 
new_test.interrepo_class = interrepo_class  | 
|
1744  | 
new_test.repository_format = repository_format  | 
|
1745  | 
new_test.repository_format_to = repository_format_to  | 
|
1746  | 
def make_new_test_id():  | 
|
1747  | 
new_id = "%s(%s)" % (new_test.id(), interrepo_class.__name__)  | 
|
1748  | 
return lambda: new_id  | 
|
1749  | 
new_test.id = make_new_test_id()  | 
|
1750  | 
result.addTest(new_test)  | 
|
1751  | 
return result  | 
|
1752  | 
||
1753  | 
    @staticmethod
 | 
|
1754  | 
def default_test_list():  | 
|
1755  | 
"""Generate the default list of interrepo permutations to test."""  | 
|
1756  | 
result = []  | 
|
1757  | 
        # test the default InterRepository between format 6 and the current 
 | 
|
1758  | 
        # default format.
 | 
|
| 
1534.1.33
by Robert Collins
 Move copy_content_into into InterRepository and InterWeaveRepo, and disable the default codepath test as we have optimised paths for all current combinations.  | 
1759  | 
        # XXX: robertc 20060220 reinstate this when there are two supported
 | 
1760  | 
        # formats which do not have an optimal code path between them.
 | 
|
| 
1556.1.3
by Robert Collins
 Rearrangment of Repository logic to be less type code driven, and bugfix InterRepository.missing_revision_ids  | 
1761  | 
result.append((InterRepository,  | 
1762  | 
RepositoryFormat6(),  | 
|
1763  | 
RepositoryFormatKnit1()))  | 
|
| 
1534.1.29
by Robert Collins
 Add a test environment for InterRepository objects, and remove the fetch corner case tests from test_repository.  | 
1764  | 
for optimiser in InterRepository._optimisers:  | 
1765  | 
result.append((optimiser,  | 
|
1766  | 
optimiser._matching_repo_format,  | 
|
1767  | 
optimiser._matching_repo_format  | 
|
1768  | 
                           ))
 | 
|
1769  | 
        # if there are specific combinations we want to use, we can add them 
 | 
|
1770  | 
        # here.
 | 
|
1771  | 
return result  | 
|
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1772  | 
|
1773  | 
||
1774  | 
class CopyConverter(object):  | 
|
1775  | 
"""A repository conversion tool which just performs a copy of the content.  | 
|
1776  | 
    
 | 
|
1777  | 
    This is slow but quite reliable.
 | 
|
1778  | 
    """
 | 
|
1779  | 
||
1780  | 
def __init__(self, target_format):  | 
|
1781  | 
"""Create a CopyConverter.  | 
|
1782  | 
||
1783  | 
        :param target_format: The format the resulting repository should be.
 | 
|
1784  | 
        """
 | 
|
1785  | 
self.target_format = target_format  | 
|
1786  | 
||
1787  | 
def convert(self, repo, pb):  | 
|
1788  | 
"""Perform the conversion of to_convert, giving feedback via pb.  | 
|
1789  | 
||
1790  | 
        :param to_convert: The disk object to convert.
 | 
|
1791  | 
        :param pb: a progress bar to use for progress information.
 | 
|
1792  | 
        """
 | 
|
1793  | 
self.pb = pb  | 
|
1794  | 
self.count = 0  | 
|
| 
1596.2.22
by Robert Collins
 Fetch changes to use new pb.  | 
1795  | 
self.total = 4  | 
| 
1556.1.4
by Robert Collins
 Add a new format for what will become knit, and the surrounding logic to upgrade repositories within metadirs, and tests for the same.  | 
1796  | 
        # this is only useful with metadir layouts - separated repo content.
 | 
1797  | 
        # trigger an assertion if not such
 | 
|
1798  | 
repo._format.get_format_string()  | 
|
1799  | 
self.repo_dir = repo.bzrdir  | 
|
1800  | 
self.step('Moving repository to repository.backup')  | 
|
1801  | 
self.repo_dir.transport.move('repository', 'repository.backup')  | 
|
1802  | 
backup_transport = self.repo_dir.transport.clone('repository.backup')  | 
|
1803  | 
self.source_repo = repo._format.open(self.repo_dir,  | 
|
1804  | 
_found=True,  | 
|
1805  | 
_override_transport=backup_transport)  | 
|
1806  | 
self.step('Creating new repository')  | 
|
1807  | 
converted = self.target_format.initialize(self.repo_dir,  | 
|
1808  | 
self.source_repo.is_shared())  | 
|
1809  | 
converted.lock_write()  | 
|
1810  | 
try:  | 
|
1811  | 
self.step('Copying content into repository.')  | 
|
1812  | 
self.source_repo.copy_content_into(converted)  | 
|
1813  | 
finally:  | 
|
1814  | 
converted.unlock()  | 
|
1815  | 
self.step('Deleting old repository content.')  | 
|
1816  | 
self.repo_dir.transport.delete_tree('repository.backup')  | 
|
1817  | 
self.pb.note('repository converted')  | 
|
1818  | 
||
1819  | 
def step(self, message):  | 
|
1820  | 
"""Update the pb by a step."""  | 
|
1821  | 
self.count +=1  | 
|
1822  | 
self.pb.update(message, self.count, self.total)  | 
|
| 
1596.1.1
by Martin Pool
 Use simple xml unescaping rather than importing xml.sax  | 
1823  | 
|
1824  | 
||
1825  | 
# Copied from xml.sax.saxutils
 | 
|
1826  | 
def _unescape_xml(data):  | 
|
1827  | 
"""Unescape &, <, and > in a string of data.  | 
|
1828  | 
    """
 | 
|
1829  | 
data = data.replace("<", "<")  | 
|
1830  | 
data = data.replace(">", ">")  | 
|
1831  | 
    # must do ampersand last
 | 
|
1832  | 
return data.replace("&", "&")  |