~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2005-06-28 03:02:31 UTC
  • Revision ID: mbp@sourcefrog.net-20050628030231-d311e4ebcd467ef4
Merge John's import-speedup branch:

                                                                                         
  777 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:20:32 -0500
      revision-id: john@arbash-meinel.com-20050627032031-e82a50db3863b18e
      bzr selftest was not using the correct bzr

  776 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:20:22 -0500
      revision-id: john@arbash-meinel.com-20050627032021-c9f21fde989ddaee
      Add was using an old mutter

  775 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 22:02:33 -0500
      revision-id: john@arbash-meinel.com-20050627030233-9165cfe98fc63298
      Cleaned up to be less different

  774 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:54:53 -0500
      revision-id: john@arbash-meinel.com-20050627025452-4260d0e744edef43
      Allow BZR_PLUGIN_PATH='' to negate plugin loading.

  773 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:49:34 -0500
      revision-id: john@arbash-meinel.com-20050627024933-b7158f67b7b9eae5
      Finished the previous cleanup (allowing load_plugins to be called twice)

  772 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:45:08 -0500
      revision-id: john@arbash-meinel.com-20050627024508-723b1df510d196fc
      Work on making the tests pass. versioning.py is calling run_cmd directly, but plugins have been loaded.

  771 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:32:29 -0500
      revision-id: john@arbash-meinel.com-20050627023228-79972744d7c53e15
      Got it down a little bit more by removing import of tree and inventory.

  770 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 21:26:05 -0500
      revision-id: john@arbash-meinel.com-20050627022604-350b9773ef622f95
      Reducing the number of import from bzrlib/__init__.py and bzrlib/branch.py

  769 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:32:25 -0500
      revision-id: john@arbash-meinel.com-20050627013225-32dd044f10d23948
      Updated revision.py and xml.py to include SubElement.

  768 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:03:56 -0500
      revision-id: john@arbash-meinel.com-20050627010356-ee66919e1c377faf
      Minor typo

  767 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 20:03:13 -0500
      revision-id: john@arbash-meinel.com-20050627010312-40d024007eb85051
      Caching the import

  766 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:51:47 -0500
      revision-id: john@arbash-meinel.com-20050627005147-5281c99e48ed1834
      Created wrapper functions for lazy import of ElementTree

  765 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:46:37 -0500
      revision-id: john@arbash-meinel.com-20050627004636-bf432902004a94c5
      Removed all of the test imports of cElementTree

  764 John Arbash Meinel <john@arbash-meinel.com>       Sun 2005-06-26 19:43:59 -0500
      revision-id: john@arbash-meinel.com-20050627004358-d137fbe9570dd71b
      Trying to make bzr startup faster.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
import sys, os, os.path, random, time, sha, sets, types, re, shutil, tempfile
19
 
import traceback, socket, fnmatch, difflib, time
20
 
from binascii import hexlify
 
18
import sys, os
21
19
 
22
20
import bzrlib
23
 
from inventory import Inventory
24
 
from trace import mutter, note
25
 
from tree import Tree, EmptyTree, RevisionTree
26
 
from inventory import InventoryEntry, Inventory
27
 
from osutils import isdir, quotefn, isfile, uuid, sha_file, username, \
28
 
     format_date, compact_date, pumpfile, user_email, rand_bytes, splitpath, \
29
 
     joinpath, sha_file, sha_string, file_kind, local_time_offset, appendpath
30
 
from store import ImmutableStore
31
 
from revision import Revision
32
 
from errors import BzrError
33
 
from textui import show_status
 
21
from bzrlib.trace import mutter, note
 
22
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, splitpath, \
 
23
     sha_file, appendpath, file_kind
 
24
from bzrlib.errors import BzrError
34
25
 
35
26
BZR_BRANCH_FORMAT = "Bazaar-NG branch, format 0.0.4\n"
36
27
## TODO: Maybe include checks for common corruption of newlines, etc?
174
165
        In the test suite, creation of new trees is tested using the
