~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tree.py

  • Committer: mbp at sourcefrog
  • Date: 2005-04-07 02:40:18 UTC
  • Revision ID: mbp@sourcefrog.net-20050407024018-cf7130ea991f4ebc0c353ed2
more notes on svk

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 osutils import pumpfile, compare_files, filesize, quotefn, sha_file, \
 
24
     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
 
23
28
from inventory import Inventory
24
29
from trace import mutter, note
25
 
from osutils import pumpfile, compare_files, filesize, quotefn, sha_file, \
26
 
     joinpath, splitpath, appendpath, isdir, isfile, file_kind, fingerprint_file
27
30
from errors import bailout
28
31
import branch
29
 
from stat import S_ISREG, S_ISDIR, ST_MODE, ST_SIZE
30
32
 
31
33
import bzrlib
32
34
 
76
78
        fp = fingerprint_file(f)
77
79
        f.seek(0)
78
80
        
79
 
        if ie.text_size is not None:
 
81
        if ie.text_size != None:
80
82
            if ie.text_size != fp['size']:
81
83
                bailout("mismatched size for file %r in %r" % (ie.file_id, self._store),
82
84
                        ["inventory expects %d bytes" % ie.text_size,
90
92
                     "store is probably damaged/corrupt"])
91
93
 
92
94
 
93
 
    def export(self, dest):
 
95
    def print_file(self, fileid):
 
96
        """Print file with id `fileid` to stdout."""
 
97
        import sys
 
98
        pumpfile(self.get_file(fileid), sys.stdout)
 
99
        
 
100
        
 
101
    def export(self, dest):        
94
102
        """Export this tree to a new directory.
95
103
 
96
104
        `dest` should not exist, and will be created holding the
113
121
            elif kind == 'file':
114
122
                pumpfile(self.get_file(ie.file_id), file(fullpath, 'wb'))
115
123
            else:
116
 
                bailout("don't know how to export {%s} of kind %r", fid, kind)
 
124
                bailout("don't know how to export {%s} of kind %r" % (fid, kind))
117
125
            mutter("  export {%s} kind %s to %s" % (ie.file_id, kind, fullpath))
118
126
 
119
127
 
149
157
        return file(self.abspath(filename), 'rb')
150
158
 
151
159
    def _get_store_filename(self, file_id):
 
160
        ## XXX: badly named; this isn't in the store at all
152
161
        return self.abspath(self.id2path(file_id))
153
162
 
154
163
    def has_id(self, file_id):
174
183
            return '?'
175
184
 
176
185
 
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
 
 
186
186
    def list_files(self):
187
187
        """Recursively list all files as (path, class, kind, id).
188
188
 
195
195
        """
196
196
        inv = self.inventory
197
197
 
198
 
        def descend(from_dir, from_dir_id, dp):
 
198
        def descend(from_dir_relpath, from_dir_id, dp):
199
199
            ls = os.listdir(dp)
200
200
            ls.sort()
201
201
            for f in ls:
206
206
                    continue
207
207
 
208
208
                # path within tree
209
 
                fp = appendpath(from_dir, f)
 
209
                fp = appendpath(from_dir_relpath, f)
210
210
 
211
211
                # absolute path
212
212
                fap = appendpath(dp, f)
238
238
                for ff in descend(fp, f_ie.file_id, fap):
239
239
                    yield ff
240
240
 
241
 
        for f in descend('', None, self.basedir):
 
241
        for f in descend('', inv.root.file_id, self.basedir):
242
242
            yield f
243
243
            
244
244
 
245
245
 
246
 
    def unknowns(self, path='', dir_id=None):
247
 
        """Yield names of unknown files in this WorkingTree.
 
246
    def unknowns(self):
 
247
        for subp in self.extras():
 
248
            if not self.is_ignored(subp):
 
249
                yield subp
 
250
 
 
251
 
 
252
    def extras(self):
 
253
        """Yield all unknown files in this WorkingTree.
248
254
 
249
255
        If there are any unknown directories then only the directory is
250
256
        returned, not all its children.  But if there are unknown files
252
258
 
253
259
        Currently returned depth-first, sorted by name within directories.
254
260
        """
255
 
        for fpath, fclass, fkind, fid in self.list_files():
256
 
            if fclass == '?':
257
 
                yield fpath
258
 
                
 
261
        ## TODO: Work from given directory downwards
 
262
        
 
263
        for path, dir_entry in self.inventory.directories():
 
264
            mutter("search for unknowns in %r" % path)
 
265
            dirabs = self.abspath(path)
 
266
            if not isdir(dirabs):
 
267
                # e.g. directory deleted
 
268
                continue
 
269
 
 
270
            fl = []
 
271
            for subf in os.listdir(dirabs):
 
272
                if (subf != '.bzr'
 
273
                    and (subf not in dir_entry.children)):
 
274
                    fl.append(subf)
 
275
            
 
276
            fl.sort()
 
277
            for subf in fl:
 
278
                subp = appendpath(path, subf)
 
279
                yield subp
 
280
 
259
281
 
260
282
    def ignored_files(self):
261
 
        for fpath, fclass, fkind, fid in self.list_files():
262
 
            if fclass == 'I':
263
 
                yield fpath
 
283
        """Yield list of PATH, IGNORE_PATTERN"""
 
284
        for subp in self.extras():
 
285
            pat = self.is_ignored(subp)
 
286
            if pat != None:
 
287
                yield subp, pat
264
288
 
265
289
 
266
290
    def get_ignore_list(self):
293
317
        
294
318
        for pat in self.get_ignore_list():
295
319
            if '/' in pat:
296
 
                if fnmatch.fnmatchcase(filename, pat):
 
320
                # as a special case, you can put ./ at the start of a pattern;
 
321
                # this is good to match in the top-level only;
 
322
                if pat[:2] == './':
 
323
                    newpat = pat[2:]
 
324
                else:
 
325
                    newpat = pat
 
326
                if fnmatch.fnmatchcase(filename, newpat):
297
327
                    return pat
298
328
            else:
299
329
                if fnmatch.fnmatchcase(splitpath(filename)[-1], pat):
409
439
 
410
440
    
411
441
 
 
442
def find_renames(old_inv, new_inv):
 
443
    for file_id in old_inv:
 
444
        if file_id not in new_inv:
 
445
            continue
 
446
        old_name = old_inv.id2path(file_id)
 
447
        new_name = new_inv.id2path(file_id)
 
448
        if old_name != new_name:
 
449
            yield (old_name, new_name)
 
450