git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/3] New remote-bzr remote helper
@ 2012-11-04  2:22 Felipe Contreras
  2012-11-04  2:22 ` [PATCH 1/3] Add new remote-bzr transport helper Felipe Contreras
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Felipe Contreras @ 2012-11-04  2:22 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano, Jeff King, Johannes Schindelin, Felipe Contreras

Hi,

This is a proof-of-concept remote helper for bzr, that turns out to work rather well.

It uses bzr-fastimport[1], which is what most current bzr<->git tools uses, but
the quality is not that great. After applying an important fix[2], it works
nicely, but you will get tons of verbose messages.

Eventually we might want to implement the same functionality as bzr-fastimport,
but for now this already works nicely enough.

Cheers.

[1] http://wiki.bazaar.canonical.com/BzrFastImport
[2] https://launchpadlibrarian.net/121967844/bzr-fastimport-no-graph.patch

Felipe Contreras (3):
  Add new remote-bzr transport helper
  remote-bzr: add support for pushing
  remote-bzr: add simple tests

 contrib/remote-helpers/git-remote-bzr | 221 ++++++++++++++++++++++++++++++++++
 contrib/remote-helpers/test-bzr.sh    | 111 +++++++++++++++++
 2 files changed, 332 insertions(+)
 create mode 100755 contrib/remote-helpers/git-remote-bzr
 create mode 100755 contrib/remote-helpers/test-bzr.sh

-- 
1.8.0

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] Add new remote-bzr transport helper
  2012-11-04  2:22 [PATCH 0/3] New remote-bzr remote helper Felipe Contreras
@ 2012-11-04  2:22 ` Felipe Contreras
  2012-11-04  2:22 ` [PATCH 2/3] remote-bzr: add support for pushing Felipe Contreras
  2012-11-04  2:22 ` [PATCH 3/3] remote-bzr: add simple tests Felipe Contreras
  2 siblings, 0 replies; 4+ messages in thread
From: Felipe Contreras @ 2012-11-04  2:22 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano, Jeff King, Johannes Schindelin, Felipe Contreras

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-helpers/git-remote-bzr | 187 ++++++++++++++++++++++++++++++++++
 1 file changed, 187 insertions(+)
 create mode 100755 contrib/remote-helpers/git-remote-bzr

diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr
new file mode 100755
index 0000000..76a609a
--- /dev/null
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -0,0 +1,187 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+
+# Just copy to your ~/bin, or anywhere in your $PATH.
+# Then you can clone with:
+# git clone bzr::/path/to/mercurial/repo/
+#
+# You need to have bzr-fastimport installed:
+# http://wiki.bazaar.canonical.com/BzrFastImport
+#
+# You might also need to find this line bzr-fastimport's
+# code, and modify it:
+#
+# self._use_known_graph = False
+
+import sys
+
+import bzrlib
+bzrlib.initialize()
+
+import bzrlib.plugin
+bzrlib.plugin.load_plugins()
+
+import bzrlib.revisionspec
+
+from bzrlib.plugins.fastimport import exporter as bzr_exporter
+
+import sys
+import os
+import json
+
+def die(msg, *args):
+    sys.stderr.write('ERROR: %s\n' % (msg % args))
+    sys.exit(1)
+
+def warn(msg, *args):
+    sys.stderr.write('WARNING: %s\n' % (msg % args))
+
+class Marks:
+
+    def __init__(self, path):
+        self.path = path
+        self.tips = {}
+        self.load()
+
+    def load(self):
+        if not os.path.exists(self.path):
+            return
+
+        tmp = json.load(open(self.path))
+        self.tips = tmp['tips']
+
+    def dict(self):
+        return { 'tips': self.tips }
+
+    def store(self):
+        json.dump(self.dict(), open(self.path, 'w'))
+
+    def __str__(self):
+        return str(self.dict())
+
+    def get_tip(self, branch):
+        return self.tips.get(branch, '1')
+
+    def set_tip(self, branch, tip):
+        self.tips[branch] = tip
+
+class Parser:
+
+    def __init__(self, repo):
+        self.repo = repo
+        self.line = self.get_line()
+
+    def get_line(self):
+        return sys.stdin.readline().strip()
+
+    def __getitem__(self, i):
+        return self.line.split()[i]
+
+    def check(self, word):
+        return self.line.startswith(word)
+
+    def each_block(self, separator):
+        while self.line != separator:
+            yield self.line
+            self.line = self.get_line()
+
+    def __iter__(self):
+        return self.each_block('')
+
+    def next(self):
+        self.line = self.get_line()
+        if self.line == 'done':
+            self.line = None
+
+def export_branch(branch, name):
+    global prefix, dirname
+
+    marks_path = os.path.join(dirname, 'marks-bzr')
+    ref = '%s/heads/%s' % (prefix, name)
+    tip = marks.get_tip(name)
+    start = "before:%s" % tip
+    rev1 = bzrlib.revisionspec.RevisionSpec.from_string(start)
+    rev2 = bzrlib.revisionspec.RevisionSpec.from_string(None)
+
+    exporter = bzr_exporter.BzrFastExporter(branch,
+        outf=sys.stdout, ref=ref,
+        checkpoint=None,
+        import_marks_file=marks_path,
+        export_marks_file=marks_path,
+        revision=[rev1, rev2],
+        verbose=None, plain_format=True,
+        rewrite_tags=False)
+    exporter.run()
+
+    marks.set_tip(name, branch.last_revision())
+
+def do_import(parser):
+    global dirname
+
+    branch = parser.repo
+    path = os.path.join(dirname, 'marks-git')
+
+    print "feature done"
+    if os.path.exists(path):
+        print "feature import-marks=%s" % path
+    print "feature export-marks=%s" % path
+    sys.stdout.flush()
+
+    while parser.check('import'):
+        ref = parser[1]
+        if ref.startswith('refs/heads/'):
+            name = ref[len('refs/heads/'):]
+            export_branch(branch, name)
+        parser.next()
+
+    print 'done'
+
+    sys.stdout.flush()
+
+def do_capabilities(parser):
+    print "import"
+    print "refspec refs/heads/*:%s/heads/*" % prefix
+    print
+
+def do_list(parser):
+    print "? refs/heads/%s" % 'master'
+    print "@refs/heads/%s HEAD" % 'master'
+    print
+
+def main(args):
+    global marks, prefix, dirname
+
+    alias = args[1]
+    url = args[2]
+
+    d = bzrlib.controldir.ControlDir.open(url)
+    repo = d.open_branch()
+
+    prefix = 'refs/bzr/%s' % alias
+
+    gitdir = os.environ['GIT_DIR']
+    dirname = os.path.join(gitdir, 'bzr', alias)
+
+    if not os.path.exists(dirname):
+        os.makedirs(dirname)
+
+    marks_path = os.path.join(dirname, 'marks-int')
+    marks = Marks(marks_path)
+
+    parser = Parser(repo)
+    for line in parser:
+        if parser.check('capabilities'):
+            do_capabilities(parser)
+        elif parser.check('list'):
+            do_list(parser)
+        elif parser.check('import'):
+            do_import(parser)
+        else:
+            die('unhandled command: %s' % line)
+        sys.stdout.flush()
+
+    marks.store()
+
+sys.exit(main(sys.argv))
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] remote-bzr: add support for pushing
  2012-11-04  2:22 [PATCH 0/3] New remote-bzr remote helper Felipe Contreras
  2012-11-04  2:22 ` [PATCH 1/3] Add new remote-bzr transport helper Felipe Contreras
@ 2012-11-04  2:22 ` Felipe Contreras
  2012-11-04  2:22 ` [PATCH 3/3] remote-bzr: add simple tests Felipe Contreras
  2 siblings, 0 replies; 4+ messages in thread
From: Felipe Contreras @ 2012-11-04  2:22 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano, Jeff King, Johannes Schindelin, Felipe Contreras

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-helpers/git-remote-bzr | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr
index 76a609a..de37217 100755
--- a/contrib/remote-helpers/git-remote-bzr
+++ b/contrib/remote-helpers/git-remote-bzr
@@ -26,6 +26,9 @@ bzrlib.plugin.load_plugins()
 import bzrlib.revisionspec
 
 from bzrlib.plugins.fastimport import exporter as bzr_exporter
+from bzrlib.plugins.fastimport.processors import generic_processor as bzr_generic_processor
+
+import fastimport.parser
 
 import sys
 import os
@@ -140,9 +143,38 @@ def do_import(parser):
 
     sys.stdout.flush()
 
+def do_export(parser):
+    global dirname
+
+    parser.next() # can't handle 'done'?
+
+    controldir = parser.repo.bzrdir
+
+    path = os.path.join(dirname, 'marks-bzr')
+    params = { 'import-marks': path, 'export-marks': path }
+
+    proc = bzr_generic_processor.GenericProcessor(controldir, params)
+    p = fastimport.parser.ImportParser(sys.stdin)
+    proc.process(p.iter_commands)
+
+    if parser.repo.last_revision() != marks.get_tip('master'):
+        print 'ok %s' % 'refs/heads/master'
+
+    print
+
 def do_capabilities(parser):
+    global dirname
+
     print "import"
+    print "export"
     print "refspec refs/heads/*:%s/heads/*" % prefix
+
+    path = os.path.join(dirname, 'marks-git')
+
+    if os.path.exists(path):
+        print "*import-marks %s" % path
+    print "*export-marks %s" % path
+
     print
 
 def do_list(parser):
@@ -178,6 +210,8 @@ def main(args):
             do_list(parser)
         elif parser.check('import'):
             do_import(parser)
+        elif parser.check('export'):
+            do_export(parser)
         else:
             die('unhandled command: %s' % line)
         sys.stdout.flush()
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] remote-bzr: add simple tests
  2012-11-04  2:22 [PATCH 0/3] New remote-bzr remote helper Felipe Contreras
  2012-11-04  2:22 ` [PATCH 1/3] Add new remote-bzr transport helper Felipe Contreras
  2012-11-04  2:22 ` [PATCH 2/3] remote-bzr: add support for pushing Felipe Contreras
@ 2012-11-04  2:22 ` Felipe Contreras
  2 siblings, 0 replies; 4+ messages in thread
