~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: mbp at sourcefrog
  • Date: 2005-03-29 01:26:19 UTC
  • Revision ID: mbp@sourcefrog.net-20050329012619-dd8959fc63b3a074
- fixup checks on retrieved files to cope with compression,
  and have less checks now there's a check command again

- move code to destroy stores into the ScratchStore subclass

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from sets import Set
21
21
import os.path, os, fnmatch
22
22
 
 
23
from inventory import Inventory
 
24
from trace import mutter, note
23
25
from osutils import pumpfile, compare_files, filesize, quotefn, sha_file, \
24
26
     joinpath, splitpath, appendpath, isdir, isfile, file_kind, fingerprint_file
25
 
import errno
26
 
from stat import S_ISREG, S_ISDIR, ST_MODE, ST_SIZE
27
 
 
28
 
from inventory import Inventory
29
 
from trace import mutter, note
30
27
from errors import bailout
31
28
import branch
 
29
from stat import S_ISREG, S_ISDIR, ST_MODE, ST_SIZE
32
30
 
33
31
import bzrlib
34
32
 
79
77
        f.seek(0)
80
78
        
81
79
        if ie.text_size is not None:
82
 
            if ie.text_size != fp['size']:
 
80
            if fs != fp['size']:
83
81
                bailout("mismatched size for file %r in %r" % (ie.file_id, self._store),
84
82
                        ["inventory expects %d bytes" % ie.text_size,
85
83
                         "file is actually %d bytes" % fp['size'],
176
174
            return '?'
177
175
 
178
176
 
 
177
    def file_kind(self, filename):
 
178
        if isfile(self.abspath(filename)):
 
179
            return 'file'
 
180
        elif isdir(self.abspath(filename)):
 
181
            return 'directory'
 
182
        else:
 
183
            return 'unknown'
 
184
 
 
185
 
179
186
    def list_files(self):
180
187
        """Recursively list all files as (path, class, kind, id).
181
188
 
192
199
            ls = os.listdir(dp)
193
200
            ls.sort()
194
201
            for f in ls:
195
 
                ## TODO: If we find a subdirectory with its own .bzr
196
 
                ## directory, then that is a separate tree and we
197
 
                ## should exclude it.
198
202
                if bzrlib.BZRDIR == f:
199
203
                    continue
200
204
 
236
240
            
237
241
 
238
242
 
239
 
    def unknowns(self):
240
 
        for subp in self.extras():
241
 
            if not self.is_ignored(subp):
242
 
                yield subp
243
 
 
244
 
 
245
 
    def extras(self):
246
 
        """Yield all unknown files in this WorkingTree.
 
243
    def unknowns(self, path='', dir_id=None):
 
244
        """Yield names of unknown files in this WorkingTree.
247
245
 
248
246
        If there are any unknown directories then only the directory is
249
247
        returned, not all its children.  But if there are unknown files
251
249
 
252
250
        Currently returned depth-first, sorted by name within directories.
253
251
        """
254
 
        ## TODO: Work from given directory downwards
255
 
        
256
 
        for path, dir_entry in self.inventory.directories():
257
 
            mutter("search for unknowns in %r" % path)
258
 
            dirabs = self.abspath(path)
259
 
            if not isdir(dirabs):
260
 
                # e.g. directory deleted
261
 
                continue
262
 
 
263
 
            fl = []
264
 
            for subf in os.listdir(dirabs):
265
 
                if (subf != '.bzr'
266
 
                    and (subf not in dir_entry.children)):
267
 
                    fl.append(subf)
268
 
            
269
 
            fl.sort()
270
 
            for subf in fl:
271
 
                subp = appendpath(path, subf)
272
 
                yield subp
273
 
 
 
252
        for fpath, fclass, fkind, fid in self.list_files():
 
253
            if fclass == '?':
 
254
                yield fpath
 
255
                
274
256
 
275
257
    def ignored_files(self):
276
 
        """Yield list of PATH, IGNORE_PATTERN"""
277
 
        for subp in self.extras():
278
 
            pat = self.is_ignored(subp)
279
 
            if pat != None:
280
 
                yield subp, pat
 
258
        for fpath, fclass, fkind, fid in self.list_files():
 
259
            if fclass == 'I':
 
260
                yield fpath
281
261
 
282
262
 
283
263
    def get_ignore_list(self):
300
280
        """Check whether the filename matches an ignore pattern.
301
281
 
302
282
        Patterns containing '/' need to match the whole path; others
303
 
        match against only the last component.
304
 
 
305
 
        If the file is ignored, returns the pattern which caused it to
306
 
        be ignored, otherwise None.  So this can simply be used as a
307
 
        boolean if desired."""
308
 
 
309
 
        ## TODO: Use '**' to match directories, and other extended globbing stuff from cvs/rsync.
310
 
        
 
283
        match against only the last component."""
 
284
        ## TODO: Use extended zsh-style globs maybe?
 
285
        ## TODO: Use '**' to match directories?
311
286
        for pat in self.get_ignore_list():
312
287
            if '/' in pat:
313
 
                # as a special case, you can put ./ at the start of a pattern;
314
 
                # this is good to match in the top-level only;
315
 
                if pat[:2] == './':
316
 
                    newpat = pat[2:]
317
 
                else:
318
 
                    newpat = pat
319
 
                if fnmatch.fnmatchcase(filename, newpat):
320
 
                    return pat
 
288
                if fnmatch.fnmatchcase(filename, pat):
 
289
                    return True
321
290
            else:
322
291
                if fnmatch.fnmatchcase(splitpath(filename)[-1], pat):
323
 
                    return pat
324
 
        return None
 
292
                    return True
 
293
        return False
325
294
        
326
295
 
327
296
        
345
314
        ie = self._inventory[file_id]
346
315
        f = self._store[ie.text_id]
347
316
        mutter("  get fileid{%s} from %r" % (file_id, self))
348
 
        self._check_retrieved(ie, f)
 
317
        ## self._check_retrieved(ie, f)
349
318
        return f
350
319
 
351
320
    def get_file_size(self, file_id):
432
401
 
433
402
    
434
403
 
435
 
def find_renames(old_inv, new_inv):
436
 
    for file_id in old_inv:
437
 
        if file_id not in new_inv:
438
 
            continue
439
 
        old_name = old_inv.id2path(file_id)
440
 
        new_name = new_inv.id2path(file_id)
441
 
        if old_name != new_name:
442
 
            yield (old_name, new_name)
443