#!/usr/bin/env python
#
# Copyright (c) 2012 Felipe Contreras
#

# Inspired by Rocco Rutte's hg-fast-export

# Just copy to your ~/bin, or anywhere in your $PATH.
# Then you can clone with:
# git clone hg::/path/to/mercurial/repo/
#
# For remote repositories a local clone is stored in
# "$GIT_DIR/hg/origin/clone/.hg/".

from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions, discovery, util

import re
import sys
import os
import json
import shutil
import subprocess
import urllib
import atexit
import urlparse, hashlib

#
# If you are not in hg-git-compat mode and want to disable the tracking of
# named branches:
# git config --global remote-hg.track-branches false
#
# If you want the equivalent of hg's clone/pull--insecure option:
# git config --global remote-hg.insecure true
#
# 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/', HEAD is a special case.
#
# hg:
# Emulate hg-git.
# Only hg bookmarks are exported as git branches.
# Commits are modified to preserve hg information and allow bidirectionality.
#

NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$')
EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)')
AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')

VERSION = 2

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)

def hgmode(mode):
    m = { '100755': 'x', '120000': 'l' }
    return m.get(mode, '')

def hghex(n):
    return node.hex(n)

def hgbin(n):
    return node.bin(n)

def hgref(ref):
    return ref.replace('___', ' ')

def gitref(ref):
    return ref.replace(' ', '___')

def check_version(*check):
    if not hg_version:
        return True
    return hg_version >= check

def get_config(config):
    cmd = ['git', 'config', '--get', config]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    output, _ = process.communicate()
    return output

def get_config_bool(config, default=False):
    value = get_config(config).rstrip('\n')
    if value == "true":
        return True
    elif value == "false":
        return False
    else:
        return default

class Marks:

    def __init__(self, path, repo):
        self.path = path
        self.repo = repo
        self.clear()
        self.load()

        if self.version < VERSION:
            if self.version == 1:
                self.upgrade_one()

            # upgraded?
            if self.version < VERSION:
                self.clear()
                self.version = VERSION

    def clear(self):
        self.tips = {}
        self.marks = {}
        self.rev_marks = {}
        self.last_mark = 0
        self.version = 0

    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']
        self.version = tmp.get('version', 1)

        for rev, mark in self.marks.iteritems():
            self.rev_marks[mark] = rev

    def upgrade_one(self):
        def get_id(rev):
            return hghex(self.repo.changelog.node(int(rev)))
        self.tips = dict((name, get_id(rev)) for name, rev in self.tips.iteritems())
        self.marks = dict((get_id(rev), mark) for rev, mark in self.marks.iteritems())
        self.rev_marks = dict((mark, get_id(rev)) for mark, rev in self.rev_marks.iteritems())
        self.version = 2

    def dict(self):
        return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version }

    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[rev]

    def to_rev(self, mark):
        return str(self.rev_marks[mark])

    def next_mark(self):
        self.last_mark += 1
        return self.last_mark

    def get_mark(self, rev):
        self.last_mark += 1
        self.marks[rev] = self.last_mark
        return self.last_mark

    def new_mark(self, rev, mark):
        self.marks[rev] = mark
        self.rev_marks[mark] = rev
        self.last_mark = mark

    def is_marked(self, rev):
        return rev in self.marks

    def get_tip(self, branch):
        return str(self.tips[branch])

    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 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):
        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 != bad_mail:
            if name:
                user = '%s <%s>' % (name, email)
            else:
                user = '<%s>' % (email)
        else:
            user = name

        if ex:
            user += ex

        tz = int(tz)
        tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
        return (user, int(date), -tz)

def fix_file_path(path):
    if not os.path.isabs(path):
        return path
    return os.path.relpath(path, '/')

