/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
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
18
import shutil
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
19
import sys
20
import os
1371 by Martin Pool
- raise NotBranchError if format file can't be read
21
import errno
1372 by Martin Pool
- avoid converting inventories to/from StringIO
22
from warnings import warn
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
23
from cStringIO import StringIO
1372 by Martin Pool
- avoid converting inventories to/from StringIO
24
1 by mbp at sourcefrog
import from baz patch-364
25
26
import bzrlib
800 by Martin Pool
Merge John's import-speedup branch:
27
from bzrlib.trace import mutter, note
1508.1.5 by Robert Collins
Move add from Branch to WorkingTree.
28
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 \
29
                            rename, splitpath, sha_file,
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
30
                            file_kind, abspath, normpath, pathjoin)
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
31
import bzrlib.errors as errors
1192 by Martin Pool
- clean up code for retrieving stored inventories
32
from bzrlib.errors import (BzrError, InvalidRevisionNumber, InvalidRevisionId,
1299 by Martin Pool
- tidy up imports
33
                           NoSuchRevision, HistoryMissing, NotBranchError,
1391 by Robert Collins
merge from integration
34
                           DivergedBranches, LockError, UnlistableStore,
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
35
                           UnlistableBranch, NoSuchFile, NotVersionedError,
36
                           NoWorkingTree)
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
37
from bzrlib.textui import show_status
1185.65.10 by Robert Collins
Rename Controlfiles to LockableFiles.
38
from bzrlib.config import TreeConfig
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
39
from bzrlib.delta import compare_trees
1185.65.15 by Robert Collins
Merge from integration.
40
import bzrlib.inventory as inventory
1192 by Martin Pool
- clean up code for retrieving stored inventories
41
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.
42
from bzrlib.lockable_files import LockableFiles
43
from bzrlib.revision import (Revision, is_ancestor, get_intervening_revisions)
44
from bzrlib.repository import Repository
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
45
from bzrlib.store import copy_all
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
46
import bzrlib.transactions as transactions
1393.2.4 by John Arbash Meinel
All tests pass.
47
from bzrlib.transport import Transport, get_transport
1185.65.15 by Robert Collins
Merge from integration.
48
from bzrlib.tree import EmptyTree, RevisionTree
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
49
import bzrlib.ui
1189 by Martin Pool
- BROKEN: partial support for commit into weave
50
import bzrlib.xml5
1104 by Martin Pool
- Add a simple UIFactory
51
1094 by Martin Pool
- merge aaron's merge improvements 999..1008
52
1186 by Martin Pool
- start implementing v5 format; Branch refuses to operate on old branches
53
BZR_BRANCH_FORMAT_4 = "Bazaar-NG branch, format 0.0.4\n"
54
BZR_BRANCH_FORMAT_5 = "Bazaar-NG branch, format 5\n"
1429 by Robert Collins
merge in niemeyers prefixed-store patch
55
BZR_BRANCH_FORMAT_6 = "Bazaar-NG branch, format 6\n"
1 by mbp at sourcefrog
import from baz patch-364
56
## TODO: Maybe include checks for common corruption of newlines, etc?
57
58
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
59
# TODO: Some operations like log might retrieve the same revisions
60
# repeatedly to calculate deltas.  We could perhaps have a weakref
1223 by Martin Pool
- store inventories in weave
61
# cache in memory to make this faster.  In general anything can be
62
# cached in memory between lock and unlock operations.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
63
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
64
def find_branch(*ignored, **ignored_too):
65
    # XXX: leave this here for about one release, then remove it
66
    raise NotImplementedError('find_branch() is not supported anymore, '
67
                              'please use one of the new branch constructors')
416 by Martin Pool
- bzr log and bzr root now accept an http URL
68
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
69
70
def needs_read_lock(unbound):
71
    """Decorate unbound to take out and release a read lock."""
72
    def decorated(self, *args, **kwargs):
73
        self.lock_read()
74
        try:
75
            return unbound(self, *args, **kwargs)
76
        finally:
77
            self.unlock()
78
    return decorated
79
80
81
def needs_write_lock(unbound):
82
    """Decorate unbound to take out and release a write lock."""
83
    def decorated(self, *args, **kwargs):
84
        self.lock_write()
85
        try:
86
            return unbound(self, *args, **kwargs)
87
        finally:
88
            self.unlock()
89
    return decorated
90
1 by mbp at sourcefrog
import from baz patch-364
91
######################################################################
92
# branch objects
93
558 by Martin Pool
- All top-level classes inherit from object
94
class Branch(object):
1 by mbp at sourcefrog
import from baz patch-364
95
    """Branch holding a history of revisions.
96
343 by Martin Pool
doc
97
    base
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
98
        Base directory/url of the branch.
99
    """
100
    base = None
101
102
    def __init__(self, *ignored, **ignored_too):
103
        raise NotImplementedError('The Branch class is abstract')
104
105
    @staticmethod
1393.1.2 by Martin Pool
- better representation in Branch factories of opening old formats
106
    def open_downlevel(base):
107
        """Open a branch which may be of an old format.
108
        
109
        Only local branches are supported."""
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
110
        return BzrBranch(get_transport(base), relax_version_check=True)
1393.1.2 by Martin Pool
- better representation in Branch factories of opening old formats
111
        
112
    @staticmethod
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
113
    def open(base):
114
        """Open an existing branch, rooted at 'base' (url)"""
1393.2.4 by John Arbash Meinel
All tests pass.
115
        t = get_transport(base)
