829
829
>>> br2.revision_history()
830
830
[u'REVISION-ID-1']
831
831
>>> br2.update_revisions(br1)
834
832
Added 0 revisions.
835
833
>>> br1.text_store.total_size() == br2.text_store.total_size()
836
from bzrlib.fetch import greedy_fetch
838
837
pb = ProgressBar()
839
838
pb.update('comparing histories')
840
839
revision_ids = self.missing_revisions(other, stop_revision)
841
count = self.install_revisions(other, revision_ids, pb=pb)
840
if len(revision_ids) > 0:
841
count = greedy_fetch(self, other, revision_ids[-1], pb)[0]
842
844
self.append_revision(*revision_ids)
843
845
print "Added %d revisions." % count
856
858
needed_texts = set()
858
for rev_id in revision_ids:
860
pb.update('fetching revision', i, len(revision_ids))
861
rev = other.get_revision(rev_id)
861
for i, rev_id in enumerate(revision_ids):
862
pb.update('fetching revision', i+1, len(revision_ids))
864
rev = other.get_revision(rev_id)
865
except bzrlib.errors.NoSuchRevision:
862
868
revisions.append(rev)
863
869
inv = other.get_inventory(str(rev.inventory_id))
864
870
for key, entry in inv.iter_entries():
872
count = self.text_store.copy_multi(other.text_store, needed_texts)
878
count, cp_fail = self.text_store.copy_multi(other.text_store,
873
880
print "Added %d texts." % count
874
881
inventory_ids = [ f.inventory_id for f in revisions ]
875
count = self.inventory_store.copy_multi(other.inventory_store,
882
count, cp_fail = self.inventory_store.copy_multi(other.inventory_store,
877
884
print "Added %d inventories." % count
878
885
revision_ids = [ f.revision_id for f in revisions]
879
count = self.revision_store.copy_multi(other.revision_store,
886
count, cp_fail = self.revision_store.copy_multi(other.revision_store,
889
assert len(cp_fail) == 0
890
return count, failures
883
892
def commit(self, *args, **kw):
884
893
from bzrlib.commit import commit
888
897
def lookup_revision(self, revision):
889
898
"""Return the revision identifier for a given revision information."""
890
revno, info = self.get_revision_info(revision)
899
revno, info = self._get_revision_info(revision)
893
902
def get_revision_info(self, revision):
898
907
revision can also be a string, in which case it is parsed for something like
899
908
'date:' or 'revid:' etc.
910
revno, rev_id = self._get_revision_info(revision)
912
raise bzrlib.errors.NoSuchRevision(self, revision)
915
def get_rev_id(self, revno, history=None):
916
"""Find the revision id of the specified revno."""
920
history = self.revision_history()
921
elif revno <= 0 or revno > len(history):
922
raise bzrlib.errors.NoSuchRevision(self, revno)
923
return history[revno - 1]
925
def _get_revision_info(self, revision):
926
"""Return (revno, revision id) for revision specifier.
928
revision can be an integer, in which case it is assumed to be revno
929
(though this will translate negative values into positive ones)
930
revision can also be a string, in which case it is parsed for something
931
like 'date:' or 'revid:' etc.
933
A revid is always returned. If it is None, the specifier referred to
934
the null revision. If the revid does not occur in the revision
935
history, revno will be None.
901
938
if revision is None:
908
945
revs = self.revision_history()
909
946
if isinstance(revision, int):
912
# Mabye we should do this first, but we don't need it if revision == 0
914
948
revno = len(revs) + revision + 1
951
rev_id = self.get_rev_id(revno, revs)
917
952
elif isinstance(revision, basestring):
918
953
for prefix, func in Branch.REVISION_NAMESPACES.iteritems():
919
954
if revision.startswith(prefix):
920
revno = func(self, revs, revision)
955
result = func(self, revs, revision)
957
revno, rev_id = result
960
rev_id = self.get_rev_id(revno, revs)
923
raise BzrError('No namespace registered for string: %r' % revision)
963
raise BzrError('No namespace registered for string: %r' %
966
raise TypeError('Unhandled revision type %s' % revision)
925
if revno is None or revno <= 0 or revno > len(revs):
926
raise BzrError("no such revision %s" % revision)
927
return revno, revs[revno-1]
970
raise bzrlib.errors.NoSuchRevision(self, revision)
929
973
def _namespace_revno(self, revs, revision):
930
974
"""Lookup a revision by revision number"""
931
975
assert revision.startswith('revno:')
933
return int(revision[6:])
977
return (int(revision[6:]),)
934
978
except ValueError:
936
980
REVISION_NAMESPACES['revno:'] = _namespace_revno
938
982
def _namespace_revid(self, revs, revision):
939
983
assert revision.startswith('revid:')
984
rev_id = revision[len('revid:'):]
941
return revs.index(revision[6:]) + 1
986
return revs.index(rev_id) + 1, rev_id
942
987
except ValueError:
944
989
REVISION_NAMESPACES['revid:'] = _namespace_revid
946
991
def _namespace_last(self, revs, revision):
949
994
offset = int(revision[5:])
950
995
except ValueError:
954
999
raise BzrError('You must supply a positive value for --revision last:XXX')
955
return len(revs) - offset + 1
1000
return (len(revs) - offset + 1,)
956
1001
REVISION_NAMESPACES['last:'] = _namespace_last
958
1003
def _namespace_tag(self, revs, revision):
1033
1078
# TODO: Handle timezone.
1034
1079
dt = datetime.datetime.fromtimestamp(r.timestamp)
1035
1080
if first >= dt and (last is None or dt >= last):
1038
1083
for i in range(len(revs)):
1039
1084
r = self.get_revision(revs[i])
1040
1085
# TODO: Handle timezone.
1041
1086
dt = datetime.datetime.fromtimestamp(r.timestamp)
1042
1087
if first <= dt and (last is None or dt <= last):
1044
1089
REVISION_NAMESPACES['date:'] = _namespace_date
1046
1091
def revision_tree(self, revision_id):