def export_files(files):
    global marks, filenodes

    final = []
    for f in files:
        fid = node.hex(f.filenode())

        if fid in filenodes:
            mark = filenodes[fid]
        else:
            mark = marks.next_mark()
            filenodes[fid] = mark
            d = f.data()

            print "blob"
            print "mark :%u" % mark
            print "data %d" % len(d)
            print d

        path = fix_file_path(f.path())
        final.append((gitmode(f.flags()), mark, path))

    return final

def get_filechanges(repo, ctx, parent):
    modified = set()
    added = set()
    removed = set()

    # load earliest manifest first for caching reasons
    prev = parent.manifest().copy()
    cur = ctx.manifest()

    for fn in cur:
        if fn in prev:
            if (cur.flags(fn) != prev.flags(fn) or cur[fn] != prev[fn]):
                modified.add(fn)
            del prev[fn]
        else:
            added.add(fn)
    removed |= set(prev.keys())

    return added | modified, removed

def fixup_user_git(user):
    name = mail = None
    user = user.replace('"', '')
    m = AUTHOR_RE.match(user)
    if m:
        name = m.group(1)
        mail = m.group(2).strip()
    else:
        m = EMAIL_RE.match(user)
        if m:
            name = m.group(1)
            mail = m.group(2)
        else:
            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 = bad_name
    if not mail:
        mail = bad_mail

    return '%s <%s>' % (name, mail)

def updatebookmarks(repo, peer):
    remotemarks = peer.listkeys('bookmarks')
    localmarks = repo._bookmarks

    if not remotemarks:
        return

    for k, v in remotemarks.iteritems():
        localmarks[k] = hgbin(v)

    if hasattr(localmarks, 'write'):
        localmarks.write()
    else:
        bookmarks.write(repo)

def get_repo(url, alias):
    global dirname, peer

    myui = ui.ui()
    myui.setconfig('ui', 'interactive', 'off')
    myui.fout = sys.stderr

    if get_config_bool('remote-hg.insecure'):
        myui.setconfig('web', 'cacerts', '')

    extensions.loadall(myui)

    if hg.islocal(url) and not os.environ.get('GIT_REMOTE_HG_TEST_REMOTE'):
        repo = hg.repository(myui, url)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
    else:
        shared_path = os.path.join(gitdir, 'hg')
        if not os.path.exists(shared_path):
            try:
                hg.clone(myui, {}, url, shared_path, update=False, pull=True)
            except:
                die('Repository error')

        if not os.path.exists(dirname):
            os.makedirs(dirname)

        local_path = os.path.join(dirname, 'clone')
        if not os.path.exists(local_path):
            hg.share(myui, shared_path, local_path, update=False)

        repo = hg.repository(myui, local_path)
        try:
            peer = hg.peer(myui, {}, url)
        except:
            die('Repository error')
        repo.pull(peer, heads=None, force=True)

        updatebookmarks(repo, peer)

    return repo

def rev_to_mark(rev):
    global marks
    return marks.from_rev(rev.hex())

def mark_to_rev(mark):
    global marks
    return marks.to_rev(mark)

def export_ref(repo, name, kind, head):
    global prefix, marks, mode

    ename = '%s/%s' % (kind, name)
    try:
        tip = marks.get_tip(ename)
        tip = repo[tip].rev()
    except:
        tip = 0

    revs = xrange(tip, head.rev() + 1)
    total = len(revs)

    for rev in revs:

        c = repo[rev]
        node = c.node()

        if marks.is_marked(c.hex()):
            continue

        (manifest, user, (time, tz), files, desc, extra) = repo.changelog.read(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 = [repo[p] for p in repo.changelog.parentrevs(rev) if p >= 0]

        if len(parents) == 0:
            modified = c.manifest().keys()
            removed = []
        else:
            modified, removed = get_filechanges(repo, c, parents[0])

        desc += '\n'

        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))

            if extra_msg:
                desc += '\n--HG--\n' + extra_msg

        if len(parents) == 0 and rev:
            print 'reset %s/%s' % (prefix, ename)

        modified_final = export_files(c.filectx(f) for f in modified)

        print "commit %s/%s" % (prefix, ename)
        print "mark :%d" % (marks.get_mark(c.hex()))
        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" % (fix_file_path(f))
        for f in modified_final:
            print "M %s :%u %s" % f
        print

        progress = (rev - tip)
        if (progress % 100 == 0):
            print "progress revision %d '%s' (%d/%d)" % (rev, name, progress, total)

    # make sure the ref is updated
    print "reset %s/%s" % (prefix, ename)
    print "from :%u" % rev_to_mark(head)
    print

    marks.set_tip(ename, head.hex())

