зеркало из https://github.com/microsoft/git.git
remote-bzr: add support for bzr repos
In bazaar, a repository can contain multiple branches, and previously we were supporting only one branch at a time. Now we fetch them all. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
5df4fad319
Коммит
95b0c60831
|
@ -27,6 +27,7 @@ import bzrlib.generate_ids
|
||||||
import bzrlib.transport
|
import bzrlib.transport
|
||||||
import bzrlib.errors
|
import bzrlib.errors
|
||||||
import bzrlib.ui
|
import bzrlib.ui
|
||||||
|
import bzrlib.urlutils
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
@ -250,12 +251,13 @@ def export_files(tree, files):
|
||||||
|
|
||||||
return final
|
return final
|
||||||
|
|
||||||
def export_branch(branch, name):
|
def export_branch(repo, name):
|
||||||
global prefix
|
global prefix
|
||||||
|
|
||||||
ref = '%s/heads/%s' % (prefix, name)
|
ref = '%s/heads/%s' % (prefix, name)
|
||||||
tip = marks.get_tip(name)
|
tip = marks.get_tip(name)
|
||||||
|
|
||||||
|
branch = branches[name]
|
||||||
repo = branch.repository
|
repo = branch.repository
|
||||||
|
|
||||||
branch.lock_read()
|
branch.lock_read()
|
||||||
|
@ -323,7 +325,7 @@ def export_branch(branch, name):
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
if (count % 100 == 0):
|
if (count % 100 == 0):
|
||||||
print "progress revision %s (%d/%d)" % (revid, count, len(revs))
|
print "progress revision %s '%s' (%d/%d)" % (revid, name, count, len(revs))
|
||||||
print "#############################################################"
|
print "#############################################################"
|
||||||
|
|
||||||
branch.unlock()
|
branch.unlock()
|
||||||
|
@ -348,7 +350,7 @@ def export_tag(repo, name):
|
||||||
def do_import(parser):
|
def do_import(parser):
|
||||||
global dirname
|
global dirname
|
||||||
|
|
||||||
branch = parser.repo
|
repo = parser.repo
|
||||||
path = os.path.join(dirname, 'marks-git')
|
path = os.path.join(dirname, 'marks-git')
|
||||||
|
|
||||||
print "feature done"
|
print "feature done"
|
||||||
|
@ -362,10 +364,10 @@ def do_import(parser):
|
||||||
ref = parser[1]
|
ref = parser[1]
|
||||||
if ref.startswith('refs/heads/'):
|
if ref.startswith('refs/heads/'):
|
||||||
name = ref[len('refs/heads/'):]
|
name = ref[len('refs/heads/'):]
|
||||||
export_branch(branch, name)
|
export_branch(repo, name)
|
||||||
if ref.startswith('refs/tags/'):
|
if ref.startswith('refs/tags/'):
|
||||||
name = ref[len('refs/tags/'):]
|
name = ref[len('refs/tags/'):]
|
||||||
export_tag(branch, name)
|
export_tag(repo, name)
|
||||||
parser.next()
|
parser.next()
|
||||||
|
|
||||||
print 'done'
|
print 'done'
|
||||||
|
@ -551,8 +553,11 @@ def parse_commit(parser):
|
||||||
ref = parser[1]
|
ref = parser[1]
|
||||||
parser.next()
|
parser.next()
|
||||||
|
|
||||||
if ref != 'refs/heads/master':
|
if ref.startswith('refs/heads/'):
|
||||||
die("bzr doesn't support multiple branches; use 'master'")
|
name = ref[len('refs/heads/'):]
|
||||||
|
branch = branches[name]
|
||||||
|
else:
|
||||||
|
die('unknown ref')
|
||||||
|
|
||||||
commit_mark = parser.get_mark()
|
commit_mark = parser.get_mark()
|
||||||
parser.next()
|
parser.next()
|
||||||
|
@ -588,8 +593,6 @@ def parse_commit(parser):
|
||||||
path = c_style_unescape(path).decode('utf-8')
|
path = c_style_unescape(path).decode('utf-8')
|
||||||
files[path] = f
|
files[path] = f
|
||||||
|
|
||||||
branch = parser.repo
|
|
||||||
|
|
||||||
committer, date, tz = committer
|
committer, date, tz = committer
|
||||||
parents = [str(mark_to_rev(p)) for p in parents]
|
parents = [str(mark_to_rev(p)) for p in parents]
|
||||||
revid = bzrlib.generate_ids.gen_revision_id(committer, date)
|
revid = bzrlib.generate_ids.gen_revision_id(committer, date)
|
||||||
|
@ -621,9 +624,6 @@ def parse_reset(parser):
|
||||||
ref = parser[1]
|
ref = parser[1]
|
||||||
parser.next()
|
parser.next()
|
||||||
|
|
||||||
if ref != 'refs/heads/master':
|
|
||||||
die("bzr doesn't support multiple branches; use 'master'")
|
|
||||||
|
|
||||||
# ugh
|
# ugh
|
||||||
if parser.check('commit'):
|
if parser.check('commit'):
|
||||||
parse_commit(parser)
|
parse_commit(parser)
|
||||||
|
@ -636,7 +636,7 @@ def parse_reset(parser):
|
||||||
parsed_refs[ref] = mark_to_rev(from_mark)
|
parsed_refs[ref] = mark_to_rev(from_mark)
|
||||||
|
|
||||||
def do_export(parser):
|
def do_export(parser):
|
||||||
global parsed_refs, dirname, peer
|
global parsed_refs, dirname
|
||||||
|
|
||||||
parser.next()
|
parser.next()
|
||||||
|
|
||||||
|
@ -654,14 +654,15 @@ def do_export(parser):
|
||||||
else:
|
else:
|
||||||
die('unhandled export command: %s' % line)
|
die('unhandled export command: %s' % line)
|
||||||
|
|
||||||
branch = parser.repo
|
|
||||||
|
|
||||||
for ref, revid in parsed_refs.iteritems():
|
for ref, revid in parsed_refs.iteritems():
|
||||||
if ref == 'refs/heads/master':
|
name = ref[len('refs/heads/'):]
|
||||||
branch.generate_revision_history(revid, marks.get_tip('master'))
|
branch = branches[name]
|
||||||
if peer:
|
branch.generate_revision_history(revid, marks.get_tip(name))
|
||||||
|
|
||||||
|
if name in peers:
|
||||||
|
peer = peers[name]
|
||||||
try:
|
try:
|
||||||
branch.push(peer, stop_revision=revid)
|
peer.bzrdir.push_branch(branch, revision_id=revid)
|
||||||
except bzrlib.errors.DivergedBranches:
|
except bzrlib.errors.DivergedBranches:
|
||||||
print "error %s non-fast forward" % ref
|
print "error %s non-fast forward" % ref
|
||||||
continue
|
continue
|
||||||
|
@ -697,9 +698,15 @@ def ref_is_valid(name):
|
||||||
|
|
||||||
def do_list(parser):
|
def do_list(parser):
|
||||||
global tags
|
global tags
|
||||||
print "? refs/heads/%s" % 'master'
|
|
||||||
|
|
||||||
branch = parser.repo
|
master_branch = None
|
||||||
|
|
||||||
|
for name in branches:
|
||||||
|
if not master_branch:
|
||||||
|
master_branch = name
|
||||||
|
print "? refs/heads/%s" % name
|
||||||
|
|
||||||
|
branch = branches[master_branch]
|
||||||
branch.lock_read()
|
branch.lock_read()
|
||||||
for tag, revid in branch.tags.get_tag_dict().items():
|
for tag, revid in branch.tags.get_tag_dict().items():
|
||||||
try:
|
try:
|
||||||
|
@ -711,42 +718,78 @@ def do_list(parser):
|
||||||
print "? refs/tags/%s" % tag
|
print "? refs/tags/%s" % tag
|
||||||
tags[tag] = revid
|
tags[tag] = revid
|
||||||
branch.unlock()
|
branch.unlock()
|
||||||
print "@refs/heads/%s HEAD" % 'master'
|
|
||||||
|
print "@refs/heads/%s HEAD" % master_branch
|
||||||
print
|
print
|
||||||
|
|
||||||
def get_repo(url, alias):
|
def get_remote_branch(origin, remote_branch, name):
|
||||||
global dirname, peer
|
global dirname, peers
|
||||||
|
|
||||||
origin = bzrlib.bzrdir.BzrDir.open(url)
|
branch_path = os.path.join(dirname, 'clone', name)
|
||||||
branch = origin.open_branch()
|
if os.path.exists(branch_path):
|
||||||
|
|
||||||
if not isinstance(origin.transport, bzrlib.transport.local.LocalTransport):
|
|
||||||
clone_path = os.path.join(dirname, 'clone')
|
|
||||||
remote_branch = branch
|
|
||||||
if os.path.exists(clone_path):
|
|
||||||
# pull
|
# pull
|
||||||
d = bzrlib.bzrdir.BzrDir.open(clone_path)
|
d = bzrlib.bzrdir.BzrDir.open(branch_path)
|
||||||
branch = d.open_branch()
|
branch = d.open_branch()
|
||||||
try:
|
try:
|
||||||
result = branch.pull(remote_branch, [], None, False)
|
branch.pull(remote_branch, [], None, False)
|
||||||
except bzrlib.errors.DivergedBranches:
|
except bzrlib.errors.DivergedBranches:
|
||||||
# use remote branch for now
|
# use remote branch for now
|
||||||
peer = None
|
|
||||||
return remote_branch
|
return remote_branch
|
||||||
else:
|
else:
|
||||||
# clone
|
# clone
|
||||||
d = origin.sprout(clone_path, None,
|
d = origin.sprout(branch_path, None,
|
||||||
hardlink=True, create_tree_if_local=False,
|
hardlink=True, create_tree_if_local=False,
|
||||||
|
force_new_repo=False,
|
||||||
source_branch=remote_branch)
|
source_branch=remote_branch)
|
||||||
branch = d.open_branch()
|
branch = d.open_branch()
|
||||||
branch.bind(remote_branch)
|
|
||||||
|
|
||||||
peer = remote_branch
|
|
||||||
else:
|
|
||||||
peer = None
|
|
||||||
|
|
||||||
return branch
|
return branch
|
||||||
|
|
||||||
|
def get_repo(url, alias):
|
||||||
|
global dirname, peer, branches
|
||||||
|
|
||||||
|
normal_url = bzrlib.urlutils.normalize_url(url)
|
||||||
|
origin = bzrlib.bzrdir.BzrDir.open(url)
|
||||||
|
is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport)
|
||||||
|
|
||||||
|
clone_path = os.path.join(dirname, 'clone')
|
||||||
|
|
||||||
|
try:
|
||||||
|
repo = origin.open_repository()
|
||||||
|
except bzrlib.errors.NoRepositoryPresent:
|
||||||
|
# branch
|
||||||
|
|
||||||
|
name = 'master'
|
||||||
|
branch = origin.open_branch()
|
||||||
|
|
||||||
|
if not is_local:
|
||||||
|
if not os.path.exists(clone_path):
|
||||||
|
os.mkdir(clone_path)
|
||||||
|
peers[name] = branch
|
||||||
|
branches[name] = get_remote_branch(origin, branch, name)
|
||||||
|
else:
|
||||||
|
branches[name] = branch
|
||||||
|
|
||||||
|
return branch.repository
|
||||||
|
else:
|
||||||
|
# repository
|
||||||
|
|
||||||
|
if not is_local and not os.path.exists(clone_path):
|
||||||
|
clonedir = bzrlib.bzrdir.BzrDir.create(clone_path)
|
||||||
|
|
||||||
|
for branch in repo.find_branches():
|
||||||
|
|
||||||
|
name = repo.user_transport.relpath(branch.base)
|
||||||
|
name = name if name != '' else 'master'
|
||||||
|
|
||||||
|
if not is_local:
|
||||||
|
peers[name] = branch
|
||||||
|
branches[name] = get_remote_branch(origin, branch, name)
|
||||||
|
else:
|
||||||
|
branches[name] = branch
|
||||||
|
|
||||||
|
return repo
|
||||||
|
|
||||||
def fix_path(alias, orig_url):
|
def fix_path(alias, orig_url):
|
||||||
url = urlparse.urlparse(orig_url, 'file')
|
url = urlparse.urlparse(orig_url, 'file')
|
||||||
if url.scheme != 'file' or os.path.isabs(url.path):
|
if url.scheme != 'file' or os.path.isabs(url.path):
|
||||||
|
@ -762,6 +805,7 @@ def main(args):
|
||||||
global parsed_refs
|
global parsed_refs
|
||||||
global files_cache
|
global files_cache
|
||||||
global is_tmp
|
global is_tmp
|
||||||
|
global branches, peers
|
||||||
|
|
||||||
alias = args[1]
|
alias = args[1]
|
||||||
url = args[2]
|
url = args[2]
|
||||||
|
@ -772,6 +816,8 @@ def main(args):
|
||||||
parsed_refs = {}
|
parsed_refs = {}
|
||||||
files_cache = {}
|
files_cache = {}
|
||||||
marks = None
|
marks = None
|
||||||
|
branches = {}
|
||||||
|
peers = {}
|
||||||
|
|
||||||
if alias[5:] == url:
|
if alias[5:] == url:
|
||||||
is_tmp = True
|
is_tmp = True
|
||||||
|
|
|
@ -264,4 +264,40 @@ test_expect_success 'pushing a merge' '
|
||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat > expected <<EOF
|
||||||
|
origin/HEAD
|
||||||
|
origin/branch
|
||||||
|
origin/trunk
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'proper bzr repo' '
|
||||||
|
mkdir -p tmp && cd tmp &&
|
||||||
|
test_when_finished "cd .. && rm -rf tmp" &&
|
||||||
|
|
||||||
|
bzr init-repo bzrrepo &&
|
||||||
|
|
||||||
|
bzr init bzrrepo/trunk &&
|
||||||
|
(
|
||||||
|
cd bzrrepo/trunk &&
|
||||||
|
echo one >> content &&
|
||||||
|
bzr add content &&
|
||||||
|
bzr commit -m one
|
||||||
|
) &&
|
||||||
|
|
||||||
|
bzr branch bzrrepo/trunk bzrrepo/branch &&
|
||||||
|
(
|
||||||
|
cd bzrrepo/branch &&
|
||||||
|
echo two >> content &&
|
||||||
|
bzr commit -m one
|
||||||
|
) &&
|
||||||
|
|
||||||
|
git clone "bzr::$PWD/bzrrepo" gitrepo &&
|
||||||
|
(
|
||||||
|
cd gitrepo &&
|
||||||
|
git for-each-ref --format "%(refname:short)" refs/remotes/origin > ../actual
|
||||||
|
) &&
|
||||||
|
|
||||||
|
test_cmp ../expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
Загрузка…
Ссылка в новой задаче