1393.1.63 by Martin Pool
- add some trace statements
116
        mutter("trying to open %r with transport %r", base, t)
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
117
        return BzrBranch(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.
1442.1.64 by Robert Collins
Branch.open_containing now returns a tuple (Branch, relative-path).
127
        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.
128
        """
1393.2.4 by John Arbash Meinel
All tests pass.
129
        t = get_transport(url)
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
130
        while True:
131
            try:
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
132
                return BzrBranch(t), t.relpath(url)
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
133
            except NotBranchError, e:
134
                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
135
            new_t = t.clone('..')
136
            if new_t.base == t.base:
137
                # reached the root, whatever that may be
1185.16.61 by mbp at sourcefrog
- start introducing hct error classes
138
                raise NotBranchError(path=url)
1185.17.2 by Martin Pool
[pick] avoid problems in fetching when .bzr is not listable
139
            t = new_t
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
140
141
    @staticmethod
142
    def initialize(base):
143
        """Create a new branch, rooted at 'base' (url)"""
1185.65.15 by Robert Collins
Merge from integration.
144
        t = get_transport(unicode(base))
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
145
        return BzrBranch(t, init=True)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
146
147
    def setup_caching(self, cache_root):
148
        """Subclasses that care about caching should override this, and set
149
        up cached stores located under cache_root.
150
        """
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
151
        self.cache_root = cache_root
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
152
1185.35.11 by Aaron Bentley
Added support for branch nicks
153
    def _get_nick(self):
154
        cfg = self.tree_config()
155
        return cfg.get_option(u"nickname", default=self.base.split('/')[-1])
156
157
    def _set_nick(self, nick):
158
        cfg = self.tree_config()
159
        cfg.set_option(nick, "nickname")
160
        assert cfg.get_option("nickname") == nick
161
162
    nick = property(_get_nick, _set_nick)
163
        
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
164
    def push_stores(self, branch_to):
165
        """Copy the content of this branches store to branch_to."""
166
        raise NotImplementedError('push_stores is abstract')
167
168
    def lock_write(self):
169
        raise NotImplementedError('lock_write is abstract')
170
        
171
    def lock_read(self):
172
        raise NotImplementedError('lock_read is abstract')
173
174
    def unlock(self):
175
        raise NotImplementedError('unlock is abstract')
176
177
    def abspath(self, name):
178
        """Return absolute filename for something in the branch
179
        
180
        XXX: Robert Collins 20051017 what is this used for? why is it a branch
181
        method and not a tree method.
182
        """
183
        raise NotImplementedError('abspath is abstract')
184
185
    def get_root_id(self):
186
        """Return the id of this branches root"""
187
        raise NotImplementedError('get_root_id is abstract')
188
1185.50.9 by John Arbash Meinel
[bug 3632] Matthieu Moy- bzr cat should default to last revision
189
    def print_file(self, file, revision_id):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
190
        """Print `file` to stdout."""
191
        raise NotImplementedError('print_file is abstract')
192
193
    def append_revision(self, *revision_ids):
194
        raise NotImplementedError('append_revision is abstract')
195
196
    def set_revision_history(self, rev_history):
197
        raise NotImplementedError('set_revision_history is abstract')
198
199
    def revision_history(self):
200
        """Return sequence of revision hashes on to this branch."""
201
        raise NotImplementedError('revision_history is abstract')
202
203
    def revno(self):
204
        """Return current revision number for this branch.
205
206
        That is equivalent to the number of revisions committed to
207
        this branch.
208
        """
209
        return len(self.revision_history())
210
211
    def last_revision(self):
212
        """Return last patch hash, or None if no history."""
213
        ph = self.revision_history()
214
        if ph:
215
            return ph[-1]
216
        else:
217
            return None
218
219
    def missing_revisions(self, other, stop_revision=None, diverged_ok=False):
220
        """Return a list of new revisions that would perfectly fit.
221
        
222
        If self and other have not diverged, return a list of the revisions
223
        present in other, but missing from self.
224
225
        >>> from bzrlib.commit import commit
226
        >>> bzrlib.trace.silent = True
227
        >>> br1 = ScratchBranch()
228
        >>> br2 = ScratchBranch()
229
        >>> br1.missing_revisions(br2)
230
        []
231
        >>> commit(br2, "lala!", rev_id="REVISION-ID-1")
232
        >>> br1.missing_revisions(br2)
233
        [u'REVISION-ID-1']
234
        >>> br2.missing_revisions(br1)
235
        []
236
        >>> commit(br1, "lala!", rev_id="REVISION-ID-1")
237
        >>> br1.missing_revisions(br2)
238
        []
239
        >>> commit(br2, "lala!", rev_id="REVISION-ID-2A")
240
        >>> br1.missing_revisions(br2)
241
        [u'REVISION-ID-2A']
242
        >>> commit(br1, "lala!", rev_id="REVISION-ID-2B")
243
        >>> br1.missing_revisions(br2)
244
        Traceback (most recent call last):
1185.56.1 by Michael Ellerman
Simplify handling of DivergedBranches in cmd_pull()
245
        DivergedBranches: These branches have diverged.  Try merge.
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
246
        """
247
        self_history = self.revision_history()
248
        self_len = len(self_history)
249
        other_history = other.revision_history()
250
        other_len = len(other_history)
251
        common_index = min(self_len, other_len) -1
252
        if common_index >= 0 and \
253
            self_history[common_index] != other_history[common_index]:
254
            raise DivergedBranches(self, other)
255
256
        if stop_revision is None:
257
            stop_revision = other_len
258
        else:
259
            assert isinstance(stop_revision, int)
260
            if stop_revision > other_len:
261
                raise bzrlib.errors.NoSuchRevision(self, stop_revision)
262
        return other_history[self_len:stop_revision]
1185.66.1 by Aaron Bentley
Merged from mainline
263
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
264
    
265
    def update_revisions(self, other, stop_revision=None):
266
        """Pull in new perfect-fit revisions."""
267
        raise NotImplementedError('update_revisions is abstract')
268
269
    def pullable_revisions(self, other, stop_revision):
270
        raise NotImplementedError('pullable_revisions is abstract')
271
        
272
    def revision_id_to_revno(self, revision_id):
273
        """Given a revision id, return its revno"""
274
        if revision_id is None:
275
            return 0
276
        history = self.revision_history()
277
        try:
278
            return history.index(revision_id) + 1
279
        except ValueError:
280
            raise bzrlib.errors.NoSuchRevision(self, revision_id)
281
282
    def get_rev_id(self, revno, history=None):
283
        """Find the revision id of the specified revno."""
284
        if revno == 0:
285
            return None
286
        if history is None:
287
            history = self.revision_history()
288
        elif revno <= 0 or revno > len(history):
289
            raise bzrlib.errors.NoSuchRevision(self, revno)
290
        return history[revno - 1]
291
292
    def working_tree(self):
1508.1.15 by Robert Collins
Merge from mpool.
293
        """Return a `Tree` for the working copy if this is a local branch."""
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
294
        raise NotImplementedError('working_tree is abstract')
295
296
    def pull(self, source, overwrite=False):
297
        raise NotImplementedError('pull is abstract')
298
299
    def basis_tree(self):
300
        """Return `Tree` object for last revision.
301
302
        If there are no revisions yet, return an `EmptyTree`.
303
        """
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
304
        return self.repository.revision_tree(self.last_revision())
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
305
306
    def rename_one(self, from_rel, to_rel):
307
        """Rename one file.
308
309
        This can change the directory or the filename or both.
310
        """
311
        raise NotImplementedError('rename_one is abstract')
312
313
    def move(self, from_paths, to_name):
314
        """Rename files.
315
316
        to_name must exist as a versioned directory.
317
318
        If to_name exists and is a directory, the files are moved into
319
        it, keeping their old names.  If it is a directory, 
320
321
        Note that to_name is only the last component of the new name;
322
        this doesn't change the directory.
323
324
        This returns a list of (from_path, to_path) pairs for each
325
        entry that is moved.
326
        """
327
        raise NotImplementedError('move is abstract')
328
329
    def get_parent(self):
330
        """Return the parent location of the branch.
331
332
        This is the default location for push/pull/missing.  The usual
333
        pattern is that the user can override it by specifying a
334
        location.
335
        """
336
        raise NotImplementedError('get_parent is abstract')
337
338
    def get_push_location(self):
339
        """Return the None or the location to push this branch to."""
340
        raise NotImplementedError('get_push_location is abstract')
341
342
    def set_push_location(self, location):
343
        """Set a new push location for this branch."""
344
        raise NotImplementedError('set_push_location is abstract')
345
346
    def set_parent(self, url):
347
        raise NotImplementedError('set_parent is abstract')
348
349
    def check_revno(self, revno):
350
        """\
351
        Check whether a revno corresponds to any revision.
352
        Zero (the NULL revision) is considered valid.
353
        """
354
        if revno != 0:
355
            self.check_real_revno(revno)
356
            
357
    def check_real_revno(self, revno):
358
        """\
359
        Check whether a revno corresponds to a real revision.
360
        Zero (the NULL revision) is considered invalid
361
        """
362
        if revno < 1 or revno > self.revno():
363
            raise InvalidRevisionNumber(revno)
364
        
365
    def sign_revision(self, revision_id, gpg_strategy):
366
        raise NotImplementedError('sign_revision is abstract')
367
368
    def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
369
        raise NotImplementedError('store_revision_signature is abstract')
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
370
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
371
    def clone(self, to_location, revision=None, basis_branch=None, to_branch_type=None):
372
        """Copy this branch into the existing directory to_location.
373
374
        Returns the newly created branch object.
375
376
        revision
377
            If not None, only revisions up to this point will be copied.
378
            The head of the new branch will be that revision.  Must be a
379
            revid or None.
380
    
381
        to_location -- The destination directory; must either exist and be 
382
            empty, or not exist, in which case it is created.
383
    
384
        basis_branch
385
            A local branch to copy revisions from, related to this branch. 
386
            This is used when branching from a remote (slow) branch, and we have
387
            a local branch that might contain some relevant revisions.
388
    
389
        to_branch_type
390
            Branch type of destination branch
391
        """
392
        assert isinstance(to_location, basestring)
393
        if not bzrlib.osutils.lexists(to_location):
394
            os.mkdir(to_location)
395
        if to_branch_type is None:
396
            to_branch_type = BzrBranch
397
        br_to = to_branch_type.initialize(to_location)
398
        mutter("copy branch from %s to %s", self, br_to)
399
        if basis_branch is not None:
400
            basis_branch.push_stores(br_to)
401
        br_to.working_tree().set_root_id(self.get_root_id())
402
        if revision is None:
403
            revision = self.last_revision()
404
        br_to.update_revisions(self, stop_revision=revision)
405
        br_to.set_parent(self.base)
1185.65.15 by Robert Collins
Merge from integration.
406
        # circular import protection
407
        from bzrlib.merge import build_working_dir
408
        build_working_dir(to_location)
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
409
        mutter("copied")
410
        return br_to
1185.66.1 by Aaron Bentley
Merged from mainline
411
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
412
class BzrBranch(Branch):
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
413
    """A branch stored in the actual filesystem.
414
415
    Note that it's "local" in the context of the filesystem; it doesn't
416
    really matter if it's on an nfs/smb/afs/coda/... share, as long as
417
    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,
418
1 by mbp at sourcefrog
import from baz patch-364
419
    """
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
420
    # We actually expect this class to be somewhat short-lived; part of its
421
    # purpose is to try to isolate what bits of the branch logic are tied to
422
    # filesystem access, so that in a later step, we can extricate them to
423
    # a separarte ("storage") class.
1223 by Martin Pool
- store inventories in weave
424
    _inventory_weave = None
1185.58.7 by John Arbash Meinel
Added the ability to disable setting permissions
425
    # If set to False (by a plugin, etc) BzrBranch will not set the
426
    # mode on created files or directories
427
    _set_file_mode = True
428
    _set_dir_mode = True
353 by Martin Pool
- Per-branch locks in read and write modes.
429
    
897 by Martin Pool
- merge john's revision-naming code
430
    # Map some sort of prefix into a namespace
431
    # stuff like "revno:10", "revid:", etc.
432
    # This should match a prefix with a function which accepts
433
    REVISION_NAMESPACES = {}
434
1391 by Robert Collins
merge from integration
435
    def push_stores(self, branch_to):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
436
        """See Branch.push_stores."""
1391 by Robert Collins
merge from integration
437
        if (self._branch_format != branch_to._branch_format
438
            or self._branch_format != 4):
439
            from bzrlib.fetch import greedy_fetch
1393 by Robert Collins
reenable remotebranch tests
440
            mutter("falling back to fetch logic to push between %s(%s) and %s(%s)",
441
                   self, self._branch_format, branch_to, branch_to._branch_format)
1391 by Robert Collins
merge from integration
442
            greedy_fetch(to_branch=branch_to, from_branch=self,
443
                         revision=self.last_revision())
444
            return
445
446
        store_pairs = ((self.text_store,      branch_to.text_store),
447
                       (self.inventory_store, branch_to.inventory_store),
448
                       (self.revision_store,  branch_to.revision_store))
449
        try:
450
            for from_store, to_store in store_pairs: 
451
                copy_all(from_store, to_store)
452
        except UnlistableStore:
453
            raise UnlistableBranch(from_store)
454
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
455
    def __init__(self, transport, init=False,
1293 by Martin Pool
- add Branch constructor option to relax version check
456
                 relax_version_check=False):
1 by mbp at sourcefrog
import from baz patch-364
457
        """Create new branch object at a particular location.
458
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
459
        transport -- A Transport object, defining how to access files.
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
460
        
254 by Martin Pool
- Doc cleanups from Magnus Therning
461
        init -- If True, create new control files in a previously
1 by mbp at sourcefrog
import from baz patch-364
462
             unversioned directory.  If False, the branch must already
463
             be versioned.
464
1293 by Martin Pool
- add Branch constructor option to relax version check
465
        relax_version_check -- If true, the usual check for the branch
466
            version is not applied.  This is intended only for
467
            upgrade/recovery type use; it's not guaranteed that
468
            all operations will work on old format branches.
469
1 by mbp at sourcefrog
import from baz patch-364
470
        In the test suite, creation of new trees is tested using the
471
        `ScratchBranch` class.
472
        """
1393.1.15 by Martin Pool
- better assertion message
473
        assert isinstance(transport, Transport), \
474
            "%r is not a Transport" % transport
1185.67.13 by Aaron Bentley
Moved the .bzr constraint out of LockableFiles
475
        self.control_files = LockableFiles(transport, bzrlib.BZRDIR, 'branch-lock')
1 by mbp at sourcefrog
import from baz patch-364
476
        if init:
477
            self._make_control()
1293 by Martin Pool
- add Branch constructor option to relax version check
478
        self._check_format(relax_version_check)
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
479
        self._find_modes()
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
480
        self.repository = Repository(transport, self._branch_format,
481
                                     dir_mode=self._dir_mode,
482
                                     file_mode=self._file_mode)
1 by mbp at sourcefrog
import from baz patch-364
483
484
    def __str__(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
485
        return '%s(%r)' % (self.__class__.__name__, self.base)
1 by mbp at sourcefrog
import from baz patch-364
486
487
    __repr__ = __str__
488
578 by Martin Pool
- start to move toward Branch.lock and unlock methods,
489
    def __del__(self):
907.1.23 by John Arbash Meinel
Branch objects now automatically create Cached stores if the protocol is_remote.
490
        # TODO: It might be best to do this somewhere else,
491
        # but it is nice for a Branch object to automatically
492
        # cache it's information.
493
        # Alternatively, we could have the Transport objects cache requests
494
        # See the earlier discussion about how major objects (like Branch)
495
        # should never expect their __del__ function to run.
1185.11.9 by John Arbash Meinel
Most tests pass, some problems with unavailable socket recv
496
        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.
497
            try:
498
                shutil.rmtree(self.cache_root)
499
            except:
500
                pass
501
            self.cache_root = None
502
907.1.17 by John Arbash Meinel
Adding a Branch.base property, removing pull_loc()
503
    def _get_base(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
504
        if self.control_files._transport:
505
            return self.control_files._transport.base
907.1.19 by John Arbash Meinel
Updated ScratchBranch and Branch.base, All Tests PASS !!!
506
        return None
907.1.17 by John Arbash Meinel
Adding a Branch.base property, removing pull_loc()
507
1442.1.5 by Robert Collins
Give branch.base a docstring.
508
    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,
509
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
510
    def _finish_transaction(self):
511
        """Exit the current transaction."""
1185.65.13 by Robert Collins
Merge from integration
512
        return self.control_files._finish_transaction()
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
513
514
    def get_transaction(self):
1185.65.13 by Robert Collins
Merge from integration
515
        """Return the current active transaction.
516
517
        If no transaction is active, this returns a passthrough object
518
        for which all data is immediately flushed and no caching happens.
519
        """
520
        # this is an explicit function so that we can do tricky stuff
521
        # when the storage in rev_storage is elsewhere.
522
        # we probably need to hook the two 'lock a location' and 
523
        # 'have a transaction' together more delicately, so that
524
        # we can have two locks (branch and storage) and one transaction
525
        # ... and finishing the transaction unlocks both, but unlocking
526
        # does not. - RBC 20051121
527
        return self.control_files.get_transaction()
528
529
    def _set_transaction(self, transaction):
1417.1.6 by Robert Collins
introduce transactions for grouping actions done to and with branches
530
        """Set a new active transaction."""
1185.65.13 by Robert Collins
Merge from integration
531
        return self.control_files._set_transaction(transaction)
353 by Martin Pool
- Per-branch locks in read and write modes.
532
67 by mbp at sourcefrog
use abspath() for the function that makes an absolute
533
    def abspath(self, name):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
534
        """See Branch.abspath."""
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
535
        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.
536
537
    def _find_modes(self, path=None):
538
        """Determine the appropriate modes for files and directories."""
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
539
        # RBC 20060103 FIXME where does this belong ?
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
540
        try:
541
            if path is None:
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
542
                path = ''
543
                #self.control_files._rel_controlfilename('')
544
            st = self.control_files._transport.stat(path)
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
545
        except errors.TransportNotPossible:
546
            self._dir_mode = 0755
547
            self._file_mode = 0644
548
        else:
549
            self._dir_mode = st.st_mode & 07777
550
            # Remove the sticky and execute bits for files
551
            self._file_mode = self._dir_mode & ~07111
1185.58.7 by John Arbash Meinel
Added the ability to disable setting permissions
552
        if not self._set_dir_mode:
553
            self._dir_mode = None
554
        if not self._set_file_mode:
555
            self._file_mode = None
1 by mbp at sourcefrog
import from baz patch-364
556
557
    def _make_control(self):
800 by Martin Pool
Merge John's import-speedup branch:
558
        from bzrlib.inventory import Inventory
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
559
        from bzrlib.weavefile import write_weave_v5
560
        from bzrlib.weave import Weave
802 by Martin Pool
- Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions
561
        
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
562
        # Create an empty inventory
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
563
        sio = StringIO()
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
564
        # if we want per-tree root ids then this is the place to set
565
        # them; they're not needed for now and so ommitted for
566
        # simplicity.
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
567
        bzrlib.xml5.serializer_v5.write_inventory(Inventory(), sio)
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
568
        empty_inv = sio.getvalue()
569
        sio = StringIO()
570
        bzrlib.weavefile.write_weave_v5(Weave(), sio)
571
        empty_weave = sio.getvalue()
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
572
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
573
        # Since we don't have a .bzr directory, inherit the
574
        # mode from the root directory
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
575
        self._find_modes('.')
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
576
577
        dirs = ['', 'revision-store', 'weaves']
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
578
        files = [('README', 
1 by mbp at sourcefrog
import from baz patch-364
579
            "This is a Bazaar-NG control directory.\n"
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
580
            "Do not change any files in this directory.\n"),
1429 by Robert Collins
merge in niemeyers prefixed-store patch
581
            ('branch-format', BZR_BRANCH_FORMAT_6),
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
582
            ('revision-history', ''),
583
            ('branch-name', ''),
584
            ('branch-lock', ''),
585
            ('pending-merges', ''),
1393.2.2 by John Arbash Meinel
Updated stores to use Transport
586
            ('inventory', empty_inv),
587
            ('inventory.weave', empty_weave),
588
            ('ancestry.weave', empty_weave)
907.1.47 by John Arbash Meinel
Created mkdir_multi, modified branch to use _multi forms when initializing a branch, creating a full test routine for transports
589
        ]
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
590
        cfn = self.control_files._rel_controlfilename
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
591
        self.control_files._transport.mkdir_multi([cfn(d) for d in dirs],
592
                                                  mode=self._dir_mode)
1185.67.5 by Aaron Bentley
Added write locks as appropriate
593
        self.control_files.lock_write()
594
        try:
595
            for file, content in files:
596
                self.control_files.put_utf8(file, content)
597
            mutter('created control directory in ' + self.base)
598
        finally:
599
            self.control_files.unlock()
802 by Martin Pool
- Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions
600
1293 by Martin Pool
- add Branch constructor option to relax version check
601
    def _check_format(self, relax_version_check):
1 by mbp at sourcefrog
import from baz patch-364
602
        """Check this branch format is supported.
603
1187 by Martin Pool
- improved check for branch version
604
        The format level is stored, as an integer, in
605
        self._branch_format for code that needs to check it later.
1 by mbp at sourcefrog
import from baz patch-364
606
607
        In the future, we might need different in-memory Branch
608
        classes to support downlevel branches.  But not yet.
163 by mbp at sourcefrog
merge win32 portability fixes
609
        """
1185.11.9 by John Arbash Meinel
Most tests pass, some problems with unavailable socket recv
610
        try:
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
611
            fmt = self.control_files.controlfile('branch-format', 'r').read()
1185.11.9 by John Arbash Meinel
Most tests pass, some problems with unavailable socket recv
612
        except NoSuchFile:
1185.16.61 by mbp at sourcefrog
- start introducing hct error classes
613
            raise NotBranchError(path=self.base)
1393.1.63 by Martin Pool
- add some trace statements
614
        mutter("got branch format %r", fmt)
1429 by Robert Collins
merge in niemeyers prefixed-store patch
615
        if fmt == BZR_BRANCH_FORMAT_6:
616
            self._branch_format = 6
617
        elif fmt == BZR_BRANCH_FORMAT_5:
1187 by Martin Pool
- improved check for branch version
618
            self._branch_format = 5
1294 by Martin Pool
- refactor branch version detection
619
        elif fmt == BZR_BRANCH_FORMAT_4:
620
            self._branch_format = 4
621
622
        if (not relax_version_check
1429 by Robert Collins
merge in niemeyers prefixed-store patch
623
            and self._branch_format not in (5, 6)):
1185.1.53 by Robert Collins
raise a specific error on unsupported branches so that they can be distinguished from generic errors
624
            raise errors.UnsupportedFormatError(
625
                           'sorry, branch format %r not supported' % fmt,
576 by Martin Pool
- raise exceptions rather than using bailout()
626
                           ['use a different bzr version',
1393.2.1 by John Arbash Meinel
Merged in split-storage-2 branch. Need to cleanup a little bit more still.
627
                            'or remove the .bzr directory'
628
                            ' and "bzr init" again'])
907.1.2 by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport.
629
1508.1.15 by Robert Collins
Merge from mpool.
630
    @needs_read_lock
909 by Martin Pool
- merge John's code to give the tree root an explicit file id
631
    def get_root_id(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
632
        """See Branch.get_root_id."""
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
633
        inv = self.repository.get_inventory(self.last_revision())
909 by Martin Pool
- merge John's code to give the tree root an explicit file id
634
        return inv.root.file_id
1 by mbp at sourcefrog
import from baz patch-364
635
1185.65.3 by Aaron Bentley
Fixed locking-- all tests pass
636
    def lock_write(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
637
        # TODO: test for failed two phase locks. This is known broken.
638
        self.control_files.lock_write()
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
639
        self.repository.lock_write()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
640
1185.65.3 by Aaron Bentley
Fixed locking-- all tests pass
641
    def lock_read(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
642
        # TODO: test for failed two phase locks. This is known broken.
643
        self.control_files.lock_read()
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
644
        self.repository.lock_read()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
645
646
    def unlock(self):
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
647
        # TODO: test for failed two phase locks. This is known broken.
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
648
        self.repository.unlock()
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
649
        self.control_files.unlock()
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
650
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
651
    @needs_read_lock
1185.50.9 by John Arbash Meinel
[bug 3632] Matthieu Moy- bzr cat should default to last revision
652
    def print_file(self, file, revision_id):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
653
        """See Branch.print_file."""
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
654
        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.
655
656
    @needs_write_lock
905 by Martin Pool
- merge aaron's append_multiple.patch
657
    def append_revision(self, *revision_ids):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
658
        """See Branch.append_revision."""
905 by Martin Pool
- merge aaron's append_multiple.patch
659
        for revision_id in revision_ids:
660
            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.
661
        rev_history = self.revision_history()
662
        rev_history.extend(revision_ids)
1442.1.68 by Robert Collins
'bzr pull' now accepts '--clobber'.
663
        self.set_revision_history(rev_history)
664
665
    @needs_write_lock
666
    def set_revision_history(self, rev_history):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
667
        """See Branch.set_revision_history."""
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
668
        old_revision = self.last_revision()
669
        new_revision = rev_history[-1]
1185.65.12 by Robert Collins
Remove the only-used-once put_controlfiles, and change put_controlfile to put and put_utf8.
670
        self.control_files.put_utf8(
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
671
            'revision-history', '\n'.join(rev_history))
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
672
        try:
1185.65.15 by Robert Collins
Merge from integration.
673
            # FIXME: RBC 20051207 this smells wrong, last_revision in the 
674
            # working tree may be != to last_revision in the branch - so
675
            # why is this passing in the branches last_revision ?
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
676
            self.working_tree().set_last_revision(new_revision, old_revision)
677
        except NoWorkingTree:
678
            mutter('Unable to set_last_revision without a working tree.')
233 by mbp at sourcefrog
- more output from test.sh
679
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
680
    def get_revision_delta(self, revno):
681
        """Return the delta for one revision.
682
683
        The delta is relative to its mainline predecessor, or the
684
        empty tree for revision 1.
685
        """
686
        assert isinstance(revno, int)
687
        rh = self.revision_history()
688
        if not (1 <= revno <= len(rh)):
689
            raise InvalidRevisionNumber(revno)
690
691
        # revno is 1-based; list is 0-based
692
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
693
        new_tree = self.repository.revision_tree(rh[revno-1])
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
694
        if revno == 1:
695
            old_tree = EmptyTree()
696
        else:
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
697
            old_tree = self.repository.revision_tree(rh[revno-2])
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
698
        return compare_trees(old_tree, new_tree)
699
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
700
    @needs_read_lock
1 by mbp at sourcefrog
import from baz patch-364
701
    def revision_history(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
702
        """See Branch.revision_history."""
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
703
        # 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.
704
        transaction = self.get_transaction()
705
        history = transaction.map.find_revision_history()
706
        if history is not None:
707
            mutter("cache hit for revision-history in %s", self)
1417.1.12 by Robert Collins
cache revision history during read transactions
708
            return list(history)
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
709
        history = [l.rstrip('\r\n') for l in
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
710
                self.control_files.controlfile('revision-history', 'r').readlines()]
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
711
        transaction.map.add_revision_history(history)
712
        # this call is disabled because revision_history is 
713
        # not really an object yet, and the transaction is for objects.
714
        # transaction.register_clean(history, precious=True)
715
        return list(history)
1 by mbp at sourcefrog
import from baz patch-364
716
974.1.28 by aaron.bentley at utoronto
factored install_revisions out of update_revisions, updated test cases for greedy_fetch
717
    def update_revisions(self, other, stop_revision=None):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
718
        """See Branch.update_revisions."""
974.1.33 by aaron.bentley at utoronto
Added greedy_fetch to update_revisions
719
        from bzrlib.fetch import greedy_fetch
974.1.75 by Aaron Bentley
Sped up pull by copying locally first
720
        if stop_revision is None:
1390 by Robert Collins
pair programming worx... merge integration and weave
721
            stop_revision = other.last_revision()
1185.12.44 by abentley
Restored branch convergence to bzr pull
722
        ### 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
723
        if (stop_revision is not None and 
724
            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
725
            return
1260 by Martin Pool
- some updates for fetch/update function
726
        greedy_fetch(to_branch=self, from_branch=other,
1261 by Martin Pool
- new method Branch.has_revision
727
                     revision=stop_revision)
1185.12.44 by abentley
Restored branch convergence to bzr pull
728
        pullable_revs = self.pullable_revisions(other, stop_revision)
1185.12.45 by abentley
Cleanups for pull
729
        if len(pullable_revs) > 0:
1261 by Martin Pool
- new method Branch.has_revision
730
            self.append_revision(*pullable_revs)
1185.12.44 by abentley
Restored branch convergence to bzr pull
731
732
    def pullable_revisions(self, other, stop_revision):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
733
        """See Branch.pullable_revisions."""
1185.12.44 by abentley
Restored branch convergence to bzr pull
734
        other_revno = other.revision_id_to_revno(stop_revision)
735
        try:
736
            return self.missing_revisions(other, other_revno)
737
        except DivergedBranches, e:
738
            try:
739
                pullable_revs = get_intervening_revisions(self.last_revision(),
1185.65.1 by Aaron Bentley
Refactored out ControlFiles and RevisionStore from _Branch
740
                                                          stop_revision, 
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
741
                                                          self.repository)
1185.12.44 by abentley
Restored branch convergence to bzr pull
742
                assert self.last_revision() not in pullable_revs
743
                return pullable_revs
744
            except bzrlib.errors.NotAncestor:
745
                if is_ancestor(self.last_revision(), stop_revision, self):
746
                    return []
747
                else:
748
                    raise e
749
        
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
750
    def basis_tree(self):
751
        """See Branch.basis_tree."""
752
        try:
753
            revision_id = self.revision_history()[-1]
1185.65.15 by Robert Collins
Merge from integration.
754
            # FIXME: This is an abstraction violation, the basis tree 
755
            # here as defined is on the working tree, the method should
756
            # be too. The basis tree for a branch can be different than
757
            # that for a working tree. RBC 20051207
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
758
            xml = self.working_tree().read_basis_inventory(revision_id)
759
            inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(xml)
1185.65.17 by Robert Collins
Merge from integration, mode-changes are broken.
760
            return RevisionTree(self.repository, inv, revision_id)
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
761
        except (IndexError, NoSuchFile, NoWorkingTree), e:
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
762
            return self.repository.revision_tree(self.last_revision())
1185.33.59 by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg)
763
1 by mbp at sourcefrog
import from baz patch-364
764
    def working_tree(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
765
        """See Branch.working_tree."""
1185.2.2 by Lalo Martins
cleaning up and refactoring the branch module.
766
        from bzrlib.workingtree import WorkingTree
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
767
        if self.base.find('://') != -1:
1497 by Robert Collins
Move Branch.read_working_inventory to WorkingTree.
768
            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.
769
        return WorkingTree(self.base, branch=self)
1 by mbp at sourcefrog
import from baz patch-364
770
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
771
    @needs_write_lock
772
    def pull(self, source, overwrite=False):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
773
        """See Branch.pull."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
774
        source.lock_read()
775
        try:
1185.33.44 by Martin Pool
[patch] show number of revisions pushed/pulled/merged (Robey Pointer)
776
            old_count = len(self.revision_history())
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
777
            try:
778
                self.update_revisions(source)
779
            except DivergedBranches:
780
                if not overwrite:
781
                    raise
1185.50.5 by John Arbash Meinel
pull --overwrite should always overwrite, not just if diverged. (Test case from Robey Pointer)
782
            if overwrite:
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
783
                self.set_revision_history(source.revision_history())
1185.33.44 by Martin Pool
[patch] show number of revisions pushed/pulled/merged (Robey Pointer)
784
            new_count = len(self.revision_history())
785
            return new_count - old_count
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
786
        finally:
787
            source.unlock()
1 by mbp at sourcefrog
import from baz patch-364
788
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
789
    def get_parent(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
790
        """See Branch.get_parent."""
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
791
        import errno
792
        _locs = ['parent', 'pull', 'x-pull']
793
        for l in _locs:
794
            try:
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
795
                return self.control_files.controlfile(l, 'r').read().strip('\n')
1185.31.45 by John Arbash Meinel
Refactoring Exceptions found some places where the wrong exception was caught.
796
            except NoSuchFile:
797
                pass
1149 by Martin Pool
- make get_parent() be a method of Branch; add simple tests for it
798
        return None
799
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
800
    def get_push_location(self):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
801
        """See Branch.get_push_location."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
802
        config = bzrlib.config.BranchConfig(self)
803
        push_loc = config.get_user_option('push_location')
804
        return push_loc
805
806
    def set_push_location(self, location):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
807
        """See Branch.set_push_location."""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
808
        config = bzrlib.config.LocationConfig(self.base)
809
        config.set_user_option('push_location', location)
810
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
811
    @needs_write_lock
1150 by Martin Pool
- add new Branch.set_parent and tests
812
    def set_parent(self, url):
1495.1.2 by Jelmer Vernooij
Move some generic methods of NativeBranch to Branch.
813
        """See Branch.set_parent."""
1150 by Martin Pool
- add new Branch.set_parent and tests
814
        # TODO: Maybe delete old location files?
815
        from bzrlib.atomicfile import AtomicFile
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
816
        f = AtomicFile(self.control_files.controlfilename('parent'))
1150 by Martin Pool
- add new Branch.set_parent and tests
817
        try:
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
818
            f.write(url + '\n')
819
            f.commit()
1150 by Martin Pool
- add new Branch.set_parent and tests
820
        finally:
1442.1.63 by Robert Collins
Remove self.lock_*...finally: self.unlock() dead chickens from branch.py.
821
            f.close()
1150 by Martin Pool
- add new Branch.set_parent and tests
822
1185.35.11 by Aaron Bentley
Added support for branch nicks
823
    def tree_config(self):
824
        return TreeConfig(self)
825
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
826
    def _get_truncated_history(self, revision_id):
827
        history = self.revision_history()
828
        if revision_id is None:
829
            return history
830
        try:
831
            idx = history.index(revision_id)
832
        except ValueError:
833
            raise InvalidRevisionId(revision_id=revision, branch=self)
834
        return history[:idx+1]
835
836
    @needs_read_lock
837
    def _clone_weave(self, to_location, revision=None, basis_branch=None):
838
        assert isinstance(to_location, basestring)
839
        if basis_branch is not None:
840
            note("basis_branch is not supported for fast weave copy yet.")
841
842
        history = self._get_truncated_history(revision)
843
        if not bzrlib.osutils.lexists(to_location):
844
            os.mkdir(to_location)
845
        branch_to = Branch.initialize(to_location)
846
        mutter("copy branch from %s to %s", self, branch_to)
847
        branch_to.working_tree().set_root_id(self.get_root_id())
848
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
849
        self.repository.copy(branch_to.repository)
974.1.54 by aaron.bentley at utoronto
Fixed the revno bug in log
850
        
1185.65.15 by Robert Collins
Merge from integration.
851
        # must be done *after* history is copied across
852
        # FIXME duplicate code with base .clone().
853
        # .. would template method be useful here.  RBC 20051207
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
854
        branch_to.set_parent(self.base)
1185.65.15 by Robert Collins
Merge from integration.
855
        branch_to.append_revision(*history)
856
        # circular import protection
857
        from bzrlib.merge import build_working_dir
858
        build_working_dir(to_location)
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
859
        mutter("copied")
860
        return branch_to
861
862
    def clone(self, to_location, revision=None, basis_branch=None, to_branch_type=None):
863
        if to_branch_type is None:
864
            to_branch_type = BzrBranch
865
866
        if to_branch_type == BzrBranch \
1185.67.2 by Aaron Bentley
Renamed Branch.storage to Branch.repository
867
            and self.repository.weave_store.listable() \
868
            and self.repository.revision_store.listable():
1185.66.8 by Aaron Bentley
Applied Jelmer's patch to make clone a branch operation
869
            return self._clone_weave(to_location, revision, basis_branch)
870
871
        return Branch.clone(self, to_location, revision, basis_branch, to_branch_type)
1185.35.11 by Aaron Bentley
Added support for branch nicks
872
1495.1.5 by Jelmer Vernooij
Rename NativeBranch -> BzrBranch
873
class ScratchBranch(BzrBranch):
1 by mbp at sourcefrog
import from baz patch-364
874
    """Special test class: a branch that cleans up after itself.
875
876
    >>> b = ScratchBranch()
877
    >>> isdir(b.base)
878
    True
879
    >>> bd = b.base
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
880
    >>> b.control_files._transport.__del__()
1 by mbp at sourcefrog
import from baz patch-364
881
    >>> isdir(bd)
882
    False
883
    """
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
884
885
    def __init__(self, files=[], dirs=[], transport=None):
1 by mbp at sourcefrog
import from baz patch-364
886
        """Make a test branch.
887
888
        This creates a temporary directory and runs init-tree in it.
889
890
        If any files are listed, they are created in the working copy.
891
        """
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
892
        if transport is None:
893
            transport = bzrlib.transport.local.ScratchTransport()
894
            super(ScratchBranch, self).__init__(transport, init=True)
895
        else:
896
            super(ScratchBranch, self).__init__(transport)
897
100 by mbp at sourcefrog
- add test case for ignore files
898
        for d in dirs:
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
899
            self.control_files._transport.mkdir(d)
100 by mbp at sourcefrog
- add test case for ignore files
900
            
1 by mbp at sourcefrog
import from baz patch-364
901
        for f in files:
1185.65.11 by Robert Collins
Disable inheritance for getting at LockableFiles, rather use composition.
902
            self.control_files._transport.put(f, 'content of %s' % f)
1 by mbp at sourcefrog
import from baz patch-364
903
622 by Martin Pool
Updated merge patch from Aaron
904
    def clone(self):
905
        """
906
        >>> orig = ScratchBranch(files=["file1", "file2"])
907
        >>> clone = orig.clone()
1185.1.40 by Robert Collins
Merge what applied of Alexander Belchenko's win32 patch.
908
        >>> if os.name != 'nt':
909
        ...   os.path.samefile(orig.base, clone.base)
910
        ... else:
911
        ...   orig.base == clone.base
912
        ...
622 by Martin Pool
Updated merge patch from Aaron
913
        False
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 \
914
        >>> os.path.isfile(pathjoin(clone.base, "file1"))
622 by Martin Pool
Updated merge patch from Aaron
915
        True
916
        """
800 by Martin Pool
Merge John's import-speedup branch:
917
        from shutil import copytree
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
918
        from bzrlib.osutils import mkdtemp
800 by Martin Pool
Merge John's import-speedup branch:
919
        base = mkdtemp()
622 by Martin Pool
Updated merge patch from Aaron
920
        os.rmdir(base)
800 by Martin Pool
Merge John's import-speedup branch:
921
        copytree(self.base, base, symlinks=True)
1442.1.42 by Robert Collins
rebuild ScratchBranch on top of ScratchTransport
922
        return ScratchBranch(
923
            transport=bzrlib.transport.local.ScratchTransport(base))
1 by mbp at sourcefrog
import from baz patch-364
924
    
925
926
######################################################################
927
# predicates
928
929
930
def is_control_file(filename):
931
    ## FIXME: better check
1185.31.38 by John Arbash Meinel
Changing os.path.normpath to osutils.normpath
932
    filename = normpath(filename)
1 by mbp at sourcefrog
import from baz patch-364
933
    while filename != '':
934
        head, tail = os.path.split(filename)
935
        ## mutter('check %r for control file' % ((head, tail), ))
936
        if tail == bzrlib.BZRDIR:
937
            return True
70 by mbp at sourcefrog
Prepare for smart recursive add.
938
        if filename == head:
939
            break
1 by mbp at sourcefrog
import from baz patch-364
940
        filename = head
941
    return False