~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
from time import time
52
52
import warnings
53
53
 
54
 
from bzrlib import bzrdir, errors, osutils, urlutils
 
54
import bzrlib
 
55
from bzrlib import bzrdir, errors, ignores, osutils, urlutils
55
56
from bzrlib.atomicfile import AtomicFile
56
57
import bzrlib.branch
57
58
from bzrlib.conflicts import Conflict, ConflictList, CONFLICT_SUFFIXES
106
107
import bzrlib.xml5
107
108
 
108
109
 
109
 
# the regex here does the following:
110
 
# 1) remove any weird characters; we don't escape them but rather
111
 
# just pull them out
112
 
 # 2) match leading '.'s to make it not hidden
113
 
_gen_file_id_re = re.compile(r'[^\w.]|(^\.*)')
 
110
# the regex removes any weird characters; we don't escape them 
 
111
# but rather just pull them out
 
112
_gen_file_id_re = re.compile(r'[^\w.]')
114
113
_gen_id_suffix = None
115
114
_gen_id_serial = 0
116
115
 
138
137
 
139
138
    The uniqueness is supplied from _next_id_suffix.
140
139
    """
141
 
    # XXX TODO: squash the filename to lowercase.
142
 
    # XXX TODO: truncate the filename to something like 20 or 30 chars.
143
 
    # XXX TODO: consider what to do with ids that look like illegal filepaths
144
 
    # on platforms we support.
145
 
    return _gen_file_id_re.sub('', name) + _next_id_suffix()
 
140
    # The real randomness is in the _next_id_suffix, the
 
141
    # rest of the identifier is just to be nice.
 
142
    # So we:
 
143
    # 1) Remove non-ascii word characters to keep the ids portable
 
144
    # 2) squash to lowercase, so the file id doesn't have to
 
145
    #    be escaped (case insensitive filesystems would bork for ids
 
146
    #    that only differred in case without escaping).
 
147
    # 3) truncate the filename to 20 chars. Long filenames also bork on some
 
148
    #    filesystems
 
149
    # 4) Removing starting '.' characters to prevent the file ids from
 
150
    #    being considered hidden.
 
151
    ascii_word_only = _gen_file_id_re.sub('', name.lower())
 
152
    short_no_dots = ascii_word_only.lstrip('.')[:20]
 
153
    return short_no_dots + _next_id_suffix()
146
154
 
147
155
 
148
156
def gen_root_id():
374
382
        """
375
383
        inv = self._inventory
376
384
        for path, ie in inv.iter_entries():
377
 
            if bzrlib.osutils.lexists(self.abspath(path)):
 
385
            if osutils.lexists(self.abspath(path)):
378
386
                yield ie.file_id
379
387
 
380
388
    def __repr__(self):
446
454
        return relpath(self.basedir, path)
447
455
 
448
456
    def has_filename(self, filename):
449
 
        return bzrlib.osutils.lexists(self.abspath(filename))
 
457
        return osutils.lexists(self.abspath(filename))
450
458
 
451
459
    def get_file(self, file_id):
452
460
        return self.get_file_byname(self.id2path(file_id))
536
544
        if not inv.has_id(file_id):
537
545
            return False
538
546
        path = inv.id2path(file_id)
539
 
        return bzrlib.osutils.lexists(self.abspath(path))
 
547
        return osutils.lexists(self.abspath(path))
540
548
 
541
549
    def has_or_had_id(self, file_id):
542
550
        if file_id == self.inventory.root.file_id:
720
728
        """
721
729
        inv = self._inventory
722
730
        # Convert these into local objects to save lookup times
723
 
        pathjoin = bzrlib.osutils.pathjoin
724
 
        file_kind = bzrlib.osutils.file_kind
 
731
        pathjoin = osutils.pathjoin
 
732
        file_kind = osutils.file_kind
725
733
 
726
734
        # transport.base ends in a slash, we want the piece
727
735
        # between the last two slashes
1097
1105
 
1098
1106
        Cached in the Tree object after the first call.
1099
1107
        """
1100
 
        if hasattr(self, '_ignorelist'):
1101
 
            return self._ignorelist
1102
 
 
1103
 
        l = []
 
1108
        ignoreset = getattr(self, '_ignoreset', None)
 
1109
        if ignoreset is not None:
 
1110
            return ignoreset
 
1111
 
 
1112
        ignore_globs = set(bzrlib.DEFAULT_IGNORE)
 
1113
        ignore_globs.update(ignores.get_runtime_ignores())
 
1114
 
 
1115
        ignore_globs.update(ignores.get_user_ignores())
 
1116
 
1104
1117
        if self.has_filename(bzrlib.IGNORE_FILENAME):
1105
1118
            f = self.get_file_byname(bzrlib.IGNORE_FILENAME)
1106
 
            l.extend([line.rstrip("\n\r").decode('utf-8') 
1107
 
                      for line in f.readlines()])
1108
 
        self._ignorelist = l
1109
 
        self._ignore_regex = self._combine_ignore_rules(l)
1110
 
        return l
 
1119
            try:
 
1120
                ignore_globs.update(ignores.parse_ignore_file(f))
 
1121
            finally:
 
1122
                f.close()
 
1123
 
 
1124
        self._ignoreset = ignore_globs
 
1125
        self._ignore_regex = self._combine_ignore_rules(ignore_globs)
 
1126
        return ignore_globs
1111
1127
 
1112
1128
    def _get_ignore_rules_as_regex(self):
1113
1129
        """Return a regex of the ignore rules and a mapping dict.
1115
1131
        :return: (ignore rules compiled regex, dictionary mapping rule group 
1116
1132
        indices to original rule.)
1117
1133
        """
1118
 
        if getattr(self, '_ignorelist', None) is None:
 
1134
        if getattr(self, '_ignoreset', None) is None:
1119
1135
            self.get_ignore_list()
1120
1136
        return self._ignore_regex
1121
1137