/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
70 by mbp at sourcefrog
Prepare for smart recursive add.
1
# Copyright (C) 2005 Canonical Ltd
2
1 by mbp at sourcefrog
import from baz patch-364
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
16
17
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
18
from copy import deepcopy
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
19
from cStringIO import StringIO
20
import errno
21
import os
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
22
import shutil
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
23
import sys
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
24
from unittest import TestSuite
1372 by Martin Pool
- avoid converting inventories to/from StringIO
25
from warnings import warn
1540.1.6 by John Arbash Meinel
fileid_involved needs to unescape the file id and revision id
26
import xml.sax.saxutils
1372 by Martin Pool
- avoid converting inventories to/from StringIO
27
1 by mbp at sourcefrog
import from baz patch-364
28
29
import bzrlib
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
30
from bzrlib.config import TreeConfig
1534.4.28 by Robert Collins
first cut at merge from integration.
31
from bzrlib.decorators import needs_read_lock, needs_write_lock
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
32
from bzrlib.delta import compare_trees
33
import bzrlib.errors as errors
34
from bzrlib.errors import (BzrError, InvalidRevisionNumber, InvalidRevisionId,
35
                           NoSuchRevision, HistoryMissing, NotBranchError,
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
36
                           DivergedBranches, LockError, 
37
                           UninitializableFormat,
38
                           UnlistableStore,
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
39
                           UnlistableBranch, NoSuchFile, NotVersionedError,
40
                           NoWorkingTree)
1185.65.15 by Robert Collins
Merge from integration.
41
import bzrlib.inventory as inventory
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
42
from bzrlib.inventory import Inventory
1185.65.14 by Robert Collins
Merge from aaron. Whee, we are synced. Yay. Begone the foul demons of merge conflicts.
43
from bzrlib.lockable_files import LockableFiles
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
44
from bzrlib.osutils import (isdir, quotefn,
1185.31.32 by John Arbash Meinel
Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \
45
                            rename, splitpath, sha_file,
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
46
                            file_kind, abspath, normpath, pathjoin,
47
                            safe_unicode,
48
                            )
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
49
from bzrlib.textui import show_status
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
50
from bzrlib.trace import mutter, note
51
from bzrlib.tree import EmptyTree, RevisionTree
1534.4.28 by Robert Collins
first cut at merge from integration.
52
from bzrlib.repository import Repository
1185.65.14 by Robert Collins
Merge from aaron. Whee, we are synced. Yay. Begone the foul demons of merge conflicts.
53
from bzrlib.revision import (Revision, is_ancestor, get_intervening_revisions)
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
54
from bzrlib.store import copy_all
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
55
from bzrlib.symbol_versioning import *
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
56
import bzrlib.transactions as transactions
1393.2.4 by John Arbash Meinel
All tests pass.
57
from bzrlib.transport import Transport, get_transport
1185.65.15 by Robert Collins
Merge from integration.
58
from bzrlib.tree import EmptyTree, RevisionTree
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
59
import bzrlib.ui
1189 by Martin Pool
- BROKEN: partial support for commit into weave
60
import bzrlib.xml5
1104 by Martin Pool
- Add a simple UIFactory
61
1094 by Martin Pool
- merge aaron's merge improvements 999..1008
62
1186 by Martin Pool
- start implementing v5 format; Branch refuses to operate on old branches
63
BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
64
BZR_BRANCH_FORMAT_5 = "Bazaar-NG branch, format 5\n"
1429 by Robert Collins
merge in niemeyers prefixed-store patch
65
BZR_BRANCH_FORMAT_6 = "Bazaar-NG branch, format 6\n"
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
66
67
68
# TODO: Maybe include checks for common corruption of newlines, etc?
1 by mbp at sourcefrog
import from baz patch-364
69
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
70
# TODO: Some operations like log might retrieve the same revisions
71
# repeatedly to calculate deltas.  We could perhaps have a weakref
1223 by Martin Pool
- store inventories in weave
72
# cache in memory to make this faster.  In general anything can be
1185.65.29 by Robert Collins
Implement final review suggestions.
73
# cached in memory between lock and unlock operations. .. nb thats
74
# what the transaction identity map provides
416 by Martin Pool
- bzr log and bzr root now accept an http URL
75
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
76
1 by mbp at sourcefrog
import from baz patch-364
77
######################################################################
78
# branch objects
79
558 by Martin Pool
- All top-level classes inherit from object
80
class Branch(object):
1 by mbp at sourcefrog
import from baz patch-364
81
    """Branch holding a history of revisions.
82
343 by Martin Pool
doc
83
    base
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
84
        Base directory/url of the branch.
85
    """
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
86
    # this is really an instance variable - FIXME move it there
87
    # - RBC 20060112
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
88
    base = None
89
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
90
    _default_initializer = None
91
    """The default initializer for making new branches."""
92
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
93
    def __init__(self, *ignored, **ignored_too):
94
        raise NotImplementedError('The Branch class is abstract')
95
96
    @staticmethod
1393.1.2 by Martin Pool
- better representation in Branch factories of opening old formats
97
    def open_downlevel(base):
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
98
        """Open a branch which may be of an old format."""
99
        return Branch.open(base, _unsupported=True)
1393.1.2 by Martin Pool
- better representation in Branch factories of opening old formats
100
        
101
    @staticmethod
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
102
    def open(base, _unsupported=False):
103
        """Open an existing branch, rooted at 'base' (url)
104
        
105
        _unsupported is a private parameter to the Branch class.
106
        """
1393.2.4 by John Arbash Meinel
All tests pass.
107
        t = get_transport(base)
1393.1.63 by Martin Pool
- add some trace statements
108
        mutter("trying to open %r with transport %r", base, t)
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
109
        format = BzrBranchFormat.find_format(t)
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
110
        if not _unsupported and not format.is_supported():
111
            # see open_downlevel to open legacy branches.
112
            raise errors.UnsupportedFormatError(
113
                    'sorry, branch format %s not supported' % format,
114
                    ['use a different bzr version',
115
                     'or remove the .bzr directory'
116
                     ' and "bzr init" again'])
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
117
        return format.open(t)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
118
119
    @staticmethod
1185.2.8 by Lalo Martins
creating the new branch constructors
120
    def open_containing(url):
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
121
        """Open an existing branch which contains url.
122
        
123
        This probes for a branch at url, and searches upwards from there.
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
124
125
        Basically we keep looking up until we find the control directory or
126
        run into the root.  If there isn't one, raises NotBranchError.
1534.4.22 by Robert Collins
update TODOs and move abstract methods that were misplaced on BzrBranchFormat5 to Branch.
127
        If there is one and it is either an unrecognised format or an unsupported 
128
        format, UnknownFormatError or UnsupportedFormatError are raised.
1442.1.64 by Robert Collins
Branch.open_containing now returns a tuple (Branch, relative-path).
129
        If there is one, it is returned, along with the unused portion of url.
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
130
        """
1393.2.4 by John Arbash Meinel
All tests pass.
131
        t = get_transport(url)
1534.4.22 by Robert Collins
update TODOs and move abstract methods that were misplaced on BzrBranchFormat5 to Branch.
132
        # this gets the normalised url back. I.e. '.' -> the full path.
1534.4.11 by Robert Collins
Convert test_open_containing from being a Remote test to being the more accurate Chrooted test.
133
        url = t.base
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
134
        while True:
135
            try:
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
136
                format = BzrBranchFormat.find_format(t)
137
                return format.open(t), t.relpath(url)
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
138
            except NotBranchError, e:
139
                mutter('not a branch in: %r %s', t.base, e)
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
140
            new_t = t.clone('..')
141
            if new_t.base == t.base:
142
                # reached the root, whatever that may be
