23
23
from bzrlib.osutils import isdir, quotefn, compact_date, rand_bytes, \
25
25
sha_file, appendpath, file_kind
26
27
from bzrlib.errors import BzrError, InvalidRevisionNumber, InvalidRevisionId
27
28
import bzrlib.errors
28
29
from bzrlib.textui import show_status
30
31
from bzrlib.xml import unpack_xml
31
32
from bzrlib.delta import compare_trees
32
33
from bzrlib.tree import EmptyTree, RevisionTree
33
from bzrlib.progress import ProgressBar
36
38
BZR_BRANCH_FORMAT = "Bazaar-NG branch, format 0.0.4\n"
37
39
## TODO: Maybe include checks for common corruption of newlines, etc?
125
128
head, tail = os.path.split(f)
127
130
# reached the root, whatever that may be
128
raise BzrError('%r is not in a branch' % orig_f)
131
raise bzrlib.errors.NotBranchError('%s is not in a branch' % orig_f)
136
# XXX: move into bzrlib.errors; subclass BzrError
131
137
class DivergedBranches(Exception):
132
138
def __init__(self, branch1, branch2):
133
139
self.branch1 = branch1
256
258
self._lock = None
257
259
self._lock_mode = self._lock_count = None
260
261
def abspath(self, name):
261
262
"""Return absolute filename for something in the branch"""
262
263
return os.path.join(self.base, name)
265
265
def relpath(self, path):
266
266
"""Return path relative to this branch of something inside it.
268
268
Raises an error if path is not in this branch."""
269
269
return _relpath(self.base, path)
272
271
def controlfilename(self, file_or_path):
273
272
"""Return location relative to branch."""
274
273
if isinstance(file_or_path, basestring):
807
803
if stop_revision is None:
808
804
stop_revision = other_len
809
805
elif stop_revision > other_len:
810
raise NoSuchRevision(self, stop_revision)
806
raise bzrlib.errors.NoSuchRevision(self, stop_revision)
812
808
return other_history[self_len:stop_revision]
815
811
def update_revisions(self, other, stop_revision=None):
816
812
"""Pull in all new revisions from other branch.
818
>>> from bzrlib.commit import commit
819
>>> bzrlib.trace.silent = True
820
>>> br1 = ScratchBranch(files=['foo', 'bar'])
823
>>> commit(br1, "lala!", rev_id="REVISION-ID-1", verbose=False)
824
>>> br2 = ScratchBranch()
825
>>> br2.update_revisions(br1)
829
>>> br2.revision_history()
831
>>> br2.update_revisions(br1)
833
>>> br1.text_store.total_size() == br2.text_store.total_size()
836
814
from bzrlib.fetch import greedy_fetch
816
pb = bzrlib.ui.ui_factory.progress_bar()
838
817
pb.update('comparing histories')
839
819
revision_ids = self.missing_revisions(other, stop_revision)
840
821
if len(revision_ids) > 0:
841
822
count = greedy_fetch(self, other, revision_ids[-1], pb)[0]
844
825
self.append_revision(*revision_ids)
845
print "Added %d revisions." % count
847
def install_revisions(self, other, revision_ids, pb=None):
826
## note("Added %d revisions." % count)
829
def install_revisions(self, other, revision_ids, pb):
850
830
if hasattr(other.revision_store, "prefetch"):
851
831
other.revision_store.prefetch(revision_ids)
852
832
if hasattr(other.inventory_store, "prefetch"):
853
833
inventory_ids = [other.get_revision(r).inventory_id
854
834
for r in revision_ids]
855
835
other.inventory_store.prefetch(inventory_ids)
838
pb = bzrlib.ui.ui_factory.progress_bar()
858
841
needed_texts = set()
861
845
for i, rev_id in enumerate(revision_ids):
862
846
pb.update('fetching revision', i+1, len(revision_ids))
878
863
count, cp_fail = self.text_store.copy_multi(other.text_store,
880
print "Added %d texts." % count
865
#print "Added %d texts." % count
881
866
inventory_ids = [ f.inventory_id for f in revisions ]
882
867
count, cp_fail = self.inventory_store.copy_multi(other.inventory_store,
884
print "Added %d inventories." % count
869
#print "Added %d inventories." % count
885
870
revision_ids = [ f.revision_id for f in revisions]
886
872
count, cp_fail = self.revision_store.copy_multi(other.revision_store,
888
874
permit_failure=True)
889
875
assert len(cp_fail) == 0
890
876
return count, failures
892
879
def commit(self, *args, **kw):
893
880
from bzrlib.commit import commit
894
881
commit(self, *args, **kw)
899
886
revno, info = self._get_revision_info(revision)
890
def revision_id_to_revno(self, revision_id):
891
"""Given a revision id, return its revno"""
892
history = self.revision_history()
894
return history.index(revision_id) + 1
896
raise bzrlib.errors.NoSuchRevision(self, revision_id)
902
899
def get_revision_info(self, revision):
903
900
"""Return (revno, revision id) for revision identifier.
1444
1441
"""Return a new tree-root file id."""
1445
1442
return gen_file_id('TREE_ROOT')
1445
def pull_loc(branch):
1446
# TODO: Should perhaps just make attribute be 'base' in
1447
# RemoteBranch and Branch?
1448
if hasattr(branch, "baseurl"):
1449
return branch.baseurl
1454
def copy_branch(branch_from, to_location, revision=None):
1455
"""Copy branch_from into the existing directory to_location.
1457
If revision is not None, the head of the new branch will be revision.
1459
from bzrlib.merge import merge
1460
from bzrlib.branch import Branch
1461
br_to = Branch(to_location, init=True)
1462
br_to.set_root_id(branch_from.get_root_id())
1463
if revision is None:
1464
revno = branch_from.revno()
1466
revno, rev_id = branch_from.get_revision_info(revision)
1467
br_to.update_revisions(branch_from, stop_revision=revno)
1468
merge((to_location, -1), (to_location, 0), this_dir=to_location,
1469
check_clean=False, ignore_zero=True)
1470
from_location = pull_loc(branch_from)
1471
br_to.controlfile("x-pull", "wb").write(from_location + "\n")