~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/mutabletree.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-11 21:41:24 UTC
  • mto: This revision was merged to the branch mainline in revision 3543.
  • Revision ID: john@arbash-meinel.com-20080711214124-qi09irlj7pd5cuzg
Shortcut the case when one revision is in the ancestry of the other.

At the cost of a heads() check, when one parent supersedes, we don't have to extract
the text for the other. Changes merge time from 3m37s => 3m21s. Using a
CachingParentsProvider would drop the time down to 3m11s.

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
    A mutable tree always has an associated Branch and BzrDir object - the
76
76
    branch and bzrdir attributes.
77
77
    """
78
 
    def __init__(self, *args, **kw):
79
 
        super(MutableTree, self).__init__(*args, **kw)
80
 
        # Is this tree on a case-insensitive or case-preserving file-system?
81
 
        # Sub-classes may initialize to False if they detect they are being
82
 
        # used on media which doesn't differentiate the case of names.
83
 
        self.case_sensitive = True
84
78
 
85
79
    @needs_tree_write_lock
86
80
    def add(self, files, ids=None, kinds=None):
187
181
        from bzrlib import commit
188
182
        if revprops is None:
189
183
            revprops = {}
190
 
        possible_master_transports=[]
191
184
        if not 'branch-nick' in revprops:
192
 
            revprops['branch-nick'] = self.branch._get_nick(
193
 
                kwargs.get('local', False),
194
 
                possible_master_transports)
 
185
            revprops['branch-nick'] = self.branch.nick
195
186
        author = kwargs.pop('author', None)
196
187
        if author is not None:
197
188
            if 'author' in revprops:
203
194
        for hook in MutableTree.hooks['start_commit']:
204
195
            hook(self)
205
196
        committed_id = commit.Commit().commit(working_tree=self,
206
 
            revprops=revprops,
207
 
            possible_master_transports=possible_master_transports,
208
 
            *args, **kwargs)
 
197
            revprops=revprops, *args, **kwargs)
209
198
        return committed_id
210
199
 
211
200
    def _gather_kinds(self, files, kinds):
212
201
        """Helper function for add - sets the entries of kinds."""
213
202
        raise NotImplementedError(self._gather_kinds)
214
203
 
215
 
    def get_file_with_stat(self, file_id, path=None):
216
 
        """Get a file handle and stat object for file_id.
217
 
 
218
 
        The default implementation returns (self.get_file, None) for backwards
219
 
        compatibility.
220
 
 
221
 
        :param file_id: The file id to read.
222
 
        :param path: The path of the file, if it is known.
223
 
        :return: A tuple (file_handle, stat_value_or_None). If the tree has
224
 
            no stat facility, or need for a stat cache feedback during commit,
225
 
            it may return None for the second element of the tuple.
226
 
        """
227
 
        return (self.get_file(file_id, path), None)
228
 
 
229
204
    @needs_read_lock
230
205
    def last_revision(self):
231
206
        """Return the revision id of the last commit performed in this tree.
272
247
        """
273
248
        raise NotImplementedError(self.mkdir)
274
249
 
275
 
    def _observed_sha1(self, file_id, path, (sha1, stat_value)):
276
 
        """Tell the tree we have observed a paths sha1.
277
 
 
278
 
        The intent of this function is to allow trees that have a hashcache to
279
 
        update the hashcache during commit. If the observed file is too new
280
 
        (based on the stat_value) to be safely hash-cached the tree will ignore
281
 
        it. 
282
 
 
283
 
        The default implementation does nothing.
284
 
 
285
 
        :param file_id: The file id
286
 
        :param path: The file path
287
 
        :param sha1: The sha 1 that was observed.
288
 
        :param stat_value: A stat result for the file the sha1 was read from.
289
 
        :return: None
290
 
        """
291
 
 
292
 
    def _fix_case_of_inventory_path(self, path):
293
 
        """If our tree isn't case sensitive, return the canonical path"""
294
 
        if not self.case_sensitive:
295
 
            path = self.get_canonical_inventory_path(path)
296
 
        return path
297
 
 
298
250
    @needs_write_lock
299
251
    def put_file_bytes_non_atomic(self, file_id, bytes):
300
252
        """Update the content of a file in the tree.
359
311
 
360
312
        # validate user file paths and convert all paths to tree 
361
313
        # relative : it's cheaper to make a tree relative path an abspath
362
 
        # than to convert an abspath to tree relative, and it's cheaper to
363
 
        # perform the canonicalization in bulk.
364
 
        for filepath in osutils.canonical_relpaths(self.basedir, file_list):
365
 
            rf = _FastPath(filepath)
 
314
        # than to convert an abspath to tree relative.
 
315
        for filepath in file_list:
 
316
            rf = _FastPath(self.relpath(filepath))
366
317
            # validate user parameters. Our recursive code avoids adding new files
367
318
            # that need such validation 
368
319
            if self.is_control_filename(rf.raw_path):
423
374
            else:
424
375
                # without the parent ie, use the relatively slower inventory 
425
376
                # probing method
426
 
                versioned = inv.has_filename(
427
 
                        self._fix_case_of_inventory_path(directory.raw_path))
 
377
                versioned = inv.has_filename(directory.raw_path)
428
378
 
429
379
            if kind == 'directory':
430
380
                try:
463
413
                else:
464
414
                    # without the parent ie, use the relatively slower inventory 
465
415
                    # probing method
466
 
                    this_id = inv.path2id(
467
 
                            self._fix_case_of_inventory_path(directory.raw_path))
 
416
                    this_id = inv.path2id(directory.raw_path)
468
417
                    if this_id is None:
469
418
                        this_ie = None
470
419
                    else:
596
545
        added = []
597
546
    else:
598
547
        # slower but does not need parent_ie
599
 
        if inv.has_filename(tree._fix_case_of_inventory_path(path.raw_path)):
 
548
        if inv.has_filename(path.raw_path):
600
549
            return []
601
550
        # its really not there : add the parent
602
551
        # note that the dirname use leads to some extra str copying etc but as