1185.16.61 by mbp at sourcefrog
- start introducing hct error classes
143
                raise NotBranchError(path=url)
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
144
            t = new_t
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
145
146
    @staticmethod
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
147
    def create(base):
148
        """Create a new Branch at the url 'bzr'.
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
149
        
150
        This will call the current default initializer with base
151
        as the only parameter.
152
        """
153
        return Branch._default_initializer(safe_unicode(base))
154
155
    @staticmethod
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
156
    @deprecated_function(zero_eight)
157
    def initialize(base):
158
        """Create a new working tree and branch, rooted at 'base' (url)
159
        """
160
        # imported here to prevent scope creep as this is going.
161
        from bzrlib.workingtree import WorkingTree
162
        return WorkingTree.create_standalone(safe_unicode(base)).branch
163
164
    @staticmethod
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
165
    def get_default_initializer():
166
        """Return the initializer being used for new branches."""
167
        return Branch._default_initializer
168
169
    @staticmethod
170
    def set_default_initializer(initializer):
171
        """Set the initializer to be used for new branches."""
172
        Branch._default_initializer = staticmethod(initializer)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
173
174
    def setup_caching(self, cache_root):
175
        """Subclasses that care about caching should override this, and set
176
        up cached stores located under cache_root.
177
        """
1185.70.6 by Martin Pool
review fixups from John
178
        # seems to be unused, 2006-01-13 mbp
179
        warn('%s is deprecated' % self.setup_caching)
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
180
        self.cache_root = cache_root
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
181
1185.35.11 by Aaron Bentley
Added support for branch nicks
182
    def _get_nick(self):
183
        cfg = self.tree_config()
1530.1.3 by Robert Collins
transport implementations now tested consistently.
184
        return cfg.get_option(u"nickname", default=self.base.split('/')[-2])
1185.35.11 by Aaron Bentley
Added support for branch nicks
185
186
    def _set_nick(self, nick):
187
        cfg = self.tree_config()
188
        cfg.set_option(nick, "nickname")
189
        assert cfg.get_option("nickname") == nick
190
191
    nick = property(_get_nick, _set_nick)
192
        
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
193
    def push_stores(self, branch_to):
194
        """Copy the content of this branches store to branch_to."""
195
        raise NotImplementedError('push_stores is abstract')
196
197
    def lock_write(self):
198
        raise NotImplementedError('lock_write is abstract')
199
        
200
    def lock_read(self):
201
        raise NotImplementedError('lock_read is abstract')
202
203
    def unlock(self):
204
        raise NotImplementedError('unlock is abstract')
205
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
206
    def peek_lock_mode(self):
207
        """Return lock mode for the Branch: 'r', 'w' or None"""
1185.70.6 by Martin Pool
review fixups from John
208
        raise NotImplementedError(self.peek_lock_mode)
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
209
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
210
    def abspath(self, name):
211
        """Return absolute filename for something in the branch
212
        
213
        XXX: Robert Collins 20051017 what is this used for? why is it a branch
214
        method and not a tree method.
215
        """
216
        raise NotImplementedError('abspath is abstract')
217
218
    def get_root_id(self):
219
        """Return the id of this branches root"""
220
        raise NotImplementedError('get_root_id is abstract')
221
1185.50.9 by John Arbash Meinel
[bug 3632] Matthieu Moy- bzr cat should default to last revision
222
    def print_file(self, file, revision_id):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
223
        """Print `file` to stdout."""
224
        raise NotImplementedError('print_file is abstract')
225
226
    def append_revision(self, *revision_ids):
227
        raise NotImplementedError('append_revision is abstract')
228
229
    def set_revision_history(self, rev_history):
230
        raise NotImplementedError('set_revision_history is abstract')
231
232
    def revision_history(self):
233
        """Return sequence of revision hashes on to this branch."""
234
        raise NotImplementedError('revision_history is abstract')
235
236
    def revno(self):
237
        """Return current revision number for this branch.
238
239
        That is equivalent to the number of revisions committed to
240
        this branch.
241
        """
242
        return len(self.revision_history())
243
244
    def last_revision(self):
245
        """Return last patch hash, or None if no history."""
246
        ph = self.revision_history()
247
        if ph:
248
            return ph[-1]
249
        else:
250
            return None
251
252
    def missing_revisions(self, other, stop_revision=None, diverged_ok=False):
253
        """Return a list of new revisions that would perfectly fit.
254
        
255
        If self and other have not diverged, return a list of the revisions
256
        present in other, but missing from self.
257
258
        >>> bzrlib.trace.silent = True
259
        >>> br1 = ScratchBranch()
260
        >>> br2 = ScratchBranch()
261
        >>> br1.missing_revisions(br2)
262
        []
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
263
        >>> br2.working_tree().commit("lala!", rev_id="REVISION-ID-1")
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
264
        >>> br1.missing_revisions(br2)
265
        [u'REVISION-ID-1']
266
        >>> br2.missing_revisions(br1)
267
        []
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
268
        >>> br1.working_tree().commit("lala!", rev_id="REVISION-ID-1")
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
269
        >>> br1.missing_revisions(br2)
270
        []
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
271
        >>> br2.working_tree().commit("lala!", rev_id="REVISION-ID-2A")
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
272
        >>> br1.missing_revisions(br2)
273
        [u'REVISION-ID-2A']
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
274
        >>> br1.working_tree().commit("lala!", rev_id="REVISION-ID-2B")
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
275
        >>> br1.missing_revisions(br2)
276
        Traceback (most recent call last):
1185.56.1 by Michael Ellerman
Simplify handling of DivergedBranches in cmd_pull()
277
        DivergedBranches: These branches have diverged.  Try merge.
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
278
        """
279
        self_history = self.revision_history()
280
        self_len = len(self_history)
281
        other_history = other.revision_history()
282
        other_len = len(other_history)
283
        common_index = min(self_len, other_len) -1
284
        if common_index >= 0 and \
285
            self_history[common_index] != other_history[common_index]:
286
            raise DivergedBranches(self, other)
287
288
        if stop_revision is None:
289
            stop_revision = other_len
290
        else:
291
            assert isinstance(stop_revision, int)
292
            if stop_revision > other_len:
293
                raise bzrlib.errors.NoSuchRevision(self, stop_revision)
294
        return other_history[self_len:stop_revision]
1185.66.1 by Aaron Bentley
Merged from mainline
295
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
296
    def update_revisions(self, other, stop_revision=None):
297
        """Pull in new perfect-fit revisions."""
298
        raise NotImplementedError('update_revisions is abstract')
299
300
    def pullable_revisions(self, other, stop_revision):
301
        raise NotImplementedError('pullable_revisions is abstract')
302
        
303
    def revision_id_to_revno(self, revision_id):
304
        """Given a revision id, return its revno"""
305
        if revision_id is None:
306
            return 0
307
        history = self.revision_history()
308
        try:
309
            return history.index(revision_id) + 1
310
        except ValueError:
311
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
312
313
    def get_rev_id(self, revno, history=None):
314
        """Find the revision id of the specified revno."""
315
        if revno == 0:
316
            return None
317
        if history is None:
318
            history = self.revision_history()
319
        elif revno <= 0 or revno > len(history):
320
            raise bzrlib.errors.NoSuchRevision(self, revno)
321
        return history[revno - 1]
322
323
    def pull(self, source, overwrite=False):
324
        raise NotImplementedError('pull is abstract')
325
326
    def basis_tree(self):
327
        """Return `Tree` object for last revision.
328
329
        If there are no revisions yet, return an `EmptyTree`.
330
        """
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
331
        return self.repository.revision_tree(self.last_revision())
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
332
333
    def rename_one(self, from_rel, to_rel):
334
        """Rename one file.
335
336
        This can change the directory or the filename or both.
337
        """
338
        raise NotImplementedError('rename_one is abstract')