175
166
        `ScratchBranch` class.
176
167
        """
 
168
        from bzrlib.store import ImmutableStore
177
169
        if init:
178
170
            self.base = os.path.realpath(base)
179
171
            self._make_control()
265
257
 
266
258
    def controlfilename(self, file_or_path):
267
259
        """Return location relative to branch."""
268
 
        if isinstance(file_or_path, types.StringTypes):
 
260
        if isinstance(file_or_path, basestring):
269
261
            file_or_path = [file_or_path]
270
262
        return os.path.join(self.base, bzrlib.BZRDIR, *file_or_path)
271
263
 
298
290
 
299
291
 
300
292
    def _make_control(self):
 
293
        from bzrlib.inventory import Inventory
301
294
        os.mkdir(self.controlfilename([]))
302
295
        self.controlfile('README', 'w').write(
303
296
            "This is a Bazaar-NG control directory.\n"
335
328
 
336
329
    def read_working_inventory(self):
337
330
        """Read the working inventory."""
338
 
        before = time.time()
 
331
        from bzrlib.inventory import Inventory
 
332
        from time import time
 
333
        before = time()
339
334
        # ElementTree does its own conversion from UTF-8, so open in
340
335
        # binary.
341
336
        self.lock_read()
342
337
        try:
343
338
            inv = Inventory.read_xml(self.controlfile('inventory', 'rb'))
344
339
            mutter("loaded inventory of %d items in %f"
345
 
                   % (len(inv), time.time() - before))
 
340
                   % (len(inv), time() - before))
346
341
            return inv
347
342
        finally:
348
343
            self.unlock()
400
395
              add all non-ignored children.  Perhaps do that in a
401
396
              higher-level method.
402
397
        """
 
398
        from bzrlib.textui import show_status
403
399
        # TODO: Re-adding a file that is removed in the working copy
404
400
        # should probably put it back with the previous ID.
405
 
        if isinstance(files, types.StringTypes):
406
 
            assert(ids is None or isinstance(ids, types.StringTypes))
 
401
        if isinstance(files, basestring):
 
402
            assert(ids is None or isinstance(ids, basestring))
407
403
            files = [files]
408
404
            if ids is not None:
409
405
                ids = [ids]
478
474
        is the opposite of add.  Removing it is consistent with most
479
475
        other tools.  Maybe an option.
480
476
        """
 
477
        from bzrlib.textui import show_status
481
478
        ## TODO: Normalize names
482
479
        ## TODO: Remove nested loops; better scalability
483
 
        if isinstance(files, types.StringTypes):
 
480
        if isinstance(files, basestring):
484
481
            files = [files]
485
482
 
486
483
        self.lock_write()
511
508
 
512
509
    # FIXME: this doesn't need to be a branch method
513
510
    def set_inventory(self, new_inventory_list):
 
511
        from bzrlib.inventory import Inventory, InventoryEntry
514
512
        inv = Inventory()
515
513
        for path, file_id, parent, kind in new_inventory_list:
516
514
            name = os.path.basename(path)
556
554
 
557
555
    def get_revision(self, revision_id):
558
556
        """Return the Revision object for a named revision"""
 
557
        from bzrlib.revision import Revision
559
558
        if not revision_id or not isinstance(revision_id, basestring):
560
559
            raise ValueError('invalid revision-id: %r' % revision_id)
561
560
        r = Revision.read_xml(self.revision_store[revision_id])
579
578
        TODO: Perhaps for this and similar methods, take a revision
580
579
               parameter which can be either an integer revno or a
581
580
               string hash."""
 
581
        from bzrlib.inventory import Inventory
582
582
        i = Inventory.read_xml(self.inventory_store[inventory_id])
583
583
        return i
584
584
 
591
591
    def get_revision_inventory(self, revision_id):
592
592
        """Return inventory of a past revision."""
