threads / patch / 31960

v4, 13 partsremote-hg: add support for pushing

Subject: [PATCH v4 03/13] remote-hg: add support for pushing

## tl;dr

75 messages between Oct 28, 2012 and Nov 5, 2012. Diffs are folded; open one to read it.

replies: 74people: 12as markdown or json

Felipe Contreras· Oct 28, 2012, 03:54 UTC · lore

[PATCH v4 00/13] New remote-hg helper

Hi,

I've ported the tests from hg-git and made sure that the output from remote-hg matches the output of hg-git. With these extensive tests I would consider this one ready for wide use. Not only do the tests pass, I've compared the generated repos of a few projects, and the SHA-1's are exactly the same :)

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
 * Active development
 * Has compatibility with hg-git
 * The required patches are available
 * No changes necesary to git core

One important alternative is the one written by Sverre Rabbelier that is now maintained and distributed in msysgit. It's hard to evaluate this option as there isn't a branch specific to this remote helper so it would be possible to evaluate the necessary patches.

Changes since v3:
 * New extensive tests
 * Add compatibility mode with hg-git
 * Added support for boomkars
 * Add mercurial information to the git msg (branch, renames, extra, etc.)
 * Properly handle HEAD
 * Fix author/committer information
 * Implement 'done' feature for error handling
 * Restore hg user properly
 * Set file correct modes
 * Match hg merge behavior
 * Prefix hg branches
 * Encoding fixes
 * Stricter parser
 * Support for 'reset' command
 * Fix support for URL pushing (unaliased)
Changes since v2:
 * Added support for pushing
 * Tests copied from original remote-hg
 * Custom default -> master renames removed
 * Code reorganized
Changes since v1:
 * Improved documentation
 * Use more common 'python' binary
 * Warn, don't barf when a branch has multiple heads
 * Fixed marks to fetch after cloned
 * Support for cloning/pulling remote repositories
 * Use a more appropriate internal directory (e.g. .git/hg/origin)
 * Fixes for python3
Felipe Contreras (13):
  Add new remote-hg transport helper
  remote-hg: add support for bookmarks
  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 support for fake remote
  remote-hg: add tests to compare with hg-git
  remote-hg: add extra author test
 contrib/remote-hg/git-remote-hg | 770 ++++++++++++++++++++++++++++++++++++++++
 t/t5802-remote-hg-hg-git.sh     | 449 +++++++++++++++++++++++
 2 files changed, 1219 insertions(+)
 create mode 100755 contrib/remote-hg/git-remote-hg
 create mode 100755 t/t5802-remote-hg-hg-git.sh
-- 
1.8.0
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 01/13] Add new remote-hg transport helper

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 356 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 356 insertions(+)
 create mode 100755 contrib/remote-hg/git-remote-hg
Show changes to contrib/remote-hg/git-remote-hg +356 −0
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
new file mode 100755
index 0000000..c771182
--- /dev/null
+++ b/contrib/remote-hg/git-remote-hg
@@ -0,0 +1,356 @@
+#!/usr/bin/python
+
+# 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
+
+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 next_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, parents):
+    l = [repo.status(p, ctx)[:3] for p in parents]
+    changed, added, removed = [set(sum(e, [])) for e in zip(*l)]
+    return added | changed, 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)
+
+        if len(parents) == 0 and rev:
+            print 'reset %s/%s' % (prefix, ename)
+
+        print "commit %s/%s" % (prefix, ename)
+        print "mark :%d" % (marks.next_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 removed:
+            print "D %s" % (f)
+        for f in modified:
+            export_file(c.filectx(f))
+        print
+
+        count += 1
+        if (count % 100 == 0):
+            print "progress revision %d '%s' (%d/%d)" % (rev, ename, 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_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], g_head[1], g_head[2])
+
+def do_capabilities(parser):
+    global prefix, dirname
+
+    print "import"
+    print "refspec refs/heads/branches/*:%s/branches/*" % 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)
+        return repo.branchtip(branch)
+
+    return heads[0]
+
+def list_branch_head(repo, cur):
+    global g_head
+
+    tip = get_branch_tip(repo, cur)
+    head = 'branches/' + cur
+    print "@refs/heads/%s HEAD" % head
+    g_head = (head, 'branches', repo[tip])
+
+def do_list(parser):
+    global branches
+
+    repo = parser.repo
+    for branch in repo.branchmap():
+        heads = repo.branchheads(branch)
+        if len(heads):
+            branches[branch] = heads
+
+    cur = repo.dirstate.branch()
+
+    list_branch_head(repo, cur)
+    for branch in branches:
+        print "? refs/heads/branches/%s" % branch
+
+    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/tags/'):
+            tag = ref[len('refs/tags/'):]
+            export_tag(repo, tag)
+
+        parser.next()
+
+    print 'done'
+
+def main(args):
+    global prefix, dirname, marks, branches
+
+    alias = args[1]
+    url = args[2]
+
+    gitdir = os.environ['GIT_DIR']
+    dirname = os.path.join(gitdir, 'hg', alias)
+    branches = {}
+
+    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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 02/13] remote-hg: add support for bookmarks

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +17 −3
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index c771182..4ba9ee6 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -6,7 +6,7 @@
 # Then you can clone with:
 # git clone hg::/path/to/mercurial/repo/
 
-from mercurial import hg, ui
+from mercurial import hg, ui, bookmarks
 
 import re
 import sys
@@ -229,6 +229,10 @@ def export_ref(repo, name, kind, head):
 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]
@@ -243,6 +247,7 @@ def do_capabilities(parser):
 
     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
 
@@ -269,7 +274,7 @@ def list_branch_head(repo, cur):
     g_head = (head, 'branches', repo[tip])
 
 def do_list(parser):
-    global branches
+    global branches, bmarks
 
     repo = parser.repo
     for branch in repo.branchmap():
@@ -277,11 +282,16 @@ def do_list(parser):
         if len(heads):
             branches[branch] = heads
 
+    for bmark, node in bookmarks.listbookmarks(repo).iteritems():
+        bmarks[bmark] = repo[node]
+
     cur = repo.dirstate.branch()
 
     list_branch_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':
@@ -310,6 +320,9 @@ def do_import(parser):
         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)
@@ -319,7 +332,7 @@ def do_import(parser):
     print 'done'
 
 def main(args):
-    global prefix, dirname, marks, branches
+    global prefix, dirname, marks, branches, bmarks
 
     alias = args[1]
     url = args[2]
@@ -327,6 +340,7 @@ def main(args):
     gitdir = os.environ['GIT_DIR']
     dirname = os.path.join(gitdir, 'hg', alias)
     branches = {}
+    bmarks = {}
 
     repo = get_repo(url, alias)
     prefix = 'refs/hg/%s' % alias
-- 
1.8.0
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 215 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 213 insertions(+), 2 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +213 −2
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 4ba9ee6..4021a7d 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -6,7 +6,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
@@ -15,6 +15,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))
@@ -29,12 +30,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()
@@ -49,6 +55,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 }
 
@@ -61,11 +70,19 @@ class Marks:
     def from_rev(self, rev):
         return self.marks[str(rev)]
 
+    def to_rev(self, mark):
+        return self.rev_marks[mark]
+
     def next_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))
 
@@ -103,6 +120,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())
@@ -157,6 +203,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
 
@@ -246,9 +296,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):
@@ -331,8 +389,159 @@ 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
+
+    a = parser.line.split(' ')
+    ref = a[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):
+    a = parser.line.split(' ')
+    ref = a[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):
+    a = parser.line.split(' ')
+    name = a[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
+
+    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/'):]
+            bookmarks.pushbookmark(parser.repo, bmark, '', node)
+        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]
@@ -341,6 +550,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 04/13] remote-hg: add support for remote pushing

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +7 −2
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 4021a7d..b10e7d1 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -180,7 +180,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')
@@ -508,7 +508,7 @@ def parse_tag(parser):
     # nothing to do
 
 def do_export(parser):
-    global parsed_refs
+    global parsed_refs, peer
 
     parser.next()
 
@@ -539,12 +539,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 05/13] remote-hg: add support to push URLs

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +12 −2
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index b10e7d1..c96e1a8 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -6,12 +6,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('^([^<>]+?)? ?<([^<>]+)>$')
@@ -551,6 +552,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 = {}
@@ -581,6 +588,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 06/13] remote-hg: make sure the encoding is correct

Independently of the environment.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
Show changes to contrib/remote-hg/git-remote-hg +11 −1
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index c96e1a8..1689573 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -6,7 +6,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
@@ -370,6 +370,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]
@@ -388,6 +391,8 @@ def do_import(parser):
 
         parser.next()
 
+    encoding.encoding = tmp
+
     print 'done'
 
 def parse_blob(parser):
@@ -471,8 +476,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 07/13] remote-hg: match hg merge behavior

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
Show changes to contrib/remote-hg/git-remote-hg +15 −0
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 1689573..57e54c2 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -406,6 +406,12 @@ 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:
+            f = { 'ctx' : repo[p1][e] }
+            files[e] = f
+
 def parse_commit(parser):
     global marks, blob_marks, bmarks, parsed_refs
 
@@ -450,6 +456,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)
@@ -472,6 +480,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 08/13] remote-hg: add support for hg-git compat mode

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 102 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 95 insertions(+), 7 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +95 −7
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 57e54c2..47bb7c1 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -13,6 +13,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('^([^<>]+?)? ?<([^<>]+)>$')
@@ -209,7 +225,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)
@@ -244,6 +260,33 @@ def export_ref(repo, name, kind, head):
         else:
             modified, removed = get_filechanges(repo, c, parents)
 
+        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)
 
@@ -332,8 +375,18 @@ def list_branch_head(repo, cur):
     print "@refs/heads/%s HEAD" % head
     g_head = (head, 'branches', repo[tip])
 
+def list_bookmark_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, 'bookmarks', node)
+
 def do_list(parser):
-    global branches, bmarks
+    global branches, bmarks, mode
 
     repo = parser.repo
     for branch in repo.branchmap():
@@ -346,9 +399,13 @@ def do_list(parser):
 
     cur = repo.dirstate.branch()
 
-    list_branch_head(repo, cur)
-    for branch in branches:
-        print "? refs/heads/branches/%s" % branch
+    if mode != 'hg':
+        list_branch_head(repo, cur)
+        for branch in branches:
+            print "? refs/heads/branches/%s" % branch
+    else:
+        list_bookmark_head(repo, cur)
+
     for bmark in bmarks:
         print "? refs/heads/%s" % bmark
 
@@ -414,6 +471,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
 
@@ -460,7 +518,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
 
@@ -487,6 +547,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)
@@ -571,12 +646,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 09/13] remote-hg: add compat for hg-git author fixes

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 59 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 53 insertions(+), 6 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +53 −6
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 47bb7c1..3bb3192 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -14,6 +14,7 @@ import os
 import json
 import shutil
 import subprocess
+import urllib
 
 #
 # If you want to switch to hg-git compatibility mode:
@@ -32,6 +33,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):
@@ -149,12 +151,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:
@@ -162,6 +172,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)
@@ -177,9 +190,9 @@ def get_filechanges(repo, ctx, parents):
     changed, added, removed = [set(sum(e, [])) for e in zip(*l)]
     return added | changed, 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)
@@ -188,11 +201,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)
 
@@ -646,7 +689,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]
@@ -662,8 +705,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
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 10/13] remote-hg: fake bookmark when there's none

Or at least no current bookmark.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
Show changes to contrib/remote-hg/git-remote-hg +12 −4
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index 3bb3192..e8e3791 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -419,12 +419,20 @@ def list_branch_head(repo, cur):
     g_head = (head, 'branches', repo[tip])
 
 def list_bookmark_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
+        tip = get_branch_tip(repo, head)
+        if not tip:
+            return
+        node = repo[tip]
+        bmarks[head] = node
+
     print "@refs/heads/%s HEAD" % head
     g_head = (head, 'bookmarks', node)
 
-- 
1.8.0
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 11/13] remote-hg: add support for fake remote

Helpful while testing.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/remote-hg/git-remote-hg | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
Show changes to contrib/remote-hg/git-remote-hg +7 −1
diff --git a/contrib/remote-hg/git-remote-hg b/contrib/remote-hg/git-remote-hg
index e8e3791..092020f 100755
--- a/contrib/remote-hg/git-remote-hg
+++ b/contrib/remote-hg/git-remote-hg
@@ -245,7 +245,13 @@ def get_repo(url, alias):
     myui = ui.ui()
     myui.setconfig('ui', 'interactive', 'off')
 
-    if hg.islocal(url):
+    if url.startswith("remote://"):
+        remote = True
+        url = "file://%s" % url[9:]
+    else:
+        remote = False
+
+    if hg.islocal(url) and not remote:
         repo = hg.repository(myui, url)
     else:
         local_path = os.path.join(dirname, 'clone')
-- 
1.8.0
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 12/13] remote-hg: add tests to compare with hg-git

The base commands come from the tests of the hg-git project.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 t/t5802-remote-hg-hg-git.sh | 445 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 445 insertions(+)
 create mode 100755 t/t5802-remote-hg-hg-git.sh
Show changes to t/t5802-remote-hg-hg-git.sh +445 −0
diff --git a/t/t5802-remote-hg-hg-git.sh b/t/t5802-remote-hg-hg-git.sh
new file mode 100755
index 0000000..3cfa9e6
--- /dev/null
+++ b/t/t5802-remote-hg-hg-git.sh
@@ -0,0 +1,445 @@
+#!/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
+
+# 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
+}
+
+test_expect_success '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"
+'
+
+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-hg/.git tag -l &&
+		hg_log hgrepo2-hg &&
+		cat hgrepo2-hg/.hgtags
+		) > output-$x
+	done &&
+
+	test_cmp output-hg output-git
+'
+
+test_done
-- 
1.8.0
Felipe Contreras· Oct 28, 2012, 03:54 UTC · re: Felipe Contreras · lore

[PATCH v4 13/13] remote-hg: add extra author test

For hg.hg.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 t/t5802-remote-hg-hg-git.sh | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
Show changes to t/t5802-remote-hg-hg-git.sh +5 −1
diff --git a/t/t5802-remote-hg-hg-git.sh b/t/t5802-remote-hg-hg-git.sh
index 3cfa9e6..1f9f85c 100755
--- a/t/t5802-remote-hg-hg-git.sh
+++ b/t/t5802-remote-hg-hg-git.sh
@@ -353,7 +353,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
Jeff King· Oct 29, 2012, 08:50 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Sun, Oct 28, 2012 at 04:54:00AM +0100, Felipe Contreras wrote:
> I've ported the tests from hg-git and made sure that the output from remote-hg
> matches the output of hg-git. With these extensive tests I would consider this
> one ready for wide use. Not only do the tests pass, I've compared the generated
> repos of a few projects, and the SHA-1's are exactly the same :)

Sounds cool. Unfortunately, the test script hangs for me, after starting up xxdiff (!).

pstree reveals that it is "hg" that starts it, but I didn't investigate beyond that.

-Peff
Felipe Contreras· Oct 29, 2012, 14:56 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 9:50 AM, Jeff King <peff@peff.net> wrote:
Show 12 quoted lines
> On Sun, Oct 28, 2012 at 04:54:00AM +0100, Felipe Contreras wrote:
>
>> I've ported the tests from hg-git and made sure that the output from remote-hg
>> matches the output of hg-git. With these extensive tests I would consider this
>> one ready for wide use. Not only do the tests pass, I've compared the generated
>> repos of a few projects, and the SHA-1's are exactly the same :)
>
> Sounds cool. Unfortunately, the test script hangs for me, after starting
> up xxdiff (!).
>
> pstree reveals that it is "hg" that starts it, but I didn't investigate
> beyond that.

Yeah, the test script is not ready for merging, it needs to check for python, hg, and hg-git.

Do you have hg-git installed?

These tests compare the output of hg-git with remote-hg. It would be nice to have tests that don't require hg-git, but I think what is there is more than worthy of getting merged to contrib. In fact, I'm thinking it's ready to be out of contrib and installed by default (once the hg-git tests have proper checks), but I haven't heard much feedback.

Cheers.
-- 
Felipe Contreras
Jeff King· Oct 29, 2012, 21:26 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 03:56:39PM +0100, Felipe Contreras wrote:
Show 15 quoted lines
> >> I've ported the tests from hg-git and made sure that the output from remote-hg
> >> matches the output of hg-git. With these extensive tests I would consider this
> >> one ready for wide use. Not only do the tests pass, I've compared the generated
> >> repos of a few projects, and the SHA-1's are exactly the same :)
> >
> > Sounds cool. Unfortunately, the test script hangs for me, after starting
> > up xxdiff (!).
> >
> > pstree reveals that it is "hg" that starts it, but I didn't investigate
> > beyond that.
> 
> Yeah, the test script is not ready for merging, it needs to check for
> python, hg, and hg-git.
> 
> Do you have hg-git installed?

No. But it's important that it fail gracefully; I can't even take it in pu if I can't run the test suite in a sane way.

I may try to figure it out later myself, but it's not a super high priority for me.

-Peff
Felipe Contreras· Oct 29, 2012, 21:47 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 10:26 PM, Jeff King <peff@peff.net> wrote:
Show 20 quoted lines
> On Mon, Oct 29, 2012 at 03:56:39PM +0100, Felipe Contreras wrote:
>
>> >> I've ported the tests from hg-git and made sure that the output from remote-hg
>> >> matches the output of hg-git. With these extensive tests I would consider this
>> >> one ready for wide use. Not only do the tests pass, I've compared the generated
>> >> repos of a few projects, and the SHA-1's are exactly the same :)
>> >
>> > Sounds cool. Unfortunately, the test script hangs for me, after starting
>> > up xxdiff (!).
>> >
>> > pstree reveals that it is "hg" that starts it, but I didn't investigate
>> > beyond that.
>>
>> Yeah, the test script is not ready for merging, it needs to check for
>> python, hg, and hg-git.
>>
>> Do you have hg-git installed?
>
> No. But it's important that it fail gracefully; I can't even take it in
> pu if I can't run the test suite in a sane way.

The contrib part is fine for 'pu'. The tests aren't even meant to exercise stuff in 'contrib', right? There might be some exceptions, but either way, there's plenty of stuff in 'contrib' without any tests. The tests I'm providing are simply a little sugar.