def export_tag(repo, tag):
    export_ref(repo, tag, 'tags', repo[hgref(tag)])

def export_bookmark(repo, bmark):
    head = bmarks[hgref(bmark)]
    export_ref(repo, bmark, 'bookmarks', head)

def export_branch(repo, branch):
    tip = get_branch_tip(repo, branch)
    head = repo[tip]
    export_ref(repo, branch, 'branches', head)

def export_head(repo):
    global g_head
    export_ref(repo, g_head[0], 'bookmarks', g_head[1])

def do_capabilities(parser):
    global prefix, dirname

    print "import"
    print "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 "option"

    print

def branch_tip(branch):
    return branches[branch][-1]

def get_branch_tip(repo, branch):
    global branches

    heads = branches.get(hgref(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 branch_tip(hgref(branch))

    return heads[0]

def list_head(repo, cur):
    global g_head, bmarks, fake_bmark

    if 'default' not in branches:
        # empty repo
        return

    node = repo[branch_tip('default')]
    head = 'master' if not 'master' in bmarks else 'default'
    fake_bmark = head
    bmarks[head] = node

    head = gitref(head)
    print "@refs/heads/%s HEAD" % head
    g_head = (head, node)

def do_list(parser):
    global branches, bmarks, track_branches

    repo = parser.repo
    for bmark, node in bookmarks.listbookmarks(repo).iteritems():
        bmarks[bmark] = repo[node]

    cur = repo.dirstate.branch()
    orig = peer if peer else repo

    for branch, heads in orig.branchmap().iteritems():
        # only open heads
        heads = [h for h in heads if 'close' not in repo.changelog.read(h)[5]]
        if heads:
            branches[branch] = heads

    list_head(repo, cur)

    if track_branches:
        for branch in branches:
            print "? refs/heads/branches/%s" % gitref(branch)

    for bmark in bmarks:
        print "? refs/heads/%s" % gitref(bmark)

    for tag, node in repo.tagslist():
        if tag == 'tip':
            continue
        print "? refs/tags/%s" % gitref(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
    print "feature force"
    sys.stdout.flush()

    tmp = encoding.encoding
    encoding.encoding = 'utf-8'

    # lets get all the import lines
    while parser.check('import'):
        ref = parser[1]

        if (ref == 'HEAD'):
            export_head(repo)
        elif ref.startswith('refs/heads/branches/'):
            branch = ref[len('refs/heads/branches/'):]
            export_branch(repo, branch)
        elif ref.startswith('refs/heads/'):
            bmark = ref[len('refs/heads/'):]
            export_bookmark(repo, bmark)
        elif ref.startswith('refs/tags/'):
            tag = ref[len('refs/tags/'):]
            export_tag(repo, tag)

        parser.next()

    encoding.encoding = tmp

    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()

def get_merge_files(repo, p1, p2, files):
    for e in repo[p1].files():
        if e not in files:
            if e not in repo[p1].manifest():
                continue
            f = { 'ctx' : repo[p1][e] }
            files[e] = f

def parse_commit(parser):
    global marks, blob_marks, parsed_refs
    global mode

    from_mark = merge_mark = None

    ref = parser[1]
    parser.next()

    commit_mark = parser.get_mark()
    parser.next()
    author = parser.get_author()
    parser.next()
    committer = parser.get_author()
    parser.next()
    data = parser.get_data()
    parser.next()
    if parser.check('from'):
        from_mark = parser.get_mark()
        parser.next()
    if parser.check('merge'):
        merge_mark = parser.get_mark()
        parser.next()
        if parser.check('merge'):
            die('octopus merges are not supported yet')

    # fast-export adds an extra newline
    if data[-1] == '\n':
        data = data[:-1]

    files = {}

    for line in parser:
        if parser.check('M'):
            t, m, mark_ref, path = line.split(' ', 3)
            mark = int(mark_ref[1:])
            f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] }
        elif parser.check('D'):
            t, path = line.split(' ', 1)
            f = { 'deleted' : True }
        else:
            die('Unknown file command: %s' % line)
        files[path] = f

    # only export the commits if we are on an internal proxy repo
    if dry_run and not peer:
        parsed_refs[ref] = None
        return

    def getfilectx(repo, memctx, f):
        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'
        rename = of.get('rename', None)
        return context.memfilectx(f, of['data'],
                is_link, is_exec, rename)

    repo = parser.repo

    user, date, tz = author
    extra = {}

    if committer != author:
        extra['committer'] = "%s %u %u" % committer

    if from_mark:
        p1 = mark_to_rev(from_mark)
    else:
        p1 = '0' * 40

    if merge_mark:
        p2 = mark_to_rev(merge_mark)
    else:
        p2 = '0' * 40

    #
    # 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)

    # Check if the ref is supposed to be a named branch
    if ref.startswith('refs/heads/branches/'):
        branch = ref[len('refs/heads/branches/'):]
        extra['branch'] = hgref(branch)

    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(' : ', 1) 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)

    tmp = encoding.encoding
    encoding.encoding = 'utf-8'

    node = hghex(repo.commitctx(ctx))

    encoding.encoding = tmp

    parsed_refs[ref] = node
    marks.new_mark(node, commit_mark)

