import bzrlib.errors
import bzrlib.ui
import bzrlib.urlutils
+import bzrlib.branch
import sys
import os
self.last_mark = mark
def get_tip(self, branch):
- return self.tips.get(branch, None)
+ try:
+ return str(self.tips[branch])
+ except KeyError:
+ return None
def set_tip(self, branch, tip):
self.tips[branch] = tip
ref = '%s/heads/%s' % (prefix, name)
tip = marks.get_tip(name)
- branch = bzrlib.branch.Branch.open(branches[name])
+ branch = get_remote_branch(name)
repo = branch.repository
branch.lock_read()
revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward')
- tip_revno = branch.revision_id_to_revno(tip)
- last_revno, _ = branch.last_revision_info()
- total = last_revno - tip_revno
+ try:
+ tip_revno = branch.revision_id_to_revno(tip)
+ last_revno, _ = branch.last_revision_info()
+ total = last_revno - tip_revno
+ except bzrlib.errors.NoSuchRevision:
+ tip_revno = 0
+ total = 0
for revid, _, seq, _ in revs:
progress = (revno - tip_revno)
if (progress % 100 == 0):
- print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total)
+ if total:
+ print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total)
+ else:
+ print "progress revision %d '%s' (%d)" % (revno, name, progress)
branch.unlock()
if ref.startswith('refs/heads/'):
name = ref[len('refs/heads/'):]
- branch = bzrlib.branch.Branch.open(branches[name])
+ branch = get_remote_branch(name)
else:
die('unknown ref')
mark = int(mark_ref[1:])
f = { 'mode' : m, 'mark' : mark }
elif parser.check('D'):
- t, path = line.split(' ')
+ t, path = line.split(' ', 1)
f = { 'deleted' : True }
else:
die('Unknown file command: %s' % line)
die('unhandled export command: %s' % line)
for ref, revid in parsed_refs.iteritems():
- name = ref[len('refs/heads/'):]
- branch = bzrlib.branch.Branch.open(branches[name])
- branch.generate_revision_history(revid, marks.get_tip(name))
+ if ref.startswith('refs/heads/'):
+ name = ref[len('refs/heads/'):]
+ branch = get_remote_branch(name)
+ branch.generate_revision_history(revid, marks.get_tip(name))
- if name in peers:
- peer = bzrlib.branch.Branch.open(peers[name])
- try:
- peer.bzrdir.push_branch(branch, revision_id=revid)
- except bzrlib.errors.DivergedBranches:
- print "error %s non-fast forward" % ref
- continue
+ if name in peers:
+ peer = bzrlib.branch.Branch.open(peers[name])
+ try:
+ peer.bzrdir.push_branch(branch, revision_id=revid)
+ except bzrlib.errors.DivergedBranches:
+ print "error %s non-fast forward" % ref
+ continue
- try:
- wt = branch.bzrdir.open_workingtree()
- wt.update()
- except bzrlib.errors.NoWorkingTree:
- pass
+ try:
+ wt = branch.bzrdir.open_workingtree()
+ wt.update()
+ except bzrlib.errors.NoWorkingTree:
+ pass
+ elif ref.startswith('refs/tags/'):
+ # TODO: implement tag push
+ print "error %s pushing tags not supported" % ref
+ continue
+ else:
+ # transport-helper/fast-export bugs
+ continue
print "ok %s" % ref
master_branch = name
print "? refs/heads/%s" % name
- branch = bzrlib.branch.Branch.open(branches[master_branch])
+ branch = get_remote_branch(master_branch)
branch.lock_read()
for tag, revid in branch.tags.get_tag_dict().items():
try:
print "@refs/heads/%s HEAD" % master_branch
print
-def get_remote_branch(origin, remote_branch, name):
- global dirname, peers
+def clone(path, remote_branch):
+ try:
+ bdir = bzrlib.bzrdir.BzrDir.create(path)
+ except bzrlib.errors.AlreadyControlDirError:
+ bdir = bzrlib.bzrdir.BzrDir.open(path)
+ repo = bdir.find_repository()
+ repo.fetch(remote_branch.repository)
+ return remote_branch.sprout(bdir, repository=repo)
+
+def get_remote_branch(name):
+ global dirname, branches
+
+ remote_branch = bzrlib.branch.Branch.open(branches[name])
+ if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport):
+ return remote_branch
branch_path = os.path.join(dirname, 'clone', name)
- if os.path.exists(branch_path):
+
+ try:
+ branch = bzrlib.branch.Branch.open(branch_path)
+ except bzrlib.errors.NotBranchError:
+ # clone
+ branch = clone(branch_path, remote_branch)
+ else:
# pull
- d = bzrlib.bzrdir.BzrDir.open(branch_path)
- branch = d.open_branch()
try:
- branch.pull(remote_branch, [], None, False)
+ branch.pull(remote_branch, overwrite=True)
except bzrlib.errors.DivergedBranches:
# use remote branch for now
return remote_branch
- else:
- # clone
- d = origin.sprout(branch_path, None,
- hardlink=True, create_tree_if_local=False,
- force_new_repo=False,
- source_branch=remote_branch)
- branch = d.open_branch()
return branch
-def find_branches(repo, wanted):
- transport = repo.user_transport
+def find_branches(repo):
+ transport = repo.bzrdir.root_transport
for fn in transport.iter_files_recursive():
if not fn.endswith('.bzr/branch-format'):
name = name if name != '' else 'master'
name = name.replace('/', '+')
- if wanted and not name in wanted:
- continue
-
try:
cur = transport.clone(subdir)
branch = bzrlib.branch.Branch.open_from_transport(cur)
except bzrlib.errors.NotBranchError:
continue
else:
- yield name, branch
+ yield name, branch.base
def get_repo(url, alias):
global dirname, peer, branches
clone_path = os.path.join(dirname, 'clone')
if not os.path.exists(clone_path):
os.mkdir(clone_path)
-
- try:
- repo = origin.open_repository()
- except bzrlib.errors.NoRepositoryPresent:
- # branch
-
- name = 'master'
- remote_branch = origin.open_branch()
-
- if not is_local:
- peers[name] = remote_branch.base
- branch = get_remote_branch(origin, remote_branch, name)
else:
- branch = remote_branch
-
- branches[name] = branch.base
-
- return branch.repository
+ # check and remove old organization
+ try:
+ bdir = bzrlib.bzrdir.BzrDir.open(clone_path)
+ bdir.destroy_repository()
+ except bzrlib.errors.NotBranchError:
+ pass
+ except bzrlib.errors.NoRepositoryPresent:
+ pass
+
+ wanted = get_config('remote-bzr.branches').rstrip().split(', ')
+ # stupid python
+ wanted = [e for e in wanted if e]
+
+ if not wanted:
+ try:
+ repo = origin.open_repository()
+ if not repo.user_transport.listable():
+ # this repository is not usable for us
+ raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir)
+ except bzrlib.errors.NoRepositoryPresent:
+ wanted = ['master']
+
+ if wanted:
+ def list_wanted(url, wanted):
+ for name in wanted:
+ subdir = name if name != 'master' else ''
+ yield name, bzrlib.urlutils.join(url, subdir)
+
+ branch_list = list_wanted(url, wanted)
else:
- # repository
+ branch_list = find_branches(repo)
- wanted = get_config('remote-bzr.branches').rstrip().split(', ')
- # stupid python
- wanted = [e for e in wanted if e]
-
- for name, remote_branch in find_branches(repo, wanted):
-
- if not is_local:
- peers[name] = remote_branch.base
- branch = get_remote_branch(origin, remote_branch, name)
- else:
- branch = remote_branch
-
- branches[name] = branch.base
+ for name, url in branch_list:
+ if not is_local:
+ peers[name] = url
+ branches[name] = url
- return repo
+ return origin
def fix_path(alias, orig_url):
url = urlparse.urlparse(orig_url, 'file')
if not os.path.exists(dirname):
os.makedirs(dirname)
- bzrlib.ui.ui_factory.be_quiet(True)
+ if hasattr(bzrlib.ui.ui_factory, 'be_quiet'):
+ bzrlib.ui.ui_factory.be_quiet(True)
repo = get_repo(url, alias)