-- 
Felipe Contreras
Jeff King· Oct 29, 2012, 21:56 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 10:47:04PM +0100, Felipe Contreras wrote:
Show 12 quoted lines
> >> Yeah, the test script is not ready for merging, it needs to check for
> >> python, hg, and hg-git.
> >>
> >> Do you have hg-git installed?
> >
> > No. But it's important that it fail gracefully; I can't even take it in
> > pu if I can't run the test suite in a sane way.
> 
> The contrib part is fine for 'pu'. The tests aren't even meant to
> exercise stuff in 'contrib', right? There might be some exceptions,
> but either way, there's plenty of stuff in 'contrib' without any
> tests. The tests I'm providing are simply a little sugar.

Yeah, contrib is a bit of a wildcard. Most things do not have tests. Completion tests run as part of the main test suite (which to me means that completion should arguably be promoted out of contrib). Subtree carries its own tests that build on the test suite, but do not run all the time.

If remote-hg is going to live in contrib, it probably makes sense to have its tests live there, too, like subtree. It means less test exposure, but the robustness of the tests does not have to be as high. You could also have no tests, but since you have them, it seems silly not to include them. People know that items in contrib/ may not be as mature as the rest of git.

-Peff
Felipe Contreras· Oct 29, 2012, 22:02 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 10:56 PM, Jeff King <peff@peff.net> wrote:
Show 18 quoted lines
> On Mon, Oct 29, 2012 at 10:47:04PM +0100, Felipe Contreras wrote:
>
>> >> Yeah, the test script is not ready for merging, it needs to check for
>> >> python, hg, and hg-git.
>> >>
>> >> Do you have hg-git installed?
>> >
>> > No. But it's important that it fail gracefully; I can't even take it in
>> > pu if I can't run the test suite in a sane way.
>>
>> The contrib part is fine for 'pu'. The tests aren't even meant to
>> exercise stuff in 'contrib', right? There might be some exceptions,
>> but either way, there's plenty of stuff in 'contrib' without any
>> tests. The tests I'm providing are simply a little sugar.
>
> Yeah, contrib is a bit of a wildcard. Most things do not have tests.
> Completion tests run as part of the main test suite (which to me means
> that completion should arguably be promoted out of contrib).

I agree, I didn't think of that when I wrote the completion tests, but now it seems appropriate, specially since there's discussion about moving the prompt out of contrib.

> If remote-hg is going to live in contrib, it probably makes sense to
> have its tests live there, too, like subtree.
Probably, I'll check that option.

But eventually I think it should be installed by default, unless somebody can come up for a reason not to. For now contrib might be OK.

Show 5 quoted lines
> It means less test
> exposure, but the robustness of the tests does not have to be as high.
> You could also have no tests, but since you have them, it seems silly
> not to include them. People know that items in contrib/ may not be as
> mature as the rest of git.
Yeah, it's only a matter of figuring out how to run them.
Cheers.
-- 
Felipe Contreras
Jeff King· Oct 29, 2012, 22:06 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 11:02:31PM +0100, Felipe Contreras wrote:
Show 7 quoted lines
> > If remote-hg is going to live in contrib, it probably makes sense to
> > have its tests live there, too, like subtree.
> 
> Probably, I'll check that option.
> 
> But eventually I think it should be installed by default, unless
> somebody can come up for a reason not to. For now contrib might be OK.

I would one day like to have it as part of the main distribution, too, but it would be nice to prove its worth in the field for a while first. I especially would like to find out how it compares in practice with the work that is in msysgit.

Show 6 quoted lines
> > It means less test exposure, but the robustness of the tests does
> > not have to be as high.  You could also have no tests, but since you
> > have them, it seems silly not to include them. People know that
> > items in contrib/ may not be as mature as the rest of git.
> 
> Yeah, it's only a matter of figuring out how to run them.

Subtree seems to copy substantial parts of t/Makefile, but I suspect you could get away with just using an "include". I'd also be OK with just including a test script that pulls in test-lib.sh, and letting people run it manually (the Makefile infrastructure is really about running a lot of tests, but if there's only one script, it's not so hard).

-Peff
Felipe Contreras· Oct 30, 2012, 17:18 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Oct 29, 2012 at 11:06 PM, Jeff King <peff@peff.net> wrote:
Show 14 quoted lines
> On Mon, Oct 29, 2012 at 11:02:31PM +0100, Felipe Contreras wrote:
>
>> > If remote-hg is going to live in contrib, it probably makes sense to
>> > have its tests live there, too, like subtree.
>>
>> Probably, I'll check that option.
>>
>> But eventually I think it should be installed by default, unless
>> somebody can come up for a reason not to. For now contrib might be OK.
>
> I would one day like to have it as part of the main distribution, too,
> but it would be nice to prove its worth in the field for a while first.
> I especially would like to find out how it compares in practice with the
> work that is in msysgit.

Yeah, I would like to compare it with that work, if only the patches were readily available somewhere.

-- 
Felipe Contreras
Johannes Schindelin· Oct 30, 2012, 17:20 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi all,
On Mon, 29 Oct 2012, Jeff King wrote:
Show 16 quoted lines
> On Mon, Oct 29, 2012 at 10:47:04PM +0100, Felipe Contreras wrote:
> 
> > >> Yeah, the test script is not ready for merging, it needs to check
> > >> for python, hg, and hg-git.
> > >>
> > >> Do you have hg-git installed?
> > >
> > > No. But it's important that it fail gracefully; I can't even take it
> > > in pu if I can't run the test suite in a sane way.
> > 
> > The contrib part is fine for 'pu'. The tests aren't even meant to
> > exercise stuff in 'contrib', right? There might be some exceptions,
> > but either way, there's plenty of stuff in 'contrib' without any
> > tests. The tests I'm providing are simply a little sugar.
> 
> Yeah, contrib is a bit of a wildcard. Most things do not have tests.

Given that the tests of remote-hg as in git://github.com/msysgit/git's 'devel' branch run just fine without additional dependencies (which probably triggered the not-quite-constructive and unnecessarily-flaming "bloated" comment of Felipe), and given that the code in said branch is well-tested and exercised by daily use, and given the fact that my major concern was not understood (and probably not addressed), and also given the fact that Sverre indicated that he could finalize the work as a 20% project, I decided that other projects I have to do unfortunately have a too-high priority to take care of testing and measuring the performance of the patch series that is discussed in this thread.

Sorry, Johannes

P.S.: I would still recommend to have a detailed look at the 'devel' branch, in particular the commits starting with "fast-export: do not refer to non-existing marks" and ending with "t5801: skip without hg". My understanding is that it was completely ignored after a brief and maybe too-cursory look. In the least, it has a couple of lessons we learnt the hard way, and if git.git is dead set on duplicating the work, making these mistakes again could be avoided by learning from our lessons.

Felipe Contreras· Oct 30, 2012, 18:10 UTC · re: Johannes Schindelin · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Tue, Oct 30, 2012 at 6:20 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 7 quoted lines
> P.S.: I would still recommend to have a detailed look at the 'devel'
> branch, in particular the commits starting with "fast-export: do not refer
> to non-existing marks" and ending with "t5801: skip without hg". My
> understanding is that it was completely ignored after a brief and maybe
> too-cursory look. In the least, it has a couple of lessons we learnt the
> hard way, and if git.git is dead set on duplicating the work, making these
> mistakes again could be avoided by learning from our lessons.

% g l --grep="t5801: skip without hg" devel 1e000d4 t5801: skip without hg bee410c t5801: skip without hg 5cdc7d0 t5801: skip without hg 05b703f t5801: skip without hg 6bb8d90 t5801: skip without hg c70b4d0 t5801: skip without hg 2f46371 t5801: skip without hg 39bc40f t5801: skip without hg d0a618b t5801: skip without hg

% g l --grep="fast-export: do not refer" devel d3ac32c fast-export: do not refer to non-existing marks bdbb22f fast-export: do not refer to non-existing marks 5d99930 fast-export: do not refer to non-existing marks 381f276 fast-export: do not refer to non-existing marks b4686c7 fast-export: do not refer to non-existing marks e3dfe01 fast-export: do not refer to non-existing marks c00fe59 fast-export: do not refer to non-existing marks ce357ce fast-export: do not refer to non-existing marks 5c1c7a4 fast-export: do not refer to non-existing marks 9c827d1 fast-export: do not refer to non-existing marks

I'll assume you are referring the latest ones:
% g log --oneline --reverse d3ac32c^..1e000d4
* d3ac32c fast-export: do not refer to non-existing marks
Not needed at all.
* b013fe0 setup_revisions: remember whether a ref was positive or not
* fb89a2c fast-export: do not export negative refs
* 7655869 setup_revisions: remember whether a ref was positive or not
I've fixed this problem already.
The solution proposed in these patches is to convoluted:
1) Requires multiple unrelated changes
2) Proposes change in committish semantics

It's hard to test, because the test to check for this is not in this patch series, and it's testing for something completely unrelated:

--- cat > expected << EOF reset refs/heads/master from $(git rev-parse master)

EOF
test_expect_success 'refs are updated even if no commits need to be exported' '
        git fast-export master..master > actual &&
        test_cmp expected actual
'
---
This is most certainly not what we want.

Notice that in my patch (a single patch) I added the tests at the same time so it's clear what it's fixing, and I also added a test to the relevant remote-helper behavior we want:

https://github.com/felipec/git/commit/76e75315bd1bd8d9d8365bb09261a745a10ceae0
* 512cb13 t5800: test pushing a new branch with old content

If this is what the patches above were trying to fix, then yes, my patch fixes that. Also, it's tainted by changes from another patch.

* a85de2c t5800: point out that deleting branches does not work
Correct, but hardly _necessary_.
* 2412a45 transport-helper: add trailing --

No description what's the problem, or what it's trying to fix, or tests, so it's not possible to know if this is _needed_ or not. But probably correct.

* 026d07c remote-helper: check helper status after import/export
Again, no explanation, but the issue was already addressed:
http://article.gmane.org/gmane.comp.version-control.git/208202
The problem is minuscule, not _needed_.
* 5165e26 remote-testgit: factor out RemoteHelper class
* 049f093 git-remote-testgit: make local a function
* f835bb2 git_remote_helpers: add fastimport library
* 088ad33 git-remote-hg: add hgimport, an hg-fast-import equivalent
* 7de6ca0 git-remote-hg: add GitHg, a helper class for converting hg
commits to git
* e3cc5ed git-remote-hg: add hgexport, an hg-fast-export equivalent
* 0edc8e9 git-remote-hg: add GitExporter/GitImporter/NonLocalGit
* 5c73277 remote-hg: adjust to hg 1.9
* 1b47007 git-remote-hg: add the helper
* 4dcc671 git-remote-hg: add tests
* 48b2769 remote-hg: Postel's law dictates we should handle Author<author@mail>
* 2587cc6 remote-hg: another case of Postel's law
* 9f934c9 remote-hg: handle another funny author line from
http://scelenic.com/hg
* a799904 remote-hg: do not interfer with hg's revs() method
All these are specific to this remote-hg version.
* ac77256 Always auto-gc after calling a fast-import transport
This might be a good idea, but not _needed_.
* 1e000d4 t5801: skip without hg
Specific to this remote-hg.

So, yeah, nothing really needed there. Some patches might be nice, but that's it.

Now, if this is really the latest and greatest remote-hg patch series, I can try to port them to git's master and see how it fares.

But you mentioned something about cooperation, and I've yet to see how is it that you are planning to cooperate. If you say you don't have time to spend on this, I don't see why I should worry about testing this series of patches.

Also, you seem to be clearly against my implementation, is there any evidence that will convince you that my version is "good"? Maybe my version passing more tests than msysgit's? Or is there truly nothing I can do to change your perception?

Cheers.
-- 
Felipe Contreras
Johannes Schindelin· Oct 30, 2012, 19:33 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi Felipe,
On Tue, 30 Oct 2012, Felipe Contreras wrote:
> But you mentioned something about cooperation, and I've yet to see how
> is it that you are planning to cooperate. If you say you don't have time
> to spend on this, I don't see why I should worry about testing this
> series of patches.

It has been mentioned before that the communication style including all these snarky and nasty comments is not helpful. It is hardly the first time that your mails have been insulting, as can be researched easily from in the public mailing list archives.

In light of the indignation when advised to keep the tone down a little, it is probable that the mails were never put through the "would I be insulted or hurt if I was the recipient of this?" test, as in "do you want me to throw away my work?" when you literally asked us to throw away our work.

So unlike others, I do not ask you to change your tone, nor your willingness to work with others. Instead, I prefer to do other things instead.

Hth, Johannes

Felipe Contreras· Oct 30, 2012, 20:15 UTC · re: Johannes Schindelin · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi,

On Tue, Oct 30, 2012 at 8:33 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 9 quoted lines
> On Tue, 30 Oct 2012, Felipe Contreras wrote:
>
>> But you mentioned something about cooperation, and I've yet to see how
>> is it that you are planning to cooperate. If you say you don't have time
>> to spend on this, I don't see why I should worry about testing this
>> series of patches.
>
> It has been mentioned before that the communication style including all
> these snarky and nasty comments is not helpful.
Snarky and nasty comments? How about this?
---
Show 23 quoted lines
> As to the functionality you seek: git-remote-hg found in
> git://github.com/msysgit/git works. It has the following advantages
> over every other solution, including the one proposed in this thread:
>
> - it works
>
> - no really, it works
>
> - it supports pushes, too
>
> - it matured over a long time
>
> - there are tests
>
> - whenever we fixed bugs, we also added tests for the bug fixes
>
> - it is rock solid
>
> - it is in constant use
>
> Without push support, remote-hg is useless to me. Without regression
> tests proving that it is rock solid, I will not use remote-hg. And I
> will not indulge in efforts to duplicate work.
---

How many times does somebody has to say "it works" before it becomes a snarky comment?

Or this?
---
> FTR, the reason that it's crashing is because you're lying. You're
> saying you already have master (by means of ^master), but you don't.
---
Or this?
---
> It seems unlikely to me that this never worked, surely no reviewer
> would accept a patch that doesn't actually implement the feature?
> What's the history here?
---
So what did I say?
> But you mentioned something about cooperation,
That's a fact.

Johannes: ---

> > It would be better to work together, but to me the code-styles are way
> > too different, the difference between night and day.
>
> Aha. Well, okay, it was an offer to collaborate.
---
> and I've yet to see how is it that you are planning to cooperate.

This is also a fact. You haven't provided a branch, you haven't reviewed my implementation, you haven't tried it. You mentioned something about testing the performance, but then retracted from it.

So, if you were planning to collaborate, now it would be a good time to mention how.

> If you say you don't have time to spend on this, I don't see why I
> should worry about testing this series of patches.

I'm just clarifying how I'm planning to spend my time, specifically if you are not going to collaborate.

What is snarky and nasty about any of these comments? I'm simply asking you if you are going to collaborate and how, because I don't see it, and what I'm going to do.

You think that's snarkier than the comments above? Well, I disagree. But I don't blame you when you are snarky, nor do I think I should.

> It is hardly the first time that your mails have been insulting, as
> can be researched easily from in the public mailing list archives.

Those who want to be insulted would get insulted. I asked a simple question "are you going to collaborate?", if you find that offensive, that's your right.

Show 5 quoted lines
> In light of the indignation when advised to keep the tone down a little,
> it is probable that the mails were never put through the "would I be
> insulted or hurt if I was the recipient of this?" test, as in "do you want
> me to throw away my work?" when you literally asked us to throw away our
> work.

How did I ask you to throw away your work? I have asked multiple times now for you to provide a branch so that we can take a look and try it.

I don't know of a better way to throw away code than to refuse to provide it, which is what you have been doing. So, if anybody can be blamed of trying to throw away code, it shouldn't be me.

I know you will find the previous statement offensive, but it happens to be true. It is sad that you will concentrate on the statement, rather than the fact, and instead of providing the branch (which will help to avoid throwing away the code), and thus nullify the statement, you choose to be offended and complain about how offended you are.

Well, I'm offended at how much you refuse to collaborate, and at how much disdain you throw at my code, but I'm not going to complain about me being offended; people get offended about all sorts of things. Why is why there's no law against offending people.

Instead, I choose to do something positive about it and improve my code with your criticism (e.g. lack of tests), even if that criticism is rude and unwarranted. But that seems to mean nothing to you.

> So unlike others, I do not ask you to change your tone, nor your
> willingness to work with others. Instead, I prefer to do other things
> instead.

I guess that answers the question; you are not going to collaborate. Got it.

I will not ask you again for a branch with the remote-hg code.
Cheers.
-- 
Felipe Contreras
Michael J Gruber· Oct 31, 2012, 09:30 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

[quotes heavily cut down by me] Felipe Contreras venit, vidit, dixit 30.10.2012 21:15:

Show 14 quoted lines
> Hi,
> 
> On Tue, Oct 30, 2012 at 8:33 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
>> On Tue, 30 Oct 2012, Felipe Contreras wrote:
>>
>>> But you mentioned something about cooperation, and I've yet to see how
>>> is it that you are planning to cooperate. If you say you don't have time
>>> to spend on this, I don't see why I should worry about testing this
>>> series of patches.
>>
>> It has been mentioned before that the communication style including all
>> these snarky and nasty comments is not helpful.
> 

For the record, Johannes is not the only one being kept from looking at this series (further) by the tone of this discussion. Per hominem attacks are neither professional nor helpful. We prefer to discuss code here, just code. From my comments on an earlier version of your series you can see I've tried. The way other comment threads on this series unfolded made me choose to be a mere by-stander again.

>> and I've yet to see how is it that you are planning to cooperate.
> 
> This is also a fact. You haven't provided a branch, you haven't reviewed
> my implementation, you haven't tried it. You mentioned something about

This does not become true through iteration. Max' recent post 'On git-remote-hg (the "native" one)' [1] points at the msysgit wiki on remote-hg [2] and his remote-hg branch [3], which is based on and points at Sverre's original branch [4] and mine [5] which is [4] being regularly rebased on origin/next. The msysgit devel branch is in heavy use; I don't use mine often but run the test suite on every rebase before pushing out.

If the issues that Sverre and Dscho tried to address with their git.git core (non-helper) patches turn out to be non-issues then I assume everyone will be happy, including them. You and they have thought a lot about these things and the way hg-git sync can work. There seems to be diagreement about the way fast-export/the remote helpers communicate which revs and refs that are to be synced and updated. This is not hg-specific, and I suggest to try and clarify that issue as thoroughly and calmly as possible. Everyone will benefit, and it will make clearer which tests are appropriate, and accordingly which fixes fix real problems.

