~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/mutabletree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 06:45:57 UTC
  • mfrom: (5247.2.41 more-ignored-exceptions)
  • Revision ID: pqm@pqm.ubuntu.com-20100901064557-qsxmjmp195ozbluf
(vila) Catch EPIPE when shutting down test servers. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
32
32
    hooks,
33
33
    osutils,
34
34
    revisiontree,
 
35
    inventory,
35
36
    symbol_versioning,
36
37
    trace,
37
38
    tree,
182
183
               **kwargs):
183
184
        # avoid circular imports
184
185
        from bzrlib import commit
185
 
        if revprops is None:
186
 
            revprops = {}
187
186
        possible_master_transports=[]
188
 
        if not 'branch-nick' in revprops:
189
 
            revprops['branch-nick'] = self.branch._get_nick(
 
187
        revprops = commit.Commit.update_revprops(
 
188
                revprops,
 
189
                self.branch,
 
190
                kwargs.pop('authors', None),
 
191
                kwargs.pop('author', None),
190
192
                kwargs.get('local', False),
191
193
                possible_master_transports)
192
 
        authors = kwargs.pop('authors', None)
193
 
        author = kwargs.pop('author', None)
194
 
        if authors is not None:
195
 
            if author is not None:
196
 
                raise AssertionError('Specifying both author and authors '
197
 
                        'is not allowed. Specify just authors instead')
198
 
            if 'author' in revprops or 'authors' in revprops:
199
 
                # XXX: maybe we should just accept one of them?
200
 
                raise AssertionError('author property given twice')
201
 
            if authors:
202
 
                for individual in authors:
203
 
                    if '\n' in individual:
204
 
                        raise AssertionError('\\n is not a valid character '
205
 
                                'in an author identity')
206
 
                revprops['authors'] = '\n'.join(authors)
207
 
        if author is not None:
208
 
            symbol_versioning.warn('The parameter author was deprecated'
209
 
                   ' in version 1.13. Use authors instead',
210
 
                   DeprecationWarning)
211
 
            if 'author' in revprops or 'authors' in revprops:
212
 
                # XXX: maybe we should just accept one of them?
213
 
                raise AssertionError('author property given twice')
214
 
            if '\n' in author:
215
 
                raise AssertionError('\\n is not a valid character '
216
 
                        'in an author identity')
217
 
            revprops['authors'] = author
218
194
        # args for wt.commit start at message from the Commit.commit method,
219
195
        args = (message, ) + args
220
196
        for hook in MutableTree.hooks['start_commit']:
258
234
            return False
259
235
 
260
236
    @needs_read_lock
 
237
    def check_changed_or_out_of_date(self, strict, opt_name,
 
238
                                     more_error, more_warning):
 
239
        """Check the tree for uncommitted changes and branch synchronization.
 
240
 
 
241
        If strict is None and not set in the config files, a warning is issued.
 
242
        If strict is True, an error is raised.
 
243
        If strict is False, no checks are done and no warning is issued.
 
244
 
 
245
        :param strict: True, False or None, searched in branch config if None.
 
246
 
 
247
        :param opt_name: strict option name to search in config file.
 
248
 
 
249
        :param more_error: Details about how to avoid the check.
 
250
 
 
251
        :param more_warning: Details about what is happening.
 
252
        """
 
253
        if strict is None:
 
254
            strict = self.branch.get_config().get_user_option_as_bool(opt_name)
 
255
        if strict is not False:
 
256
            err_class = None
 
257
            if (self.has_changes()):
 
258
                err_class = errors.UncommittedChanges
 
259
            elif self.last_revision() != self.branch.last_revision():
 
260
                # The tree has lost sync with its branch, there is little
 
261
                # chance that the user is aware of it but he can still force
 
262
                # the action with --no-strict
 
263
                err_class = errors.OutOfDateTree
 
264
            if err_class is not None:
 
265
                if strict is None:
 
266
                    err = err_class(self, more=more_warning)
 
267
                    # We don't want to interrupt the user if he expressed no
 
268
                    # preference about strict.
 
269
                    trace.warning('%s', err._format())
 
270
                else:
 
271
                    err = err_class(self, more=more_error)
 
272
                    raise err
 
273
 
 
274
    @needs_read_lock
261
275
    def last_revision(self):
262
276
        """Return the revision id of the last commit performed in this tree.
263
277
 
362
376
        This is designed more towards DWIM for humans than API clarity.
363
377
        For the specific behaviour see the help for cmd_add().
364
378
 
 
379
        :param file_list: List of zero or more paths.  *NB: these are 
 
380
            interpreted relative to the process cwd, not relative to the 
 
381
            tree.*  (Add and most other tree methods use tree-relative
 
382
            paths.)
365
383
        :param action: A reporter to be called with the inventory, parent_ie,
366
384
            path and kind of the path being added. It may return a file_id if
367
385
            a specific one should be used.
380
398
 
381
399
        if not file_list:
382
400
            # no paths supplied: add the entire tree.
 
401
            # FIXME: this assumes we are running in a working tree subdir :-/
 
402
            # -- vila 20100208
383
403
            file_list = [u'.']
384
404
        # mutter("smart add of %r")
385
405
        inv = self.inventory
387
407
        ignored = {}
388
408
        dirs_to_add = []
389
409
        user_dirs = set()
 
410
        conflicts_related = set()
 
411
        # Not all mutable trees can have conflicts
 
412
        if getattr(self, 'conflicts', None) is not None:
 
413
            # Collect all related files without checking whether they exist or
 
414
            # are versioned. It's cheaper to do that once for all conflicts
 
415
            # than trying to find the relevant conflict for each added file.
 
416
            for c in self.conflicts():
 
417
                conflicts_related.update(c.associated_filenames())
 
418
 
 
419
        # expand any symlinks in the directory part, while leaving the
 
420
        # filename alone
 
421
        file_list = map(osutils.normalizepath, file_list)
390
422
 
391
423
        # validate user file paths and convert all paths to tree
392
424
        # relative : it's cheaper to make a tree relative path an abspath
453
485
            if illegalpath_re.search(directory.raw_path):
454
486
                trace.warning("skipping %r (contains \\n or \\r)" % abspath)
455
487
                continue
 
488
            if directory.raw_path in conflicts_related:
 
489
                # If the file looks like one generated for a conflict, don't
 
490
                # add it.
 
491
                trace.warning(
 
492
                    'skipping %s (generated to help resolve conflicts)',
 
493
                    abspath)
 
494
                continue
456
495
 
457
496
            if parent_ie is not None:
458
497
                versioned = directory.base_path in parent_ie.children
685
724
        file_id or None to generate a new file id
686
725
    :returns: None
687
726
    """
 
727
    # if the parent exists, but isn't a directory, we have to do the
 
728
    # kind change now -- really the inventory shouldn't pretend to know
 
729
    # the kind of wt files, but it does.
 
730
    if parent_ie.kind != 'directory':
 
731
        # nb: this relies on someone else checking that the path we're using
 
732
        # doesn't contain symlinks.
 
733
        new_parent_ie = inventory.make_entry('directory', parent_ie.name,
 
734
            parent_ie.parent_id, parent_ie.file_id)
 
735
        del inv[parent_ie.file_id]
 
736
        inv.add(new_parent_ie)
 
737
        parent_ie = new_parent_ie
688
738
    file_id = file_id_callback(inv, parent_ie, path, kind)
689
739
    entry = inv.make_entry(kind, path.base_path, parent_ie.file_id,
690
740
        file_id=file_id)