def parse_reset(parser):
    global parsed_refs

    ref = parser[1]
    parser.next()
    # ugh
    if parser.check('commit'):
        parse_commit(parser)
        return
    if not parser.check('from'):
        return
    from_mark = parser.get_mark()
    parser.next()

    try:
        rev = mark_to_rev(from_mark)
    except KeyError:
        rev = None
    parsed_refs[ref] = rev

def parse_tag(parser):
    name = parser[1]
    parser.next()
    from_mark = parser.get_mark()
    parser.next()
    tagger = parser.get_author()
    parser.next()
    data = parser.get_data()
    parser.next()

    parsed_tags[name] = (tagger, data)

def write_tag(repo, tag, node, msg, author):
    branch = repo[node].branch()
    tip = branch_tip(branch)
    tip = repo[tip]

    def getfilectx(repo, memctx, f):
        try:
            fctx = tip.filectx(f)
            data = fctx.data()
        except error.ManifestLookupError:
            data = ""
        content = data + "%s %s\n" % (node, tag)
        return context.memfilectx(f, content, False, False, None)

    p1 = tip.hex()
    p2 = '0' * 40
    if author:
        user, date, tz = author
        date_tz = (date, tz)
    else:
        cmd = ['git', 'var', 'GIT_COMMITTER_IDENT']
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        output, _ = process.communicate()
        m = re.match('^.* <.*>', output)
        if m:
            user = m.group(0)
        else:
            user = repo.ui.username()
        date_tz = None

    ctx = context.memctx(repo, (p1, p2), msg,
            ['.hgtags'], getfilectx,
            user, date_tz, {'branch' : branch})

    tmp = encoding.encoding
    encoding.encoding = 'utf-8'

    tagnode = repo.commitctx(ctx)

    encoding.encoding = tmp

    return (tagnode, branch)