Orthogonal to this, it seems that all hg-git interfaces could take advantage of a "git heads" feature if we resurrect the old ideas (can't find the thread right now).

Hoping for the best, Michael

[1] http://permalink.gmane.org/gmane.comp.version-control.git/201083 [2] https://github.com/msysgit/msysgit/wiki/Guide-to-git-remote-hg [3] https://github.com/fingolfin/git/tree/remote-hg [4] https://github.com/SRabbelier/git/tree/remote-hg [5] https://github.com/mjg/git/tree/remote-hg

Jeff King· Oct 31, 2012, 10:27 UTC · re: Michael J Gruber · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 10:30:50AM +0100, Michael J Gruber wrote:
Show 6 quoted lines
> For the record, Johannes is not the only one being kept from looking at
> this series (further) by the tone of this discussion. Per hominem
> attacks are neither professional nor helpful. We prefer to discuss code
> here, just code. From my comments on an earlier version of your series
> you can see I've tried. The way other comment threads on this series
> unfolded made me choose to be a mere by-stander again.

Me too. I really like some of the directions the series is taking, and as the maintainer, I'd like to pick it up. But there is a big question mark for me still about how it relates to the work in msysgit, especially:

  - What advantages does this implementation have over the one in
    msysgit (i.e., new features that the other one does not have)?
  - What disadvantages? If this implementation goes into git.git,
    the msysgit one is likely to wane in popularity. What will we be
    losing by doing so? If the answer is not "nothing", how hard would
    it be to port over the missing bits?
  - The msysgit one got held up by fixes needed for fast-export. Why
    aren't those a problem for this implementation? If we are using a
    different strategy that avoids the issue, what are the limitations
    (if any) of that strategy?

I have a feeling that some of those answers are buried deep within the discussion, but I have had a hard time following all of the back and forth due to the volume and tone of the discussion. Are we at a point now where some of the participants can try to summarize the situation?

I am not saying that this implementation must be 100% better than the msysgit one. I do not want perfect to to be the enemy of good and end up with nothing. But at the same time, there really are two competing implementations, one of which has received substantially more field use. Even though the msysgit one is not in git.git, it seems like the path for making it happen exists (even if it has not been followed yet). Before merging an alternative implementation, I would want to know what we are potentially throwing away from the msysgit side, and make sure that we are not following a wrong path that msysgit has already tried and found to be lacking.

-Peff
Felipe Contreras· Oct 31, 2012, 15:58 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 11:27 AM, Jeff King <peff@peff.net> wrote:
Show 16 quoted lines
> On Wed, Oct 31, 2012 at 10:30:50AM +0100, Michael J Gruber wrote:
>
>> For the record, Johannes is not the only one being kept from looking at
>> this series (further) by the tone of this discussion. Per hominem
>> attacks are neither professional nor helpful. We prefer to discuss code
>> here, just code. From my comments on an earlier version of your series
>> you can see I've tried. The way other comment threads on this series
>> unfolded made me choose to be a mere by-stander again.
>
> Me too. I really like some of the directions the series is taking, and
> as the maintainer, I'd like to pick it up. But there is a big question
> mark for me still about how it relates to the work in msysgit,
> especially:
>
>   - What advantages does this implementation have over the one in
>     msysgit (i.e., new features that the other one does not have)?
>From the top of my head:
 * Support for tags
 * Support for bookmarks
 * Support for hg-git compatibility
 * Extensive tests (truly extensive)
 * _Much_ simpler code
 * No dependencies

But let's forget about msysgit, because it's not really clear what series of patches we are talking about. If we want to make a real try, and a real comparison, we need a clear set of patches, which seem to be available only on Max Horn's repo[1].

>   - What disadvantages? If this implementation goes into git.git,
>     the msysgit one is likely to wane in popularity. What will we be
>     losing by doing so? If the answer is not "nothing", how hard would
>     it be to port over the missing bits?
Honestly I am not aware of anything we would loose.
>   - The msysgit one got held up by fixes needed for fast-export. Why
>     aren't those a problem for this implementation? If we are using a
>     different strategy that avoids the issue, what are the limitations
>     (if any) of that strategy?

I explained that already. If indeed I was looking at the right commits, then I already sent patches that tackle, or otherwise deal with the very same problems (albet in much simpler way). These patches should have held the code, as they are not _needed_ but merely improving things. The rest of the patches would barely make any difference.

This is of course my guess by reading the code, I have not tried it.

In short, only this patch helps: http://article.gmane.org/gmane.comp.version-control.git/208729

And the rest of the code should work just fine on top of latest git.git.
> I have a feeling that some of those answers are buried deep within the
> discussion, but I have had a hard time following all of the back and
> forth due to the volume and tone of the discussion. Are we at a point
> now where some of the participants can try to summarize the situation?

Let me try to summarize the situation: Johannes is not willing to collaborate, and nobody else has offered to push forward the patches in msysgit.

Show 10 quoted lines
> I am not saying that this implementation must be 100% better than the
> msysgit one. I do not want perfect to to be the enemy of good and end up
> with nothing. But at the same time, there really are two competing
> implementations, one of which has received substantially more field use.
> Even though the msysgit one is not in git.git, it seems like the path
> for making it happen exists (even if it has not been followed yet).
> Before merging an alternative implementation, I would want to know what
> we are potentially throwing away from the msysgit side, and make sure
> that we are not following a wrong path that msysgit has already tried
> and found to be lacking.

I also would like somebody to compare the two, so that we can have healthy competition, and hopefully also cooperation. But that doesn't seem to be likely.

So, what to do? Should I be the one making an analysis of that code? Since nobody else is willing to try to compare the two, I don't see many other choices, but when/if my conclusion is that my version is superior, I presume nobody would take my word for it, so what would be the point?

Cheers.
[1] http://github.com/fingolfin/git/tree/remote-hg

-- Felipe Contreras

Johannes Schindelin· Oct 31, 2012, 18:20 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi Peff,
On Wed, 31 Oct 2012, Jeff King wrote:
> I really like some of the directions the series is taking, and as the
> maintainer, I'd like to pick it up.
Code-wise, I agree.
Show 5 quoted lines
> But there is a big question mark for me still about how it relates to
> the work in msysgit, especially:
> 
>   - What advantages does this implementation have over the one in
>     msysgit (i.e., new features that the other one does not have)?
Disclaimer: I do not know the details (as I said, I have higher priorities
elsewhere since the remote-hg I need for everyday work continues to do its
job, and the patch series bringing Python to msysGit is more pressing,
and I will enjoy its review much more, too).

The biggest advantage seems to me that it was started later than msysGit's remote-hg and as such could potentially exploit recent improvements in git.git.

>   - What disadvantages? If this implementation goes into git.git,
>     the msysgit one is likely to wane in popularity. What will we be
>     losing by doing so? If the answer is not "nothing", how hard would
>     it be to port over the missing bits?

The biggest advantage msysGit's series has is that it had a fix for a fundamental flaw in fast-export. Fast-export was intended to work incrementally, so the incantation "git branch blub master && git fast-export ^master blub" is expected to update the ref "blub" properly.

I just tested this with junio/next and it seems this issue is still unfixed: instead of

	reset refs/heads/blub
	from e7510461b7db54b181d07acced0ed3b1ada072c8
I get
	reset refs/heads/blub
	from :0
when running "git fast-export ^master blub".

Having said that, we have no problem to throw away the fix that was rejected by Junio (who wanted something much more general which I refused to implement both due to lack of time and lack of need -- think YAGNI) and rebase our stuff on top of whatever goes into git.git's next (or master, we are still deciding in the msysGit project whether we should stop tracking next).

Another thing that I really like about remote-hg as it is in msysGit is that it was designed with extensibility in mind. It should not be too hard to support other fast-import/export based backends using that infrastructure. I am particularly interested in bzr myself, but there is no day-job related project I could use as an excuse to give that project a higher priority that the other things I am doing at the moment.

>   - The msysgit one got held up by fixes needed for fast-export. Why
>   aren't those a problem for this implementation? If we are using a
>   different strategy that avoids the issue, what are the limitations (if
>   any) of that strategy?

Junio wanted a more general solution, adding infrastructure to the rev-list engine that I did not need -- and did not see the need for, either -- and given the amount of time I had invested in a working remote-hg and given that I needed it desperately for my day-job project, I decided to just put it into msysGit and give up my hopes for it to become official.

It has worked well in the meantime and met my needs. The only thing missing is the support for octopus merges. But I would need that only to satisfy my geek self: I would set up an automatic Hg mirror of git.git itself on bitbucket.

> I have a feeling that some of those answers are buried deep within the
> discussion, but I have had a hard time following all of the back and
> forth due to the volume and tone of the discussion. Are we at a point
> now where some of the participants can try to summarize the situation?
Hopefully my attempt met your expectations.

Thank you, Dscho

Felipe Contreras· Oct 31, 2012, 18:41 UTC · re: Johannes Schindelin · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi,

On Wed, Oct 31, 2012 at 7:20 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 22 quoted lines
>>   - What disadvantages? If this implementation goes into git.git,
>>     the msysgit one is likely to wane in popularity. What will we be
>>     losing by doing so? If the answer is not "nothing", how hard would
>>     it be to port over the missing bits?
>
> The biggest advantage msysGit's series has is that it had a fix for a
> fundamental flaw in fast-export. Fast-export was intended to work
> incrementally, so the incantation "git branch blub master && git
> fast-export ^master blub" is expected to update the ref "blub" properly.
>
> I just tested this with junio/next and it seems this issue is still
> unfixed: instead of
>
>         reset refs/heads/blub
>         from e7510461b7db54b181d07acced0ed3b1ada072c8
>
> I get
>
>         reset refs/heads/blub
>         from :0
>
> when running "git fast-export ^master blub".

That is not a problem. It has been discussed extensively, and the consensus seems to be that such command should throw nothing:

http://article.gmane.org/gmane.comp.version-control.git/208729

But that doesn't affect remote helpers, what we _really_ want is for this to work:

git fast-export --import-marks=tmp-marks \
  --export-marks=tmp-marks master > /dev/null &&
git fast-export --import-marks=tmp-marks \
  --export-marks=tmp-marks blub > actual &&

And that's fixed in this patch: (for which the consensus seems to be that it's also OK)

http://article.gmane.org/gmane.comp.version-control.git/208730
But none of these patches are *required* for remote-hg (any of them) to work.
Cheers.

-- Felipe Contreras

Jonathan Nieder· Oct 31, 2012, 18:59 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

Felipe Contreras wrote:
> On Wed, Oct 31, 2012 at 7:20 PM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
Show 17 quoted lines
>> I just tested this with junio/next and it seems this issue is still
>> unfixed: instead of
>>
>>         reset refs/heads/blub
>>         from e7510461b7db54b181d07acced0ed3b1ada072c8
>>
>> I get
>>
>>         reset refs/heads/blub
>>         from :0
>>
>> when running "git fast-export ^master blub".
>
> That is not a problem. It has been discussed extensively, and the
> consensus seems to be that such command should throw nothing:
>
> http://article.gmane.org/gmane.comp.version-control.git/208729

Um. Are you claiming I have said that "git fast-export ^master blub" should silently emit nothing? Or has this been discussed extensively with someone else?

Jonathan
Felipe Contreras· Oct 31, 2012, 19:24 UTC · re: Jonathan Nieder · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi,
On Wed, Oct 31, 2012 at 7:59 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 25 quoted lines
> Felipe Contreras wrote:
>> On Wed, Oct 31, 2012 at 7:20 PM, Johannes Schindelin
>> <Johannes.Schindelin@gmx.de> wrote:
>
>>> I just tested this with junio/next and it seems this issue is still
>>> unfixed: instead of
>>>
>>>         reset refs/heads/blub
>>>         from e7510461b7db54b181d07acced0ed3b1ada072c8
>>>
>>> I get
>>>
>>>         reset refs/heads/blub
>>>         from :0
>>>
>>> when running "git fast-export ^master blub".
>>
>> That is not a problem. It has been discussed extensively, and the
>> consensus seems to be that such command should throw nothing:
>>
>> http://article.gmane.org/gmane.comp.version-control.git/208729
>
> Um.  Are you claiming I have said that "git fast-export ^master blub"
> should silently emit nothing?  Or has this been discussed extensively
> with someone else?
Maybe I misunderstood when you said:
> A patch meeting the above description would make perfect sense to me.
Anyway, when you have:

% git fast-export ^next next^{commit} # nothing % git fast-export ^next next~0 # nothing % git fast-export ^next next~1 # nothing % git fast-export ^next next~2 # nothing

It only makes sense that:

% git fast-export ^next next # nothing

It doesn't get any more obvious than that. But to each his own.
Cheers.

-- Felipe Contreras

Johannes Schindelin· Oct 31, 2012, 20:28 UTC · re: Felipe Contreras · lore

Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Hi,
On Wed, 31 Oct 2012, Felipe Contreras wrote:
> It doesn't get any more obvious than that. But to each his own.

In my opinion, Jonathan does not deserve any of such condescending words. But maybe the Git maintainers are okay with such a tone on this list?

Hth, Johannes

Felipe Contreras· Oct 31, 2012, 20:37 UTC · re: Johannes Schindelin · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 9:28 PM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 8 quoted lines
> Hi,
>
> On Wed, 31 Oct 2012, Felipe Contreras wrote:
>
>> It doesn't get any more obvious than that. But to each his own.
>
> In my opinion, Jonathan does not deserve any of such condescending words.
> But maybe the Git maintainers are okay with such a tone on this list?

Jonathan and I already agreed to disagree, there's nothing wrong with that. To me the above behavior is obviously correct, to him it's not. Everybody is entitled to their own opinion, are we not?

-- 
Felipe Contreras
Junio C Hamano· Nov 1, 2012, 01:32 UTC · re: Johannes Schindelin · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
Show 7 quoted lines
>On Wed, 31 Oct 2012, Felipe Contreras wrote:
>
>> It doesn't get any more obvious than that. But to each his own.
>
>In my opinion, Jonathan does not deserve any of such condescending
>words.
>But maybe the Git maintainers are okay with such a tone on this list?
Agreed, and no.
We've been hoping we can do without a rigid code of conduct written down to maintain cordial community focused on technical merits, and instead relied on people's common sense, but sense may not be so common, unfortunately, so we may have to have one.
Felipe Contreras· Nov 1, 2012, 02:58 UTC · re: Junio C Hamano · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 2:32 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 13 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>
>>On Wed, 31 Oct 2012, Felipe Contreras wrote:
>>
>>> It doesn't get any more obvious than that. But to each his own.
>>
>>In my opinion, Jonathan does not deserve any of such condescending
>>words.
>>But maybe the Git maintainers are okay with such a tone on this list?
>
> Agreed, and no.
>
> We've been hoping we can do without a rigid code of conduct written down to maintain cordial community focused on technical merits, and instead relied on people's common sense, but sense may not be so common, unfortunately, so we may have to have one.
Just for the record, what exactly is the problem with the above?
1) The fact that I say it's obvious
2) The fact that I say everyone is entitled to their own opinions
I don't think I said anything else.
-- 
Felipe Contreras
René Scharfe· Nov 1, 2012, 13:46 UTC · re: Felipe Contreras · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Am 01.11.2012 03:58, schrieb Felipe Contreras:
Show 19 quoted lines
> On Thu, Nov 1, 2012 at 2:32 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>>
>>> On Wed, 31 Oct 2012, Felipe Contreras wrote:
>>>
>>>> It doesn't get any more obvious than that. But to each his own.
>>>
>>> In my opinion, Jonathan does not deserve any of such condescending
>>> words.
>>> But maybe the Git maintainers are okay with such a tone on this list?
>>
>> Agreed, and no.
>>
>> We've been hoping we can do without a rigid code of conduct written down to maintain cordial community focused on technical merits, and instead relied on people's common sense, but sense may not be so common, unfortunately, so we may have to have one.
>
> Just for the record, what exactly is the problem with the above?
>
> 1) The fact that I say it's obvious
> 2) The fact that I say everyone is entitled to their own opinions

Obviousness is in the eye of the beholder. This is a fact that I tend to forget just too easily as well.

You probably didn't intend it, but your sentences at the top can be read more like: "This is a logical consequence. If you don't understand that, your mental capabilities must be lacking.". That's obviously (ha!) a rude thing to say.

Also, and I'm sure you didn't know that, "Jedem das Seine" (to each his own) was the slogan of the Buchenwald concentration camp. For that reason some (including me) hear the unspoken cynical half-sentence "and some people just have to be sent to the gas chamber" when someone uses this proverb.

No accusations intended, just trying to answer your question from my point of view.

René
Tomas Carnecky· Nov 1, 2012, 14:18 UTC · re: René Scharfe · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 1:46 PM, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:

> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each his own)
> was the slogan of the Buchenwald concentration camp.  For that reason some
> (including me) hear the unspoken cynical half-sentence "and some people just
> have to be sent to the gas chamber" when someone uses this proverb.
Godwin's Law. That went fast, just one day :)
Martin Langhoff· Nov 1, 2012, 14:18 UTC · re: René Scharfe · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 9:46 AM, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:

> You probably didn't intend it, but your sentences at the top can be read
> more like: "This is a logical consequence.  If you don't understand that,
> your mental capabilities must be lacking.".  That's obviously (ha!) a rude
> thing to say.
+1
> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each his own)

Ouch! I sure didn't know that. Thanks for that tidbit. Working with people from all over the world always teaches me that I might be saying the wrong thing... accidentally. And to be tolerant of others' sayings.