339
340
    def move(self, from_paths, to_name):
341
        """Rename files.
342
343
        to_name must exist as a versioned directory.
344
345
        If to_name exists and is a directory, the files are moved into
346
        it, keeping their old names.  If it is a directory, 
347
348
        Note that to_name is only the last component of the new name;
349
        this doesn't change the directory.
350
351
        This returns a list of (from_path, to_path) pairs for each
352
        entry that is moved.
353
        """
354
        raise NotImplementedError('move is abstract')
355
356
    def get_parent(self):
357
        """Return the parent location of the branch.
358
359
        This is the default location for push/pull/missing.  The usual
360
        pattern is that the user can override it by specifying a
361
        location.
362
        """
363
        raise NotImplementedError('get_parent is abstract')
364
365
    def get_push_location(self):
366
        """Return the None or the location to push this branch to."""
367
        raise NotImplementedError('get_push_location is abstract')
368
369
    def set_push_location(self, location):
370
        """Set a new push location for this branch."""
371
        raise NotImplementedError('set_push_location is abstract')
372
373
    def set_parent(self, url):
374
        raise NotImplementedError('set_parent is abstract')
375
376
    def check_revno(self, revno):
377
        """\
378
        Check whether a revno corresponds to any revision.
379
        Zero (the NULL revision) is considered valid.
380
        """
381
        if revno != 0:
382
            self.check_real_revno(revno)
383
            
384
    def check_real_revno(self, revno):
385
        """\
386
        Check whether a revno corresponds to a real revision.
387
        Zero (the NULL revision) is considered invalid
388
        """
389
        if revno < 1 or revno > self.revno():
390
            raise InvalidRevisionNumber(revno)
391
        
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
392
    def clone(self, to_location, revision=None, basis_branch=None, to_branch_format=None):
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
393
        """Copy this branch into the existing directory to_location.
394
395
        Returns the newly created branch object.
396
397
        revision
398
            If not None, only revisions up to this point will be copied.
399
            The head of the new branch will be that revision.  Must be a
400
            revid or None.
401
    
402
        to_location -- The destination directory; must either exist and be 
403
            empty, or not exist, in which case it is created.
404
    
405
        basis_branch
406
            A local branch to copy revisions from, related to this branch. 
407
            This is used when branching from a remote (slow) branch, and we have
408
            a local branch that might contain some relevant revisions.
409
    
410
        to_branch_type
411
            Branch type of destination branch
412
        """
1534.4.28 by Robert Collins
first cut at merge from integration.
413
        from bzrlib.workingtree import WorkingTree
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
414
        assert isinstance(to_location, basestring)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
415
        segments = to_location.split('/')
416
        if segments and segments[-1] not in ('', '.'):
417
            parent = '/'.join(segments[:-1])
418
            t = get_transport(parent)
419
            try:
420
                t.mkdir(segments[-1])
421
            except errors.FileExists:
422
                pass
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
423
        if to_branch_format is None:
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
424
            # use the default
425
            br_to = Branch.create(to_location)
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
426
        else:
427
            br_to = to_branch_format.initialize(to_location)
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
428
        mutter("copy branch from %s to %s", self, br_to)
429
        if basis_branch is not None:
430
            basis_branch.push_stores(br_to)
431
        if revision is None:
432
            revision = self.last_revision()
433
        br_to.update_revisions(self, stop_revision=revision)
434
        br_to.set_parent(self.base)
435
        mutter("copied")
436
        return br_to
1185.66.1 by Aaron Bentley
Merged from mainline
437
1534.4.22 by Robert Collins
update TODOs and move abstract methods that were misplaced on BzrBranchFormat5 to Branch.
438
    def fileid_involved_between_revs(self, from_revid, to_revid):
439
        """ This function returns the file_id(s) involved in the
440
            changes between the from_revid revision and the to_revid
441
            revision
442
        """
443
        raise NotImplementedError('fileid_involved_between_revs is abstract')
444
445
    def fileid_involved(self, last_revid=None):
446
        """ This function returns the file_id(s) involved in the
447
            changes up to the revision last_revid
448
            If no parametr is passed, then all file_id[s] present in the
449
            repository are returned
450
        """
451
        raise NotImplementedError('fileid_involved is abstract')
452
453
    def fileid_involved_by_set(self, changes):
454
        """ This function returns the file_id(s) involved in the
455
            changes present in the set 'changes'
456
        """
457
        raise NotImplementedError('fileid_involved_by_set is abstract')
458
459
    def fileid_involved_between_revs(self, from_revid, to_revid):
460
        """ This function returns the file_id(s) involved in the
461
            changes between the from_revid revision and the to_revid
462
            revision
463
        """
464
        raise NotImplementedError('fileid_involved_between_revs is abstract')
465
466
    def fileid_involved(self, last_revid=None):
467
        """ This function returns the file_id(s) involved in the
468
            changes up to the revision last_revid
469
            If no parametr is passed, then all file_id[s] present in the
470
            repository are returned
471
        """
472
        raise NotImplementedError('fileid_involved is abstract')
473
474
    def fileid_involved_by_set(self, changes):
475
        """ This function returns the file_id(s) involved in the
476
            changes present in the set 'changes'
477
        """
478
        raise NotImplementedError('fileid_involved_by_set is abstract')
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
479
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
480
class BzrBranchFormat(object):
481
    """An encapsulation of the initialization and open routines for a format.
482
483
    Formats provide three things:
484
     * An initialization routine,
485
     * a format string,
486
     * an open routine.
487
488
    Formats are placed in an dict by their format string for reference 
489
    during branch opening. Its not required that these be instances, they
490
    can be classes themselves with class methods - it simply depends on 
491
    whether state is needed for a given format or not.
492
493
    Once a format is deprecated, just deprecate the initialize and open
494
    methods on the format class. Do not deprecate the object, as the 
495
    object will be created every time regardless.
496
    """
497
498
    _formats = {}
499
    """The known formats."""
500
501
    @classmethod
1534.4.4 by Robert Collins
Make BzrBranchFormat.find_format take a transport not a url for efficiency.
502
    def find_format(klass, transport):
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
503
        """Return the format registered for URL."""
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
504
        try:
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
505
            format_string = transport.get(".bzr/branch-format").read()
506
            return klass._formats[format_string]
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
507
        except NoSuchFile:
508
            raise NotBranchError(path=transport.base)
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
509
        except KeyError:
510
            raise errors.UnknownFormatError(format_string)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
511
512
    def get_format_string(self):
513
        """Return the ASCII format string that identifies this format."""
514
        raise NotImplementedError(self.get_format_string)
515
516
    def _find_modes(self, t):
517
        """Determine the appropriate modes for files and directories.
518
        
519
        FIXME: When this merges into, or from storage,
520
        this code becomes delgatable to a LockableFiles instance.
521
522
        For now its cribbed and returns (dir_mode, file_mode)
523
        """
524
        try:
525
            st = t.stat('.')
526
        except errors.TransportNotPossible:
527
            dir_mode = 0755
528
            file_mode = 0644
529
        else:
530
            dir_mode = st.st_mode & 07777
531
            # Remove the sticky and execute bits for files
532
            file_mode = dir_mode & ~07111
533
        if not BzrBranch._set_dir_mode:
534
            dir_mode = None
535
        if not BzrBranch._set_file_mode:
536
            file_mode = None
537
        return dir_mode, file_mode
538
539
    def initialize(self, url):
540
        """Create a branch of this format at url and return an open branch."""
541
        t = get_transport(url)
542
        from bzrlib.weavefile import write_weave_v5
543
        from bzrlib.weave import Weave
544
        
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
545
        # Create an empty weave
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
546
        sio = StringIO()
547
        bzrlib.weavefile.write_weave_v5(Weave(), sio)