def checkheads_bmark(repo, ref, ctx):
    bmark = ref[len('refs/heads/'):]
    if not bmark in bmarks:
        # new bmark
        return True

    ctx_old = bmarks[bmark]
    ctx_new = ctx
    if not repo.changelog.descendant(ctx_old.rev(), ctx_new.rev()):
        if force_push:
            print "ok %s forced update" % ref
        else:
            print "error %s non-fast forward" % ref
            return False

    return True

def checkheads(repo, remote, p_revs):

    remotemap = remote.branchmap()
    if not remotemap:
        # empty repo
        return True

    new = {}
    ret = True

    for node, ref in p_revs.iteritems():
        ctx = repo[node]
        branch = ctx.branch()
        if not branch in remotemap:
            # new branch
            continue
        if not ref.startswith('refs/heads/branches'):
            if ref.startswith('refs/heads/'):
                if not checkheads_bmark(repo, ref, ctx):
                    ret = False

            # only check branches
            continue
        new.setdefault(branch, []).append(ctx.rev())

    for branch, heads in new.iteritems():
        old = [repo.changelog.rev(x) for x in remotemap[branch]]
        for rev in heads:
            if check_version(2, 3):
                ancestors = repo.changelog.ancestors([rev], stoprev=min(old))
            else:
                ancestors = repo.changelog.ancestors(rev)
            found = False

            for x in old:
                if x in ancestors:
                    found = True
                    break

            if found:
                continue

            node = repo.changelog.node(rev)
            ref = p_revs[node]
            if force_push:
                print "ok %s forced update" % ref
            else:
                print "error %s non-fast forward" % ref
                ret = False

    return ret

def push_unsafe(repo, remote, parsed_refs, p_revs):

    force = force_push

    fci = discovery.findcommonincoming
    commoninc = fci(repo, remote, force=force)
    common, _, remoteheads = commoninc

    if not checkheads(repo, remote, p_revs):
        return None

    cg = repo.getbundle('push', heads=list(p_revs), common=common)

    unbundle = remote.capable('unbundle')
    if unbundle:
        if force:
            remoteheads = ['force']
        return remote.unbundle(cg, remoteheads, 'push')
    else:
        return remote.addchangegroup(cg, 'push', repo.url())

def push(repo, remote, parsed_refs, p_revs):
    if hasattr(remote, 'canpush') and not remote.canpush():
        print "error cannot push"

    if not p_revs:
        # nothing to push
        return

    lock = None
    unbundle = remote.capable('unbundle')
    if not unbundle:
        lock = remote.lock()
    try:
        ret = push_unsafe(repo, remote, parsed_refs, p_revs)
    finally:
        if lock is not None:
            lock.release()

    return ret

def check_tip(ref, kind, name, heads):
    try:
        ename = '%s/%s' % (kind, name)
        tip = marks.get_tip(ename)
    except KeyError:
        return True
    else:
        return tip in heads