{ To dispel any confusion, no, I am not German. I'm from a big melting-pot of peoples :-) }

m
-- 
 martin.langhoff@gmail.com
 martin@laptop.org -- Software Architect - OLPC
 - ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 - http://wiki.laptop.org/go/User:Martinlanghoff
Felipe Contreras· Nov 1, 2012, 14:34 UTC · re: René Scharfe · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 2:46 PM, René Scharfe <rene.scharfe@lsrfire.ath.cx> wrote:

Show 31 quoted lines
> Am 01.11.2012 03:58, schrieb Felipe Contreras:
>
>> On Thu, Nov 1, 2012 at 2:32 AM, Junio C Hamano <gitster@pobox.com> wrote:
>>>
>>> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>>>
>>>> On Wed, 31 Oct 2012, Felipe Contreras wrote:
>>>>
>>>>> It doesn't get any more obvious than that. But to each his own.
>>>>
>>>>
>>>> In my opinion, Jonathan does not deserve any of such condescending
>>>> words.
>>>> But maybe the Git maintainers are okay with such a tone on this list?
>>>
>>>
>>> Agreed, and no.
>>>
>>> We've been hoping we can do without a rigid code of conduct written down
>>> to maintain cordial community focused on technical merits, and instead
>>> relied on people's common sense, but sense may not be so common,
>>> unfortunately, so we may have to have one.
>>
>>
>> Just for the record, what exactly is the problem with the above?
>>
>> 1) The fact that I say it's obvious
>> 2) The fact that I say everyone is entitled to their own opinions
>
>
> Obviousness is in the eye of the beholder.

Sometimes. Other times things are obviously obvious, not for the person uttering the words, but for everyone. But I agree that others would disagree, which is why I followed that sentence to one making sure that I understand that there's a disagreement.

> This is a fact that I tend to forget just too easily as well.
I didn't.
And even if I did, what is the problem with saying "this is obvious"?
> You probably didn't intend it, but your sentences at the top can be read
> more like: "This is a logical consequence.  If you don't understand that,
> your mental capabilities must be lacking.".  That's obviously (ha!) a rude
> thing to say.

People can read things in many ways. If you need to pass every sentence you write in a *technical* mailing list through a public relation professional, well, the throughput of such mailing list is going to suffer.

That being said, I did wonder what must be going through his mind to not see that as obvious, but I did NOT *say* anything offensive. Specially because I know people have different perspectives, and the fact that a perspective doesn't allow you to see something obvious doesn't say anything about your mental capabilities, only about your perspectives, biases, or even current mental state. Who knows, maybe you skipped your coffee.

To assume otherwise is reading too much into things. Read what is being said, and nothing more. Don't make assumptions.

And a guideline I love from Wikipedia: Always assume *good faith*. Sometimes, of course, even if you assume good faith things are offensive. This is not the case here.

> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each his own)
> was the slogan of the Buchenwald concentration camp.
No, I don't know, and frankly, I don't care.

Cultural differences go both ways. You need to assume that whatever cultural reference you are thinking of, might not be the same for the other person. Again: assume *good faith*.

And in English, and probably most Latin language countries, "to each his own" is pretty well understood:

http://en.wiktionary.org/wiki/to_each_his_own

Etymology A calque of Latin suum cuique, short for suum cuique pulchrum est (“to each his own is beautiful”).

Proverb to each his own Every person is entitled to his or her personal preferences and tastes. I would never want my bathroom decorated in chartreuse and turquoise, but to each his own, I suppose.

Synonyms there's no accounting for taste

> For that reason some
> (including me) hear the unspoken cynical half-sentence "and some people just
> have to be sent to the gas chamber" when someone uses this proverb.
I never said anything of the sort, and assuming otherwise is a mistake.

If you always assume bad faith you will inevitably get offended by things that were never meant to be offensive. It's not a good guideline.

> No accusations intended, just trying to answer your question from my point
> of view.

Thanks, but I think if others are thinking along the same lines, this is not good. Following the guideline of always assuming good faith makes it easier for people to communicate, and people not getting hurt when in fact no offense was intended, which it turns out to be most of the time.

Cheers.
-- 
Felipe Contreras
Martin Langhoff· Nov 1, 2012, 14:47 UTC · re: Felipe Contreras · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Felipe,
I'll invite you to reread some of your words:
> That being said, I did wonder what must be going through his mind to
> not see that as obvious,
(...)
> Following the guideline of always assuming good faith

So perhaps it does apply that you could try to assume good intellectual faith in others. When you wonder "what must be going through his mind to not see it as obvious"... you should consider "hey, maybe I am missing some aspect of this".

cheers,
m
-- 
 martin.langhoff@gmail.com
 martin@laptop.org -- Software Architect - OLPC
 - ask interesting questions
 - don't get distracted with shiny stuff  - working code first
 - http://wiki.laptop.org/go/User:Martinlanghoff
Felipe Contreras· Nov 1, 2012, 17:13 UTC · re: Martin Langhoff · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 3:47 PM, Martin Langhoff <martin.langhoff@gmail.com> wrote:

Show 14 quoted lines
> Felipe,
>
> I'll invite you to reread some of your words:
>
>> That being said, I did wonder what must be going through his mind to
>> not see that as obvious,
> (...)
>
>> Following the guideline of always assuming good faith
>
> So perhaps it does apply that you could try to assume good
> intellectual faith in others. When you wonder "what must be going
> through his mind to not see it as obvious"... you should consider
> "hey, maybe I am missing some aspect of this".
That's what I did.

But even if I didn't, that's not offensive, that only means I made a mistake and it is actually not obvious. But that would be a *technical* mistake.

When I feel something is obvious, I say "I think this is obvious", when I feel something is obvious to me, but not to others, I say "This is obvious to me", when I believe with every fiber of my being that something is obvious with a very low margin of error, not only to me, but to other people, I say "this is as obvious as it gets". Of course, there's the possibility that I missed something, there's always that possibility, but even if I did, that would be a *technical* mistake.

If you want to discuss the technical aspect of whether or not that is obvious, feel free to comment in the other thread. This one is about netiquette. And I've yet to see what is wrong with saying "this is obvious", *specially* if we are assuming good faith from both sides, and both sides have already agreed that there's a disagreement, no insults, no name calling, not ad hominem attacks; simply a disagreement. Nothing wrong with disagreeing, even if it's strongly.

Cheers.
-- 
Felipe Contreras
Andreas Ericsson· Nov 2, 2012, 09:38 UTC · re: René Scharfe · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On 11/01/2012 02:46 PM, René Scharfe wrote:
Show 7 quoted lines
> 
> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each
> his own) was the slogan of the Buchenwald concentration camp.  For
> that reason some (including me) hear the unspoken cynical
> half-sentence "and some people just have to be sent to the gas
> chamber" when someone uses this proverb.
> 
It goes further back than that.

"Suum cuique pulchrum est" ("To each his own is a beautiful thing") is a latin phrase said to be used frequently in the roman senate when senators politely agreed to disagree and let a vote decide the outcome rather than debating further.

Please don't let the twisted views of whatever nazi idiot thought it meant "you may have the wrong faith and therefore deserve to die, so you shall" pollute it. The original meaning is both poetic and democratic, and I firmly believe most people have the original meaning to the fore of their mind when using it. After all, very few people knowingly quote nazi concentration camp slogans.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.
Michael J Gruber· Nov 2, 2012, 11:03 UTC · re: Andreas Ericsson · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Andreas Ericsson venit, vidit, dixit 02.11.2012 10:38:
Show 23 quoted lines
> On 11/01/2012 02:46 PM, René Scharfe wrote:
>>
>> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each
>> his own) was the slogan of the Buchenwald concentration camp.  For
>> that reason some (including me) hear the unspoken cynical
>> half-sentence "and some people just have to be sent to the gas
>> chamber" when someone uses this proverb.
>>
> 
> It goes further back than that.
> 
> "Suum cuique pulchrum est" ("To each his own is a beautiful thing") is
> a latin phrase said to be used frequently in the roman senate when
> senators politely agreed to disagree and let a vote decide the outcome
> rather than debating further.
> 
> Please don't let the twisted views of whatever nazi idiot thought it
> meant "you may have the wrong faith and therefore deserve to die, so you
> shall" pollute it. The original meaning is both poetic and democratic,
> and I firmly believe most people have the original meaning to the fore
> of their mind when using it. After all, very few people knowingly quote
> nazi concentration camp slogans.
>

In fact, many German terms and words are "forbidden area" since Nazi times, but I don't think this one carries the same connotation.

But that is a side track.

Collaboration (and code review is a form of collaboration) requires communication. The linked code of conduct pages describe quite well how to ensure a productive environment in which "everyone" feels comfortable communicating and collaborating. But even reading pages like these requires a common sense (of the many undefined terms therein), a sense which is usually present here on the list, and thus renders a page like these unnecessary for us. Once there is a lack of commonality, there is a lack of agreement about those undefined terms (what constitutes a personal attack etc.).

Consequently, the only practical test for commonality and community acceptance appears to be just that: commonality and community acceptance. If many people in a community consider a tone or formulation offensive, then it is offensive by the very definition of common sense (common to that community), and there's no point at all in arguing about it. If I don't like a community's sense I either deal with it or leave it.

It's really not that different from coding style. If we prefer
if (cond) {
over

if (cond) {

then you either do it that way or your code gets rejected. The difference is that coding style is easier to define, of course. The common thing is that there's no point in arguing about it.

Michael
Felipe Contreras· Nov 2, 2012, 16:09 UTC · re: Michael J Gruber · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 12:03 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 34 quoted lines
> Andreas Ericsson venit, vidit, dixit 02.11.2012 10:38:
>> On 11/01/2012 02:46 PM, René Scharfe wrote:
>>>
>>> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each
>>> his own) was the slogan of the Buchenwald concentration camp.  For
>>> that reason some (including me) hear the unspoken cynical
>>> half-sentence "and some people just have to be sent to the gas
>>> chamber" when someone uses this proverb.
>>>
>>
>> It goes further back than that.
>>
>> "Suum cuique pulchrum est" ("To each his own is a beautiful thing") is
>> a latin phrase said to be used frequently in the roman senate when
>> senators politely agreed to disagree and let a vote decide the outcome
>> rather than debating further.
>>
>> Please don't let the twisted views of whatever nazi idiot thought it
>> meant "you may have the wrong faith and therefore deserve to die, so you
>> shall" pollute it. The original meaning is both poetic and democratic,
>> and I firmly believe most people have the original meaning to the fore
>> of their mind when using it. After all, very few people knowingly quote
>> nazi concentration camp slogans.
>>
>
> In fact, many German terms and words are "forbidden area" since Nazi
> times, but I don't think this one carries the same connotation.
>
> But that is a side track.
>
> Collaboration (and code review is a form of collaboration) requires
> communication. The linked code of conduct pages describe quite well how
> to ensure a productive environment in which "everyone" feels comfortable
> communicating and collaborating.

Yes, but that's assuming we want "everyone" to feel comfortable communicating and collaborating. I cite again the example of the Linux kernel, where certainly not "everyone" feels that way. But somehow they manage to be perhaps the most successful software project in history. And I would argue even more: it's _because_ not everyone feels comfortable, it's because ideas and code are criticized freely, and because only the ones that do have merit stand. If you are able to take criticism, and you are not emotionally and personally attacked to your code and your ideas, you would thrive in this environment. If you don't want your precious little baby code to fight against the big guys, then you shouldn't send it out to the world.

Junio mentioned "technical merit", and I believe for that open and _honest_ communication is more important than making "everyone" feel comfortable.

And FWIW I don't feel comfortable expressing my opinion any more, because even if I criticize ideas and code on a *technical* basis, I'm assumed to be referencing Nazism and whatnot without any regards of what my original intentions were, or what I actually said, and definitely not assuming good faith. And when asked for clarification of what exactly that I said was offensive, I get no clear answer.

The dangers of "everyone" following the same style of communication, and making "everyone" feel comfortable, is that "everyone" ends up being the same kind of people, and the ones that don't fit the definition of "everyone" feel like outsiders, or outright leave the project. And you end up with an homogeneous group of people incapable of criticizing each other honestly (on a technical basis), whether it's because of lack of a different perspective, or unwillingness to speak openly, or difficulty in finding the right polite words. I've seen many projects fall into this, and erode with time, since nothing important actually happens, and real deep issues within the code or the community get ignored.

Anyway, I've yet to find what was actually wrong in the words I said.
Cheers.
-- 
Felipe Contreras
Michael J Gruber· Nov 5, 2012, 09:25 UTC · re: Felipe Contreras · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Felipe Contreras venit, vidit, dixit 02.11.2012 17:09:
Show 39 quoted lines
> On Fri, Nov 2, 2012 at 12:03 PM, Michael J Gruber
> <git@drmicha.warpmail.net> wrote:
>> Andreas Ericsson venit, vidit, dixit 02.11.2012 10:38:
>>> On 11/01/2012 02:46 PM, René Scharfe wrote:
>>>>
>>>> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each
>>>> his own) was the slogan of the Buchenwald concentration camp.  For
>>>> that reason some (including me) hear the unspoken cynical
>>>> half-sentence "and some people just have to be sent to the gas
>>>> chamber" when someone uses this proverb.
>>>>
>>>
>>> It goes further back than that.
>>>
>>> "Suum cuique pulchrum est" ("To each his own is a beautiful thing") is
>>> a latin phrase said to be used frequently in the roman senate when
>>> senators politely agreed to disagree and let a vote decide the outcome
>>> rather than debating further.
>>>
>>> Please don't let the twisted views of whatever nazi idiot thought it
>>> meant "you may have the wrong faith and therefore deserve to die, so you
>>> shall" pollute it. The original meaning is both poetic and democratic,
>>> and I firmly believe most people have the original meaning to the fore
>>> of their mind when using it. After all, very few people knowingly quote
>>> nazi concentration camp slogans.
>>>
>>
>> In fact, many German terms and words are "forbidden area" since Nazi
>> times, but I don't think this one carries the same connotation.
>>
>> But that is a side track.
>>
>> Collaboration (and code review is a form of collaboration) requires
>> communication. The linked code of conduct pages describe quite well how
>> to ensure a productive environment in which "everyone" feels comfortable
>> communicating and collaborating.
> 
> Yes, but that's assuming we want "everyone" to feel comfortable
> communicating and collaborating.

I put "everyone" in quotes because you can never reach 100%, so "everyone" means almost everyone.

Undeniably, the answers in this and the other threads show that on the git mailing list, "everyone" wants "everyone" to feel comfortable communicating and collaborating.

> I cite again the example of the Linux
> kernel, where certainly not "everyone" feels that way. But somehow

It's a different list with different standards and tone, so it doesn't really matter for our list. That being said:

Show 8 quoted lines
> they manage to be perhaps the most successful software project in
> history. And I would argue even more: it's _because_ not everyone
> feels comfortable, it's because ideas and code are criticized freely,
> and because only the ones that do have merit stand. If you are able to
> take criticism, and you are not emotionally and personally attacked to
> your code and your ideas, you would thrive in this environment. If you
> don't want your precious little baby code to fight against the big
> guys, then you shouldn't send it out to the world.

For one thing, contributors on the kernel list are open to technical arguments, and that includes the arguments of others; just like we are here. On the other hand, you seem to rebuke "any" (most) technical argument in harsh words as if it were a personal attack; at least that's how your answers come across to me (and apparently others). That really makes it difficult for most of us here to argue with you technically, which is a pity. That lack of openness for the arguments of others would make your life difficult on the kernel list also.

A completely different issue is that of language. You talk German on a German list and English on an international list. You talk "kernel English" on the kernel list, which is full of words and phrases you would never use in a normal social setting where you talk to people in person; it would be completely unacceptable. Here on the Git list, we prefer to talk like in a normal, albeit colloquial social setting. If you're open for advice: just imagine talking to the people here in person, to colleagues across your desk, and you have a good guideline.

And no, using the same or similar language does not make us the same at all. Using the same language is the natural prerequisite for successful communication.

Felipe, please try to see the efforts many of us are making here in order to keep you as a contributor, and reward it by accepting the advice to revise your language: colleague to colleague.

Michael
Felipe Contreras· Nov 5, 2012, 15:22 UTC · re: Michael J Gruber · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Nov 5, 2012 at 10:25 AM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 47 quoted lines
> Felipe Contreras venit, vidit, dixit 02.11.2012 17:09:
>> On Fri, Nov 2, 2012 at 12:03 PM, Michael J Gruber
>> <git@drmicha.warpmail.net> wrote:
>>> Andreas Ericsson venit, vidit, dixit 02.11.2012 10:38:
>>>> On 11/01/2012 02:46 PM, René Scharfe wrote:
>>>>>
>>>>> Also, and I'm sure you didn't know that, "Jedem das Seine" (to each
>>>>> his own) was the slogan of the Buchenwald concentration camp.  For
>>>>> that reason some (including me) hear the unspoken cynical
>>>>> half-sentence "and some people just have to be sent to the gas
>>>>> chamber" when someone uses this proverb.
>>>>>
>>>>
>>>> It goes further back than that.
>>>>
>>>> "Suum cuique pulchrum est" ("To each his own is a beautiful thing") is
>>>> a latin phrase said to be used frequently in the roman senate when
>>>> senators politely agreed to disagree and let a vote decide the outcome
>>>> rather than debating further.
>>>>
>>>> Please don't let the twisted views of whatever nazi idiot thought it
>>>> meant "you may have the wrong faith and therefore deserve to die, so you
>>>> shall" pollute it. The original meaning is both poetic and democratic,
>>>> and I firmly believe most people have the original meaning to the fore
>>>> of their mind when using it. After all, very few people knowingly quote
>>>> nazi concentration camp slogans.
>>>>
>>>
>>> In fact, many German terms and words are "forbidden area" since Nazi
>>> times, but I don't think this one carries the same connotation.
>>>
>>> But that is a side track.
>>>
>>> Collaboration (and code review is a form of collaboration) requires
>>> communication. The linked code of conduct pages describe quite well how
>>> to ensure a productive environment in which "everyone" feels comfortable
>>> communicating and collaborating.
>>
>> Yes, but that's assuming we want "everyone" to feel comfortable
>> communicating and collaborating.
>
> I put "everyone" in quotes because you can never reach 100%, so
> "everyone" means almost everyone.
>
> Undeniably, the answers in this and the other threads show that on the
> git mailing list, "everyone" wants "everyone" to feel comfortable
> communicating and collaborating.

And that might be a mistake. Because "everyone" doesn't include the people that are able to put personal differences aside, and concentrate on technical merits.

Show 5 quoted lines
>> I cite again the example of the Linux
>> kernel, where certainly not "everyone" feels that way. But somehow
>
> It's a different list with different standards and tone, so it doesn't
> really matter for our list. That being said:

If you don't want to take into consideration what the most successful software project in history does... up to you.

