~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: 2011-04-05 14:47:26 UTC
  • mfrom: (5752.2.11 2.4-windows-lfstat)
  • Revision ID: pqm@pqm.ubuntu.com-20110405144726-zi3lj2kwvjml4kx5
(jameinel) Add osutils.lstat/fstat so that even on Windows lstat(fname) ==
 fstat(open(fname).fileno()) (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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
 
    symbol_versioning,
 
35
    inventory,
36
36
    trace,
37
37
    tree,
38
38
    )
79
79
        # used on media which doesn't differentiate the case of names.
80
80
        self.case_sensitive = True
81
81
 
 
82
    def is_control_filename(self, filename):
 
83
        """True if filename is the name of a control file in this tree.
 
84
 
 
85
        :param filename: A filename within the tree. This is a relative path
 
86
        from the root of this tree.
 
87
 
 
88
        This is true IF and ONLY IF the filename is part of the meta data
 
89
        that bzr controls in this tree. I.E. a random .bzr directory placed
 
90
        on disk will not be a control file for this tree.
 
91
        """
 
92
        raise NotImplementedError(self.is_control_filename)
 
93
 
82
94
    @needs_tree_write_lock
83
95
    def add(self, files, ids=None, kinds=None):
84
96
        """Add paths to the set of versioned paths.
182
194
               **kwargs):
183
195
        # avoid circular imports
184
196
        from bzrlib import commit
185
 
        if revprops is None:
186
 
            revprops = {}
187
197
        possible_master_transports=[]
188
 
        if not 'branch-nick' in revprops:
189
 
            revprops['branch-nick'] = self.branch._get_nick(
 
198
        revprops = commit.Commit.update_revprops(
 
199
                revprops,
 
200
                self.branch,
 
201
                kwargs.pop('authors', None),
 
202
                kwargs.pop('author', None),
190
203
                kwargs.get('local', False),
191
204
                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
205
        # args for wt.commit start at message from the Commit.commit method,
219
206
        args = (message, ) + args
220
207
        for hook in MutableTree.hooks['start_commit']:
400
387
        This is designed more towards DWIM for humans than API clarity.
401
388
        For the specific behaviour see the help for cmd_add().
402
389
 
 
390
        :param file_list: List of zero or more paths.  *NB: these are 
 
391
            interpreted relative to the process cwd, not relative to the 
 
392
            tree.*  (Add and most other tree methods use tree-relative
 
393
            paths.)
403
394
        :param action: A reporter to be called with the inventory, parent_ie,
404
395
            path and kind of the path being added. It may return a file_id if
405
396
            a specific one should be used.
436
427
            for c in self.conflicts():
437
428
                conflicts_related.update(c.associated_filenames())
438
429
 
 
430
        # expand any symlinks in the directory part, while leaving the
 
431
        # filename alone
 
432
        # only expanding if symlinks are supported avoids windows path bugs
 
433
        if osutils.has_symlinks():
 
434
            file_list = map(osutils.normalizepath, file_list)
 
435
 
439
436
        # validate user file paths and convert all paths to tree
440
437
        # relative : it's cheaper to make a tree relative path an abspath
441
438
        # than to convert an abspath to tree relative, and it's cheaper to
561
558
                        this_ie = None
562
559
                    else:
563
560
                        this_ie = inv[this_id]
 
561
                        # Same as in _add_one below, if the inventory doesn't
 
562
                        # think this is a directory, update the inventory
 
563
                        if this_ie.kind != 'directory':
 
564
                            this_ie = inventory.make_entry('directory',
 
565
                                this_ie.name, this_ie.parent_id, this_id)
 
566
                            del inv[this_id]
 
567
                            inv.add(this_ie)
564
568
 
565
569
                for subf in sorted(os.listdir(abspath)):
566
570
                    # here we could use TreeDirectory rather than
647
651
        """Create the default hooks.
648
652
 
649
653
        """
650
 
        hooks.Hooks.__init__(self)
651
 
        self.create_hook(hooks.HookPoint('start_commit',
 
654
        hooks.Hooks.__init__(self, "bzrlib.mutabletree", "MutableTree.hooks")
 
655
        self.add_hook('start_commit',
652
656
            "Called before a commit is performed on a tree. The start commit "
653
657
            "hook is able to change the tree before the commit takes place. "
654
658
            "start_commit is called with the bzrlib.mutabletree.MutableTree "
655
 
            "that the commit is being performed on.", (1, 4), None))
656
 
        self.create_hook(hooks.HookPoint('post_commit',
 
659
            "that the commit is being performed on.", (1, 4))
 
660
        self.add_hook('post_commit',
657
661
            "Called after a commit is performed on a tree. The hook is "
658
662
            "called with a bzrlib.mutabletree.PostCommitHookParams object. "
659
663
            "The mutable tree the commit was performed on is available via "
660
 
            "the mutable_tree attribute of that object.", (2, 0), None))
 
664
            "the mutable_tree attribute of that object.", (2, 0))
661
665
 
662
666
 
663
667
# install the default hooks into the MutableTree class.
740
744
        file_id or None to generate a new file id
741
745
    :returns: None
742
746
    """
 
747
    # if the parent exists, but isn't a directory, we have to do the
 
748
    # kind change now -- really the inventory shouldn't pretend to know
 
749
    # the kind of wt files, but it does.
 
750
    if parent_ie.kind != 'directory':
 
751
        # nb: this relies on someone else checking that the path we're using
 
752
        # doesn't contain symlinks.
 
753
        new_parent_ie = inventory.make_entry('directory', parent_ie.name,
 
754
            parent_ie.parent_id, parent_ie.file_id)
 
755
        del inv[parent_ie.file_id]
 
756
        inv.add(new_parent_ie)
 
757
        parent_ie = new_parent_ie
743
758
    file_id = file_id_callback(inv, parent_ie, path, kind)
744
759
    entry = inv.make_entry(kind, path.base_path, parent_ie.file_id,
745
760
        file_id=file_id)