* [PATCH v6 00/16] New remote-hg helper:w
@ 2012-11-04 2:13 Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 01/16] Add new remote-hg transport helper Felipe Contreras
` (15 more replies)
0 siblings, 16 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Hi,
Only a few updates, and has been moved to contrib/remote-helpers
(git-remote-bzr is on the way).
This remote-hg has advantages other tools don't have:
* Uses transport-helper (git clone hg::path)
* The code is small
* The code is simple
* No external dependencies (other than mercurial)
* It's easy to install (put into your path)
* Has extensive tests (for real)
* Active development
* Has compatibility with hg-git
* The required patches are available
* No changes necesary to git core
* Support for bookmarks
* Support for tags
One important alternative is the one written by Sverre Rabbelier that is
now maintained and distributed in msysgit. A list of issues with that
approach (not exhaustive):
* Doesn't work on newer versions of mercurial
* There are multiple versions, each with different issues
* Don't pass a single of this remote-hg's tests
To use it add it to your $PATH (e.g. ~/bin).
% git clone hd:///full/path/or/url/to/hg/repo
To run the tests:
% make -C contrib/remote-helpers test
The only caveat is that you need 'python' in your $PATH.
Changes since v5:
* Move to contrib/remote-helpers
* Reorganize tests
* Fix update of bookmarks
* Fix for older versions of python
* Performance improvements
* Improve default branch/bookmark handling
* Add fixes test-lib
* Cleanups
Changes since v4:
Felipe Contreras (16):
Add new remote-hg transport helper
remote-hg: add support for pushing
remote-hg: add support for remote pushing
remote-hg: add support to push URLs
remote-hg: make sure the encoding is correct
remote-hg: match hg merge behavior
remote-hg: add support for hg-git compat mode
remote-hg: add compat for hg-git author fixes
remote-hg: fake bookmark when there's none
remote-hg: add basic tests
test-lib: avoid full path to store test results
remote-hg: add bidirectional tests
remote-hg: add tests to compare with hg-git
remote-hg: add extra author test
remote-hg: add option to not track branches
remote-hg: the author email can be null
contrib/remote-helpers/Makefile | 13 +
contrib/remote-helpers/git-remote-hg | 785 +++++++++++++++++++++++++++++++
contrib/remote-helpers/test-hg-bidi.sh | 243 ++++++++++
contrib/remote-helpers/test-hg-hg-git.sh | 466 ++++++++++++++++++
contrib/remote-helpers/test-hg.sh | 112 +++++
t/test-lib.sh | 3 +-
6 files changed, 1621 insertions(+), 1 deletion(-)
create mode 100644 contrib/remote-helpers/Makefile
create mode 100755 contrib/remote-helpers/git-remote-hg
create mode 100755 contrib/remote-helpers/test-hg-bidi.sh
create mode 100755 contrib/remote-helpers/test-hg-hg-git.sh
create mode 100755 contrib/remote-helpers/test-hg.sh
--
1.8.0
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v6 01/16] Add new remote-hg transport helper
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 02/16] remote-hg: add support for pushing Felipe Contreras
` (14 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 391 +++++++++++++++++++++++++++++++++++
1 file changed, 391 insertions(+)
create mode 100755 contrib/remote-helpers/git-remote-hg
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
new file mode 100755
index 0000000..e37e278
--- /dev/null
+++ b/contrib/remote-helpers/git-remote-hg
@@ -0,0 +1,391 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+
+# Inspired by Rocco Rutte's hg-fast-export
+
+# Just copy to your ~/bin, or anywhere in your $PATH.
+# Then you can clone with:
+# git clone hg::/path/to/mercurial/repo/
+
+from mercurial import hg, ui, bookmarks
+
+import re
+import sys
+import os
+import json
+
+NAME_RE = re.compile('^([^<>]+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
+
+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))
+
+def gitmode(flags):
+ return 'l' in flags and '120000' or 'x' in flags and '100755' or '100644'
+
+def gittz(tz):
+ return '%+03d%02d' % (-tz / 3600, -tz % 3600 / 60)
+
+class Marks:
+
+ def __init__(self, path):
+ self.path = path
+ self.tips = {}
+ self.marks = {}
+ self.last_mark = 0
+
+ self.load()
+
+ def load(self):
+ if not os.path.exists(self.path):
+ return
+
+ tmp = json.load(open(self.path))
+
+ self.tips = tmp['tips']
+ self.marks = tmp['marks']
+ self.last_mark = tmp['last-mark']
+
+ def dict(self):
+ return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark }
+
+ def store(self):
+ json.dump(self.dict(), open(self.path, 'w'))
+
+ def __str__(self):
+ return str(self.dict())
+
+ def from_rev(self, rev):
+ return self.marks[str(rev)]
+
+ def get_mark(self, rev):
+ self.last_mark += 1
+ self.marks[str(rev)] = self.last_mark
+ return self.last_mark
+
+ def is_marked(self, rev):
+ return self.marks.has_key(str(rev))
+
+ def get_tip(self, branch):
+ return self.tips.get(branch, 0)
+
+ 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_file(fc):
+ d = fc.data()
+ print "M %s inline %s" % (gitmode(fc.flags()), fc.path())
+ print "data %d" % len(d)
+ print d
+
+def get_filechanges(repo, ctx, parent):
+ modified = set()
+ added = set()
+ removed = set()
+
+ cur = ctx.manifest()
+ prev = repo[parent].manifest().copy()
+
+ for fn in cur:
+ if fn in prev:
+ if (cur.flags(fn) != prev.flags(fn) or cur[fn] != prev[fn]):
+ modified.add(fn)
+ del prev[fn]
+ else:
+ added.add(fn)
+ removed |= set(prev.keys())
+
+ return added | modified, removed
+
+def fixup_user(user):
+ user = user.replace('"', '')
+ name = mail = None
+ m = AUTHOR_RE.match(user)
+ if m:
+ name = m.group(1)
+ mail = m.group(2).strip()
+ else:
+ m = NAME_RE.match(user)
+ if m:
+ name = m.group(1).strip()
+
+ if not name:
+ name = 'Unknown'
+ if not mail:
+ mail = 'unknown'
+
+ return '%s <%s>' % (name, mail)
+
+def get_repo(url, alias):
+ global dirname
+
+ myui = ui.ui()
+ myui.setconfig('ui', 'interactive', 'off')
+
+ if hg.islocal(url):
+ repo = hg.repository(myui, url)
+ else:
+ local_path = os.path.join(dirname, 'clone')
+ if not os.path.exists(local_path):
+ peer, dstpeer = hg.clone(myui, {}, url, local_path, update=False, pull=True)
+ repo = dstpeer.local()
+ else:
+ repo = hg.repository(myui, local_path)
+ peer = hg.peer(myui, {}, url)
+ repo.pull(peer, heads=None, force=True)
+
+ return repo
+
+def rev_to_mark(rev):
+ global marks
+ return marks.from_rev(rev)
+
+def export_ref(repo, name, kind, head):
+ global prefix, marks
+
+ ename = '%s/%s' % (kind, name)
+ tip = marks.get_tip(ename)
+
+ # mercurial takes too much time checking this
+ if tip and tip == head.rev():
+ # nothing to do
+ return
+ revs = repo.revs('%u:%u' % (tip, head))
+ count = 0
+
+ revs = [rev for rev in revs if not marks.is_marked(rev)]
+
+ for rev in revs:
+
+ c = repo[rev]
+ (manifest, user, (time, tz), files, desc, extra) = repo.changelog.read(c.node())
+ rev_branch = extra['branch']
+
+ author = "%s %d %s" % (fixup_user(user), time, gittz(tz))
+ if 'committer' in extra:
+ user, time, tz = extra['committer'].rsplit(' ', 2)
+ committer = "%s %s %s" % (user, time, gittz(int(tz)))
+ else:
+ committer = author
+
+ parents = [p for p in repo.changelog.parentrevs(rev) if p >= 0]
+
+ if len(parents) == 0:
+ modified = c.manifest().keys()
+ removed = []
+ else:
+ modified, removed = get_filechanges(repo, c, parents[0])
+
+ if len(parents) == 0 and rev:
+ print 'reset %s/%s' % (prefix, ename)
+
+ print "commit %s/%s" % (prefix, ename)
+ print "mark :%d" % (marks.get_mark(rev))
+ print "author %s" % (author)
+ print "committer %s" % (committer)
+ print "data %d" % (len(desc))
+ print desc
+
+ if len(parents) > 0:
+ print "from :%s" % (rev_to_mark(parents[0]))
+ if len(parents) > 1:
+ print "merge :%s" % (rev_to_mark(parents[1]))
+
+ for f in modified:
+ export_file(c.filectx(f))
+ for f in removed:
+ print "D %s" % (f)
+ print
+
+ count += 1
+ if (count % 100 == 0):
+ print "progress revision %d '%s' (%d/%d)" % (rev, name, count, len(revs))
+ print "#############################################################"
+
+ # make sure the ref is updated
+ print "reset %s/%s" % (prefix, ename)
+ print "from :%u" % rev_to_mark(rev)
+ print
+
+ marks.set_tip(ename, rev)
+
+def export_tag(repo, tag):
+ export_ref(repo, tag, 'tags', repo[tag])
+
+def export_bookmark(repo, bmark):
+ head = bmarks[bmark]
+ export_ref(repo, bmark, 'bookmarks', head)
+
+def export_branch(repo, branch):
+ tip = get_branch_tip(repo, branch)
+ head = repo[tip]
+ export_ref(repo, branch, 'branches', head)
+
+def export_head(repo):
+ global g_head
+ export_ref(repo, g_head[0], 'bookmarks', g_head[1])
+
+def do_capabilities(parser):
+ global prefix, dirname
+
+ print "import"
+ print "refspec refs/heads/branches/*:%s/branches/*" % prefix
+ print "refspec refs/heads/*:%s/bookmarks/*" % prefix
+ print "refspec refs/tags/*:%s/tags/*" % prefix
+ print
+
+def get_branch_tip(repo, branch):
+ global branches
+
+ heads = branches.get(branch, None)
+ if not heads:
+ return None
+
+ # verify there's only one head
+ if (len(heads) > 1):
+ warn("Branch '%s' has more than one head, consider merging" % branch)
+ # older versions of mercurial don't have this
+ if hasattr(repo, "branchtip"):
+ return repo.branchtip(branch)
+
+ return heads[0]
+
+def list_head(repo, cur):
+ global g_head
+
+ head = bookmarks.readcurrent(repo)
+ if not head:
+ return
+ node = repo[head]
+ print "@refs/heads/%s HEAD" % head
+ g_head = (head, node)
+
+def do_list(parser):
+ global branches, bmarks
+
+ repo = parser.repo
+ for branch in repo.branchmap():
+ heads = repo.branchheads(branch)
+ if len(heads):
+ branches[branch] = heads
+
+ for bmark, node in bookmarks.listbookmarks(repo).iteritems():
+ bmarks[bmark] = repo[node]
+
+ cur = repo.dirstate.branch()
+
+ list_head(repo, cur)
+ for branch in branches:
+ print "? refs/heads/branches/%s" % branch
+ for bmark in bmarks:
+ print "? refs/heads/%s" % bmark
+
+ for tag, node in repo.tagslist():
+ if tag == 'tip':
+ continue
+ print "? refs/tags/%s" % tag
+
+ print
+
+def do_import(parser):
+ repo = 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()
+
+ # lets get all the import lines
+ while parser.check('import'):
+ ref = parser[1]
+
+ if (ref == 'HEAD'):
+ export_head(repo)
+ elif ref.startswith('refs/heads/branches/'):
+ branch = ref[len('refs/heads/branches/'):]
+ export_branch(repo, branch)
+ elif ref.startswith('refs/heads/'):
+ bmark = ref[len('refs/heads/'):]
+ export_bookmark(repo, bmark)
+ elif ref.startswith('refs/tags/'):
+ tag = ref[len('refs/tags/'):]
+ export_tag(repo, tag)
+
+ parser.next()
+
+ print 'done'
+
+def main(args):
+ global prefix, dirname, marks, branches, bmarks
+
+ alias = args[1]
+ url = args[2]
+
+ gitdir = os.environ['GIT_DIR']
+ dirname = os.path.join(gitdir, 'hg', alias)
+ branches = {}
+ bmarks = {}
+
+ repo = get_repo(url, alias)
+ prefix = 'refs/hg/%s' % alias
+
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+
+ marks_path = os.path.join(dirname, 'marks-hg')
+ 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)
+ elif parser.check('export'):
+ do_export(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] 22+ messages in thread
* [PATCH v6 02/16] remote-hg: add support for pushing
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 01/16] Add new remote-hg transport helper Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 03/16] remote-hg: add support for remote pushing Felipe Contreras
` (13 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 217 ++++++++++++++++++++++++++++++++++-
1 file changed, 215 insertions(+), 2 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index e37e278..fcceede 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -9,7 +9,7 @@
# Then you can clone with:
# git clone hg::/path/to/mercurial/repo/
-from mercurial import hg, ui, bookmarks
+from mercurial import hg, ui, bookmarks, context
import re
import sys
@@ -18,6 +18,7 @@ import json
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
+RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.+)> (\d+) ([+-]\d+)')
def die(msg, *args):
sys.stderr.write('ERROR: %s\n' % (msg % args))
@@ -32,12 +33,17 @@ def gitmode(flags):
def gittz(tz):
return '%+03d%02d' % (-tz / 3600, -tz % 3600 / 60)
+def hgmode(mode):
+ m = { '0100755': 'x', '0120000': 'l' }
+ return m.get(mode, '')
+
class Marks:
def __init__(self, path):
self.path = path
self.tips = {}
self.marks = {}
+ self.rev_marks = {}
self.last_mark = 0
self.load()
@@ -52,6 +58,9 @@ class Marks:
self.marks = tmp['marks']
self.last_mark = tmp['last-mark']
+ for rev, mark in self.marks.iteritems():
+ self.rev_marks[mark] = int(rev)
+
def dict(self):
return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark }
@@ -64,11 +73,19 @@ class Marks:
def from_rev(self, rev):
return self.marks[str(rev)]
+ def to_rev(self, mark):
+ return self.rev_marks[mark]
+
def get_mark(self, rev):
self.last_mark += 1
self.marks[str(rev)] = self.last_mark
return self.last_mark
+ def new_mark(self, rev, mark):
+ self.marks[str(rev)] = mark
+ self.rev_marks[mark] = rev
+ self.last_mark = mark
+
def is_marked(self, rev):
return self.marks.has_key(str(rev))
@@ -106,6 +123,35 @@ class Parser:
if self.line == 'done':
self.line = None
+ def get_mark(self):
+ i = self.line.index(':') + 1
+ return int(self.line[i:])
+
+ def get_data(self):
+ if not self.check('data'):
+ return None
+ i = self.line.index(' ') + 1
+ size = int(self.line[i:])
+ return sys.stdin.read(size)
+
+ def get_author(self):
+ m = RAW_AUTHOR_RE.match(self.line)
+ if not m:
+ return None
+ _, name, email, date, tz = m.groups()
+
+ if email != 'unknown':
+ if name:
+ user = '%s <%s>' % (name, email)
+ else:
+ user = '<%s>' % (email)
+ else:
+ user = name
+
+ tz = int(tz)
+ tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
+ return (user, int(date), -tz)
+
def export_file(fc):
d = fc.data()
print "M %s inline %s" % (gitmode(fc.flags()), fc.path())
@@ -174,6 +220,10 @@ def rev_to_mark(rev):
global marks
return marks.from_rev(rev)
+def mark_to_rev(mark):
+ global marks
+ return marks.to_rev(mark)
+
def export_ref(repo, name, kind, head):
global prefix, marks
@@ -263,9 +313,17 @@ def do_capabilities(parser):
global prefix, dirname
print "import"
+ print "export"
print "refspec refs/heads/branches/*:%s/branches/*" % prefix
print "refspec refs/heads/*:%s/bookmarks/*" % prefix
print "refspec refs/tags/*:%s/tags/*" % 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 get_branch_tip(repo, branch):
@@ -352,8 +410,161 @@ def do_import(parser):
print 'done'
+def parse_blob(parser):
+ global blob_marks
+
+ parser.next()
+ mark = parser.get_mark()
+ parser.next()
+ data = parser.get_data()
+ blob_marks[mark] = data
+ parser.next()
+ return
+
+def parse_commit(parser):
+ global marks, blob_marks, bmarks, parsed_refs
+
+ from_mark = merge_mark = None
+
+ ref = parser[1]
+ parser.next()
+
+ commit_mark = parser.get_mark()
+ parser.next()
+ author = parser.get_author()
+ parser.next()
+ committer = parser.get_author()
+ parser.next()
+ data = parser.get_data()
+ parser.next()
+ if parser.check('from'):
+ from_mark = parser.get_mark()
+ parser.next()
+ if parser.check('merge'):
+ merge_mark = parser.get_mark()
+ parser.next()
+ if parser.check('merge'):
+ die('octopus merges are not supported yet')
+
+ files = {}
+
+ for line in parser:
+ if parser.check('M'):
+ t, m, mark_ref, path = line.split(' ')
+ mark = int(mark_ref[1:])
+ f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] }
+ elif parser.check('D'):
+ t, path = line.split(' ')
+ f = { 'deleted' : True }
+ else:
+ die('Unknown file command: %s' % line)
+ files[path] = f
+
+ def getfilectx(repo, memctx, f):
+ of = files[f]
+ if 'deleted' in of:
+ raise IOError
+ is_exec = of['mode'] == 'x'
+ is_link = of['mode'] == 'l'
+ return context.memfilectx(f, of['data'], is_link, is_exec, None)
+
+ repo = parser.repo
+
+ user, date, tz = author
+ extra = {}
+
+ if committer != author:
+ extra['committer'] = "%s %u %u" % committer
+
+ if from_mark:
+ p1 = repo.changelog.node(mark_to_rev(from_mark))
+ else:
+ p1 = '\0' * 20
+
+ if merge_mark:
+ p2 = repo.changelog.node(mark_to_rev(merge_mark))
+ else:
+ p2 = '\0' * 20
+
+ ctx = context.memctx(repo, (p1, p2), data,
+ files.keys(), getfilectx,
+ user, (date, tz), extra)
+
+ node = repo.commitctx(ctx)
+
+ rev = repo[node].rev()
+
+ parsed_refs[ref] = node
+
+ marks.new_mark(rev, commit_mark)
+
+def parse_reset(parser):
+ ref = parser[1]
+ parser.next()
+ # ugh
+ if parser.check('commit'):
+ parse_commit(parser)
+ return
+ if not parser.check('from'):
+ return
+ from_mark = parser.get_mark()
+ parser.next()
+
+ node = parser.repo.changelog.node(mark_to_rev(from_mark))
+ parsed_refs[ref] = node
+
+def parse_tag(parser):
+ name = parser[1]
+ parser.next()
+ from_mark = parser.get_mark()
+ parser.next()
+ tagger = parser.get_author()
+ parser.next()
+ data = parser.get_data()
+ parser.next()
+
+ # nothing to do
+
+def do_export(parser):
+ global parsed_refs, bmarks
+
+ parser.next()
+
+ for line in parser.each_block('done'):
+ if parser.check('blob'):
+ parse_blob(parser)
+ elif parser.check('commit'):
+ parse_commit(parser)
+ elif parser.check('reset'):
+ parse_reset(parser)
+ elif parser.check('tag'):
+ parse_tag(parser)
+ elif parser.check('feature'):
+ pass
+ else:
+ die('unhandled export command: %s' % line)
+
+ for ref, node in parsed_refs.iteritems():
+ if ref.startswith('refs/heads/branches'):
+ pass
+ elif ref.startswith('refs/heads/'):
+ bmark = ref[len('refs/heads/'):]
+ if bmark in bmarks:
+ old = bmarks[bmark].hex()
+ else:
+ old = ''
+ if not bookmarks.pushbookmark(parser.repo, bmark, old, node):
+ continue
+ elif ref.startswith('refs/tags/'):
+ tag = ref[len('refs/tags/'):]
+ parser.repo.tag([tag], node, None, True, None, {})
+ print "ok %s" % ref
+
+ print
+
def main(args):
- global prefix, dirname, marks, branches, bmarks
+ global prefix, dirname, branches, bmarks
+ global marks, blob_marks, parsed_refs
alias = args[1]
url = args[2]
@@ -362,6 +573,8 @@ def main(args):
dirname = os.path.join(gitdir, 'hg', alias)
branches = {}
bmarks = {}
+ blob_marks = {}
+ parsed_refs = {}
repo = get_repo(url, alias)
prefix = 'refs/hg/%s' % alias
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 03/16] remote-hg: add support for remote pushing
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 01/16] Add new remote-hg transport helper Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 02/16] remote-hg: add support for pushing Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 04/16] remote-hg: add support to push URLs Felipe Contreras
` (12 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index fcceede..45629e0 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -197,7 +197,7 @@ def fixup_user(user):
return '%s <%s>' % (name, mail)
def get_repo(url, alias):
- global dirname
+ global dirname, peer
myui = ui.ui()
myui.setconfig('ui', 'interactive', 'off')
@@ -526,7 +526,7 @@ def parse_tag(parser):
# nothing to do
def do_export(parser):
- global parsed_refs, bmarks
+ global parsed_refs, bmarks, peer
parser.next()
@@ -562,12 +562,17 @@ def do_export(parser):
print
+ if peer:
+ parser.repo.push(peer, force=False)
+
def main(args):
global prefix, dirname, branches, bmarks
global marks, blob_marks, parsed_refs
+ global peer
alias = args[1]
url = args[2]
+ peer = None
gitdir = os.environ['GIT_DIR']
dirname = os.path.join(gitdir, 'hg', alias)
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 04/16] remote-hg: add support to push URLs
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (2 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 03/16] remote-hg: add support for remote pushing Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 05/16] remote-hg: make sure the encoding is correct Felipe Contreras
` (11 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 45629e0..a5023c9 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -9,12 +9,13 @@
# Then you can clone with:
# git clone hg::/path/to/mercurial/repo/
-from mercurial import hg, ui, bookmarks, context
+from mercurial import hg, ui, bookmarks, context, util
import re
import sys
import os
import json
+import shutil
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
@@ -574,6 +575,12 @@ def main(args):
url = args[2]
peer = None
+ if alias[4:] == url:
+ is_tmp = True
+ alias = util.sha1(alias).hexdigest()
+ else:
+ is_tmp = False
+
gitdir = os.environ['GIT_DIR']
dirname = os.path.join(gitdir, 'hg', alias)
branches = {}
@@ -604,6 +611,9 @@ def main(args):
die('unhandled command: %s' % line)
sys.stdout.flush()
- marks.store()
+ if not is_tmp:
+ marks.store()
+ else:
+ shutil.rmtree(dirname)
sys.exit(main(sys.argv))
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 05/16] remote-hg: make sure the encoding is correct
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (3 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 04/16] remote-hg: add support to push URLs Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 06/16] remote-hg: match hg merge behavior Felipe Contreras
` (10 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Independently of the environment.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index a5023c9..503a9fc 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -9,7 +9,7 @@
# Then you can clone with:
# git clone hg::/path/to/mercurial/repo/
-from mercurial import hg, ui, bookmarks, context, util
+from mercurial import hg, ui, bookmarks, context, util, encoding
import re
import sys
@@ -391,6 +391,9 @@ def do_import(parser):
print "feature export-marks=%s" % path
sys.stdout.flush()
+ tmp = encoding.encoding
+ encoding.encoding = 'utf-8'
+
# lets get all the import lines
while parser.check('import'):
ref = parser[1]
@@ -409,6 +412,8 @@ def do_import(parser):
parser.next()
+ encoding.encoding = tmp
+
print 'done'
def parse_blob(parser):
@@ -491,8 +496,13 @@ def parse_commit(parser):
files.keys(), getfilectx,
user, (date, tz), extra)
+ tmp = encoding.encoding
+ encoding.encoding = 'utf-8'
+
node = repo.commitctx(ctx)
+ encoding.encoding = tmp
+
rev = repo[node].rev()
parsed_refs[ref] = node
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 06/16] remote-hg: match hg merge behavior
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (4 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 05/16] remote-hg: make sure the encoding is correct Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 07/16] remote-hg: add support for hg-git compat mode Felipe Contreras
` (9 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 503a9fc..247b7cb 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -427,6 +427,14 @@ def parse_blob(parser):
parser.next()
return
+def get_merge_files(repo, p1, p2, files):
+ for e in repo[p1].files():
+ if e not in files:
+ if e not in repo[p1].manifest():
+ continue
+ f = { 'ctx' : repo[p1][e] }
+ files[e] = f
+
def parse_commit(parser):
global marks, blob_marks, bmarks, parsed_refs
@@ -470,6 +478,8 @@ def parse_commit(parser):
of = files[f]
if 'deleted' in of:
raise IOError
+ if 'ctx' in of:
+ return of['ctx']
is_exec = of['mode'] == 'x'
is_link = of['mode'] == 'l'
return context.memfilectx(f, of['data'], is_link, is_exec, None)
@@ -492,6 +502,13 @@ def parse_commit(parser):
else:
p2 = '\0' * 20
+ #
+ # If files changed from any of the parents, hg wants to know, but in git if
+ # nothing changed from the first parent, nothing changed.
+ #
+ if merge_mark:
+ get_merge_files(repo, p1, p2, files)
+
ctx = context.memctx(repo, (p1, p2), data,
files.keys(), getfilectx,
user, (date, tz), extra)
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 07/16] remote-hg: add support for hg-git compat mode
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (5 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 06/16] remote-hg: match hg merge behavior Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-28 20:23 ` W. Trevor King
2012-11-04 2:13 ` [PATCH v6 08/16] remote-hg: add compat for hg-git author fixes Felipe Contreras
` (8 subsequent siblings)
15 siblings, 1 reply; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 89 +++++++++++++++++++++++++++++++++---
1 file changed, 83 insertions(+), 6 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 247b7cb..d585756 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -16,6 +16,22 @@ import sys
import os
import json
import shutil
+import subprocess
+
+#
+# If you want to switch to hg-git compatibility mode:
+# git config --global remote-hg.hg-git-compat true
+#
+# git:
+# Sensible defaults for git.
+# hg bookmarks are exported as git branches, hg branches are prefixed
+# with 'branches/'.
+#
+# hg:
+# Emulate hg-git.
+# Only hg bookmarks are exported as git branches.
+# Commits are modified to preserve hg information and allow biridectionality.
+#
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
@@ -226,7 +242,7 @@ def mark_to_rev(mark):
return marks.to_rev(mark)
def export_ref(repo, name, kind, head):
- global prefix, marks
+ global prefix, marks, mode
ename = '%s/%s' % (kind, name)
tip = marks.get_tip(ename)
@@ -261,6 +277,33 @@ def export_ref(repo, name, kind, head):
else:
modified, removed = get_filechanges(repo, c, parents[0])
+ if mode == 'hg':
+ extra_msg = ''
+
+ if rev_branch != 'default':
+ extra_msg += 'branch : %s\n' % rev_branch
+
+ renames = []
+ for f in c.files():
+ if f not in c.manifest():
+ continue
+ rename = c.filectx(f).renamed()
+ if rename:
+ renames.append((rename[0], f))
+
+ for e in renames:
+ extra_msg += "rename : %s => %s\n" % e
+
+ for key, value in extra.iteritems():
+ if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'):
+ continue
+ else:
+ extra_msg += "extra : %s : %s\n" % (key, urllib.quote(value))
+
+ desc += '\n'
+ if extra_msg:
+ desc += '\n--HG--\n' + extra_msg
+
if len(parents) == 0 and rev:
print 'reset %s/%s' % (prefix, ename)
@@ -354,7 +397,7 @@ def list_head(repo, cur):
g_head = (head, node)
def do_list(parser):
- global branches, bmarks
+ global branches, bmarks, mode
repo = parser.repo
for branch in repo.branchmap():
@@ -368,8 +411,11 @@ def do_list(parser):
cur = repo.dirstate.branch()
list_head(repo, cur)
- for branch in branches:
- print "? refs/heads/branches/%s" % branch
+
+ if mode != 'hg':
+ for branch in branches:
+ print "? refs/heads/branches/%s" % branch
+
for bmark in bmarks:
print "? refs/heads/%s" % bmark
@@ -437,6 +483,7 @@ def get_merge_files(repo, p1, p2, files):
def parse_commit(parser):
global marks, blob_marks, bmarks, parsed_refs
+ global mode
from_mark = merge_mark = None
@@ -482,7 +529,9 @@ def parse_commit(parser):
return of['ctx']
is_exec = of['mode'] == 'x'
is_link = of['mode'] == 'l'
- return context.memfilectx(f, of['data'], is_link, is_exec, None)
+ rename = of.get('rename', None)
+ return context.memfilectx(f, of['data'],
+ is_link, is_exec, rename)
repo = parser.repo
@@ -509,6 +558,21 @@ def parse_commit(parser):
if merge_mark:
get_merge_files(repo, p1, p2, files)
+ if mode == 'hg':
+ i = data.find('\n--HG--\n')
+ if i >= 0:
+ tmp = data[i + len('\n--HG--\n'):].strip()
+ for k, v in [e.split(' : ') for e in tmp.split('\n')]:
+ if k == 'rename':
+ old, new = v.split(' => ', 1)
+ files[new]['rename'] = old
+ elif k == 'branch':
+ extra[k] = v
+ elif k == 'extra':
+ ek, ev = v.split(' : ', 1)
+ extra[ek] = urllib.unquote(ev)
+ data = data[:i]
+
ctx = context.memctx(repo, (p1, p2), data,
files.keys(), getfilectx,
user, (date, tz), extra)
@@ -596,12 +660,25 @@ def do_export(parser):
def main(args):
global prefix, dirname, branches, bmarks
global marks, blob_marks, parsed_refs
- global peer
+ global peer, mode
alias = args[1]
url = args[2]
peer = None
+ cmd = ['git', 'config', '--get', 'remote-hg.hg-git-compat']
+ hg_git_compat = False
+ try:
+ if subprocess.check_output(cmd) == 'true\n':
+ hg_git_compat = True
+ except subprocess.CalledProcessError:
+ pass
+
+ if hg_git_compat:
+ mode = 'hg'
+ else:
+ mode = 'git'
+
if alias[4:] == url:
is_tmp = True
alias = util.sha1(alias).hexdigest()
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 08/16] remote-hg: add compat for hg-git author fixes
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (6 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 07/16] remote-hg: add support for hg-git compat mode Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 09/16] remote-hg: fake bookmark when there's none Felipe Contreras
` (7 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 59 ++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 6 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index d585756..9db4b7e 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -17,6 +17,7 @@ import os
import json
import shutil
import subprocess
+import urllib
#
# If you want to switch to hg-git compatibility mode:
@@ -35,6 +36,7 @@ import subprocess
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
+AUTHOR_HG_RE = re.compile('^(.*?) ?<(.+?)(?:>(.+)?)?$')
RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.+)> (\d+) ([+-]\d+)')
def die(msg, *args):
@@ -152,12 +154,20 @@ class Parser:
return sys.stdin.read(size)
def get_author(self):
+ global bad_mail
+
+ ex = None
m = RAW_AUTHOR_RE.match(self.line)
if not m:
return None
_, name, email, date, tz = m.groups()
+ if name and 'ext:' in name:
+ m = re.match('^(.+?) ext:\((.+)\)$', name)
+ if m:
+ name = m.group(1)
+ ex = urllib.unquote(m.group(2))
- if email != 'unknown':
+ if email != bad_mail:
if name:
user = '%s <%s>' % (name, email)
else:
@@ -165,6 +175,9 @@ class Parser:
else:
user = name
+ if ex:
+ user += ex
+
tz = int(tz)
tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
return (user, int(date), -tz)
@@ -194,9 +207,9 @@ def get_filechanges(repo, ctx, parent):
return added | modified, removed
-def fixup_user(user):
- user = user.replace('"', '')
+def fixup_user_git(user):
name = mail = None
+ user = user.replace('"', '')
m = AUTHOR_RE.match(user)
if m:
name = m.group(1)
@@ -205,11 +218,41 @@ def fixup_user(user):
m = NAME_RE.match(user)
if m:
name = m.group(1).strip()
+ return (name, mail)
+
+def fixup_user_hg(user):
+ def sanitize(name):
+ # stole this from hg-git
+ return re.sub('[<>\n]', '?', name.lstrip('< ').rstrip('> '))
+
+ m = AUTHOR_HG_RE.match(user)
+ if m:
+ name = sanitize(m.group(1))
+ mail = sanitize(m.group(2))
+ ex = m.group(3)
+ if ex:
+ name += ' ext:(' + urllib.quote(ex) + ')'
+ else:
+ name = sanitize(user)
+ if '@' in user:
+ mail = name
+ else:
+ mail = None
+
+ return (name, mail)
+
+def fixup_user(user):
+ global mode, bad_mail
+
+ if mode == 'git':
+ name, mail = fixup_user_git(user)
+ else:
+ name, mail = fixup_user_hg(user)
if not name:
- name = 'Unknown'
+ name = bad_name
if not mail:
- mail = 'unknown'
+ mail = bad_mail
return '%s <%s>' % (name, mail)
@@ -660,7 +703,7 @@ def do_export(parser):
def main(args):
global prefix, dirname, branches, bmarks
global marks, blob_marks, parsed_refs
- global peer, mode
+ global peer, mode, bad_mail, bad_name
alias = args[1]
url = args[2]
@@ -676,8 +719,12 @@ def main(args):
if hg_git_compat:
mode = 'hg'
+ bad_mail = 'none@none'
+ bad_name = ''
else:
mode = 'git'
+ bad_mail = 'unknown'
+ bad_name = 'Unknown'
if alias[4:] == url:
is_tmp = True
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 09/16] remote-hg: fake bookmark when there's none
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (7 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 08/16] remote-hg: add compat for hg-git author fixes Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 10/16] remote-hg: add basic tests Felipe Contreras
` (6 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Or at least no current bookmark.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 9db4b7e..dbe309a 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -26,7 +26,7 @@ import urllib
# git:
# Sensible defaults for git.
# hg bookmarks are exported as git branches, hg branches are prefixed
-# with 'branches/'.
+# with 'branches/', HEAD is a special case.
#
# hg:
# Emulate hg-git.
@@ -430,12 +430,21 @@ def get_branch_tip(repo, branch):
return heads[0]
def list_head(repo, cur):
- global g_head
+ global g_head, bmarks
head = bookmarks.readcurrent(repo)
- if not head:
- return
- node = repo[head]
+ if head:
+ node = repo[head]
+ else:
+ # fake bookmark from current branch
+ head = cur
+ node = repo['.']
+ if not node:
+ return
+ if head == 'default':
+ head = 'master'
+ bmarks[head] = node
+
print "@refs/heads/%s HEAD" % head
g_head = (head, node)
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 10/16] remote-hg: add basic tests
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (8 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 09/16] remote-hg: fake bookmark when there's none Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 11/16] test-lib: avoid full path to store test results Felipe Contreras
` (5 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/Makefile | 13 +++++
contrib/remote-helpers/test-hg.sh | 112 ++++++++++++++++++++++++++++++++++++++
2 files changed, 125 insertions(+)
create mode 100644 contrib/remote-helpers/Makefile
create mode 100755 contrib/remote-helpers/test-hg.sh
diff --git a/contrib/remote-helpers/Makefile b/contrib/remote-helpers/Makefile
new file mode 100644
index 0000000..9a76575
--- /dev/null
+++ b/contrib/remote-helpers/Makefile
@@ -0,0 +1,13 @@
+TESTS := $(wildcard test*.sh)
+
+export T := $(addprefix $(CURDIR)/,$(TESTS))
+export MAKE := $(MAKE) -e
+export PATH := $(CURDIR):$(PATH)
+
+test:
+ $(MAKE) -C ../../t $@
+
+$(TESTS):
+ $(MAKE) -C ../../t $(CURDIR)/$@
+
+.PHONY: $(TESTS)
diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh
new file mode 100755
index 0000000..40e6e3c
--- /dev/null
+++ b/contrib/remote-helpers/test-hg.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+# Base commands from hg-git tests:
+# https://bitbucket.org/durin42/hg-git/src
+#
+
+test_description='Test remote-hg'
+
+. ./test-lib.sh
+
+if ! test_have_prereq PYTHON; then
+ skip_all='skipping remote-hg tests; python not available'
+ test_done
+fi
+
+if ! "$PYTHON_PATH" -c 'import mercurial'; then
+ skip_all='skipping remote-hg tests; mercurial 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
+}
+
+test_expect_success 'cloning' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ hg init hgrepo &&
+ cd hgrepo &&
+ echo zero > content &&
+ hg add content &&
+ hg commit -m zero
+ ) &&
+
+ git clone "hg::$PWD/hgrepo" gitrepo &&
+ check gitrepo zero master
+'
+
+test_expect_success 'cloning with branches' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ cd hgrepo &&
+ hg branch next &&
+ echo next > content &&
+ hg commit -m next
+ ) &&
+
+ git clone "hg::$PWD/hgrepo" gitrepo &&
+ check gitrepo next next &&
+
+ (cd hgrepo && hg checkout default) &&
+
+ git clone "hg::$PWD/hgrepo" gitrepo2 &&
+ check gitrepo2 zero master
+'
+
+test_expect_success 'cloning with bookmarks' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ cd hgrepo &&
+ hg bookmark feature-a &&
+ echo feature-a > content &&
+ hg commit -m feature-a
+ ) &&
+
+ git clone "hg::$PWD/hgrepo" gitrepo &&
+ check gitrepo feature-a feature-a
+'
+
+test_expect_success 'cloning with detached head' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ cd hgrepo &&
+ hg update -r 0
+ ) &&
+
+ git clone "hg::$PWD/hgrepo" gitrepo &&
+ check gitrepo zero master
+'
+
+test_expect_success 'update bookmark' '
+ test_when_finished "rm -rf gitrepo*" &&
+
+ (
+ cd hgrepo &&
+ hg bookmark devel
+ ) &&
+
+ (
+ git clone "hg::$PWD/hgrepo" gitrepo &&
+ cd gitrepo &&
+ git checkout devel &&
+ echo devel > content &&
+ git commit -a -m devel &&
+ git push
+ ) &&
+
+ hg -R hgrepo bookmarks | grep "devel\s\+3:"
+'
+
+test_done
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 11/16] test-lib: avoid full path to store test results
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (9 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 10/16] remote-hg: add basic tests Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 12/16] remote-hg: add bidirectional tests Felipe Contreras
` (4 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
No reason to use the full path in case this is used externally.
Otherwise we might get errors such as:
./test-lib.sh: line 394: /home/bob/dev/git/t/test-results//home/bob/dev/git/contrib/remote-hg/test-2894.counts: No such file or directory
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
t/test-lib.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 514282c..5a3d665 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -389,7 +389,8 @@ test_done () {
then
test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
- test_results_path="$test_results_dir/${0%.sh}-$$.counts"
+ base=${0##*/}
+ test_results_path="$test_results_dir/${base%.sh}-$$.counts"
cat >>"$test_results_path" <<-EOF
total $test_count
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 12/16] remote-hg: add bidirectional tests
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (10 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 11/16] test-lib: avoid full path to store test results Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 13/16] remote-hg: add tests to compare with hg-git Felipe Contreras
` (3 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Base commands from hg-git tests:
https://bitbucket.org/durin42/hg-git/src
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/test-hg-bidi.sh | 243 +++++++++++++++++++++++++++++++++
1 file changed, 243 insertions(+)
create mode 100755 contrib/remote-helpers/test-hg-bidi.sh
diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
new file mode 100755
index 0000000..a94eb28
--- /dev/null
+++ b/contrib/remote-helpers/test-hg-bidi.sh
@@ -0,0 +1,243 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+# Base commands from hg-git tests:
+# https://bitbucket.org/durin42/hg-git/src
+#
+
+test_description='Test biridectionality of remote-hg'
+
+. ./test-lib.sh
+
+if ! test_have_prereq PYTHON; then
+ skip_all='skipping remote-hg tests; python not available'
+ test_done
+fi
+
+if ! "$PYTHON_PATH" -c 'import mercurial'; then
+ skip_all='skipping remote-hg tests; mercurial not available'
+ test_done
+fi
+
+# clone to a git repo
+git_clone () {
+ hg -R $1 bookmark -f -r tip master &&
+ git clone -q "hg::$PWD/$1" $2
+}
+
+# clone to an hg repo
+hg_clone () {
+ (
+ hg init $2 &&
+ cd $1 &&
+ git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
+ ) &&
+
+ (cd $2 && hg -q update)
+}
+
+# push an hg repo
+hg_push () {
+ (
+ cd $2
+ old=$(git symbolic-ref --short HEAD)
+ git checkout -q -b tmp &&
+ git fetch -q "hg::$PWD/../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
+ git checkout -q $old &&
+ git branch -q -D tmp 2> /dev/null || true
+ )
+}
+
+hg_log () {
+ hg -R $1 log --graph --debug | grep -v 'tag: *default/'
+}
+
+setup () {
+ (
+ echo "[ui]"
+ echo "username = A U Thor <author@example.com>"
+ echo "[defaults]"
+ echo "backout = -d \"0 0\""
+ echo "commit = -d \"0 0\""
+ echo "debugrawcommit = -d \"0 0\""
+ echo "tag = -d \"0 0\""
+ ) >> "$HOME"/.hgrc &&
+ git config --global remote-hg.hg-git-compat true
+
+ export HGEDITOR=/usr/bin/true
+
+ export GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
+ export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+}
+
+setup
+
+test_expect_success 'encoding' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add älphà" &&
+
+ export GIT_AUTHOR_NAME="tést èncödîng" &&
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta" &&
+
+ echo gamma > gamma &&
+ git add gamma &&
+ git commit -m "add gämmâ" &&
+
+ : TODO git config i18n.commitencoding latin-1 &&
+ echo delta > delta &&
+ git add delta &&
+ git commit -m "add déltà"
+ ) &&
+
+ hg_clone gitrepo hgrepo &&
+ git_clone hgrepo gitrepo2 &&
+ hg_clone gitrepo2 hgrepo2 &&
+
+ HGENCODING=utf-8 hg_log hgrepo > expected &&
+ HGENCODING=utf-8 hg_log hgrepo2 > actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'file removal' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta"
+ mkdir foo &&
+ echo blah > foo/bar &&
+ git add foo &&
+ git commit -m "add foo" &&
+ git rm alpha &&
+ git commit -m "remove alpha" &&
+ git rm foo/bar &&
+ git commit -m "remove foo/bar"
+ ) &&
+
+ hg_clone gitrepo hgrepo &&
+ git_clone hgrepo gitrepo2 &&
+ hg_clone gitrepo2 hgrepo2 &&
+
+ hg_log hgrepo > expected &&
+ hg_log hgrepo2 > actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'git tags' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+ git config receive.denyCurrentBranch ignore &&
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ git tag alpha &&
+
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta" &&
+ git tag -a -m "added tag beta" beta
+ ) &&
+
+ hg_clone gitrepo hgrepo &&
+ git_clone hgrepo gitrepo2 &&
+ hg_clone gitrepo2 hgrepo2 &&
+
+ hg_log hgrepo > expected &&
+ hg_log hgrepo2 > actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'hg branch' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -q -m "add alpha" &&
+ git checkout -q -b not-master
+ ) &&
+
+ (
+ hg_clone gitrepo hgrepo &&
+
+ cd hgrepo &&
+ hg -q co master &&
+ hg mv alpha beta &&
+ hg -q commit -m "rename alpha to beta" &&
+ hg branch gamma | grep -v "permanent and global" &&
+ hg -q commit -m "started branch gamma"
+ ) &&
+
+ hg_push hgrepo gitrepo &&
+ hg_clone gitrepo hgrepo2 &&
+
+ : TODO, avoid "master" bookmark &&
+ (cd hgrepo2 && hg checkout gamma) &&
+
+ hg_log hgrepo > expected &&
+ hg_log hgrepo2 > actual &&
+
+ test_cmp expected actual
+'
+
+test_expect_success 'hg tags' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ git checkout -q -b not-master
+ ) &&
+
+ (
+ hg_clone gitrepo hgrepo &&
+
+ cd hgrepo &&
+ hg co master &&
+ hg tag alpha
+ ) &&
+
+ hg_push hgrepo gitrepo &&
+ hg_clone gitrepo hgrepo2 &&
+
+ hg_log hgrepo > expected &&
+ hg_log hgrepo2 > actual &&
+
+ test_cmp expected actual
+'
+
+test_done
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 13/16] remote-hg: add tests to compare with hg-git
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (11 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 12/16] remote-hg: add bidirectional tests Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 14/16] remote-hg: add extra author test Felipe Contreras
` (2 subsequent siblings)
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
The base commands come from the tests of the hg-git project.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/test-hg-hg-git.sh | 462 +++++++++++++++++++++++++++++++
1 file changed, 462 insertions(+)
create mode 100755 contrib/remote-helpers/test-hg-hg-git.sh
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh
new file mode 100755
index 0000000..e07bba5
--- /dev/null
+++ b/contrib/remote-helpers/test-hg-hg-git.sh
@@ -0,0 +1,462 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Felipe Contreras
+#
+# Base commands from hg-git tests:
+# https://bitbucket.org/durin42/hg-git/src
+#
+
+test_description='Test remote-hg output compared to hg-git'
+
+. ./test-lib.sh
+
+if ! test_have_prereq PYTHON; then
+ skip_all='skipping remote-hg tests; python not available'
+ test_done
+fi
+
+if ! "$PYTHON_PATH" -c 'import mercurial'; then
+ skip_all='skipping remote-hg tests; mercurial not available'
+ test_done
+fi
+
+if ! "$PYTHON_PATH" -c 'import hggit'; then
+ skip_all='skipping remote-hg tests; hg-git not available'
+ test_done
+fi
+
+# clone to a git repo with git
+git_clone_git () {
+ hg -R $1 bookmark -f -r tip master &&
+ git clone -q "hg::$PWD/$1" $2
+}
+
+# clone to an hg repo with git
+hg_clone_git () {
+ (
+ hg init $2 &&
+ cd $1 &&
+ git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
+ ) &&
+
+ (cd $2 && hg -q update)
+}
+
+# clone to a git repo with hg
+git_clone_hg () {
+ (
+ git init -q $2 &&
+ cd $1 &&
+ hg bookmark -f -r tip master &&
+ hg -q push -r master ../$2 || true
+ )
+}
+
+# clone to an hg repo with hg
+hg_clone_hg () {
+ hg -q clone $1 $2
+}
+
+# push an hg repo with git
+hg_push_git () {
+ (
+ cd $2
+ old=$(git symbolic-ref --short HEAD)
+ git checkout -q -b tmp &&
+ git fetch -q "hg::$PWD/../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
+ git checkout -q $old &&
+ git branch -q -D tmp 2> /dev/null || true
+ )
+}
+
+# push an hg git repo with hg
+hg_push_hg () {
+ (
+ cd $1 &&
+ hg -q push ../$2 || true
+ )
+}
+
+hg_log () {
+ hg -R $1 log --graph --debug | grep -v 'tag: *default/'
+}
+
+git_log () {
+ git --git-dir=$1/.git fast-export --branches
+}
+
+setup () {
+ (
+ echo "[ui]"
+ echo "username = A U Thor <author@example.com>"
+ echo "[defaults]"
+ echo "backout = -d \"0 0\""
+ echo "commit = -d \"0 0\""
+ echo "debugrawcommit = -d \"0 0\""
+ echo "tag = -d \"0 0\""
+ echo "[extensions]"
+ echo "hgext.bookmarks ="
+ echo "hggit ="
+ ) >> "$HOME"/.hgrc &&
+ git config --global receive.denycurrentbranch warn
+ git config --global remote-hg.hg-git-compat true
+
+ export HGEDITOR=/usr/bin/true
+
+ export GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
+ export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+}
+
+setup
+
+test_expect_success 'merge conflict 1' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ hg init hgrepo1 &&
+ cd hgrepo1 &&
+ echo A > afile &&
+ hg add afile &&
+ hg ci -m "origin" &&
+
+ echo B > afile &&
+ hg ci -m "A->B" &&
+
+ hg up -r0 &&
+ echo C > afile &&
+ hg ci -m "A->C" &&
+
+ hg merge -r1 || true &&
+ echo C > afile &&
+ hg resolve -m afile &&
+ hg ci -m "merge to C"
+ ) &&
+
+ for x in hg git; do
+ git_clone_$x hgrepo1 gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+ hg_log hgrepo2-$x > hg-log-$x &&
+ git_log gitrepo-$x > git-log-$x
+ done &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'merge conflict 2' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ hg init hgrepo1 &&
+ cd hgrepo1 &&
+ echo A > afile &&
+ hg add afile &&
+ hg ci -m "origin" &&
+
+ echo B > afile &&
+ hg ci -m "A->B" &&
+
+ hg up -r0 &&
+ echo C > afile &&
+ hg ci -m "A->C" &&
+
+ hg merge -r1 || true &&
+ echo B > afile &&
+ hg resolve -m afile &&
+ hg ci -m "merge to B"
+ ) &&
+
+ for x in hg git; do
+ git_clone_$x hgrepo1 gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+ hg_log hgrepo2-$x > hg-log-$x &&
+ git_log gitrepo-$x > git-log-$x
+ done &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'converged merge' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ hg init hgrepo1 &&
+ cd hgrepo1 &&
+ echo A > afile &&
+ hg add afile &&
+ hg ci -m "origin" &&
+
+ echo B > afile &&
+ hg ci -m "A->B" &&
+
+ echo C > afile &&
+ hg ci -m "B->C" &&
+
+ hg up -r0 &&
+ echo C > afile &&
+ hg ci -m "A->C" &&
+
+ hg merge -r2 || true &&
+ hg ci -m "merge"
+ ) &&
+
+ for x in hg git; do
+ git_clone_$x hgrepo1 gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+ hg_log hgrepo2-$x > hg-log-$x &&
+ git_log gitrepo-$x > git-log-$x
+ done &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'encoding' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add älphà" &&
+
+ export GIT_AUTHOR_NAME="tést èncödîng" &&
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta" &&
+
+ echo gamma > gamma &&
+ git add gamma &&
+ git commit -m "add gämmâ" &&
+
+ : TODO git config i18n.commitencoding latin-1 &&
+ echo delta > delta &&
+ git add delta &&
+ git commit -m "add déltà"
+ ) &&
+
+ for x in hg git; do
+ hg_clone_$x gitrepo hgrepo-$x &&
+ git_clone_$x hgrepo-$x gitrepo2-$x &&
+
+ HGENCODING=utf-8 hg_log hgrepo-$x > hg-log-$x &&
+ git_log gitrepo2-$x > git-log-$x
+ done &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'file removal' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta"
+ mkdir foo &&
+ echo blah > foo/bar &&
+ git add foo &&
+ git commit -m "add foo" &&
+ git rm alpha &&
+ git commit -m "remove alpha" &&
+ git rm foo/bar &&
+ git commit -m "remove foo/bar"
+ ) &&
+
+ for x in hg git; do
+ (
+ hg_clone_$x gitrepo hgrepo-$x &&
+ cd hgrepo-$x &&
+ hg_log . &&
+ hg manifest -r 3 &&
+ hg manifest
+ ) > output-$x &&
+
+ git_clone_$x hgrepo-$x gitrepo2-$x &&
+ git_log gitrepo2-$x > log-$x
+ done &&
+
+ test_cmp output-hg output-git &&
+ test_cmp log-hg log-git
+'
+
+test_expect_success 'git tags' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ (
+ git init -q gitrepo &&
+ cd gitrepo &&
+ git config receive.denyCurrentBranch ignore &&
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ git tag alpha &&
+
+ echo beta > beta &&
+ git add beta &&
+ git commit -m "add beta" &&
+ git tag -a -m "added tag beta" beta
+ ) &&
+
+ for x in hg git; do
+ hg_clone_$x gitrepo hgrepo-$x &&
+ hg_log hgrepo-$x > log-$x
+ done &&
+
+ test_cmp log-hg log-git
+'
+
+test_expect_success 'hg author' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ for x in hg git; do
+ (
+ git init -q gitrepo-$x &&
+ cd gitrepo-$x &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ git checkout -q -b not-master
+ ) &&
+
+ (
+ hg_clone_$x gitrepo-$x hgrepo-$x &&
+ cd hgrepo-$x &&
+
+ hg co master &&
+ echo beta > beta &&
+ hg add beta &&
+ hg commit -u "test" -m "add beta" &&
+
+ echo gamma >> beta &&
+ hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
+
+ echo gamma > gamma &&
+ hg add gamma &&
+ hg commit -u "<test@example.com>" -m "add gamma" &&
+
+ echo delta > delta &&
+ hg add delta &&
+ hg commit -u "name<test@example.com>" -m "add delta" &&
+
+ echo epsilon > epsilon &&
+ hg add epsilon &&
+ hg commit -u "name <test@example.com" -m "add epsilon" &&
+
+ echo zeta > zeta &&
+ hg add zeta &&
+ hg commit -u " test " -m "add zeta" &&
+
+ echo eta > eta &&
+ hg add eta &&
+ hg commit -u "test < test@example.com >" -m "add eta" &&
+
+ echo theta > theta &&
+ hg add theta &&
+ hg commit -u "test >test@example.com>" -m "add theta"
+ ) &&
+
+ hg_push_$x hgrepo-$x gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+
+ hg_log hgrepo2-$x > hg-log-$x &&
+ git_log gitrepo-$x > git-log-$x
+ done &&
+
+ test_cmp git-log-hg git-log-git &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'hg branch' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ for x in hg git; do
+ (
+ git init -q gitrepo-$x &&
+ cd gitrepo-$x &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -q -m "add alpha" &&
+ git checkout -q -b not-master
+ ) &&
+
+ (
+ hg_clone_$x gitrepo-$x hgrepo-$x &&
+
+ cd hgrepo-$x &&
+ hg -q co master &&
+ hg mv alpha beta &&
+ hg -q commit -m "rename alpha to beta" &&
+ hg branch gamma | grep -v "permanent and global" &&
+ hg -q commit -m "started branch gamma"
+ ) &&
+
+ hg_push_$x hgrepo-$x gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+
+ hg_log hgrepo2-$x > hg-log-$x &&
+ git_log gitrepo-$x > git-log-$x
+ done &&
+
+ test_cmp hg-log-hg hg-log-git &&
+ test_cmp git-log-hg git-log-git
+'
+
+test_expect_success 'hg tags' '
+ mkdir -p tmp && cd tmp &&
+ test_when_finished "cd .. && rm -rf tmp" &&
+
+ for x in hg git; do
+ (
+ git init -q gitrepo-$x &&
+ cd gitrepo-$x &&
+
+ echo alpha > alpha &&
+ git add alpha &&
+ git commit -m "add alpha" &&
+ git checkout -q -b not-master
+ ) &&
+
+ (
+ hg_clone_$x gitrepo-$x hgrepo-$x &&
+
+ cd hgrepo-$x &&
+ hg co master &&
+ hg tag alpha
+ ) &&
+
+ hg_push_$x hgrepo-$x gitrepo-$x &&
+ hg_clone_$x gitrepo-$x hgrepo2-$x &&
+
+ (
+ git --git-dir=gitrepo-$x/.git tag -l &&
+ hg_log hgrepo2-$x &&
+ cat hgrepo2-$x/.hgtags
+ ) > output-$x
+ done &&
+
+ test_cmp output-hg output-git
+'
+
+test_done
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 14/16] remote-hg: add extra author test
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (12 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 13/16] remote-hg: add tests to compare with hg-git Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 15/16] remote-hg: add option to not track branches Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 16/16] remote-hg: the author email can be null Felipe Contreras
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
For hg.hg.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/test-hg-hg-git.sh | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh
index e07bba5..3e76d9f 100755
--- a/contrib/remote-helpers/test-hg-hg-git.sh
+++ b/contrib/remote-helpers/test-hg-hg-git.sh
@@ -370,7 +370,11 @@ test_expect_success 'hg author' '
echo theta > theta &&
hg add theta &&
- hg commit -u "test >test@example.com>" -m "add theta"
+ hg commit -u "test >test@example.com>" -m "add theta" &&
+
+ echo iota > iota &&
+ hg add iota &&
+ hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
hg_push_$x hgrepo-$x gitrepo-$x &&
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 15/16] remote-hg: add option to not track branches
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (13 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 14/16] remote-hg: add extra author test Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 16/16] remote-hg: the author email can be null Felipe Contreras
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Some people prefer it this way.
% git config --global remote-hg.track-branches false
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index dbe309a..a9ae844 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -449,14 +449,9 @@ def list_head(repo, cur):
g_head = (head, node)
def do_list(parser):
- global branches, bmarks, mode
+ global branches, bmarks, mode, track_branches
repo = parser.repo
- for branch in repo.branchmap():
- heads = repo.branchheads(branch)
- if len(heads):
- branches[branch] = heads
-
for bmark, node in bookmarks.listbookmarks(repo).iteritems():
bmarks[bmark] = repo[node]
@@ -464,7 +459,12 @@ def do_list(parser):
list_head(repo, cur)
- if mode != 'hg':
+ if track_branches:
+ for branch in repo.branchmap():
+ heads = repo.branchheads(branch)
+ if len(heads):
+ branches[branch] = heads
+
for branch in branches:
print "? refs/heads/branches/%s" % branch
@@ -713,16 +713,22 @@ def main(args):
global prefix, dirname, branches, bmarks
global marks, blob_marks, parsed_refs
global peer, mode, bad_mail, bad_name
+ global track_branches
alias = args[1]
url = args[2]
peer = None
- cmd = ['git', 'config', '--get', 'remote-hg.hg-git-compat']
hg_git_compat = False
+ track_branches = True
try:
+ cmd = ['git', 'config', '--get', 'remote-hg.hg-git-compat']
if subprocess.check_output(cmd) == 'true\n':
hg_git_compat = True
+ track_branches = False
+ cmd = ['git', 'config', '--get', 'remote-hg.track-branches']
+ if subprocess.check_output(cmd) == 'false\n':
+ track_branches = False
except subprocess.CalledProcessError:
pass
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v6 16/16] remote-hg: the author email can be null
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
` (14 preceding siblings ...)
2012-11-04 2:13 ` [PATCH v6 15/16] remote-hg: add option to not track branches Felipe Contreras
@ 2012-11-04 2:13 ` Felipe Contreras
15 siblings, 0 replies; 22+ messages in thread
From: Felipe Contreras @ 2012-11-04 2:13 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Jeff King, Sverre Rabbelier, Johannes Schindelin,
Ilari Liusvaara, Daniel Barkalow, Michael J Gruber,
Felipe Contreras
Like 'Foo <>'.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
contrib/remote-helpers/git-remote-hg | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index a9ae844..7929eec 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -35,9 +35,9 @@ import urllib
#
NAME_RE = re.compile('^([^<>]+)')
-AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]+)>$')
-AUTHOR_HG_RE = re.compile('^(.*?) ?<(.+?)(?:>(.+)?)?$')
-RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.+)> (\d+) ([+-]\d+)')
+AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
+AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
+RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
def die(msg, *args):
sys.stderr.write('ERROR: %s\n' % (msg % args))
--
1.8.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v6 07/16] remote-hg: add support for hg-git compat mode
2012-11-04 2:13 ` [PATCH v6 07/16] remote-hg: add support for hg-git compat mode Felipe Contreras
@ 2012-11-28 20:23 ` W. Trevor King
2013-01-08 15:47 ` [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos W. Trevor King
0 siblings, 1 reply; 22+ messages in thread
From: W. Trevor King @ 2012-11-28 20:23 UTC (permalink / raw)
To: Felipe Contreras
Cc: git, Junio C Hamano, Jeff King, Sverre Rabbelier,
Johannes Schindelin, Ilari Liusvaara, Daniel Barkalow,
Michael J Gruber
I'm not sure if this is the most recent patch iteration for this
feature, but I just saw this typo in `pu`.
On Sun, Nov 04, 2012 at 03:13:29AM +0100, Felipe Contreras wrote:
> +# Commits are modified to preserve hg information and allow biridectionality.
^^^^^^^^
s/biridectionality/bidirectionality/
Cheers,
Trevor
--
This email may be signed or encrypted with GnuPG (http://www.gnupg.org).
For more information, see http://en.wikipedia.org/wiki/Pretty_Good_Privacy
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos
2012-11-28 20:23 ` W. Trevor King
@ 2013-01-08 15:47 ` W. Trevor King
2013-01-08 17:32 ` Junio C Hamano
0 siblings, 1 reply; 22+ messages in thread
From: W. Trevor King @ 2013-01-08 15:47 UTC (permalink / raw)
To: Felipe Contreras
Cc: git, Junio C Hamano, Jeff King, Sverre Rabbelier,
Johannes Schindelin, Ilari Liusvaara, Daniel Barkalow,
Michael J Gruber
[-- Attachment #1: Type: text/plain, Size: 1850 bytes --]
Signed-off-by: W. Trevor King <wking@tremily.us>
---
I was looking for one of my older messages to the Git list, and I
found this, which seems to have fallen through the cracks:
On Wed, Nov 28, 2012 at 03:23:20PM -0500, W. Trevor King wrote:
> I'm not sure if this is the most recent patch iteration for this
> feature, but I just saw this typo in `pu`.
>
> On Sun, Nov 04, 2012 at 03:13:29AM +0100, Felipe Contreras wrote:
> > +# Commits are modified to preserve hg information and allow biridectionality.
> ^^^^^^^^
> s/biridectionality/bidirectionality/
This fixes that instance (which has since landed in master) and
another similar typo.
contrib/remote-helpers/git-remote-hg | 2 +-
contrib/remote-helpers/test-hg-bidi.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index 016cdad..c700600 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -31,7 +31,7 @@ import urllib
# hg:
# Emulate hg-git.
# Only hg bookmarks are exported as git branches.
-# Commits are modified to preserve hg information and allow biridectionality.
+# Commits are modified to preserve hg information and allow bidirectionality.
#
NAME_RE = re.compile('^([^<>]+)')
diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
index a94eb28..1d61982 100755
--- a/contrib/remote-helpers/test-hg-bidi.sh
+++ b/contrib/remote-helpers/test-hg-bidi.sh
@@ -6,7 +6,7 @@
# https://bitbucket.org/durin42/hg-git/src
#
-test_description='Test biridectionality of remote-hg'
+test_description='Test bidirectionality of remote-hg'
. ./test-lib.sh
--
1.8.1.151.g32238ae
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos
2013-01-08 15:47 ` [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos W. Trevor King
@ 2013-01-08 17:32 ` Junio C Hamano
2013-01-08 17:50 ` W. Trevor King
0 siblings, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2013-01-08 17:32 UTC (permalink / raw)
To: W. Trevor King
Cc: Felipe Contreras, git, Jeff King, Sverre Rabbelier,
Johannes Schindelin, Ilari Liusvaara, Daniel Barkalow,
Michael J Gruber
"W. Trevor King" <wking@tremily.us> writes:
> Signed-off-by: W. Trevor King <wking@tremily.us>
> ---
>
> I was looking for one of my older messages to the Git list, and I
> found this, which seems to have fallen through the cracks:
Thanks; didn't Documentation/SubmittingPatches ask you not to do PGP
multipart but send patches in plain text?
> On Wed, Nov 28, 2012 at 03:23:20PM -0500, W. Trevor King wrote:
>> I'm not sure if this is the most recent patch iteration for this
>> feature, but I just saw this typo in `pu`.
>>
>> On Sun, Nov 04, 2012 at 03:13:29AM +0100, Felipe Contreras wrote:
>> > +# Commits are modified to preserve hg information and allow biridectionality.
>> ^^^^^^^^
>> s/biridectionality/bidirectionality/
>
> This fixes that instance (which has since landed in master) and
> another similar typo.
>
> contrib/remote-helpers/git-remote-hg | 2 +-
> contrib/remote-helpers/test-hg-bidi.sh | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
> index 016cdad..c700600 100755
> --- a/contrib/remote-helpers/git-remote-hg
> +++ b/contrib/remote-helpers/git-remote-hg
> @@ -31,7 +31,7 @@ import urllib
> # hg:
> # Emulate hg-git.
> # Only hg bookmarks are exported as git branches.
> -# Commits are modified to preserve hg information and allow biridectionality.
> +# Commits are modified to preserve hg information and allow bidirectionality.
> #
>
> NAME_RE = re.compile('^([^<>]+)')
> diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh
> index a94eb28..1d61982 100755
> --- a/contrib/remote-helpers/test-hg-bidi.sh
> +++ b/contrib/remote-helpers/test-hg-bidi.sh
> @@ -6,7 +6,7 @@
> # https://bitbucket.org/durin42/hg-git/src
> #
>
> -test_description='Test biridectionality of remote-hg'
> +test_description='Test bidirectionality of remote-hg'
>
> . ./test-lib.sh
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos
2013-01-08 17:32 ` Junio C Hamano
@ 2013-01-08 17:50 ` W. Trevor King
2013-01-08 18:10 ` Junio C Hamano
0 siblings, 1 reply; 22+ messages in thread
From: W. Trevor King @ 2013-01-08 17:50 UTC (permalink / raw)
To: Junio C Hamano
Cc: Felipe Contreras, git, Jeff King, Sverre Rabbelier,
Johannes Schindelin, Ilari Liusvaara, Daniel Barkalow,
Michael J Gruber
[-- Attachment #1: Type: text/plain, Size: 253 bytes --]
On Tue, Jan 08, 2013 at 09:32:07AM -0800, Junio C Hamano wrote:
> Thanks; didn't Documentation/SubmittingPatches ask you not to do PGP
> multipart but send patches in plain text?
Gah. I need to tell myself to reread that every time I send a patch
:p.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos
2013-01-08 17:50 ` W. Trevor King
@ 2013-01-08 18:10 ` Junio C Hamano
0 siblings, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2013-01-08 18:10 UTC (permalink / raw)
To: W. Trevor King
Cc: Felipe Contreras, git, Jeff King, Sverre Rabbelier,
Johannes Schindelin, Ilari Liusvaara, Daniel Barkalow,
Michael J Gruber
"W. Trevor King" <wking@tremily.us> writes:
> On Tue, Jan 08, 2013 at 09:32:07AM -0800, Junio C Hamano wrote:
>> Thanks; didn't Documentation/SubmittingPatches ask you not to do PGP
>> multipart but send patches in plain text?
>
> Gah. I need to tell myself to reread that every time I send a patch
> :p.
No need to worry; thanks for a patch---applied to 'maint'.
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2013-01-08 18:10 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-04 2:13 [PATCH v6 00/16] New remote-hg helper:w Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 01/16] Add new remote-hg transport helper Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 02/16] remote-hg: add support for pushing Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 03/16] remote-hg: add support for remote pushing Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 04/16] remote-hg: add support to push URLs Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 05/16] remote-hg: make sure the encoding is correct Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 06/16] remote-hg: match hg merge behavior Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 07/16] remote-hg: add support for hg-git compat mode Felipe Contreras
2012-11-28 20:23 ` W. Trevor King
2013-01-08 15:47 ` [PATCH] remote-hg: Fix biridectionality -> bidirectionality typos W. Trevor King
2013-01-08 17:32 ` Junio C Hamano
2013-01-08 17:50 ` W. Trevor King
2013-01-08 18:10 ` Junio C Hamano
2012-11-04 2:13 ` [PATCH v6 08/16] remote-hg: add compat for hg-git author fixes Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 09/16] remote-hg: fake bookmark when there's none Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 10/16] remote-hg: add basic tests Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 11/16] test-lib: avoid full path to store test results Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 12/16] remote-hg: add bidirectional tests Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 13/16] remote-hg: add tests to compare with hg-git Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 14/16] remote-hg: add extra author test Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 15/16] remote-hg: add option to not track branches Felipe Contreras
2012-11-04 2:13 ` [PATCH v6 16/16] remote-hg: the author email can be null Felipe Contreras
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.