From: Felipe Contreras @ 2012-11-04  2:22 UTC (permalink / raw
  To: git; +Cc: Junio C Hamano, Jeff King, Johannes Schindelin, Felipe Contreras

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-helpers/test-bzr.sh | 111 +++++++++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100755 contrib/remote-helpers/test-bzr.sh

diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh
new file mode 100755
index 0000000..8594ffc
--- /dev/null
+++ b/contrib/remote-helpers/test-bzr.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+
+test_description='Test remote-bzr'
+
+. ./test-lib.sh
+
+if ! test_have_prereq PYTHON; then
+	skip_all='skipping remote-bzr tests; python not available'
+	test_done
+fi
+
+if ! "$PYTHON_PATH" -c 'import bzrlib'; then
+	skip_all='skipping remote-bzr tests; bzr not available'
+	test_done
+fi
+
+cmd=<<EOF
+import bzrlib
+bzrlib.initialize()
+import bzrlib.plugin
+bzrlib.plugin.load_plugins()
+import bzrlib.plugins.fastimport
+EOF
+
+if ! "$PYTHON_PATH" -c "$cmd"; then
+	echo "consider setting BZR_PLUGIN_PATH=$HOME/.bazaar/plugins" 1>&2
+	skip_all='skipping remote-bzr tests; bzr-fastimport not available'
+	test_done
+fi
+
+check () {
+	(cd $1 &&
+	git log --format='%s' -1 &&
+	git symbolic-ref HEAD) > actual &&
+	(echo $2 &&
+	echo "refs/heads/$3") > expected &&
+	test_cmp expected actual
+}
+
+bzr whoami "A U Thor <author@example.com>"
+
+test_expect_success 'cloning' '
+  (bzr init bzrrepo &&
+  cd bzrrepo &&
+  echo one > content &&
+  bzr add content &&
+  bzr commit -m one
+  ) &&
+
+  git clone "bzr::$PWD/bzrrepo" gitrepo &&
+  check gitrepo one master
+'
+
+test_expect_success 'pulling' '
+  (cd bzrrepo &&
+  echo two > content &&
+  bzr commit -m two
+  ) &&
+
+  (cd gitrepo && git pull) &&
+
+  check gitrepo two master
+'
+
+test_expect_success 'pushing' '
+  (cd gitrepo &&
+  echo three > content &&
+  git commit -a -m three &&
+  git push
+  ) &&
+
+  echo three > expected &&
+  cat bzrrepo/content > actual &&
+  test_cmp expected actual
+'
+
+test_expect_success 'roundtrip' '
+  (cd gitrepo &&
+  git pull &&
+  git log --format="%s" -1 origin/master > actual) &&
+  echo three > expected &&
+  test_cmp expected actual &&
+
+  (cd gitrepo && git push && git pull) &&
+
+  (cd bzrrepo &&
+  echo four > content &&
+  bzr commit -m four
+  ) &&
+
+  (cd gitrepo && git pull && git push) &&
+
+  check gitrepo four master &&
+
+  (cd gitrepo &&
+  echo five > content &&
+  git commit -a -m five &&
+  git push && git pull
+  ) &&
+
+  (cd bzrrepo && bzr revert) &&
+
+  echo five > expected &&
+  cat bzrrepo/content > actual &&
+  test_cmp expected actual
+'
+
+test_done
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-11-04  2:22 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-04  2:22 [PATCH 0/3] New remote-bzr remote helper Felipe Contreras
2012-11-04  2:22 ` [PATCH 1/3] Add new remote-bzr transport helper Felipe Contreras
2012-11-04  2:22 ` [PATCH 2/3] remote-bzr: add support for pushing Felipe Contreras
2012-11-04  2:22 ` [PATCH 3/3] remote-bzr: add simple tests Felipe Contreras

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).