From 99a4fdb950b214de3a0ad0ac255f6a2491f975d4 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:19 -0500 Subject: [PATCH 1/8] remote-bzr: recover from failed clones Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 10300c63d1..8a4df51fad 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -769,22 +769,24 @@ def get_remote_branch(origin, remote_branch, name): global dirname, peers branch_path = os.path.join(dirname, 'clone', name) - if os.path.exists(branch_path): - # pull + + try: d = bzrlib.bzrdir.BzrDir.open(branch_path) branch = d.open_branch() - try: - branch.pull(remote_branch, [], None, False) - except bzrlib.errors.DivergedBranches: - # use remote branch for now - return remote_branch - else: + except bzrlib.errors.NotBranchError: # 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() + else: + # pull + try: + branch.pull(remote_branch, [], None, False) + except bzrlib.errors.DivergedBranches: + # use remote branch for now + return remote_branch return branch From ad44a7209534a6298c85a2a0fe107c56de0c8849 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:20 -0500 Subject: [PATCH 2/8] remote-bzr: fix for files with spaces Set the maximum number of splits to make when dividing the diff stat lines based on space characters. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 8a4df51fad..35664c6523 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -621,7 +621,7 @@ def parse_commit(parser): 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) From 1bf09d4fbf402e42b3a0be2411a9c4feb1ba8d25 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:21 -0500 Subject: [PATCH 3/8] remote-bzr: simplify get_remote_branch() No need for 'origin', it's only needed for the bzrdir 'sprout' method, which can be greatly simplified. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 35664c6523..5c4201ac31 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -765,25 +765,26 @@ def do_list(parser): print "@refs/heads/%s HEAD" % master_branch print -def get_remote_branch(origin, remote_branch, name): +def clone(path, remote_branch): + bdir = bzrlib.bzrdir.BzrDir.create(path) + repo = bdir.find_repository() + repo.fetch(remote_branch.repository) + return remote_branch.sprout(bdir, repository=repo) + +def get_remote_branch(remote_branch, name): global dirname, peers branch_path = os.path.join(dirname, 'clone', name) try: - d = bzrlib.bzrdir.BzrDir.open(branch_path) - branch = d.open_branch() + branch = bzrlib.branch.Branch.open(branch_path) except bzrlib.errors.NotBranchError: # 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() + branch = clone(branch_path, remote_branch) else: # pull 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 @@ -856,7 +857,7 @@ def get_repo(url, alias): if not is_local: peers[name] = remote_branch.base - branch = get_remote_branch(origin, remote_branch, name) + branch = get_remote_branch(remote_branch, name) else: branch = remote_branch @@ -874,7 +875,7 @@ def get_repo(url, alias): if not is_local: peers[name] = remote_branch.base - branch = get_remote_branch(origin, remote_branch, name) + branch = get_remote_branch(remote_branch, name) else: branch = remote_branch From 2ae078e8476639b0dcd559d9b797771e6ffd97ff Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:22 -0500 Subject: [PATCH 4/8] remote-bzr: delay cloning/pulling Until the branch is actually going to be used. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 28 +++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 5c4201ac31..202a4f7f44 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -278,7 +278,7 @@ def export_branch(repo, name): 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() @@ -590,7 +590,7 @@ def parse_commit(parser): 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') @@ -692,7 +692,7 @@ def do_export(parser): for ref, revid in parsed_refs.iteritems(): if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] - branch = bzrlib.branch.Branch.open(branches[name]) + branch = get_remote_branch(name) branch.generate_revision_history(revid, marks.get_tip(name)) if name in peers: @@ -749,7 +749,7 @@ def do_list(parser): 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: @@ -771,8 +771,12 @@ def clone(path, remote_branch): repo.fetch(remote_branch.repository) return remote_branch.sprout(bdir, repository=repo) -def get_remote_branch(remote_branch, name): - global dirname, peers +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) @@ -857,13 +861,10 @@ def get_repo(url, alias): if not is_local: peers[name] = remote_branch.base - branch = get_remote_branch(remote_branch, name) - else: - branch = remote_branch - branches[name] = branch.base + branches[name] = remote_branch.base - return branch.repository + return remote_branch.repository else: # repository @@ -875,11 +876,8 @@ def get_repo(url, alias): if not is_local: peers[name] = remote_branch.base - branch = get_remote_branch(remote_branch, name) - else: - branch = remote_branch - branches[name] = branch.base + branches[name] = remote_branch.base return repo From 0454c399c9ce75bbdf7d35223845cfc98f51d5d9 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:23 -0500 Subject: [PATCH 5/8] remote-bzr: change global repo It's not used anyway. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 202a4f7f44..80ed59f430 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -864,7 +864,7 @@ def get_repo(url, alias): branches[name] = remote_branch.base - return remote_branch.repository + return origin else: # repository @@ -879,7 +879,7 @@ def get_repo(url, alias): branches[name] = remote_branch.base - return repo + return origin def fix_path(alias, orig_url): url = urlparse.urlparse(orig_url, 'file') From a8ffc3ade273c5d6b2383450f1b4970c2da89d7d Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:24 -0500 Subject: [PATCH 6/8] remote-bzr: trivial cleanups Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 80ed59f430..34025c3bea 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -815,7 +815,7 @@ def find_branches(repo, wanted): except bzrlib.errors.NotBranchError: continue else: - yield name, branch + yield name, branch.base def get_repo(url, alias): global dirname, peer, branches @@ -857,12 +857,12 @@ def get_repo(url, alias): # branch name = 'master' - remote_branch = origin.open_branch() + branch = origin.open_branch().base if not is_local: - peers[name] = remote_branch.base + peers[name] = branch - branches[name] = remote_branch.base + branches[name] = branch return origin else: @@ -872,12 +872,12 @@ def get_repo(url, alias): # stupid python wanted = [e for e in wanted if e] - for name, remote_branch in find_branches(repo, wanted): + for name, branch in find_branches(repo, wanted): if not is_local: - peers[name] = remote_branch.base + peers[name] = branch - branches[name] = remote_branch.base + branches[name] = branch return origin From e56660a73f778546f7c40989d982ac2f21462975 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:25 -0500 Subject: [PATCH 7/8] remote-bzr: reorganize the way 'wanted' works If the user specified a list of branches, we ignore what the remote repository lists, and simply use the branches directly. Since some remotes don't report the branches correctly, this is useful. Otherwise either fetch the repo, or the branch. Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 58 ++++++++++++--------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 34025c3bea..3248586b13 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -795,7 +795,7 @@ def get_remote_branch(name): return branch -def find_branches(repo, wanted): +def find_branches(repo): transport = repo.bzrdir.root_transport for fn in transport.iter_files_recursive(): @@ -806,9 +806,6 @@ def find_branches(repo, wanted): 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) @@ -848,38 +845,35 @@ def get_repo(url, alias): except bzrlib.errors.NoRepositoryPresent: pass - 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: - # branch - - name = 'master' - branch = origin.open_branch().base - - if not is_local: - peers[name] = branch + wanted = get_config('remote-bzr.branches').rstrip().split(', ') + # stupid python + wanted = [e for e in wanted if e] - branches[name] = branch - - return origin + 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 - - wanted = get_config('remote-bzr.branches').rstrip().split(', ') - # stupid python - wanted = [e for e in wanted if e] + branch_list = find_branches(repo) - for name, branch in find_branches(repo, wanted): - - if not is_local: - peers[name] = branch - - branches[name] = branch + for name, url in branch_list: + if not is_local: + peers[name] = url + branches[name] = url - return origin + return origin def fix_path(alias, orig_url): url = urlparse.urlparse(orig_url, 'file') From 85f931d3d5adf9d628aa3a75cfdd2f8f940f3d56 Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 24 May 2013 21:24:26 -0500 Subject: [PATCH 8/8] remote-bzr: add fallback check for a partial clone Signed-off-by: Felipe Contreras Signed-off-by: Junio C Hamano --- contrib/remote-helpers/git-remote-bzr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 3248586b13..3cd65723c3 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -766,7 +766,10 @@ def do_list(parser): print def clone(path, remote_branch): - bdir = bzrlib.bzrdir.BzrDir.create(path) + 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)