def do_export(parser):
    global parsed_refs, bmarks, peer

    p_bmarks = []
    p_revs = {}

    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)

    need_fetch = False

    for ref, node in parsed_refs.iteritems():
        bnode = hgbin(node) if node else None
        if ref.startswith('refs/heads/branches'):
            branch = ref[len('refs/heads/branches/'):]
            if branch in branches and bnode in branches[branch]:
                # up to date
                continue

            if peer:
                remotemap = peer.branchmap()
                if remotemap and branch in remotemap:
                    heads = [hghex(e) for e in remotemap[branch]]
                    if not check_tip(ref, 'branches', branch, heads):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
            print "ok %s" % ref
        elif ref.startswith('refs/heads/'):
            bmark = ref[len('refs/heads/'):]
            new = node
            old = bmarks[bmark].hex() if bmark in bmarks else ''

            if old == new:
                continue

            print "ok %s" % ref
            if bmark != fake_bmark and \
                    not (bmark == 'master' and bmark not in parser.repo._bookmarks):
                p_bmarks.append((ref, bmark, old, new))

            if peer:
                remote_old = peer.listkeys('bookmarks').get(bmark)
                if remote_old:
                    if not check_tip(ref, 'bookmarks', bmark, remote_old):
                        print "error %s fetch first" % ref
                        need_fetch = True
                        continue

            p_revs[bnode] = ref
        elif ref.startswith('refs/tags/'):
            if dry_run:
                print "ok %s" % ref
                continue
            tag = ref[len('refs/tags/'):]
            tag = hgref(tag)
            author, msg = parsed_tags.get(tag, (None, None))
            if mode == 'git':
                if not msg:
                    msg = 'Added tag %s for changeset %s' % (tag, node[:12]);
                tagnode, branch = write_tag(parser.repo, tag, node, msg, author)
                p_revs[tagnode] = 'refs/heads/branches/' + gitref(branch)
            else:
                fp = parser.repo.opener('localtags', 'a')
                fp.write('%s %s\n' % (node, tag))
                fp.close()
            p_revs[bnode] = ref
            print "ok %s" % ref
        else:
            # transport-helper/fast-export bugs
            continue

    if need_fetch:
        print
        return

    if dry_run:
        if peer and not force_push:
            checkheads(parser.repo, peer, p_revs)
        print
        return

    if peer:
        if not push(parser.repo, peer, parsed_refs, p_revs):
            # do not update bookmarks
            print
            return

        # update remote bookmarks
        remote_bmarks = peer.listkeys('bookmarks')
        for ref, bmark, old, new in p_bmarks:
            if force_push:
                old = remote_bmarks.get(bmark, '')
            if not peer.pushkey('bookmarks', bmark, old, new):
                print "error %s" % ref
    else:
        # update local bookmarks
        for ref, bmark, old, new in p_bmarks:
            if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
                print "error %s" % ref

    print

def do_option(parser):
    global dry_run, force_push
    _, key, value = parser.line.split(' ')
    if key == 'dry-run':
        dry_run = (value == 'true')
        print 'ok'
    elif key == 'force':
        force_push = (value == 'true')
        print 'ok'
    else:
        print 'unsupported'

def fix_path(alias, repo, orig_url):
    url = urlparse.urlparse(orig_url, 'file')
    if url.scheme != 'file' or os.path.isabs(url.path):
        return
    abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url)
    cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url]
    subprocess.call(cmd)

def main(args):
    global prefix, gitdir, dirname, branches, bmarks
    global marks, blob_marks, parsed_refs
    global peer, mode, bad_mail, bad_name
    global track_branches, force_push, is_tmp
    global parsed_tags
    global filenodes
    global fake_bmark, hg_version
    global dry_run

    alias = args[1]
    url = args[2]
    peer = None

    hg_git_compat = get_config_bool('remote-hg.hg-git-compat')
    track_branches = get_config_bool('remote-hg.track-branches', True)
    force_push = False

    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
        alias = hashlib.sha1(alias).hexdigest()
    else:
        is_tmp = False

    gitdir = os.environ['GIT_DIR']
    dirname = os.path.join(gitdir, 'hg', alias)
    branches = {}
    bmarks = {}
    blob_marks = {}
    parsed_refs = {}
    marks = None
    parsed_tags = {}
    filenodes = {}
    fake_bmark = None
    try:
        hg_version = tuple(int(e) for e in util.version().split('.'))
    except:
        hg_version = None
    dry_run = False

    repo = get_repo(url, alias)
    prefix = 'refs/hg/%s' % alias

    if not is_tmp:
        fix_path(alias, peer or repo, url)

    marks_path = os.path.join(dirname, 'marks-hg')
    marks = Marks(marks_path, repo)

    if sys.platform == 'win32':
        import msvcrt
        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

    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)
        elif parser.check('option'):
            do_option(parser)
        else:
            die('unhandled command: %s' % line)
        sys.stdout.flush()

def bye():
    if not marks:
        return
    if not is_tmp:
        marks.store()
    else:
        shutil.rmtree(dirname)

atexit.register(bye)
sys.exit(main(sys.argv))