Show 17 quoted lines
>> they manage to be perhaps the most successful software project in
>> history. And I would argue even more: it's _because_ not everyone
>> feels comfortable, it's because ideas and code are criticized freely,
>> and because only the ones that do have merit stand. If you are able to
>> take criticism, and you are not emotionally and personally attacked to
>> your code and your ideas, you would thrive in this environment. If you
>> don't want your precious little baby code to fight against the big
>> guys, then you shouldn't send it out to the world.
>
> For one thing, contributors on the kernel list are open to technical
> arguments, and that includes the arguments of others; just like we are
> here. On the other hand, you seem to rebuke "any" (most) technical
> argument in harsh words as if it were a personal attack; at least that's
> how your answers come across to me (and apparently others). That really
> makes it difficult for most of us here to argue with you technically,
> which is a pity. That lack of openness for the arguments of others would
> make your life difficult on the kernel list also.
It doesn't. And I don't.

There is no lack of openness from my part. I hear all technical arguments, and I reply on a technical basis. The problem seems to be is that you expect the code submitted to be criticized, but not the criticism it receives. IOW; the submitter has to put up with anything anybody says about his/her code and ideas, but the *reviewer* is untouchable; the submitter cannot ever criticize the reviewer. I can tell you that doesn't happen in the Linux kernel; the review process is a _discussion_, not a one-way communication, and discussions can be heated up, but the end result is better code, *both* sides are open to criticism, the submitter, *and* the reviewer.

It seems to me that you think in the git mailing list the submitter should never put in question the criticism of the reviewer.

If that's not the case, show me a single instance when I rebuke technical arguments in *harsh* words... perhaps, you think any rebuking is "harsh". Specifically, show me an instance were *I* was harsh, and the reviewer was not.

If you cannot show instances of this, then your statement that I rebuke harshly doesn't stand; I rebuke, that's all.

Show 8 quoted lines
> A completely different issue is that of language. You talk German on a
> German list and English on an international list. You talk "kernel
> English" on the kernel list, which is full of words and phrases you
> would never use in a normal social setting where you talk to people in
> person; it would be completely unacceptable. Here on the Git list, we
> prefer to talk like in a normal, albeit colloquial social setting. If
> you're open for advice: just imagine talking to the people here in
> person, to colleagues across your desk, and you have a good guideline.

If a submitter cannot rebuke, why would I want to contribute to such a project? If we cannot speak openly why would I want to contribute?

I wouldn't.
> And no, using the same or similar language does not make us the same at
> all. Using the same language is the natural prerequisite for successful
> communication.
Nobody said otherwise.
> Felipe, please try to see the efforts many of us are making here in
> order to keep you as a contributor, and reward it by accepting the
> advice to revise your language: colleague to colleague.

Thanks, but no thanks. I contribute on my free time, and if contributing is not a fun process, why would I?

It seems to me that you feel you are not only entitled to my code, but to never criticize back. I've seen this happen multiple times now, when I send patches, which are a *contribution*, and the reviewers expect me to address every and all issues they raise without criticizing back, or that somehow it's my *responsibility* to address their concerns, even if I don't agree. I'm sorry but it's not.

In a truly technical project code speaks, and if you as a reviewer feel something has to be changed, and the submitter (which is acting on his/her own volition and free time) is not willing to do it, he/her himself/herself can take the code and do whatever modifications to it, or the commit message, seem necessary. *Not* to keep bashing the submitter until they do it exactly as they want as if somehow it was their *responsibility*.

