~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Martin Pool
  • Date: 2009-07-24 03:15:56 UTC
  • mfrom: (4565 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4566.
  • Revision ID: mbp@sourcefrog.net-20090724031556-5zyef6f1ixtn6r3z
merge news

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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
58
58
    errors,
59
59
    generate_ids,
60
60
    globbing,
 
61
    graph as _mod_graph,
61
62
    hashcache,
62
63
    ignores,
63
64
    inventory,
477
478
        incorrectly attributed to CURRENT_REVISION (but after committing, the
478
479
        attribution will be correct).
479
480
        """
480
 
        basis = self.basis_tree()
481
 
        basis.lock_read()
482
 
        try:
483
 
            changes = self.iter_changes(basis, True, [self.id2path(file_id)],
484
 
                require_versioned=True).next()
485
 
            changed_content, kind = changes[2], changes[6]
486
 
            if not changed_content:
487
 
                return basis.annotate_iter(file_id)
488
 
            if kind[1] is None:
489
 
                return None
490
 
            import annotate
491
 
            if kind[0] != 'file':
492
 
                old_lines = []
493
 
            else:
494
 
                old_lines = list(basis.annotate_iter(file_id))
495
 
            old = [old_lines]
496
 
            for tree in self.branch.repository.revision_trees(
497
 
                self.get_parent_ids()[1:]):
498
 
                if file_id not in tree:
499
 
                    continue
500
 
                old.append(list(tree.annotate_iter(file_id)))
501
 
            return annotate.reannotate(old, self.get_file(file_id).readlines(),
502
 
                                       default_revision)
503
 
        finally:
504
 
            basis.unlock()
 
481
        maybe_file_parent_keys = []
 
482
        for parent_id in self.get_parent_ids():
 
483
            try:
 
484
                parent_tree = self.revision_tree(parent_id)
 
485
            except errors.NoSuchRevisionInTree:
 
486
                parent_tree = self.branch.repository.revision_tree(parent_id)
 
487
            parent_tree.lock_read()
 
488
            try:
 
489
                if file_id not in parent_tree:
 
490
                    continue
 
491
                ie = parent_tree.inventory[file_id]
 
492
                if ie.kind != 'file':
 
493
                    # Note: this is slightly unnecessary, because symlinks and
 
494
                    # directories have a "text" which is the empty text, and we
 
495
                    # know that won't mess up annotations. But it seems cleaner
 
496
                    continue
 
497
                parent_text_key = (file_id, ie.revision)
 
498
                if parent_text_key not in maybe_file_parent_keys:
 
499
                    maybe_file_parent_keys.append(parent_text_key)
 
500
            finally:
 
501
                parent_tree.unlock()
 
502
        graph = _mod_graph.Graph(self.branch.repository.texts)
 
503
        heads = graph.heads(maybe_file_parent_keys)
 
504
        file_parent_keys = []
 
505
        for key in maybe_file_parent_keys:
 
506
            if key in heads:
 
507
                file_parent_keys.append(key)
 
508
 
 
509
        # Now we have the parents of this content
 
510
        annotator = self.branch.repository.texts.get_annotator()
 
511
        text = self.get_file(file_id).read()
 
512
        this_key =(file_id, default_revision)
 
513
        annotator.add_special_text(this_key, file_parent_keys, text)
 
514
        annotations = [(key[-1], line)
 
515
                       for key, line in annotator.annotate_flat(this_key)]
 
516
        return annotations
505
517
 
506
518
    def _get_ancestors(self, default_revision):
507
519
        ancestors = set([default_revision])
1464
1476
        from_tail = splitpath(from_rel)[-1]
1465
1477
        from_id = inv.path2id(from_rel)
1466
1478
        if from_id is None:
1467
 
            raise errors.BzrRenameFailedError(from_rel,to_rel,
1468
 
                errors.NotVersionedError(path=str(from_rel)))
1469
 
        from_entry = inv[from_id]
 
1479
            # if file is missing in the inventory maybe it's in the basis_tree
 
1480
            basis_tree = self.branch.basis_tree()
 
1481
            from_id = basis_tree.path2id(from_rel)
 
1482
            if from_id is None:
 
1483
                raise errors.BzrRenameFailedError(from_rel,to_rel,
 
1484
                    errors.NotVersionedError(path=str(from_rel)))
 
1485
            # put entry back in the inventory so we can rename it
 
1486
            from_entry = basis_tree.inventory[from_id].copy()
 
1487
            inv.add(from_entry)
 
1488
        else:
 
1489
            from_entry = inv[from_id]
1470
1490
        from_parent_id = from_entry.parent_id
1471
1491
        to_dir, to_tail = os.path.split(to_rel)
1472
1492
        to_dir_id = inv.path2id(to_dir)