593
593
        if revision_id == None:
 
594
            from bzrlib.inventory import Inventory
594
595
            return Inventory()
595
596
        else:
596
597
            return self.get_inventory(self.get_revision(revision_id).inventory_id)
763
764
        True
764
765
        """
765
766
        from bzrlib.progress import ProgressBar
 
767
        try:
 
768
            set
 
769
        except NameError:
 
770
            from sets import Set as set
766
771
 
767
772
        pb = ProgressBar()
768
773
 
777
782
            other.inventory_store.prefetch(inventory_ids)
778
783
                
779
784
        revisions = []
780
 
        needed_texts = sets.Set()
 
785
        needed_texts = set()
781
786
        i = 0
782
787
        for rev_id in revision_ids:
783
788
            i += 1
829
834
 
830
835
        `revision_id` may be None for the null revision, in which case
831
836
        an `EmptyTree` is returned."""
 
837
        from bzrlib.tree import EmptyTree, RevisionTree
832
838
        # TODO: refactor this to use an existing revision object
833
839
        # so we don't need to read it in twice.
834
840
        if revision_id == None:
849
855
 
850
856
        If there are no revisions yet, return an `EmptyTree`.
851
857
        """
 
858
        from bzrlib.tree import EmptyTree, RevisionTree
852
859
        r = self.last_patch()
853
860
        if r == None:
854
861
            return EmptyTree()
1035
1042
 
1036
1043
        If any files are listed, they are created in the working copy.
1037
1044
        """
 
1045
        from tempfile import mkdtemp
1038
1046
        init = False
1039
1047
        if base is None:
1040
 
            base = tempfile.mkdtemp()
 
1048
            base = mkdtemp()
1041
1049
            init = True
1042
1050
        Branch.__init__(self, base, init=init)
1043
1051
        for d in dirs:
1056
1064
        >>> os.path.isfile(os.path.join(clone.base, "file1"))
1057
1065
        True
1058
1066
        """
1059
 
        base = tempfile.mkdtemp()
 
1067
        from shutil import copytree
 
1068
        from tempfile import mkdtemp
 
1069
        base = mkdtemp()
1060
1070
        os.rmdir(base)
1061
 
        shutil.copytree(self.base, base, symlinks=True)
 
1071
        copytree(self.base, base, symlinks=True)
1062
1072
        return ScratchBranch(base=base)
1063
1073
        
1064
1074
    def __del__(self):
1066
1076
 
1067
1077
    def destroy(self):
1068
1078
        """Destroy the test branch, removing the scratch directory."""
 
1079
        from shutil import rmtree
1069
1080
        try:
1070
1081
            if self.base:
1071
1082
                mutter("delete ScratchBranch %s" % self.base)
1072
 
                shutil.rmtree(self.base)
 
1083
                rmtree(self.base)
1073
1084
        except OSError, e:
1074
1085
            # Work around for shutil.rmtree failing on Windows when
1075
1086
            # readonly files are encountered
1077
1088
            for root, dirs, files in os.walk(self.base, topdown=False):
1078
1089
                for name in files:
1079
1090
                    os.chmod(os.path.join(root, name), 0700)
1080
 
            shutil.rmtree(self.base)
 
1091
            rmtree(self.base)
1081
1092
        self.base = None
1082
1093
 
1083
1094
    
1108
1119
    cope with just randomness because running uuidgen every time is
1109
1120
    slow."""
1110
1121
    import re
 
1122
    from binascii import hexlify
 
1123
    from time import time
1111
1124
 
1112
1125
    # get last component
1113
1126
    idx = name.rfind('/')
1125
1138
    name = re.sub(r'[^\w.]', '', name)
1126
1139
 
1127
1140
    s = hexlify(rand_bytes(8))
1128
 
    return '-'.join((name, compact_date(time.time()), s))
 
1141
    return '-'.join((name, compact_date(time()), s))