The spirit of open source is *collaboration*, and what you seem to expect here is that I do everything. Not only do I have to come up with the code, I have to come up with a full book chapter of commit message explaining all the history and introducing how the code works to people unfamiliar with it, and I have to hear review criticism without arguing back, and I have to implement it even if I disagree, and I have to be careful about what every word I say might be taken by people from other cultures (but they don't), and I can never say anything that might under certain circumstances and assumptions be considered offensive (even though they can). And never criticize back the hidden guidelines.

This is not collaborative, this only ensures that you will get a very specific kind of contributors.

If what you want is a closely-knitted circle of friends that are like-minded, then this seems like the right approach.

If what you want is to have a good project, with good code, it might not.
Cheers.
-- 
Felipe Contreras
Felipe Contreras· Nov 5, 2012, 15:58 UTC · re: Felipe Contreras · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Nov 5, 2012 at 4:22 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

> On Mon, Nov 5, 2012 at 10:25 AM, Michael J Gruber
> <git@drmicha.warpmail.net> wrote:
Show 8 quoted lines
>> For one thing, contributors on the kernel list are open to technical
>> arguments, and that includes the arguments of others; just like we are
>> here. On the other hand, you seem to rebuke "any" (most) technical
>> argument in harsh words as if it were a personal attack; at least that's
>> how your answers come across to me (and apparently others). That really
>> makes it difficult for most of us here to argue with you technically,
>> which is a pity. That lack of openness for the arguments of others would
>> make your life difficult on the kernel list also.
...
Show 7 quoted lines
> If that's not the case, show me a single instance when I rebuke
> technical arguments in *harsh* words... perhaps, you think any
> rebuking is "harsh". Specifically, show me an instance were *I* was
> harsh, and the reviewer was not.
>
> If you cannot show instances of this, then your statement that I
> rebuke harshly doesn't stand; I rebuke, that's all.

In addition to this, I'm still waiting for an answer of what's wrong with the words that started this thread:

On Wed, 31 Oct 2012, Felipe Contreras wrote:
> It doesn't get any more obvious than that. But to each his own.
Cheers.
-- 
Felipe Contreras
Michael J Gruber· Nov 5, 2012, 16:00 UTC · re: Felipe Contreras · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

[trimmed down heavily by mjg] Felipe Contreras venit, vidit, dixit 05.11.2012 16:22:

Show 5 quoted lines
> On Mon, Nov 5, 2012 at 10:25 AM, Michael J Gruber
> <git@drmicha.warpmail.net> wrote:
>> Felipe Contreras venit, vidit, dixit 02.11.2012 17:09:
>>> On Fri, Nov 2, 2012 at 12:03 PM, Michael J Gruber
>>> <git@drmicha.warpmail.net> wrote:
Show 6 quoted lines
> There is no lack of openness from my part. I hear all technical
> arguments, and I reply on a technical basis. The problem seems to be
> is that you expect the code submitted to be criticized, but not the
> criticism it receives. IOW; the submitter has to put up with anything
> anybody says about his/her code and ideas, but the *reviewer* is
> untouchable; the submitter cannot ever criticize the reviewer. I can

Feel free to criticize the criticism, just don't offend the criticizer (be it the reviewer or the submitter).

> tell you that doesn't happen in the Linux kernel; the review process
> is a _discussion_, not a one-way communication, and discussions can be
> heated up, but the end result is better code, *both* sides are open to
> criticism, the submitter, *and* the reviewer.
Exactly, both.
Show 5 quoted lines
>> And no, using the same or similar language does not make us the same at
>> all. Using the same language is the natural prerequisite for successful
>> communication.
> 
> Nobody said otherwise.
Well, you did in the post I responded to:
>>> The dangers of "everyone" following the same style of communication,
>>> and making "everyone" feel comfortable, is that "everyone" ends up
>>> being the same kind of people

In any case, I feel I've showed enough efforts and there's no point in dragging this on.

Michael
Felipe Contreras· Nov 5, 2012, 16:15 UTC · re: Michael J Gruber · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Nov 5, 2012 at 5:00 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 17 quoted lines
> [trimmed down heavily by mjg]
> Felipe Contreras venit, vidit, dixit 05.11.2012 16:22:
>> On Mon, Nov 5, 2012 at 10:25 AM, Michael J Gruber
>> <git@drmicha.warpmail.net> wrote:
>>> Felipe Contreras venit, vidit, dixit 02.11.2012 17:09:
>>>> On Fri, Nov 2, 2012 at 12:03 PM, Michael J Gruber
>>>> <git@drmicha.warpmail.net> wrote:
>
>> There is no lack of openness from my part. I hear all technical
>> arguments, and I reply on a technical basis. The problem seems to be
>> is that you expect the code submitted to be criticized, but not the
>> criticism it receives. IOW; the submitter has to put up with anything
>> anybody says about his/her code and ideas, but the *reviewer* is
>> untouchable; the submitter cannot ever criticize the reviewer. I can
>
> Feel free to criticize the criticism, just don't offend the criticizer
> (be it the reviewer or the submitter).
As I've said before; I've yet to see where exactly I have done so.
Show 11 quoted lines
>>> And no, using the same or similar language does not make us the same at
>>> all. Using the same language is the natural prerequisite for successful
>>> communication.
>>
>> Nobody said otherwise.
>
> Well, you did in the post I responded to:
>
>>>> The dangers of "everyone" following the same style of communication,
>>>> and making "everyone" feel comfortable, is that "everyone" ends up
>>>> being the same kind of people
Style of communication != language.
You can use the same language and have vastly different styles of communication.

Imagine a society where everyone has the same style of communication. Where your free speech ends the moment you diverge from this style. Well, historically we know these societies have not worked, because there's people with different styles of communication, and quite often it's these styles of communication that are needed for certain messages important to society to be heard.

Sure, it doesn't make you all the same, but it certainly makes it a narrow spectrum.

> In any case, I feel I've showed enough efforts and there's no point in
> dragging this on.

How convenient. When I ask you specifically for examples where I have offended anybody, or been harsh, you feel you have "showed enough efforts"?

Claims require evidence.
Cheers.
-- 
Felipe Contreras
Jonathan Nieder· Nov 1, 2012, 20:46 UTC · re: Junio C Hamano · lore

Re: Lack of netiquette, was Re: [PATCH v4 00/13] New remote-hg helper

Junio C Hamano wrote:
> We've been hoping we can do without a rigid code of conduct written
> down to maintain cordial community focused on technical merits, and
> instead relied on people's common sense, but sense may not be so
> common, unfortunately, so we may have to have one.

I think that except for occasional lapses this list stays pretty close to what, for example, the Fedora[1] and Ubuntu[2] codes of conduct require, and what Emily Postnews's guide[3] explains not to do.

What's the next step?

[1] http://www.ubuntu.com/project/about-ubuntu/conduct [2] http://www.ubuntu.com/project/about-ubuntu/conduct [3] http://www.templetons.com/brad/emily.html

Daniel Barkalow· Oct 31, 2012, 23:14 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, 31 Oct 2012, Felipe Contreras wrote:
Show 49 quoted lines
> Hi,
> 
> On Wed, Oct 31, 2012 at 7:59 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
> > Felipe Contreras wrote:
> >> On Wed, Oct 31, 2012 at 7:20 PM, Johannes Schindelin
> >> <Johannes.Schindelin@gmx.de> wrote:
> >
> >>> I just tested this with junio/next and it seems this issue is still
> >>> unfixed: instead of
> >>>
> >>>         reset refs/heads/blub
> >>>         from e7510461b7db54b181d07acced0ed3b1ada072c8
> >>>
> >>> I get
> >>>
> >>>         reset refs/heads/blub
> >>>         from :0
> >>>
> >>> when running "git fast-export ^master blub".
> >>
> >> That is not a problem. It has been discussed extensively, and the
> >> consensus seems to be that such command should throw nothing:
> >>
> >> http://article.gmane.org/gmane.comp.version-control.git/208729
> >
> > Um.  Are you claiming I have said that "git fast-export ^master blub"
> > should silently emit nothing?  Or has this been discussed extensively
> > with someone else?
> 
> Maybe I misunderstood when you said:
> > A patch meeting the above description would make perfect sense to me.
> 
> Anyway, when you have:
> 
> % git fast-export ^next next^{commit}
> # nothing
> % git fast-export ^next next~0
> # nothing
> % git fast-export ^next next~1
> # nothing
> % git fast-export ^next next~2
> # nothing
> 
> It only makes sense that:
> 
> % git fast-export ^next next
> # nothing
> 
> It doesn't get any more obvious than that. But to each his own.

I think that may be true where you have "next" in both places, but I think:

$ git checkout -b new-branch master $ git fast-export ^master new-branch

ought to emit no "commit" lines, but needs to emit a "reset" line. After all, you haven't told fast-export that the ref "new-branch" is up to date, and you have told it that you want it to be exported. If you create a new branch off of an existing commit, don't change it, and push it to hg, it shouldn't be up to remote-hg to figure out what should happen with no input; it should get a:

reset refs/heads/new-branch from [something]

I don't know why Johannes seems to want [something] not to be a mark reference (unless he's complaining about getting an invalid mark reference when there aren't any marks defined), but surely something of the above form is necessary to tell remote-hg to create the new branch.

I think it would be worth testing that:

$ git checkout -b new-branch master $ git push hg new-branch

creates the new branch successfully (which I think it does, but wouldn't if "git fast-export ^master new-branch" actually returned nothing; parsed_refs gets it from the reset line).

AFAICT, your code relies on getting the behavior that fast-export actually gives, not the behavior you seem to want or the behavior Johannes seems to want. And the reason that you don't need any changes to fast-export is that your process maps marks instead of sha1s.

	-Daniel
*This .sig left intentionally blank*
Felipe Contreras· Nov 1, 2012, 02:46 UTC · re: Daniel Barkalow · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 12:14 AM, Daniel Barkalow <barkalow@iabervon.org> wrote:
Show 20 quoted lines
> I think that may be true where you have "next" in both places, but I
> think:
>
> $ git checkout -b new-branch master
> $ git fast-export ^master new-branch
>
> ought to emit no "commit" lines, but needs to emit a "reset" line. After
> all, you haven't told fast-export that the ref "new-branch" is up to date,
> and you have told it that you want it to be exported. If you create a new
> branch off of an existing commit, don't change it, and push it to hg, it
> shouldn't be up to remote-hg to figure out what should happen with no
> input; it should get a:
>
> reset refs/heads/new-branch
> from [something]
>
> I don't know why Johannes seems to want [something] not to be a mark
> reference (unless he's complaining about getting an invalid mark
> reference when there aren't any marks defined), but surely something of
> the above form is necessary to tell remote-hg to create the new branch.

I don't know what Johannes wants, but it has been discussed that not everybody is using marks.

When you use marks, the following patch fixes the issue:
http://article.gmane.org/gmane.comp.version-control.git/208730
Show 8 quoted lines
> I think it would be worth testing that:
>
> $ git checkout -b new-branch master
> $ git push hg new-branch
>
> creates the new branch successfully (which I think it does, but wouldn't
> if "git fast-export ^master new-branch" actually returned nothing;
> parsed_refs gets it from the reset line).
And it does, with the above patch, a similar command is even in the tests.

The reason why 'git fast-export ^master new-branch' returning nothing doesn't affect, is that transport helpers wouldn't use negative refs (e.g. ^master). Transport helper passes whatever the uses specifies. I you say 'new-branch', that's exactly what the transport helper will receive. It works because transport helpers use marks.

Nobody expects '^master new-branch' to do something useful, everybody uses marks.

> AFAICT, your code relies on getting the behavior that fast-export actually
> gives, not the behavior you seem to want or the behavior Johannes seems to
> want. And the reason that you don't need any changes to fast-export is
> that your process maps marks instead of sha1s.
No. In order to make use of this bug, the user would have to do:
% git push hg ^master new-branch

Otherwise nothing would get pushed, with or without my first patch[1]. To make 'git push hg new-branch' work, you need my second patch[2].

Cheers.

[1] http://article.gmane.org/gmane.comp.version-control.git/208729 [2] http://article.gmane.org/gmane.comp.version-control.git/208730

-- 
Felipe Contreras
Junio C Hamano· Nov 1, 2012, 01:41 UTC · re: Johannes Schindelin · lore

Re: [PATCH v4 00/13] New remote-hg helper

Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
Show 5 quoted lines
>Junio wanted a more general solution, adding infrastructure to the
>rev-list engine that I did not need -- and did not see the need for,
>either -- and given the amount of time I had invested in a working
>remote-hg and given that I needed it desperately for my day-job
>project, ...
This is relatively long ago (and I am away from my machine, so I cannot check) so I may misremembering things, but my impression is that since that discussion, we added a minimal "infrastructure" to the rev-list (I think we caled it rev-list-cmdline or something like that) and Sverre used it to update fast-export.
It may well be that what we have is still not sufficient to do everything you need, but it may be close enough to get extended for your original use case.
Felipe Contreras· Nov 1, 2012, 02:54 UTC · re: Junio C Hamano · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 2:41 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 13 quoted lines
>
>
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>
>>Junio wanted a more general solution, adding infrastructure to the
>>rev-list engine that I did not need -- and did not see the need for,
>>either -- and given the amount of time I had invested in a working
>>remote-hg and given that I needed it desperately for my day-job
>>project, ...
>
> This is relatively long ago (and I am away from my machine, so I cannot check) so I may misremembering things, but my impression is that since that discussion, we added a minimal "infrastructure" to the rev-list (I think we caled it rev-list-cmdline or something like that) and Sverre used it to update fast-export.
>
> It may well be that what we have is still not sufficient to do everything you need, but it may be close enough to get extended for your original use case.

I don't think there's missing, the following patch works fine: http://article.gmane.org/gmane.comp.version-control.git/208730

There's a minute issue, but I think that would require changes in fast-export itself and its marks, not rev-list. But nobody would care anyway, it's not a problem.

Cheers.
-- 
Felipe Contreras
Felipe Contreras· Oct 31, 2012, 15:39 UTC · re: Michael J Gruber · lore

Re: [PATCH v4 00/13] New remote-hg helper

Hi,

On Wed, Oct 31, 2012 at 10:30 AM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

> [quotes heavily cut down by me]
> Felipe Contreras venit, vidit, dixit 30.10.2012 21:15:
Show 17 quoted lines
>> On Tue, Oct 30, 2012 at 8:33 PM, Johannes Schindelin
>> <Johannes.Schindelin@gmx.de> wrote:
>>> On Tue, 30 Oct 2012, Felipe Contreras wrote:
>>>
>>>> But you mentioned something about cooperation, and I've yet to see how
>>>> is it that you are planning to cooperate. If you say you don't have time
>>>> to spend on this, I don't see why I should worry about testing this
>>>> series of patches.
>>>
>>> It has been mentioned before that the communication style including all
>>> these snarky and nasty comments is not helpful.
>>
>
> For the record, Johannes is not the only one being kept from looking at
> this series (further) by the tone of this discussion. Per hominem
> attacks are neither professional nor helpful. We prefer to discuss code
> here, just code.
Show me a "per hominem" attack coming from me. I never threw any such attacks.

Johannes is the one that complained about it, and that's the very definition of *not* concentrating on the code, and discussing other topics.

> The way other comment threads on this series
> unfolded made me choose to be a mere by-stander again.

This is precisely ad hominem; you are ignoring the code, not because of the code, because of the person. This is as ad hominem as it gets.

As for how "professional or helpful" that is, it's debatable. The Linux kernel mailing list is known for being harsh, and yet, they manage to get more things done than any other. They truly look at the code, just the code, they don't consider criticism to the code personally (nobody should), nor linger on any personal beefs that only distract from the end goal.

Show 6 quoted lines
>>> and I've yet to see how is it that you are planning to cooperate.
>>
>> This is also a fact. You haven't provided a branch, you haven't reviewed
>> my implementation, you haven't tried it. You mentioned something about
>
> This does not become true through iteration. Max' recent post

Thee key word is _Max's_, not Johannes'. I never said nobody did, I said Johannes didn't.

Show 7 quoted lines
> 'On
> git-remote-hg (the "native" one)' [1] points at the msysgit wiki on
> remote-hg [2] and his remote-hg branch [3], which is based on and points
> at Sverre's original branch [4] and mine [5] which is [4] being
> regularly rebased on origin/next. The msysgit devel branch is in heavy
> use; I don't use mine often but run the test suite on every rebase
> before pushing out.

This is good information, why Johannes didn't provide it? It was easy to copy-paste an URL. Lets suppose I did try this branch, and I come up with a list of problems, Johannes could easily say; "I'm not responsible for that code, I don't know what bugs could have been on the rebase". Or something along those lines, which is potentially the reason he didn't provide that.

But enough about Johannes, if I go on to Max's branch and give a try to the code, make a list of issues, run my extensive tests and so on, and make a report of the status, and a comparison with my code. Would that make it more likely for you to stop being a by-stander?

Didn't think so. The truth of the matter is that it doesn't matter what I do code-wise.

Show 9 quoted lines
> If the issues that Sverre and Dscho tried to address with their git.git
> core (non-helper) patches turn out to be non-issues then I assume
> everyone will be happy, including them. You and they have thought a lot
> about these things and the way hg-git sync can work. There seems to be
> diagreement about the way fast-export/the remote helpers communicate
> which revs and refs that are to be synced and updated. This is not
> hg-specific, and I suggest to try and clarify that issue as thoroughly
> and calmly as possible. Everyone will benefit, and it will make clearer
> which tests are appropriate, and accordingly which fixes fix real problems.

I believe there is no disagreement any more, AFAICS my patches have been accepted by Sverre and Jonathan... the commit messages is another story. Johannes chose not to collaborate.

> Orthogonal to this, it seems that all hg-git interfaces could take
> advantage of a "git heads" feature if we resurrect the old ideas (can't
> find the thread right now).
Never heard of that.

You accused me of ad hominem, now I ask you; can you ignore any personal biases and look at the code, and only at the code?

And finally, what do more do you expect me to do? About the code, and only the code.

Cheers.

-- Felipe Contreras

Michael J Gruber· Oct 31, 2012, 15:55 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

Felipe Contreras venit, vidit, dixit 31.10.2012 16:39:
> This is precisely ad hominem; you are ignoring the code, not because
> of the code, because of the person. This is as ad hominem as it gets.

I am not rejecting your code (I reviewed an early series) but reject the communication style and manners displayed in this thread.

Show 6 quoted lines
> As for how "professional or helpful" that is, it's debatable. The
> Linux kernel mailing list is known for being harsh, and yet, they
> manage to get more things done than any other. They truly look at the
> code, just the code, they don't consider criticism to the code
> personally (nobody should), nor linger on any personal beefs that only
> distract from the end goal.

There are people who choose not to be on that list because of its style. For this list, I think we should follow this list's style, not that one.

> But enough about Johannes, if I go on to Max's branch and give a try
> to the code, make a list of issues, run my extensive tests and so on,
> and make a report of the status, and a comparison with my code. Would
> that make it more likely for you to stop being a by-stander?
Sure, that's what I and others have asked for.
> Didn't think so. The truth of the matter is that it doesn't matter
> what I do code-wise.
Just try, seriously.
Show 8 quoted lines
>> Orthogonal to this, it seems that all hg-git interfaces could take
>> advantage of a "git heads" feature if we resurrect the old ideas (can't
>> find the thread right now).
> 
> Never heard of that.
> 
> You accused me of ad hominem, now I ask you; can you ignore any
> personal biases and look at the code, and only at the code?

My efforts here prove that I either have no biases or ignore them. I'm not going to ignore the style of communication, though. As a patch submitter, you ("generic you") want the attention of others as reviewers. It's in your own (again "generic you") interest not to put them off, in the same way as it's up to the submitter to argue why a patch is desirable and correct.

Michael
Felipe Contreras· Oct 31, 2012, 16:11 UTC · re: Michael J Gruber · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 4:55 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

Show 7 quoted lines
> Felipe Contreras venit, vidit, dixit 31.10.2012 16:39:
>
>> This is precisely ad hominem; you are ignoring the code, not because
>> of the code, because of the person. This is as ad hominem as it gets.
>
> I am not rejecting your code (I reviewed an early series) but reject the
> communication style and manners displayed in this thread.

All right, you are not rejecting it, but you are staying away from it, and presumably if it was coming from somebody else, you wouldn't.

Show 9 quoted lines
>> As for how "professional or helpful" that is, it's debatable. The
>> Linux kernel mailing list is known for being harsh, and yet, they
>> manage to get more things done than any other. They truly look at the
>> code, just the code, they don't consider criticism to the code
>> personally (nobody should), nor linger on any personal beefs that only
>> distract from the end goal.
>
> There are people who choose not to be on that list because of its style.
> For this list, I think we should follow this list's style, not that one.
And what is this lists' style? I don't see any guidelines anywhere.

But my point wasn't that we should follow Linux's style, my point is that it's debatable how one should engage in discussions.

And yet, I haven't seen where exactly did I throw those ad hominem attacks. I can point you to where Johannes threw such attacks (or at least snarky), to me, but I don't think that's relevant.

Show 6 quoted lines
>> But enough about Johannes, if I go on to Max's branch and give a try
>> to the code, make a list of issues, run my extensive tests and so on,
>> and make a report of the status, and a comparison with my code. Would
>> that make it more likely for you to stop being a by-stander?
>
> Sure, that's what I and others have asked for.

Except nobody ever provided a link to the actual patches. You are the first one to do so.

Show 5 quoted lines
>> You accused me of ad hominem, now I ask you; can you ignore any
>> personal biases and look at the code, and only at the code?
>
> My efforts here prove that I either have no biases or ignore them. I'm
> not going to ignore the style of communication, though.

And yet earlier before you said in this list "we prefer to discuss the code, just the code", and now you are saying you are not going to ignore the style of communication, which is not code, and yet you are discussing about it.

Show 5 quoted lines
> As a patch
> submitter, you ("generic you") want the attention of others as
> reviewers. It's in your own (again "generic you") interest not to put
> them off, in the same way as it's up to the submitter to argue why a
> patch is desirable and correct.
Ah, so you are making me a favor by reviewing the code?

How about we concentrate on what's good for the project? Our users don't care about petty personal beefs. Support to pull and push mercurial repositories, _that_ they do care about.

Cheers.

-- Felipe Contreras

Jeff King· Nov 2, 2012, 14:46 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 05:11:39PM +0100, Felipe Contreras wrote:
Show 7 quoted lines
> > As a patch
> > submitter, you ("generic you") want the attention of others as
> > reviewers. It's in your own (again "generic you") interest not to put
> > them off, in the same way as it's up to the submitter to argue why a
> > patch is desirable and correct.
> 
> Ah, so you are making me a favor by reviewing the code?

I do not want to get embroiled in a discussion of manners and netiquette (or, for that matter, nazis). But I think this point is worth calling attention to, because it seems to be at the crux of the matter.

Basically, my opinion is that yes, he is doing a favor to you by reviewing the code. Just as you have done us a favor by submitting the code. And this is not specific to this topic or to you as a submitter. It is a part of how the open source process works.

We have an existing code base that works well. It certainly has some bugs, and it certainly is missing some features. But people use it every day and are happy. The maintainers of that code base would want it to improve over time, but they would also have to be careful not to introduce regressions. And not just specific regressions in behavior; I mean regressions in overall quality. A half-implemented feature that crashes is worse than no feature at all. A change that fixes one bug but hurts the readability of the code, leading to many future bugs, is a net negative.

So when a contributor shows up with code, we are very grateful that they've spent their time improving our software. But at the same time, we must recognize that the contributor is generally scratching their own itch. And we must make sure that in doing so, they did not hurt other people's use cases, nor regress the overall quality of the code base.

It is the job of the maintainer to measure the risk and reward of each change and to find a balance in accepting patches. But it's difficult to do alone, and that is why volunteer reviewers on the list are very valuable. They distribute the reviewing load across many brains, and in many cases have expertise in particular areas that the maintainer can rely on.

A submitter has scratched their own itch by writing the code. But if they cannot cooperate with reviewers enough to get feedback, then the maintainer has only two choices: review the patches themselves, or reject the change. And when there is conflict with the regular reviewers and the submitter, it is a red flag to the maintainer that it might not be worth spending a lot of time there.

Does the code base suffer for this in the end? Perhaps. There are features we might reject that could have benefited everybody. But we might also be saving ourselves from the headaches caused by poorly thought-out changes. The system cannot work if everybody does not show up and cooperate.

Now, as for this specific topic: it is proposed for contrib, which means that expectations are lower, and the rest of git does not suffer too much if it has rough edges. At the same time, it also means that it could live fairly easily outside of the tree. In fact, I think Michael and others have been reasonably happy with their own out-of-tree implementation.

I do think the proliferation of various implementations has made it hard for users to see which ones are worth trying. So I think there is value in carrying something in contrib/, as it would focus the attention of users, and of other developers to make improvements.

So I think what I'd like to do is take your latest series into pu, with the intention of merging it into next soon, and then cooking it in next for a while. That would hopefully make it very easy for people following 'next' to try it out and see how it compares in the field with other tools they have used (the msysgit one, or others).

I'm a little worried about hurting progress on the msysgit version; it sounds like the functionality of your implementation is at parity with that one (thanks to both you and Johannes for answering my other email asking for a summary). Johannes did mention that the design of their tool was meant to eventually facilitate more backends. That's something that might be valuable; on the other hand, that development hasn't been happening, and there has been no effort lately on getting it merged into git.git. I don't want to hold working code hostage to a future plan that might or might not happen. So I hope by keeping it in next for a bit, that will give msysgit people time to check it out and mobilize their efforts to improve their version if they would like.

-Peff
Felipe Contreras· Nov 2, 2012, 18:39 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 3:46 PM, Jeff King <peff@peff.net> wrote:
Show 17 quoted lines
> On Wed, Oct 31, 2012 at 05:11:39PM +0100, Felipe Contreras wrote:
>
>> > As a patch
>> > submitter, you ("generic you") want the attention of others as
>> > reviewers. It's in your own (again "generic you") interest not to put
>> > them off, in the same way as it's up to the submitter to argue why a
>> > patch is desirable and correct.
>>
>> Ah, so you are making me a favor by reviewing the code?
>
> I do not want to get embroiled in a discussion of manners and netiquette
> (or, for that matter, nazis). But I think this point is worth calling
> attention to, because it seems to be at the crux of the matter.
>
> Basically, my opinion is that yes, he is doing a favor to you by
> reviewing the code. Just as you have done us a favor by submitting the
> code.

Who cares about _us_? What is important is the bigger picture, git, the project, and its users.

Yes, some people might think only about themselves, and that's their choice, but I don't think us (the git project) should worry about making me favors, only about improving the project.

> And this is not specific to this topic or to you as a submitter.
> It is a part of how the open source process works.

I disagree. The open source process works not by making favors to each other, but by everyone sharing and improving the code, by *collaborating*. "I review your code if you review mine", or "if you by me a bear in the next conference" is not the spirit of open source, although it might happen often.

Show 9 quoted lines
> We have an existing code base that works well. It certainly has some
> bugs, and it certainly is missing some features. But people use it every
> day and are happy. The maintainers of that code base would want it to
> improve over time, but they would also have to be careful not to
> introduce regressions. And not just specific regressions in behavior; I
> mean regressions in overall quality. A half-implemented feature that
> crashes is worse than no feature at all. A change that fixes one bug but
> hurts the readability of the code, leading to many future bugs, is a net
> negative.

Indeed, but that has nothing to do with _us_ making _us_ favors, this is about the *project*.

And having said that, this particular remote-hg helper is meant for the *contrib* area, it's not half-implemented at all, and it's certainly not crashing, or at least nobody has shown any evidence of that. And for that matter, I'm sure I can point out to code that sits in contrib that does meat that criteria (it's half-implemented, and might even crash).

I know that you didn't mean otherwise, but in the context of remote-hg, this seems hardly relevant.

And even if this wasn't for contrib, and this was half-implemented, and this crashed... he still wouldn't be making _me_ any favors. The review is for the project, not for me.

Show 5 quoted lines
> So when a contributor shows up with code, we are very grateful that
> they've spent their time improving our software. But at the same time,
> we must recognize that the contributor is generally scratching their own
> itch. And we must make sure that in doing so, they did not hurt other
> people's use cases, nor regress the overall quality of the code base.
I fail to see how any code sitting in 'contrib/remote-hg' could do any of that.
Show 6 quoted lines
> It is the job of the maintainer to measure the risk and reward of each
> change and to find a balance in accepting patches. But it's difficult to
> do alone, and that is why volunteer reviewers on the list are very
> valuable. They distribute the reviewing load across many brains, and in
> many cases have expertise in particular areas that the maintainer can
> rely on.
Yes, that is helpful, _for the project_.
Show 6 quoted lines
> A submitter has scratched their own itch by writing the code. But if
> they cannot cooperate with reviewers enough to get feedback, then the
> maintainer has only two choices: review the patches themselves, or
> reject the change. And when there is conflict with the regular reviewers
> and the submitter, it is a red flag to the maintainer that it might not
> be worth spending a lot of time there.

That would be unfortunate, _for the project_, not for the submitter. I can still run the code, and I can still share it on github.

Reviewers wouldn't be making _me_ any favors. It's the project that benefits, and it's for the project that they should do it, or for themselves, not for me.

Show 5 quoted lines
> Does the code base suffer for this in the end? Perhaps. There are
> features we might reject that could have benefited everybody. But we
> might also be saving ourselves from the headaches caused by poorly
> thought-out changes. The system cannot work if everybody does not show
> up and cooperate.
Maybe, but most probably not. Take a look at this example:

% git log --oneline contrib/hg-to-git 44211e8 Correct references to /usr/bin/python which does not exist on FreeBSD 0def5b6 hg-to-git: fix COMMITTER type-o b0c051d hg-to-git: don't import the unused popen2 module af9a01e hg-to-git: use git init instead of git init-db 96f2395 hg-to-git: rewrite "git-frotz" to "git frotz" 2553ede hg-to-git: abort if the project directory is not a hg repo 6376cff hg-to-git: avoid raising a string exception 37a12dd hg-to-git: add --verbose option 13bf1a9 hg-to-git: fix parent analysis 1bc7c13 hg-to-git: improve popen calls 90e0653 hg-to-git: handle an empty dir in hg. 7c0d741 hg-to-git speedup through selectable repack intervals 98d47d4 Add hg-to-git conversion utility.

Is this fully implemented? Is this not crashing? Is the people involved showing up and cooperating?

It doesn't look like that, yet, it has not given you any headaches, probably because it's segregated in the contrib area, which what I have tried to do with my patches. _Precisely_ to minimize possible headaches.

Perhaps this is a case of double standards.
Show 6 quoted lines
> Now, as for this specific topic: it is proposed for contrib, which means
> that expectations are lower, and the rest of git does not suffer too
> much if it has rough edges. At the same time, it also means that it
> could live fairly easily outside of the tree. In fact, I think Michael
> and others have been reasonably happy with their own out-of-tree
> implementation.
It certainly could... to the detriment of the project.
Show 10 quoted lines
> I do think the proliferation of various implementations has made it hard
> for users to see which ones are worth trying. So I think there is value
> in carrying something in contrib/, as it would focus the attention of
> users, and of other developers to make improvements.
>
> So I think what I'd like to do is take your latest series into pu, with
> the intention of merging it into next soon, and then cooking it in next
> for a while. That would hopefully make it very easy for people following
> 'next' to try it out and see how it compares in the field with other
> tools they have used (the msysgit one, or others).

Excellent! I do agree that this would make it easier for everybody: users to try it, developers to contribute, and keep track of the changes, etc.

Show 11 quoted lines
> I'm a little worried about hurting progress on the msysgit version; it
> sounds like the functionality of your implementation is at parity with
> that one (thanks to both you and Johannes for answering my other email
> asking for a summary).  Johannes did mention that the design of their
> tool was meant to eventually facilitate more backends. That's something
> that might be valuable; on the other hand, that development hasn't been
> happening, and there has been no effort lately on getting it merged into
> git.git. I don't want to hold working code hostage to a future plan that
> might or might not happen.  So I hope by keeping it in next for a bit,
> that will give msysgit people time to check it out and mobilize their
> efforts to improve their version if they would like.

Fair enough. I do think my version would facilitate more backends because the code is very simple and it should be easy to see what you need to change, and you don't need to get familiarized with any framework, or classes of classes, and so on. I also think that if needed, I could come up with such a framework as well, and the resulting framework would be much simpler.

As a rule, I don't see much value in writing a framework that works only for one case, that smells more like over-engineering. If we had two cases (hg and bzr), then we might be able to know with a modicum of certainty what such a framework should have. So I would prefer to have two standalone remote-helpers, and _then_ do a framework to simplify both, but not before. But that's my personal opinion.

Now that I have free time, I might be able to spend time writing such a proof-of-concept remote-bzr, and a simple framework. But I would be concentrated on remote-hg.

That would be the last one of the supposed advantages of the msysGit remote-hg approach, and I make emphasis on supposed because we don't know _for sure_ if the current framework would be useful for a remote-bzr or not, *not* because I'm trying to offend anybody (in case anybody is thinking that). Hopefully that would show the people that have been working on this other tool that there is indeed value in this code, put aside their personal differences and work together _for the project_, but I wouldn't be holding my breath.

But to me _first_ what is important is to provide the functionality to users, and _then_ is how we organize the code to make life easier for us (the project).

Cheers.
-- 
Felipe Contreras
Felipe Contreras· Nov 2, 2012, 19:20 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 7:39 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

Show 10 quoted lines
> As a rule, I don't see much value in writing a framework that works
> only for one case, that smells more like over-engineering. If we had
> two cases (hg and bzr), then we might be able to know with a modicum
> of certainty what such a framework should have. So I would prefer to
> have two standalone remote-helpers, and _then_ do a framework to
> simplify both, but not before. But that's my personal opinion.
>
> Now that I have free time, I might be able to spend time writing such
> a proof-of-concept remote-bzr, and a simple framework. But I would be
> concentrated on remote-hg.
Actually, there's no point in that; there's already a git-remote-bzr:
http://bazaar.launchpad.net/~bzr-git/bzr-git/trunk/view/head:/git-remote-bzr
So, what do we need a python framework for?
Cheers.
-- 
Felipe Contreras
Felipe Contreras· Nov 4, 2012, 02:28 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 8:20 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

Show 17 quoted lines
> On Fri, Nov 2, 2012 at 7:39 PM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>
>> As a rule, I don't see much value in writing a framework that works
>> only for one case, that smells more like over-engineering. If we had
>> two cases (hg and bzr), then we might be able to know with a modicum
>> of certainty what such a framework should have. So I would prefer to
>> have two standalone remote-helpers, and _then_ do a framework to
>> simplify both, but not before. But that's my personal opinion.
>>
>> Now that I have free time, I might be able to spend time writing such
>> a proof-of-concept remote-bzr, and a simple framework. But I would be
>> concentrated on remote-hg.
>
> Actually, there's no point in that; there's already a git-remote-bzr:
>
> http://bazaar.launchpad.net/~bzr-git/bzr-git/trunk/view/head:/git-remote-bzr

Turns out the quality of that tools is not that great, so I decided to write a simple one using bzr-fastimport. It works nicely, although I wouldn't trust the quality of bzr-fastimport too much.

It's so simple I don't see the need of a framework, but if needed, one could be done taking these git-remote-{hg,bzr} as a basis.

Cheers.
-- 
Felipe Contreras
Thomas Adam· Nov 2, 2012, 23:18 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On 2 November 2012 18:39, Felipe Contreras <felipe.contreras@gmail.com> wrote:
Show 5 quoted lines
> I disagree. The open source process works not by making favors to each
> other, but by everyone sharing and improving the code, by
> *collaborating*. "I review your code if you review mine", or "if you
> by me a bear in the next conference" is not the spirit of open source,
> although it might happen often.
So shunning any attempt at explanation, and peddling your own thoughts
over and over again, irrespective of whether you contribute code or
not -- doesn't mean to say you're right, Felipe.  And that's the
fundamental issue here -- your code speaks for itself, sure, no one
denies that, but the code is not even *half* of what makes up the
discussion.  And so far, the surrounding context and attitude from you
doesn't help or enhance the process under which your code is reviewed.
 And no, you cannot philosophise this, or wriggle out of it through
idealism or some other "charter" or "code of conduct" -- as reviewers
of your code, we have to interact with you to be able to better it.
But you seem very reluctant to do that.
The fact that we're even having the conversation is evident of that.
-- Thomas Adam
Felipe Contreras· Nov 2, 2012, 23:52 UTC · re: Thomas Adam · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Sat, Nov 3, 2012 at 12:18 AM, Thomas Adam <thomas@xteddy.org> wrote:
Show 10 quoted lines
> On 2 November 2012 18:39, Felipe Contreras <felipe.contreras@gmail.com> wrote:
>> I disagree. The open source process works not by making favors to each
>> other, but by everyone sharing and improving the code, by
>> *collaborating*. "I review your code if you review mine", or "if you
>> by me a bear in the next conference" is not the spirit of open source,
>> although it might happen often.
>
> So shunning any attempt at explanation, and peddling your own thoughts
> over and over again, irrespective of whether you contribute code or
> not -- doesn't mean to say you're right, Felipe.
Who is saying I'm right? Certainly not me.

I have explained patches over and over, even to the point that people apparently get offended, and now you say I should explain more?

I'm sorry, but no, you cannot have your cake and eat it at the same time. Either you want me to explain things, or not.

Show 5 quoted lines
> And that's the
> fundamental issue here -- your code speaks for itself, sure, no one
> denies that, but the code is not even *half* of what makes up the
> discussion.  And so far, the surrounding context and attitude from you
> doesn't help or enhance the process under which your code is reviewed.

I would say it's the other way around, it's the attitude of other people that believe they are entitled to their opinion not being shined in a critical fashion, while at the same time being very critical themselves.

If you want to disagree, fine, but it's still the project that gets hurt, not me, reviewing code is still for the benefit of the project.

>  And no, you cannot philosophise this, or wriggle out of it through
> idealism or some other "charter" or "code of conduct" -- as reviewers
> of your code, we have to interact with you to be able to better it.
That's right, for the benefit of the project.
> But you seem very reluctant to do that.

Reluctant to what? Interact? I've answered every single question, and then some. I've also implemented tests, and addressed every criticism of this patch series however rude that criticism was thrown.

It's actually the other way around. There's a thread about netiquette, precisely to avoid certain kinds of discussion.

Show me a *single* instance where I've ignored a review comment, or whatever you mean by being reluctant to interact.

> The fact that we're even having the conversation is evident of that.

The fact that the sun raised at east and set at the west was evident that it was rotating around the Earth, but that, like many other assumptions, was wrong.

Cheers.
-- 
Felipe Contreras
Felipe Contreras· Oct 31, 2012, 18:04 UTC · re: Michael J Gruber · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 4:55 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

> Felipe Contreras venit, vidit, dixit 31.10.2012 16:39:
>> Didn't think so. The truth of the matter is that it doesn't matter
>> what I do code-wise.
>
> Just try, seriously.
All right.
First of all, I clone the repositories pointed out:

git://github.com/fingolfin/git.git (remote-hg) git://github.com/mjg/git.git (remote-hg) git://github.com/msysgit/git.git (d3ac32c^..1e000d4)

I rebase them on top ov v1.8.0... all 3 branches are different from each other. I'll pick yours.

% git clone hg::~/dev/hg
Cloning into 'hg'...
Traceback (most recent call last):
  File "/opt/git-2/libexec/git-core/git-remote-hg", line 101, in <module>
    sys.exit(HgRemoteHelper().main(sys.argv))
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 196, in main
    repo = self.get_repo(alias, url)
  File "/opt/git-2/libexec/git-core/git-remote-hg", line 35, in get_repo
    if repo.capable('branchmap'):
AttributeError: 'mqrepo' object has no attribute 'capable'
Let's try msysgit... The same.
Max's? The same.
Maybe it's just the setup and the tests actually pass?
# failed 11 among 14 test(s)
Nope.

All right, it probably doesn't work with recent versions of mercurial. Let's try with hg v2.2:

# failed 4 among 14 test(s)
All right, that's progress.
Can I clone now?
% git clone hg::~/dev/hg
Cloning into 'hg'...
progress Exported revision 0.
progress Exported revision 1000.
fatal: Missing space before < in ident string: Anupam
Kapoor<anupam.kapoor@gmail.com> <none@none> 1127407335 -0700
fast-import: dumping crash report to /tmp/hg/.git/fast_import_crash_18197
fatal: Error while running fast-import
Traceback (most recent call last):
  File "/opt/git-2/libexec/git-core/git-remote-hg", line 101, in <module>
    sys.exit(HgRemoteHelper().main(sys.argv))
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 204, in main
    more = self.read_one_line(repo)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 169, in read_one_line
    func(repo, cmdline)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 108, in do_import
    repo.exporter.export_repo(repo.gitdir, refs)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/exporter.py",
line 27, in export_repo
    exporter.export_repo(refs)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 246, in export_repo
    exported = self.export_revision(ctx) or exported
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 215, in export_revision
    self.export_files(ctx)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 190, in export_files
    self.write_file(ctx, name, idnum)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 105, in write_file
    self.write_blob(data, idnum)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 99, in write_blob
    self.write_data(data)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 91, in write_data
    self.write(data, LF)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 52, in write
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe
Nope.
All right, let's go back to hg v1.9 (Jun 2011).
# passed all 14 test(s)
Yay!
% git clone hg::~/dev/hg
Cloning into 'hg'...
progress Exported revision 0.
progress Exported revision 1000.
fatal: Missing space before < in ident string: Anupam
Kapoor<anupam.kapoor@gmail.com> <none@none> 1127407335 -0700
fast-import: dumping crash report to /tmp/hg/.git/fast_import_crash_18646
fatal: Error while running fast-import
Traceback (most recent call last):
  File "/opt/git-2/libexec/git-core/git-remote-hg", line 101, in
<module>
    sys.exit(HgRemoteHelper().main(sys.argv))
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 204, in main
    more = self.read_one_line(repo)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 169, in read_one_line
    func(repo, cmdline)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/helper.py",
line 108, in do_import
    repo.exporter.export_repo(repo.gitdir, refs)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/exporter.py",
line 27, in export_repo
    exporter.export_repo(refs)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 246, in export_repo
    exported = self.export_revision(ctx) or exported
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 215, in export_revision
    self.export_files(ctx)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 190, in export_files
    self.write_file(ctx, name, idnum)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 105, in write_file
    self.write_blob(data, idnum)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 99, in write_blob
    self.write_data(data)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 91, in write_data
    self.write(data, LF)
  File "/opt/git-2/lib/python2.7/site-packages/git_remote_helpers/hg/hgexport.py",
line 52, in write
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe
Still doesn't work.
Let's try msysgit.

% git clone hg::~/dev/hg Cloning into 'hg'... progress Exported revision 0. progress Exported revision 1000. progress Exported revision 2000. progress Exported revision 3000. progress Exported revision 4000. progress Exported revision 5000. progress Exported revision 6000. progress Exported revision 7000. progress Exported revision 8000. progress Exported revision 9000. progress Exported revision 10000. progress Exported revision 11000. progress Exported revision 12000. progress Exported revision 13000. progress Exported revision 14000. progress Exported revision 15000. progress Exported revision 16000. progress Exported revision 17000.

Finally!
Let's run my tests:

test.sh: # failed 1 among 1 test(s)

test-bidi.sh: # failed 5 among 6 test(s)

test-hg-git.sh # failed 9 among 10 test(s)

Other than the setup tests which really don't exercise any code, all the tests fail.

And it's not only a silly error like couldn't find remote-hg; the tests do really fail:

Traceback (most recent call last):
  File "/home/felipec/dev/git-other-remote-hg/git-remote-hg", line
101, in <module>
    sys.exit(HgRemoteHelper().main(sys.argv))
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/helper.py",
line 204, in main
    more = self.read_one_line(repo)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/helper.py",
line 169, in read_one_line
    func(repo, cmdline)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/helper.py",
line 122, in do_export
    localrepo.importer.do_import(localrepo.gitdir)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/hg/importer.py",
line 27, in do_import
    processor.parseMany(sources, parser.ImportParser, procc)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/fastimport/processor.py",
line 219, in parseMany
    processor.process(parser.parse())
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/fastimport/processor.py",
line 76, in process
    handler(self, cmd)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/hg/hgimport.py",
line 262, in commit_handler
    self.idmap[cmd.id] = self.putcommit(modified, modes, copies, cmt)
  File "/home/felipec/dev/git-other-remote-hg/t/../git_remote_helpers/build/lib/git_remote_helpers/hg/hgimport.py",
line 294, in putcommit
    self.repo.commitctx(ctx)
  File "/home/felipec/dev/hg/mercurial/localrepo.py", line 1112, in commitctx
    user, ctx.date(), ctx.extra().copy())
  File "/home/felipec/dev/hg/mercurial/changelog.py", line 213, in add
    user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
  File "/home/felipec/dev/hg/mercurial/encoding.py", line 133, in fromlocal
    raise error.Abort("decoding near '%s': %s!" % (sub, inst))
mercurial.error.Abort: decoding near 'add älphà
': 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in
range(128)!
Let's gather what we have:
* msysgit: works in hg v2.2, but not hg v2.3
* yours: kind of works on hg v1.9, but not really
* Max's: works on hg v2.2, but not hg v2.3
None of them pass even one of my tests.
Now lets remove all the supposed required patches to git core:
# passed all 14 test(s)
But that doesn't really say much, these tests are _really_ simple.
How about performance?
 Performance counter stats for 'git clone hg::~/dev/hg':
     241391.332748 task-clock                #    1.387 CPUs utilized
            53,357 context-switches          #    0.221 K/sec
             3,797 CPU-migrations            #    0.016 K/sec
         1,258,346 page-faults               #    0.005 M/sec
   433,914,358,895 cycles                    #    1.798 GHz
   185,410,787,111 stalled-cycles-frontend   #   42.73% frontend cycles idle
   <not supported> stalled-cycles-backend
   581,663,561,600 instructions              #    1.34  insns per cycle
                                             #    0.32  stalled cycles per insn
   101,993,199,721 branches                  #  422.522 M/sec
     5,208,212,657 branch-misses             #    5.11% of all branches
     174.038642915 seconds time elapsed
Compared to;
 Performance counter stats for 'git clone hg::~/dev/hg':
     412892.981091 task-clock                #    1.211 CPUs utilized
           200,029 context-switches          #    0.484 K/sec
             9,288 CPU-migrations            #    0.022 K/sec
           632,783 page-faults               #    0.002 M/sec
   741,785,312,967 cycles                    #    1.797 GHz
   306,533,270,745 stalled-cycles-frontend   #   41.32% frontend cycles idle
   <not supported> stalled-cycles-backend
 1,012,488,224,809 instructions              #    1.36  insns per cycle
                                             #    0.30  stalled cycles per insn
   168,056,255,731 branches                  #  407.021 M/sec
     9,528,432,325 branch-misses             #    5.67% of all branches
     340.976843750 seconds time elapsed

Looks like there's something to improve in this area, but I wouldn't be surprised if the reason for the better performance is that something is not being done. I'll investigate.

And all this for the low price of:
 .gitignore                                    |   1 +
 Makefile                                      |   1 +
 git-remote-hg.py                              | 101 +++++++++++
 git-remote-testgit.py                         | 295
++++++------------------------
 git_remote_helpers/fastimport/commands.py     | 469
+++++++++++++++++++++++++++++++++++++++++++++++
 git_remote_helpers/fastimport/dates.py        |  79 ++++++++
 git_remote_helpers/fastimport/errors.py       | 182 +++++++++++++++++++
 git_remote_helpers/fastimport/head_tracker.py |  47 +++++
 git_remote_helpers/fastimport/helpers.py      |  88 +++++++++
 git_remote_helpers/fastimport/idmapfile.py    |  65 +++++++
 git_remote_helpers/fastimport/parser.py       | 621
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 git_remote_helpers/fastimport/processor.py    | 222 +++++++++++++++++++++++
 git_remote_helpers/git/importer.py            |  30 +--
 git_remote_helpers/git/repo.py                |   8 +-
 git_remote_helpers/helper.py                  | 207 +++++++++++++++++++++
 git_remote_helpers/hg/exporter.py             |  29 +++
 git_remote_helpers/hg/hg.py                   | 126 +++++++++++++
 git_remote_helpers/hg/hgexport.py             | 280
++++++++++++++++++++++++++++
 git_remote_helpers/hg/hgimport.py             | 401
+++++++++++++++++++++++++++++++++++++++++
 git_remote_helpers/hg/importer.py             |  29 +++
 git_remote_helpers/hg/non_local.py            |  51 ++++++
 git_remote_helpers/hg/util.py                 |  14 ++
 git_remote_helpers/setup.py                   |   3 +-
 t/t5800-remote-helpers.sh                     |  19 ++
 t/t5801-remote-hg.sh                          | 143 +++++++++++++++
 25 files changed, 3242 insertions(+), 269 deletions(-)
Compared to:
 contrib/remote-hg/Makefile       |  13 ++
 contrib/remote-hg/git-remote-hg  | 780
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 contrib/remote-hg/test-bidi.sh   | 241 ++++++++++++++++++++++++
 contrib/remote-hg/test-hg-git.sh | 464
+++++++++++++++++++++++++++++++++++++++++++++
 contrib/remote-hg/test.sh        |  45 +++++
 5 files changed, 1543 insertions(+)

Now, sure, I am biased, but the truth is I don't know of a single feature that this remote-hg supports that my version doesn't. If there's any, I'm all ears; I'll implement it right away.

At no point in time did I ever suggested this code to be thrown away, but if there's any possibility salvaging some of this code, they only way I see it is if I myself do it, because nobody has stepped up to work on this. And quite frankly, I think I've already done more than enough, so...

Cheers.

-- Felipe Contreras

Felipe Contreras· Oct 31, 2012, 19:47 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 7:04 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

> How about performance?
>      174.038642915 seconds time elapsed
>
> Compared to;
Show 5 quoted lines
>      340.976843750 seconds time elapsed
>
> Looks like there's something to improve in this area, but I wouldn't
> be surprised if the reason for the better performance is that
> something is not being done. I'll investigate.

Turns out msysgit's remote-hg is not exporting the whole repository, that's why it's faster =/

Let's try with a smaller repo:
 Performance counter stats for 'git clone hg::~/dev/love love-2':
      16130.554299 task-clock                #    1.311 CPUs utilized
             5,625 context-switches          #    0.349 K/sec
               241 CPU-migrations            #    0.015 K/sec
            84,042 page-faults               #    0.005 M/sec
    28,985,094,782 cycles                    #    1.797 GHz
    12,235,424,421 stalled-cycles-frontend   #   42.21% frontend cycles idle
   <not supported> stalled-cycles-backend
    38,762,850,763 instructions              #    1.34  insns per cycle
                                             #    0.32  stalled cycles per insn
     6,727,815,043 branches                  #  417.085 M/sec
       354,887,290 branch-misses             #    5.27% of all branches
      12.300536156 seconds time elapsed
And mine:
 Performance counter stats for 'git clone hg::~/dev/love love-1':
      16116.643370 task-clock                #    1.295 CPUs utilized
             6,270 context-switches          #    0.389 K/sec
               183 CPU-migrations            #    0.011 K/sec
            57,767 page-faults               #    0.004 M/sec
    28,962,073,772 cycles                    #    1.797 GHz
    11,844,122,698 stalled-cycles-frontend   #   40.90% frontend cycles idle
   <not supported> stalled-cycles-backend
    39,679,556,857 instructions              #    1.37  insns per cycle
                                             #    0.30  stalled cycles per insn
     6,609,397,307 branches                  #  410.098 M/sec
       371,092,848 branch-misses             #    5.61% of all branches
      12.446643210 seconds time elapsed

That's more like it. msysgit's is still missing a few commits, but nothing mayor.

Cheers.

-- Felipe Contreras

Felipe Contreras· Nov 1, 2012, 04:08 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Wed, Oct 31, 2012 at 8:47 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

Show 17 quoted lines
> On Wed, Oct 31, 2012 at 7:04 PM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>
>> How about performance?
>
>>      174.038642915 seconds time elapsed
>>
>> Compared to;
>
>>      340.976843750 seconds time elapsed
>>
>> Looks like there's something to improve in this area, but I wouldn't
>> be surprised if the reason for the better performance is that
>> something is not being done. I'll investigate.
>
> Turns out msysgit's remote-hg is not exporting the whole repository,
> that's why it's faster =/

It seems the reason is that it would only export to the point where the branch is checked out. After updating the to the tip I noticed there was a performance difference.

I investigated and found two reasons:
1) msysgit's version doesn't export files twice, I've now implemented the same
2) msysgit's version uses a very simple algorithm to find out file changes