548
        empty_weave = sio.getvalue()
549
550
        # Since we don't have a .bzr directory, inherit the
551
        # mode from the root directory
1534.4.28 by Robert Collins
first cut at merge from integration.
552
        temp_control = LockableFiles(t, '')
553
        temp_control._transport.mkdir('.bzr',
554
                                      mode=temp_control._dir_mode)
555
        file_mode = temp_control._file_mode
556
        del temp_control
557
        mutter('created control directory in ' + t.base)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
558
        control = t.clone('.bzr')
559
        dirs = ['revision-store', 'weaves']
1534.4.28 by Robert Collins
first cut at merge from integration.
560
        lock_file = 'branch-lock'
561
        utf8_files = [('README', 
562
                       "This is a Bazaar-NG control directory.\n"
563
                       "Do not change any files in this directory.\n"),
564
                      ('branch-format', self.get_format_string()),
565
                      ('revision-history', ''),
566
                      ('branch-name', ''),
567
                      ]
568
        files = [('inventory.weave', StringIO(empty_weave)), 
569
                 ]
570
        
571
        # FIXME: RBC 20060125 dont peek under the covers
572
        # NB: no need to escape relative paths that are url safe.
573
        control.put(lock_file, StringIO(), mode=file_mode)
574
        control_files = LockableFiles(control, lock_file)
575
        control_files.lock_write()
576
        control_files._transport.mkdir_multi(dirs,
577
                mode=control_files._dir_mode)
578
        try:
579
            for file, content in utf8_files:
580
                control_files.put_utf8(file, content)
581
            for file, content in files:
582
                control_files.put(file, content)
583
        finally:
584
            control_files.unlock()
585
        return BzrBranch(t, _format=self, _control_files=control_files)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
586
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
587
    def is_supported(self):
588
        """Is this format supported?
589
590
        Supported formats can be initialized and opened.
591
        Unsupported formats may not support initialization or committing or 
592
        some other features depending on the reason for not being supported.
593
        """
594
        return True
595
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
596
    def open(self, transport):
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
597
        """Fill out the data in branch for the branch at url."""
1534.4.28 by Robert Collins
first cut at merge from integration.
598
        return BzrBranch(transport, _format=self)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
599
600
    @classmethod
601
    def register_format(klass, format):
602
        klass._formats[format.get_format_string()] = format
603
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
604
    @classmethod
605
    def unregister_format(klass, format):
606
        assert klass._formats[format.get_format_string()] is format
607
        del klass._formats[format.get_format_string()]
608
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
609
610
class BzrBranchFormat4(BzrBranchFormat):
611
    """Bzr branch format 4.
612
613
    This format has:
614
     - flat stores
615
     - TextStores for texts, inventories,revisions.
616
617
    This format is deprecated: it indexes texts using a text it which is
618
    removed in format 5; write support for this format has been removed.
619
    """
620
621
    def get_format_string(self):
622
        """See BzrBranchFormat.get_format_string()."""
623
        return BZR_BRANCH_FORMAT_4
624
625
    def initialize(self, url):
626
        """Format 4 branches cannot be created."""
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
627
        raise UninitializableFormat(self)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
628
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
629
    def is_supported(self):
630
        """Format 4 is not supported.
631
632
        It is not supported because the model changed from 4 to 5 and the
633
        conversion logic is expensive - so doing it on the fly was not 
634
        feasible.
635
        """
636
        return False
637
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
638
639
class BzrBranchFormat5(BzrBranchFormat):
640
    """Bzr branch format 5.
641
642
    This format has:
643
     - weaves for file texts and inventory
644
     - flat stores
645
     - TextStores for revisions and signatures.
646
    """
647
648
    def get_format_string(self):
649
        """See BzrBranchFormat.get_format_string()."""
650
        return BZR_BRANCH_FORMAT_5
651
652
653
class BzrBranchFormat6(BzrBranchFormat):
654
    """Bzr branch format 6.
655
656
    This format has:
657
     - weaves for file texts and inventory
658
     - hash subdirectory based stores.
659
     - TextStores for revisions and signatures.
660
    """
661
662
    def get_format_string(self):
663
        """See BzrBranchFormat.get_format_string()."""
664
        return BZR_BRANCH_FORMAT_6
665
666
667
BzrBranchFormat.register_format(BzrBranchFormat4())
668
BzrBranchFormat.register_format(BzrBranchFormat5())
669
BzrBranchFormat.register_format(BzrBranchFormat6())
670
1534.4.19 by Robert Collins
merge from integration.
671
# TODO: jam 20060108 Create a new branch format, and as part of upgrade
672
#       make sure that ancestry.weave is deleted (it is never used, but
673
#       used to be created)
1534.1.10 by Robert Collins
Merge from jam-integration.
674
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
675
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
676
class BzrBranch(Branch):
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
677
    """A branch stored in the actual filesystem.
678
679
    Note that it's "local" in the context of the filesystem; it doesn't
680
    really matter if it's on an nfs/smb/afs/coda/... share, as long as
681
    it's writable, and can be accessed via the normal filesystem API.
578 by Martin Pool
- start to move toward Branch.lock and unlock methods,
682
1 by mbp at sourcefrog
import from baz patch-364
683
    """
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
684
    # We actually expect this class to be somewhat short-lived; part of its
685
    # purpose is to try to isolate what bits of the branch logic are tied to
686
    # filesystem access, so that in a later step, we can extricate them to
687
    # a separarte ("storage") class.
1223 by Martin Pool
- store inventories in weave
688
    _inventory_weave = None
353 by Martin Pool
- Per-branch locks in read and write modes.
689
    
897 by Martin Pool
- merge john's revision-naming code
690
    # Map some sort of prefix into a namespace
691
    # stuff like "revno:10", "revid:", etc.
692
    # This should match a prefix with a function which accepts
693
    REVISION_NAMESPACES = {}
694
1391 by Robert Collins
merge from integration
695
    def push_stores(self, branch_to):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
696
        """See Branch.push_stores."""
1534.4.8 by Robert Collins
Unfuck upgrade.
697
        if (not isinstance(self._branch_format, BzrBranchFormat4) or
698
            self._branch_format != branch_to._branch_format):
1391 by Robert Collins
merge from integration
699
            from bzrlib.fetch import greedy_fetch
1534.4.8 by Robert Collins
Unfuck upgrade.
700
            mutter("Using fetch logic to push between %s(%s) and %s(%s)",
1393 by Robert Collins
reenable remotebranch tests
701
                   self, self._branch_format, branch_to, branch_to._branch_format)
1391 by Robert Collins
merge from integration
702
            greedy_fetch(to_branch=branch_to, from_branch=self,
703
                         revision=self.last_revision())
704
            return
705
1534.4.8 by Robert Collins
Unfuck upgrade.
706
        # format 4 to format 4 logic only.
1391 by Robert Collins
merge from integration
707
        store_pairs = ((self.text_store,      branch_to.text_store),
708
                       (self.inventory_store, branch_to.inventory_store),
709
                       (self.revision_store,  branch_to.revision_store))
710
        try:
711
            for from_store, to_store in store_pairs: 
712
                copy_all(from_store, to_store)
713
        except UnlistableStore:
714
            raise UnlistableBranch(from_store)
715
1534.4.32 by Robert Collins
Rename deprecated_nonce to DEPRECATED_PARAMETER
716
    def __init__(self, transport, init=DEPRECATED_PARAMETER,
717
                 relax_version_check=DEPRECATED_PARAMETER, _format=None,
1534.4.28 by Robert Collins
first cut at merge from integration.
718
                 _control_files=None):
