~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

[merge] from aaron

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
                           DivergedBranches, LockError, UnlistableStore,
36
36
                           UnlistableBranch, NoSuchFile)
37
37
from bzrlib.textui import show_status
38
 
from bzrlib.revision import Revision
 
38
from bzrlib.revision import Revision, is_ancestor, get_intervening_revisions
 
39
 
39
40
from bzrlib.delta import compare_trees
40
41
from bzrlib.tree import EmptyTree, RevisionTree
41
42
from bzrlib.inventory import Inventory
853
854
        finally:
854
855
            self.unlock()
855
856
 
856
 
    def common_ancestor(self, other, self_revno=None, other_revno=None):
857
 
        """
858
 
        >>> from bzrlib.commit import commit
859
 
        >>> sb = ScratchBranch(files=['foo', 'foo~'])
860
 
        >>> sb.common_ancestor(sb) == (None, None)
861
 
        True
862
 
        >>> commit(sb, "Committing first revision", verbose=False)
863
 
        >>> sb.common_ancestor(sb)[0]
864
 
        1
865
 
        >>> clone = sb.clone()
866
 
        >>> commit(sb, "Committing second revision", verbose=False)
867
 
        >>> sb.common_ancestor(sb)[0]
868
 
        2
869
 
        >>> sb.common_ancestor(clone)[0]
870
 
        1
871
 
        >>> commit(clone, "Committing divergent second revision", 
872
 
        ...               verbose=False)
873
 
        >>> sb.common_ancestor(clone)[0]
874
 
        1
875
 
        >>> sb.common_ancestor(clone) == clone.common_ancestor(sb)
876
 
        True
877
 
        >>> sb.common_ancestor(sb) != clone.common_ancestor(clone)
878
 
        True
879
 
        >>> clone2 = sb.clone()
880
 
        >>> sb.common_ancestor(clone2)[0]
881
 
        2
882
 
        >>> sb.common_ancestor(clone2, self_revno=1)[0]
883
 
        1
884
 
        >>> sb.common_ancestor(clone2, other_revno=1)[0]
885
 
        1
886
 
        """
887
 
        my_history = self.revision_history()
888
 
        other_history = other.revision_history()
889
 
        if self_revno is None:
890
 
            self_revno = len(my_history)
891
 
        if other_revno is None:
892
 
            other_revno = len(other_history)
893
 
        indices = range(min((self_revno, other_revno)))
894
 
        indices.reverse()
895
 
        for r in indices:
896
 
            if my_history[r] == other_history[r]:
897
 
                return r+1, my_history[r]
898
 
        return None, None
899
 
 
900
 
 
901
857
    def revno(self):
902
858
        """Return current revision number for this branch.
903
859
 
945
901
        Traceback (most recent call last):
946
902
        DivergedBranches: These branches have diverged.
947
903
        """
948
 
        # FIXME: If the branches have diverged, but the latest
949
 
        # revision in this branch is completely merged into the other,
950
 
        # then we should still be able to pull.
951
904
        self_history = self.revision_history()
952
905
        self_len = len(self_history)
953
906
        other_history = other.revision_history()
967
920
 
968
921
    def update_revisions(self, other, stop_revision=None):
969
922
        """Pull in new perfect-fit revisions."""
 
923
        # FIXME: If the branches have diverged, but the latest
 
924
        # revision in this branch is completely merged into the other,
 
925
        # then we should still be able to pull.
970
926
        from bzrlib.fetch import greedy_fetch
971
 
        from bzrlib.revision import get_intervening_revisions
972
927
        if stop_revision is None:
973
928
            stop_revision = other.last_revision()
 
929
        ### Should this be checking is_ancestor instead of revision_history?
974
930
        if (stop_revision is not None and 
975
931
            stop_revision in self.revision_history()):
976
932
            return
977
933
        greedy_fetch(to_branch=self, from_branch=other,
978
934
                     revision=stop_revision)
979
 
        pullable_revs = self.missing_revisions(
980
 
            other, other.revision_id_to_revno(stop_revision))
981
 
        if pullable_revs:
982
 
            greedy_fetch(to_branch=self,
983
 
                         from_branch=other,
984
 
                         revision=pullable_revs[-1])
 
935
        pullable_revs = self.pullable_revisions(other, stop_revision)
 
936
        if len(pullable_revs) > 0:
985
937
            self.append_revision(*pullable_revs)
986
 
    
 
938
 
 
939
    def pullable_revisions(self, other, stop_revision):
 
940
        other_revno = other.revision_id_to_revno(stop_revision)
 
941
        try:
 
942
            return self.missing_revisions(other, other_revno)
 
943
        except DivergedBranches, e:
 
944
            try:
 
945
                pullable_revs = get_intervening_revisions(self.last_revision(),
 
946
                                                          stop_revision, self)
 
947
                assert self.last_revision() not in pullable_revs
 
948
                return pullable_revs
 
949
            except bzrlib.errors.NotAncestor:
 
950
                if is_ancestor(self.last_revision(), stop_revision, self):
 
951
                    return []
 
952
                else:
 
953
                    raise e
 
954
        
987
955
 
988
956
    def commit(self, *args, **kw):
989
957
        from bzrlib.commit import Commit