This second point causes msysgit to miss some file changes. Using the same algorithm I get the same performance, but the output is not correct.

Here's after the latest updates:
 Performance counter stats for 'git clone hg::~/dev/hg-clean hg-clean-5':
     288338.286545 task-clock                #    1.299 CPUs utilized
            46,441 context-switches          #    0.161 K/sec
             6,098 CPU-migrations            #    0.021 K/sec
           509,600 page-faults               #    0.002 M/sec
   518,370,729,897 cycles                    #    1.798 GHz
   204,476,102,906 stalled-cycles-frontend   #   39.45% frontend cycles idle
   <not supported> stalled-cycles-backend
   726,005,034,102 instructions              #    1.40  insns per cycle
                                             #    0.28  stalled cycles per insn
   127,662,400,651 branches                  #  442.752 M/sec
     6,758,976,722 branch-misses             #    5.29% of all branches
     222.020233009 seconds time elapsed

Which is taking roughly 60% more time than msysgit, but the output is actually correct.

Cheers.
-- 
Felipe Contreras
Jeff King· Nov 2, 2012, 14:48 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 01, 2012 at 05:08:52AM +0100, Felipe Contreras wrote:
Show 15 quoted lines
> > Turns out msysgit's remote-hg is not exporting the whole repository,
> > that's why it's faster =/
> 
> It seems the reason is that it would only export to the point where
> the branch is checked out. After updating the to the tip I noticed
> there was a performance difference.
> 
> I investigated and found two reasons:
> 
> 1) msysgit's version doesn't export files twice, I've now implemented the same
> 2) msysgit's version uses a very simple algorithm to find out file changes
> 
> This second point causes msysgit to miss some file changes. Using the
> same algorithm I get the same performance, but the output is not
> correct.