1 by mbp at sourcefrog
import from baz patch-364
719
        """Create new branch object at a particular location.
720
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
721
        transport -- A Transport object, defining how to access files.
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
722
        
254 by Martin Pool
- Doc cleanups from Magnus Therning
723
        init -- If True, create new control files in a previously
1 by mbp at sourcefrog
import from baz patch-364
724
             unversioned directory.  If False, the branch must already
725
             be versioned.
726
1293 by Martin Pool
- add Branch constructor option to relax version check
727
        relax_version_check -- If true, the usual check for the branch
728
            version is not applied.  This is intended only for
729
            upgrade/recovery type use; it's not guaranteed that
730
            all operations will work on old format branches.
731
1 by mbp at sourcefrog
import from baz patch-364
732
        In the test suite, creation of new trees is tested using the
733
        `ScratchBranch` class.
734
        """
1393.1.15 by Martin Pool
- better assertion message
735
        assert isinstance(transport, Transport), \
736
            "%r is not a Transport" % transport
907.1.8 by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport
737
        self._transport = transport
1534.4.28 by Robert Collins
first cut at merge from integration.
738
        self._base = self._transport.base
739
        if _control_files is None:
740
            _control_files = LockableFiles(self._transport.clone(bzrlib.BZRDIR),
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
741
                                           'branch-lock')
1534.4.28 by Robert Collins
first cut at merge from integration.
742
        self.control_files = _control_files
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
743
        if deprecated_passed(init):
744
            warn("BzrBranch.__init__(..., init=XXX): The init parameter is "
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
745
                 "deprecated as of bzr 0.8. Please use Branch.create().",
746
                 DeprecationWarning,
747
                 stacklevel=2)
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
748
            if init:
749
                # this is slower than before deprecation, oh well never mind.
750
                # -> its deprecated.
751
                self._initialize(transport.base)
1534.4.28 by Robert Collins
first cut at merge from integration.
752
        self._check_format(_format)
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
753
        if deprecated_passed(relax_version_check):
754
            warn("BzrBranch.__init__(..., relax_version_check=XXX_: The "
755
                 "relax_version_check parameter is deprecated as of bzr 0.8. "
756
                 "Please use Branch.open_downlevel, or a BzrBranchFormat's "
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
757
                 "open() method.",
758
                 DeprecationWarning,
759
                 stacklevel=2)
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
760
            if (not relax_version_check
1534.4.8 by Robert Collins
Unfuck upgrade.
761
                and not self._branch_format.is_supported()):
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
762
                raise errors.UnsupportedFormatError(
763
                        'sorry, branch format %r not supported' % fmt,
764
                        ['use a different bzr version',
765
                         'or remove the .bzr directory'
766
                         ' and "bzr init" again'])
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
767
        self.repository = Repository(transport, self._branch_format)
1 by mbp at sourcefrog
import from baz patch-364
768
769
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
770
    @staticmethod
771
    def _initialize(base):
772
        """Create a bzr branch in the latest format."""