Do you have a test case that demonstrates this? It would be helpful for reviewers, but also helpful to msysgit people if they want to fix their implementation.

-Peff
Felipe Contreras· Nov 2, 2012, 16:41 UTC · re: Jeff King · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 3:48 PM, Jeff King <peff@peff.net> wrote:
Show 21 quoted lines
> On Thu, Nov 01, 2012 at 05:08:52AM +0100, Felipe Contreras wrote:
>
>> > Turns out msysgit's remote-hg is not exporting the whole repository,
>> > that's why it's faster =/
>>
>> It seems the reason is that it would only export to the point where
>> the branch is checked out. After updating the to the tip I noticed
>> there was a performance difference.
>>
>> I investigated and found two reasons:
>>
>> 1) msysgit's version doesn't export files twice, I've now implemented the same
>> 2) msysgit's version uses a very simple algorithm to find out file changes
>>
>> This second point causes msysgit to miss some file changes. Using the
>> same algorithm I get the same performance, but the output is not
>> correct.
>
> Do you have a test case that demonstrates this? It would be helpful for
> reviewers, but also helpful to msysgit people if they want to fix their
> implementation.
Cloning the mercurial repo:

% hg log --stat -r 131 changeset: 131:c9d51742471c parent: 127:44538462d3c8 user: jake@edge2.net date: Sat May 21 11:35:26 2005 -0700 summary: moving hgweb to mercurial subdir

 hgweb.py           |  377
------------------------------------------------------------------------------------------
 mercurial/hgweb.py |  377
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 377 insertions(+), 377 deletions(-)
% git show --stat 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
commit 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
Author: jake@edge2.net <none@none>
Date:   Sat May 21 11:35:26 2005 -0700
    moving hgweb to mercurial subdir
 mercurial/hgweb.py | 377
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 377 insertions(+)
Cheers.
-- 
Felipe Contreras
Felipe Contreras· Nov 2, 2012, 18:01 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Fri, Nov 2, 2012 at 5:41 PM, Felipe Contreras <felipe.contreras@gmail.com> wrote:

Show 48 quoted lines
> On Fri, Nov 2, 2012 at 3:48 PM, Jeff King <peff@peff.net> wrote:
>> On Thu, Nov 01, 2012 at 05:08:52AM +0100, Felipe Contreras wrote:
>>
>>> > Turns out msysgit's remote-hg is not exporting the whole repository,
>>> > that's why it's faster =/
>>>
>>> It seems the reason is that it would only export to the point where
>>> the branch is checked out. After updating the to the tip I noticed
>>> there was a performance difference.
>>>
>>> I investigated and found two reasons:
>>>
>>> 1) msysgit's version doesn't export files twice, I've now implemented the same
>>> 2) msysgit's version uses a very simple algorithm to find out file changes
>>>
>>> This second point causes msysgit to miss some file changes. Using the
>>> same algorithm I get the same performance, but the output is not
>>> correct.
>>
>> Do you have a test case that demonstrates this? It would be helpful for
>> reviewers, but also helpful to msysgit people if they want to fix their
>> implementation.
>
> Cloning the mercurial repo:
>
> % hg log --stat -r 131
> changeset:   131:c9d51742471c
> parent:      127:44538462d3c8
> user:        jake@edge2.net
> date:        Sat May 21 11:35:26 2005 -0700
> summary:     moving hgweb to mercurial subdir
>
>  hgweb.py           |  377
> ------------------------------------------------------------------------------------------
>  mercurial/hgweb.py |  377
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 377 insertions(+), 377 deletions(-)
>
> % git show --stat 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
> commit 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
> Author: jake@edge2.net <none@none>
> Date:   Sat May 21 11:35:26 2005 -0700
>
>     moving hgweb to mercurial subdir
>
>  mercurial/hgweb.py | 377
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 377 insertions(+)

I talked with some people in #mercurial, and apparently there is a concept of a 'changelog' that is supposed to store these changes, but since the format has changed, the content of it is unreliable. That's not a big problem because it's used mostly for reporting purposes (log, query), not for doing anything reliable.

To reliably see the changes, one has to compare the 'manifest' of the revisions involved, which contain *all* the files in them.

That's what I was doing already, but I found a more efficient way to do it. msysGit is using the changelog, which is quite fast, but not reliable.

Unfortunately while going trough mercurial's code, I found an issue, and it turns out that 1) is not correct.

In mercurial, a file hash contains also the parent file nodes, which means that even if two files have the same content, they would not have the same hash, so there's no point in keeping track of them to avoid extracting the data unnecessarily, because in order to make sure they are different, you need to extract the data anyway, defeating the purpose.

Which means mercurial doesn't really behave as one would expect:
# add files with the same content
 $ echo a > a
  $ hg ci -Am adda
  adding a
  $ echo a >> a
  $ hg ci -m changea
  $ echo a > a
  $ hg st --rev 0
  $ hg ci -m reverta
  $ hg log -G --template '{rev} {desc}\n'
  @  2 reverta
  |
  o  1 changea
  |
  o  0 adda
# check the difference between the first and the last revision
  $ hg st --rev 0:2
  M a
  $ hg cat -r 0 a
  a
  $ hg cat -r 2 a
  a

I will be checking again from where did I get the performance improvements, but most likely it's from my implementation of mercurial's repo.status().

Cheers.
-- 
Felipe Contreras
Michael J Gruber· Nov 5, 2012, 14:13 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

Felipe Contreras venit, vidit, dixit 02.11.2012 19:01:
Show 56 quoted lines
> On Fri, Nov 2, 2012 at 5:41 PM, Felipe Contreras
> <felipe.contreras@gmail.com> wrote:
>> On Fri, Nov 2, 2012 at 3:48 PM, Jeff King <peff@peff.net> wrote:
>>> On Thu, Nov 01, 2012 at 05:08:52AM +0100, Felipe Contreras wrote:
>>>
>>>>> Turns out msysgit's remote-hg is not exporting the whole repository,
>>>>> that's why it's faster =/
>>>>
>>>> It seems the reason is that it would only export to the point where
>>>> the branch is checked out. After updating the to the tip I noticed
>>>> there was a performance difference.
>>>>
>>>> I investigated and found two reasons:
>>>>
>>>> 1) msysgit's version doesn't export files twice, I've now implemented the same
>>>> 2) msysgit's version uses a very simple algorithm to find out file changes
>>>>
>>>> This second point causes msysgit to miss some file changes. Using the
>>>> same algorithm I get the same performance, but the output is not
>>>> correct.
>>>
>>> Do you have a test case that demonstrates this? It would be helpful for
>>> reviewers, but also helpful to msysgit people if they want to fix their
>>> implementation.
>>
>> Cloning the mercurial repo:
>>
>> % hg log --stat -r 131
>> changeset:   131:c9d51742471c
>> parent:      127:44538462d3c8
>> user:        jake@edge2.net
>> date:        Sat May 21 11:35:26 2005 -0700
>> summary:     moving hgweb to mercurial subdir
>>
>>  hgweb.py           |  377
>> ------------------------------------------------------------------------------------------
>>  mercurial/hgweb.py |  377
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 377 insertions(+), 377 deletions(-)
>>
>> % git show --stat 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
>> commit 1f9bcfe7cc3d7af7b4533895181acd316ce172d8
>> Author: jake@edge2.net <none@none>
>> Date:   Sat May 21 11:35:26 2005 -0700
>>
>>     moving hgweb to mercurial subdir
>>
>>  mercurial/hgweb.py | 377
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 377 insertions(+)
> 
> I talked with some people in #mercurial, and apparently there is a
> concept of a 'changelog' that is supposed to store these changes, but
> since the format has changed, the content of it is unreliable. That's
> not a big problem because it's used mostly for reporting purposes
> (log, query), not for doing anything reliable.

Is the changelog stored in the repo (i.e. generated by the hg version at commit time) or generated on the fly (i.e. generated by the hg version at hand)? See also below.

> To reliably see the changes, one has to compare the 'manifest' of the
> revisions involved, which contain *all* the files in them.

'manifest' == '(exploded) tree', right? Just making sure my hg fu is not subzero.

Show 13 quoted lines
> That's what I was doing already, but I found a more efficient way to
> do it. msysGit is using the changelog, which is quite fast, but not
> reliable.
> 
> Unfortunately while going trough mercurial's code, I found an issue,
> and it turns out that 1) is not correct.
> 
> In mercurial, a file hash contains also the parent file nodes, which
> means that even if two files have the same content, they would not
> have the same hash, so there's no point in keeping track of them to
> avoid extracting the data unnecessarily, because in order to make sure
> they are different, you need to extract the data anyway, defeating the
> purpose.

Do I understand correctly that neither the msysgit version nor yours can detect duplicate blobs (without requesting them) because of that sha1 issue?

I'm really wondering why a file blob hash carries its history along in the sha1. This appears completely strange to gitters (being brain washed about "content tracking"), but may be due to hg's extensive use of delta, or really: delta chains (which do have their merit on the server side).

Show 27 quoted lines
> Which means mercurial doesn't really behave as one would expect:
> 
> # add files with the same content
> 
>  $ echo a > a
>   $ hg ci -Am adda
>   adding a
>   $ echo a >> a
>   $ hg ci -m changea
>   $ echo a > a
>   $ hg st --rev 0
>   $ hg ci -m reverta
>   $ hg log -G --template '{rev} {desc}\n'
>   @  2 reverta
>   |
>   o  1 changea
>   |
>   o  0 adda
> 
> # check the difference between the first and the last revision
> 
>   $ hg st --rev 0:2
>   M a
>   $ hg cat -r 0 a
>   a
>   $ hg cat -r 2 a
>   a

That is really scary. What use is "hg stat --rev" then? Not blaming you for hg, of course.

On that tangent, I just noticed recently that hg has no python api. Seriously [1]. They even tell us not to use the internal python api. msysgit has been lacking support for newer hg, and you've had to add support for older versions (hg 1.9 will be around on quite some stable/LTS/EL distro releases) after developing on newer/current ones. I'm wondering how well that scales in the long term (telling from git-svn experience: it does not scale well), or whether using some stable api like 'hgapi' would be a huge bottleneck.

Cheers, Michael

[1] http://mercurial.selenic.com/wiki/MercurialApi
Really funny to see they recommend the command line as api ;)
Felipe Contreras· Nov 5, 2012, 15:36 UTC · re: Michael J Gruber · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Mon, Nov 5, 2012 at 3:13 PM, Michael J Gruber <git@drmicha.warpmail.net> wrote:

> Felipe Contreras venit, vidit, dixit 02.11.2012 19:01:
Show 9 quoted lines
>> I talked with some people in #mercurial, and apparently there is a
>> concept of a 'changelog' that is supposed to store these changes, but
>> since the format has changed, the content of it is unreliable. That's
>> not a big problem because it's used mostly for reporting purposes
>> (log, query), not for doing anything reliable.
>
> Is the changelog stored in the repo (i.e. generated by the hg version at
> commit time) or generated on the fly (i.e. generated by the hg version
> at hand)? See also below.

I don't know. I would expect it to be the former, and then when the format changes, generated by the tool that did the conversion.

Show 5 quoted lines
>> To reliably see the changes, one has to compare the 'manifest' of the
>> revisions involved, which contain *all* the files in them.
>
> 'manifest' == '(exploded) tree', right? Just making sure my hg fu is not
> subzero.
Yeah, the tree. As I said, it contains all the files.
Show 16 quoted lines
>> That's what I was doing already, but I found a more efficient way to
>> do it. msysGit is using the changelog, which is quite fast, but not
>> reliable.
>>
>> Unfortunately while going trough mercurial's code, I found an issue,
>> and it turns out that 1) is not correct.
>>
>> In mercurial, a file hash contains also the parent file nodes, which
>> means that even if two files have the same content, they would not
>> have the same hash, so there's no point in keeping track of them to
>> avoid extracting the data unnecessarily, because in order to make sure
>> they are different, you need to extract the data anyway, defeating the
>> purpose.
>
> Do I understand correctly that neither the msysgit version nor yours can
> detect duplicate blobs (without requesting them) because of that sha1 issue?
That's correct.
Show 5 quoted lines
> I'm really wondering why a file blob hash carries its history along in
> the sha1. This appears completely strange to gitters (being brain washed
> about "content tracking"), but may be due to hg's extensive use of
> delta, or really: delta chains (which do have their merit on the server
> side).
It is a surprise to me too. I see absolutely no reason why that would be useful.

It seems like bazaar does store the file hashes without the parent info, like git.

Show 39 quoted lines
>> Which means mercurial doesn't really behave as one would expect:
>>
>> # add files with the same content
>>
>>  $ echo a > a
>>   $ hg ci -Am adda
>>   adding a
>>   $ echo a >> a
>>   $ hg ci -m changea
>>   $ echo a > a
>>   $ hg st --rev 0
>>   $ hg ci -m reverta
>>   $ hg log -G --template '{rev} {desc}\n'
>>   @  2 reverta
>>   |
>>   o  1 changea
>>   |
>>   o  0 adda
>>
>> # check the difference between the first and the last revision
>>
>>   $ hg st --rev 0:2
>>   M a
>>   $ hg cat -r 0 a
>>   a
>>   $ hg cat -r 2 a
>>   a
>
> That is really scary. What use is "hg stat --rev" then? Not blaming you
> for hg, of course.
>
> On that tangent, I just noticed recently that hg has no python api.
> Seriously [1]. They even tell us not to use the internal python api.
> msysgit has been lacking support for newer hg, and you've had to add
> support for older versions (hg 1.9 will be around on quite some
> stable/LTS/EL distro releases) after developing on newer/current ones.
> I'm wondering how well that scales in the long term (telling from
> git-svn experience: it does not scale well), or whether using some
> stable api like 'hgapi' would be a huge bottleneck.

I don't know. I have never really used mercurial until recently. I don't know how often they change their APIs and/or repository formats. I would say the burden of updating to newer APIs is probably much less than the burden of implementing code that accesses their repositories directly, and eventually possibly rewriting the code when they change the format.

If we were to access the repository directly, I would choose to use Ruby for that, but given that 'we' is increasingly looking like 'I'. I probably wouldn't.

Cheers.
-- 
Felipe Contreras
Junio C Hamano· Nov 1, 2012, 01:22 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 00/13] New remote-hg helper

Felipe Contreras <felipe.contreras@gmail.com> wrote:
>And finally, what do more do you expect me to do? About the code, and
>only the code.
The analysis that does in the log messages is an important part of "code" in this project, so that may be a good place to start. Both Jonathan and J6t asked specific updates to your log message, no?
Felipe Contreras· Nov 1, 2012, 02:50 UTC · re: Junio C Hamano · lore

Re: [PATCH v4 00/13] New remote-hg helper

On Thu, Nov 1, 2012 at 2:22 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 8 quoted lines
>
>
> Felipe Contreras <felipe.contreras@gmail.com> wrote:
>
>>And finally, what do more do you expect me to do? About the code, and
>>only the code.
>
> The analysis that does in the log messages is an important part of "code" in this project, so that may be a good place to start. Both Jonathan and J6t asked specific updates to your log message, no?

Regarding git-remote-hg? No. They haven't said anything about any of those patches.

-- 
Felipe Contreras

← back to recent threads