1534.4.2 by Robert Collins
Introduce BranchFormats - factoring out intialisation of Branches.
773
        return BzrBranchFormat6().initialize(base)
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
774
1 by mbp at sourcefrog
import from baz patch-364
775
    def __str__(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
776
        return '%s(%r)' % (self.__class__.__name__, self.base)
1 by mbp at sourcefrog
import from baz patch-364
777
778
    __repr__ = __str__
779
578 by Martin Pool
- start to move toward Branch.lock and unlock methods,
780
    def __del__(self):
907.1.23 by John Arbash Meinel
Branch objects now automatically create Cached stores if the protocol is_remote.
781
        # TODO: It might be best to do this somewhere else,
782
        # but it is nice for a Branch object to automatically
783
        # cache it's information.
784
        # Alternatively, we could have the Transport objects cache requests
785
        # See the earlier discussion about how major objects (like Branch)
786
        # should never expect their __del__ function to run.
1185.70.6 by Martin Pool
review fixups from John
787
        # XXX: cache_root seems to be unused, 2006-01-13 mbp
1185.11.9 by John Arbash Meinel
Most tests pass, some problems with unavailable socket recv
788
        if hasattr(self, 'cache_root') and self.cache_root is not None:
907.1.23 by John Arbash Meinel
Branch objects now automatically create Cached stores if the protocol is_remote.
789
            try:
790
                shutil.rmtree(self.cache_root)
791
            except:
792
                pass
793
            self.cache_root = None
794
907.1.17 by John Arbash Meinel
Adding a Branch.base property, removing pull_loc()
795
    def _get_base(self):
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
796
        return self._base
907.1.17 by John Arbash Meinel
Adding a Branch.base property, removing pull_loc()
797
1442.1.5 by Robert Collins
Give branch.base a docstring.
798
    base = property(_get_base, doc="The URL for the root of this branch.")
578 by Martin Pool
- start to move toward Branch.lock and unlock methods,
799
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
800
    def _finish_transaction(self):
801
        """Exit the current transaction."""
1185.65.13 by Robert Collins
Merge from integration
802
        return self.control_files._finish_transaction()
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
803
804
    def get_transaction(self):
1185.65.13 by Robert Collins
Merge from integration
805
        """Return the current active transaction.
806
807
        If no transaction is active, this returns a passthrough object
808
        for which all data is immediately flushed and no caching happens.
809
        """
810
        # this is an explicit function so that we can do tricky stuff
811
        # when the storage in rev_storage is elsewhere.
812
        # we probably need to hook the two 'lock a location' and 
813
        # 'have a transaction' together more delicately, so that
814
        # we can have two locks (branch and storage) and one transaction
815
        # ... and finishing the transaction unlocks both, but unlocking
816
        # does not. - RBC 20051121
817
        return self.control_files.get_transaction()
818
819
    def _set_transaction(self, transaction):
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
820
        """Set a new active transaction."""
1185.65.13 by Robert Collins
Merge from integration
821
        return self.control_files._set_transaction(transaction)
353 by Martin Pool
- Per-branch locks in read and write modes.
822
67 by mbp at sourcefrog
use abspath() for the function that makes an absolute
823
    def abspath(self, name):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
824
        """See Branch.abspath."""
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
825
        return self.control_files._transport.abspath(name)
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
826
1534.4.7 by Robert Collins
Move downlevel check up to the Branch.open logic, removing it from the Branch constructor and deprecating relax_version_check to the same.
827
    def _check_format(self, format):
1534.4.8 by Robert Collins
Unfuck upgrade.
828
        """Identify the branch format if needed.
1 by mbp at sourcefrog
import from baz patch-364
829
1534.4.8 by Robert Collins
Unfuck upgrade.
830
        The format is stored as a reference to the format object in
1187 by Martin Pool
- improved check for branch version
831
        self._branch_format for code that needs to check it later.
1 by mbp at sourcefrog
import from baz patch-364
832
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
833
        The format parameter is either None or the branch format class
834
        used to open this branch.
163 by mbp at sourcefrog
merge win32 portability fixes
835
        """
1534.4.5 by Robert Collins
Turn branch format.open into a factory.
836
        if format is None:
837
            format = BzrBranchFormat.find_format(self._transport)
1534.4.8 by Robert Collins
Unfuck upgrade.
838
        self._branch_format = format
839
        mutter("got branch format %s", self._branch_format)
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
840
1508.1.15 by Robert Collins
Merge from mpool.
841
    @needs_read_lock
909 by Martin Pool
- merge John's code to give the tree root an explicit file id
842
    def get_root_id(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
843
        """See Branch.get_root_id."""
1534.4.28 by Robert Collins
first cut at merge from integration.
844
        tree = self.repository.revision_tree(self.last_revision())
845
        return tree.inventory.root.file_id
1 by mbp at sourcefrog
import from baz patch-364
846
1185.65.3 by Aaron Bentley
Fixed locking-- all tests pass
847
    def lock_write(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
848
        # TODO: test for failed two phase locks. This is known broken.
849
        self.control_files.lock_write()
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
850
        self.repository.lock_write()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
851
1185.65.3 by Aaron Bentley
Fixed locking-- all tests pass
852
    def lock_read(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
853
        # TODO: test for failed two phase locks. This is known broken.
854
        self.control_files.lock_read()
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
855
        self.repository.lock_read()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
856
857
    def unlock(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
858
        # TODO: test for failed two phase locks. This is known broken.
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
859
        self.repository.unlock()
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
860
        self.control_files.unlock()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
861
1185.70.3 by Martin Pool
Various updates to make storage branch mergeable:
862
    def peek_lock_mode(self):
863
        if self.control_files._lock_count == 0:
864
            return None
865
        else:
866
            return self.control_files._lock_mode
867
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
868
    @needs_read_lock
1185.50.9 by John Arbash Meinel
[bug 3632] Matthieu Moy- bzr cat should default to last revision
869
    def print_file(self, file, revision_id):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
870
        """See Branch.print_file."""
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
871
        return self.repository.print_file(file, revision_id)
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
872
873
    @needs_write_lock
905 by Martin Pool
- merge aaron's append_multiple.patch
874
    def append_revision(self, *revision_ids):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
875
        """See Branch.append_revision."""
905 by Martin Pool
- merge aaron's append_multiple.patch
876
        for revision_id in revision_ids:
877
            mutter("add {%s} to revision-history" % revision_id)
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
878
        rev_history = self.revision_history()
879
        rev_history.extend(revision_ids)
1442.1.68 by Robert Collins
'bzr pull' now accepts '--clobber'.
880
        self.set_revision_history(rev_history)
881
882
    @needs_write_lock
883
    def set_revision_history(self, rev_history):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
884
        """See Branch.set_revision_history."""
1185.65.12 by Robert Collins
Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8.
885
        self.control_files.put_utf8(
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
886
            'revision-history', '\n'.join(rev_history))
233 by mbp at sourcefrog
- more output from test.sh
887
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
888
    def get_revision_delta(self, revno):
889
        """Return the delta for one revision.
890
891
        The delta is relative to its mainline predecessor, or the
892
        empty tree for revision 1.
893
        """
894
        assert isinstance(revno, int)
895
        rh = self.revision_history()
896
        if not (1 <= revno <= len(rh)):
897
            raise InvalidRevisionNumber(revno)
898
899
        # revno is 1-based; list is 0-based
900
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
901
        new_tree = self.repository.revision_tree(rh[revno-1])
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
902
        if revno == 1:
903
            old_tree = EmptyTree()
904
        else:
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
905
            old_tree = self.repository.revision_tree(rh[revno-2])
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
906
        return compare_trees(old_tree, new_tree)
907
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
908
    @needs_read_lock
1 by mbp at sourcefrog
import from baz patch-364
909
    def revision_history(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
910
        """See Branch.revision_history."""
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
911
        # FIXME are transactions bound to control files ? RBC 20051121
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
912
        transaction = self.get_transaction()
913
        history = transaction.map.find_revision_history()
914
        if history is not None:
915
            mutter("cache hit for revision-history in %s", self)
1417.1.12 by Robert Collins
cache revision history during read transactions
916
            return list(history)
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
917
        history = [l.rstrip('\r\n') for l in
1185.65.29 by Robert Collins
Implement final review suggestions.
918
                self.control_files.get_utf8('revision-history').readlines()]
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
919
        transaction.map.add_revision_history(history)
920
        # this call is disabled because revision_history is 
921
        # not really an object yet, and the transaction is for objects.
922
        # transaction.register_clean(history, precious=True)
923
        return list(history)
1 by mbp at sourcefrog
import from baz patch-364
924
974.1.28 by aaron.bentley at utoronto
factored install_revisions out of update_revisions, updated test cases for greedy_fetch
925
    def update_revisions(self, other, stop_revision=None):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
926
        """See Branch.update_revisions."""
974.1.33 by aaron.bentley at utoronto
Added greedy_fetch to update_revisions
927
        from bzrlib.fetch import greedy_fetch
974.1.75 by Aaron Bentley
Sped up pull by copying locally first
928
        if stop_revision is None:
1390 by Robert Collins
pair programming worx... merge integration and weave
929
            stop_revision = other.last_revision()
1185.12.44 by abentley
Restored branch convergence to bzr pull
930
        ### Should this be checking is_ancestor instead of revision_history?
1441 by Robert Collins
tests passing is a good idea - move the branch open in cmd_branch to ensure this, and remove noise from the test suite
931
        if (stop_revision is not None and 
932
            stop_revision in self.revision_history()):
1440 by Robert Collins
further tuning of pull, do not do a local merge or fetch at all, if the remote branch is no newer than we are
933
            return
1260 by Martin Pool
- some updates for fetch/update function
934
        greedy_fetch(to_branch=self, from_branch=other,
1261 by Martin Pool
- new method Branch.has_revision
935
                     revision=stop_revision)
1185.12.44 by abentley
Restored branch convergence to bzr pull
936
        pullable_revs = self.pullable_revisions(other, stop_revision)
1185.12.45 by abentley
Cleanups for pull
937
        if len(pullable_revs) > 0:
1261 by Martin Pool
- new method Branch.has_revision
938
            self.append_revision(*pullable_revs)
1185.12.44 by abentley
Restored branch convergence to bzr pull
939
940
    def pullable_revisions(self, other, stop_revision):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
941
        """See Branch.pullable_revisions."""
1185.12.44 by abentley
Restored branch convergence to bzr pull
942
        other_revno = other.revision_id_to_revno(stop_revision)
943
        try:
944
            return self.missing_revisions(other, other_revno)
945
        except DivergedBranches, e:
946
            try:
947
                pullable_revs = get_intervening_revisions(self.last_revision(),
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
948
                                                          stop_revision, 
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
949
                                                          self.repository)
1185.12.44 by abentley
Restored branch convergence to bzr pull
950
                assert self.last_revision() not in pullable_revs
951
                return pullable_revs
952
            except bzrlib.errors.NotAncestor:
953
                if is_ancestor(self.last_revision(), stop_revision, self):
954
                    return []
955
                else:
956
                    raise e
957
        
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
958
    def basis_tree(self):
959
        """See Branch.basis_tree."""
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
960
        return self.repository.revision_tree(self.last_revision())
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
961
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
962
    @deprecated_method(zero_eight)
1 by mbp at sourcefrog
import from baz patch-364
963
    def working_tree(self):
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
964
        """Create a Working tree object for this branch."""
1185.2.2 by Lalo Martins
cleaning up and refactoring the branch module.
965
        from bzrlib.workingtree import WorkingTree
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
966
        from bzrlib.transport.local import LocalTransport
1534.4.28 by Robert Collins
first cut at merge from integration.
967
        if (self.base.find('://') != -1 or 
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
968
            not isinstance(self._transport, LocalTransport)):
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
969
            raise NoWorkingTree(self.base)
1457.1.1 by Robert Collins
rather than getting the branch inventory, WorkingTree can use the whole Branch, or make its own.
970
        return WorkingTree(self.base, branch=self)
1 by mbp at sourcefrog
import from baz patch-364
971
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
972
    @needs_write_lock
973
    def pull(self, source, overwrite=False):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
974
        """See Branch.pull."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
975
        source.lock_read()
976
        try:
1185.33.44 by Martin Pool
[patch] show number of revisions pushed/pulled/merged (Robey Pointer)
977
            old_count = len(self.revision_history())
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
978
            try:
979
                self.update_revisions(source)
980
            except DivergedBranches:
981
                if not overwrite:
982
                    raise
1185.50.5 by John Arbash Meinel
pull --overwrite should always overwrite, not just if diverged. (Test case from Robey Pointer)
983
            if overwrite:
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
984
                self.set_revision_history(source.revision_history())
1185.33.44 by Martin Pool
[patch] show number of revisions pushed/pulled/merged (Robey Pointer)
985
            new_count = len(self.revision_history())
986
            return new_count - old_count
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
987
        finally:
988
            source.unlock()
1 by mbp at sourcefrog
import from baz patch-364
989
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
990
    def get_parent(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
991
        """See Branch.get_parent."""
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
992
        import errno
993
        _locs = ['parent', 'pull', 'x-pull']
994
        for l in _locs:
995
            try:
1185.65.29 by Robert Collins
Implement final review suggestions.
996
                return self.control_files.get_utf8(l).read().strip('\n')
1185.31.45 by John Arbash Meinel
Refactoring Exceptions found some places where the wrong exception was caught.
997
            except NoSuchFile:
998
                pass
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
999
        return None
1000
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
1001
    def get_push_location(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
1002
        """See Branch.get_push_location."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
1003
        config = bzrlib.config.BranchConfig(self)
1004
        push_loc = config.get_user_option('push_location')
1005
        return push_loc
1006
1007
    def set_push_location(self, location):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
1008
        """See Branch.set_push_location."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
1009
        config = bzrlib.config.LocationConfig(self.base)
1010
        config.set_user_option('push_location', location)
1011
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
1012
    @needs_write_lock
1150 by Martin Pool
- add new Branch.set_parent and tests
1013
    def set_parent(self, url):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
1014
        """See Branch.set_parent."""
1150 by Martin Pool
- add new Branch.set_parent and tests
1015
        # TODO: Maybe delete old location files?
1185.65.29 by Robert Collins
Implement final review suggestions.
1016
        # URLs should never be unicode, even on the local fs,
1017
        # FIXUP this and get_parent in a future branch format bump:
1018
        # read and rewrite the file, and have the new format code read
1019
        # using .get not .get_utf8. RBC 20060125
1020
        self.control_files.put_utf8('parent', url + '\n')
1150 by Martin Pool
- add new Branch.set_parent and tests
1021
1185.35.11 by Aaron Bentley
Added support for branch nicks
1022
    def tree_config(self):
1023
        return TreeConfig(self)
1024
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1025
    def _get_truncated_history(self, revision_id):
1026
        history = self.revision_history()
1027
        if revision_id is None:
1028
            return history
1029
        try:
1030
            idx = history.index(revision_id)
1031
        except ValueError:
1032
            raise InvalidRevisionId(revision_id=revision, branch=self)
1033
        return history[:idx+1]
1034
1035
    @needs_read_lock
1036
    def _clone_weave(self, to_location, revision=None, basis_branch=None):
1534.4.28 by Robert Collins
first cut at merge from integration.
1037
        # prevent leakage
1038
        from bzrlib.workingtree import WorkingTree
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1039
        assert isinstance(to_location, basestring)
1040
        if basis_branch is not None:
1041
            note("basis_branch is not supported for fast weave copy yet.")
1042
1043
        history = self._get_truncated_history(revision)
1044
        if not bzrlib.osutils.lexists(to_location):
1045
            os.mkdir(to_location)
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
1046
        branch_to = BzrBranchFormat6().initialize(to_location)
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1047
        mutter("copy branch from %s to %s", self, branch_to)
1048
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
1049
        self.repository.copy(branch_to.repository)
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
1050
        
1185.65.15 by Robert Collins
Merge from integration.
1051
        # must be done *after* history is copied across
1052
        # FIXME duplicate code with base .clone().
1534.4.28 by Robert Collins
first cut at merge from integration.
1053
        # .. would template method be useful here?  RBC 20051207
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1054
        branch_to.set_parent(self.base)
1185.65.15 by Robert Collins
Merge from integration.
1055
        branch_to.append_revision(*history)
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
1056
        WorkingTree.create(branch_to, branch_to.base)
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1057
        mutter("copied")
1058
        return branch_to
1059
1060
    def clone(self, to_location, revision=None, basis_branch=None, to_branch_type=None):
1534.4.28 by Robert Collins
first cut at merge from integration.
1061
        print "FIXME: clone via create and fetch is probably faster when versioned file comes in."
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
1062
        if (to_branch_type is None
1063
            and self.repository.weave_store.listable()
1064
            and self.repository.revision_store.listable()):
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
1065
            return self._clone_weave(to_location, revision, basis_branch)
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
1066
        else:
1067
            return Branch.clone(self, to_location, revision, basis_branch, to_branch_type)
1185.35.11 by Aaron Bentley
Added support for branch nicks
1068
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1069
    def fileid_involved_between_revs(self, from_revid, to_revid):
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1070
        """Find file_id(s) which are involved in the changes between revisions.
1071
1072
        This determines the set of revisions which are involved, and then
1073
        finds all file ids affected by those revisions.
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1074
        """
1540.1.8 by John Arbash Meinel
Add an assert that fileid_involved won't be used if the branch format hasn't been determined to work with it. And a TODO about what needs to be fixed for weave inclusions.
1075
        # TODO: jam 20060119 This code assumes that w.inclusions will
1076
        #       always be correct. But because of the presence of ghosts
1077
        #       it is possible to be wrong.
1078
        #       One specific example from Robert Collins:
1079
        #       Two branches, with revisions ABC, and AD
1080
        #       C is a ghost merge of D.
1081
        #       Inclusions doesn't recognize D as an ancestor.
1082
        #       If D is ever merged in the future, the weave
1083
        #       won't be fixed, because AD never saw revision C
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1084
        #       to cause a conflict which would force a reweave.
1185.65.30 by Robert Collins
Merge integration.
1085
        w = self.repository.get_inventory_weave()
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1086
        from_set = set(w.inclusions([w.lookup(from_revid)]))
1087
        to_set = set(w.inclusions([w.lookup(to_revid)]))
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1088
        included = to_set.difference(from_set)
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1089
        changed = map(w.idx_to_name, included)
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1090
        return self._fileid_involved_by_set(changed)
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1091
1092
    def fileid_involved(self, last_revid=None):
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1093
        """Find all file_ids modified in the ancestry of last_revid.
1094
1095
        :param last_revid: If None, last_revision() will be used.
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1096
        """
1185.65.30 by Robert Collins
Merge integration.
1097
        w = self.repository.get_inventory_weave()
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1098
        if not last_revid:
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1099
            changed = set(w._names)
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1100
        else:
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1101
            included = w.inclusions([w.lookup(last_revid)])
1102
            changed = map(w.idx_to_name, included)
1103
        return self._fileid_involved_by_set(changed)
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1104
1105
    def fileid_involved_by_set(self, changes):
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1106
        """Find all file_ids modified by the set of revisions passed in.
1107
1108
        :param changes: A set() of revision ids
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1109
        """
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1110
        # TODO: jam 20060119 This line does *nothing*, remove it.
1111
        #       or better yet, change _fileid_involved_by_set so
1112
        #       that it takes the inventory weave, rather than
1113
        #       pulling it out by itself.
1185.65.30 by Robert Collins
Merge integration.
1114
        w = self.repository.get_inventory_weave()
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1115
        return self._fileid_involved_by_set(changes)
1116
1117
    def _fileid_involved_by_set(self, changes):
1540.1.10 by John Arbash Meinel
PEP8 comment fixes, and spelling error fix.
1118
        """Find the set of file-ids affected by the set of revisions.
1119
1120
        :param changes: A set() of revision ids.
1121
        :return: A set() of file ids.
1122
        
1123
        This peaks at the Weave, interpreting each line, looking to
1124
        see if it mentions one of the revisions. And if so, includes
1125
        the file id mentioned.
1126
        This expects both the Weave format, and the serialization
1127
        to have a single line per file/directory, and to have
1128
        fileid="" and revision="" on that line.
1129
        """
1534.4.19 by Robert Collins
merge from integration.
1130
        assert (isinstance(self._branch_format, BzrBranchFormat5) or
1131
                isinstance(self._branch_format, BzrBranchFormat6)), \
1540.1.8 by John Arbash Meinel
Add an assert that fileid_involved won't be used if the branch format hasn't been determined to work with it. And a TODO about what needs to be fixed for weave inclusions.
1132
            "fileid_involved only supported for branches which store inventory as xml"
1133
1185.65.30 by Robert Collins
Merge integration.
1134
        w = self.repository.get_inventory_weave()
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1135
        file_ids = set()
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1136
        for line in w._weave:
1137
1138
            # it is ugly, but it is due to the weave structure
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1139
            if not isinstance(line, basestring): continue
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1140
1141
            start = line.find('file_id="')+9
1142
            if start < 9: continue
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1143
            end = line.find('"', start)
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1144
            assert end>= 0
1540.1.6 by John Arbash Meinel
fileid_involved needs to unescape the file id and revision id
1145
            file_id = xml.sax.saxutils.unescape(line[start:end])
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1146
1147
            # check if file_id is already present
1148
            if file_id in file_ids: continue
1149
1150
            start = line.find('revision="')+10
1151
            if start < 10: continue
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1152
            end = line.find('"', start)
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1153
            assert end>= 0
1540.1.6 by John Arbash Meinel
fileid_involved needs to unescape the file id and revision id
1154
            revision_id = xml.sax.saxutils.unescape(line[start:end])
1185.64.7 by Goffredo Baroncelli
added test for function fileid_involved
1155
1156
            if revision_id in changes:
1185.64.2 by Goffredo Baroncelli
- implemented some suggestion by Robert Collins
1157
                file_ids.add(file_id)
1158
1159
        return file_ids
1185.64.1 by Goffredo Baroncelli
function file_involved added
1160
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1161
1534.4.1 by Robert Collins
Allow parameterisation of the branch initialisation for bzrlib.
1162
Branch.set_default_initializer(BzrBranch._initialize)
1163
1164
1534.4.3 by Robert Collins
Implement BranchTestProviderAdapter, so tests now run across all branch formats.
1165
class BranchTestProviderAdapter(object):
1166
    """A tool to generate a suite testing multiple branch formats at once.
1167
1168
    This is done by copying the test once for each transport and injecting
1169
    the transport_server, transport_readonly_server, and branch_format
1170
    classes into each copy. Each copy is also given a new id() to make it
1171
    easy to identify.
1172
    """
1173
1174
    def __init__(self, transport_server, transport_readonly_server, formats):
1175
        self._transport_server = transport_server
1176
        self._transport_readonly_server = transport_readonly_server
1177
        self._formats = formats
1178
    
1179
    def adapt(self, test):
1180
        result = TestSuite()
1181
        for format in self._formats:
1182
            new_test = deepcopy(test)
1183
            new_test.transport_server = self._transport_server
1184
            new_test.transport_readonly_server = self._transport_readonly_server
1185
            new_test.branch_format = format
1186
            def make_new_test_id():
1187
                new_id = "%s(%s)" % (new_test.id(), format.__class__.__name__)
1188
                return lambda: new_id
1189
            new_test.id = make_new_test_id()
1190
            result.addTest(new_test)
1191
        return result
1192
1193
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
1194
class ScratchBranch(BzrBranch):
1 by mbp at sourcefrog
import from baz patch-364
1195
    """Special test class: a branch that cleans up after itself.
1196
1197
    >>> b = ScratchBranch()
1198
    >>> isdir(b.base)
1199
    True
1200
    >>> bd = b.base
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1201
    >>> b._transport.__del__()
1 by mbp at sourcefrog
import from baz patch-364
1202
    >>> isdir(bd)
1203
    False
1204
    """
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
1205
1206
    def __init__(self, files=[], dirs=[], transport=None):
1 by mbp at sourcefrog
import from baz patch-364
1207
        """Make a test branch.
1208
1209
        This creates a temporary directory and runs init-tree in it.
1210
1211
        If any files are listed, they are created in the working copy.
1212
        """
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
1213
        if transport is None:
1214
            transport = bzrlib.transport.local.ScratchTransport()
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
1215
            # local import for scope restriction
1216
            from bzrlib.workingtree import WorkingTree
1217
            WorkingTree.create_standalone(transport.base)
1534.4.6 by Robert Collins
Remove last uses of the init= parameter to BzrBranch.
1218
            super(ScratchBranch, self).__init__(transport)
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
1219
        else:
1220
            super(ScratchBranch, self).__init__(transport)
1221
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1222
        # BzrBranch creates a clone to .bzr and then forgets about the
1223
        # original transport. A ScratchTransport() deletes itself and
1224
        # everything underneath it when it goes away, so we need to
1225
        # grab a local copy to prevent that from happening
1226
        self._transport = transport
1227
100 by mbp at sourcefrog
- add test case for ignore files
1228
        for d in dirs:
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1229
            self._transport.mkdir(d)
100 by mbp at sourcefrog
- add test case for ignore files
1230
            
1 by mbp at sourcefrog
import from baz patch-364
1231
        for f in files:
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1232
            self._transport.put(f, 'content of %s' % f)
1 by mbp at sourcefrog
import from baz patch-364
1233
622 by Martin Pool
Updated merge patch from Aaron
1234
    def clone(self):
1235
        """
1236
        >>> orig = ScratchBranch(files=["file1", "file2"])
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1237
        >>> os.listdir(orig.base)
1238
        [u'.bzr', u'file1', u'file2']
622 by Martin Pool
Updated merge patch from Aaron
1239
        >>> clone = orig.clone()
1185.1.40 by Robert Collins
Merge what applied of Alexander Belchenko's win32 patch.
1240
        >>> if os.name != 'nt':
1241
        ...   os.path.samefile(orig.base, clone.base)
1242
        ... else:
1243
        ...   orig.base == clone.base
1244
        ...
622 by Martin Pool
Updated merge patch from Aaron
1245
        False
1185.69.2 by John Arbash Meinel
Changed LockableFiles to take the root directory directly. Moved mode information into LockableFiles instead of Branch
1246
        >>> os.listdir(clone.base)
1247
        [u'.bzr', u'file1', u'file2']
622 by Martin Pool
Updated merge patch from Aaron
1248
        """
800 by Martin Pool
Merge John's import-speedup branch:
1249
        from shutil import copytree
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
1250
        from bzrlib.osutils import mkdtemp
800 by Martin Pool
Merge John's import-speedup branch:
1251
        base = mkdtemp()
622 by Martin Pool
Updated merge patch from Aaron
1252
        os.rmdir(base)
800 by Martin Pool
Merge John's import-speedup branch:
1253
        copytree(self.base, base, symlinks=True)
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
1254
        return ScratchBranch(
1255
            transport=bzrlib.transport.local.ScratchTransport(base))
1 by mbp at sourcefrog
import from baz patch-364
1256
    
1257
1258
######################################################################
1259
# predicates
1260
1261
1262
def is_control_file(filename):
1263
    ## FIXME: better check
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
1264
    filename = normpath(filename)
1 by mbp at sourcefrog
import from baz patch-364
1265
    while filename != '':
1266
        head, tail = os.path.split(filename)
1534.1.11 by Robert Collins
Format tweaks for latest merges.
1267
        ## mutter('check %r for control file' % ((head, tail),))
1 by mbp at sourcefrog
import from baz patch-364
1268
        if tail == bzrlib.BZRDIR:
1269
            return True
70 by mbp at sourcefrog
Prepare for smart recursive add.
1270
        if filename == head:
1271
            break
1 by mbp at sourcefrog
import from baz patch-364
1272
        filename = head
1273
    return False