import subprocess
import urllib
import atexit
-import urlparse
+import urlparse, hashlib
-#
-# If you want to switch to hg-git compatibility mode:
-# git config --global remote-hg.hg-git-compat true
#
# If you are not in hg-git-compat mode and want to disable the tracking of
# named branches:
# git config --global remote-hg.force-push false
#
# If you want the equivalent of hg's clone/pull--insecure option:
-# git config remote-hg.insecure true
+# 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.
AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
+VERSION = 1
+
def die(msg, *args):
sys.stderr.write('ERROR: %s\n' % (msg % args))
sys.exit(1)
def hghex(node):
return hg.node.hex(node)
+def hgbin(node):
+ return hg.node.bin(node)
+
def hgref(ref):
return ref.replace('___', ' ')
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):
self.path = path
+ self.clear()
+ self.load()
+
+ if self.version < VERSION:
+ self.clear()
+ self.version = VERSION
+
+ def clear(self):
self.tips = {}
self.marks = {}
self.rev_marks = {}
self.last_mark = 0
-
- self.load()
+ self.version = 0
def load(self):
if not os.path.exists(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] = int(rev)
def dict(self):
- return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark }
+ 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'))
removed = set()
# load earliest manifest first for caching reasons
- prev = repo[parent].manifest().copy()
+ prev = parent.manifest().copy()
cur = ctx.manifest()
for fn in cur:
myui.setconfig('ui', 'interactive', 'off')
myui.fout = sys.stderr
- try:
- if get_config('remote-hg.insecure') == 'true\n':
- myui.setconfig('web', 'cacerts', '')
- except subprocess.CalledProcessError:
- pass
+ if get_config_bool('remote-hg.insecure'):
+ myui.setconfig('web', 'cacerts', '')
- try:
- mod = extensions.load(myui, 'hgext.schemes', None)
- mod.extsetup(myui)
- except ImportError:
- pass
+ extensions.loadall(myui)
if hg.islocal(url):
repo = hg.repository(myui, url)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
else:
- local_path = os.path.join(dirname, 'clone')
- if not os.path.exists(local_path):
- try:
- peer, dstpeer = hg.clone(myui, {}, url, local_path, update=True, pull=True)
- except:
- die('Repository error')
- repo = dstpeer.local()
- else:
- repo = hg.repository(myui, local_path)
+ shared_path = os.path.join(gitdir, 'hg')
+ if not os.path.exists(shared_path):
try:
- peer = hg.peer(myui, {}, url)
+ hg.clone(myui, {}, url, shared_path, update=False, pull=True)
except:
die('Repository error')
- repo.pull(peer, heads=None, force=True)
+
+ 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)
return repo
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 = xrange(tip, head.rev() + 1)
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())
+ node = c.node()
+
+ if marks.is_marked(c.hex()):
+ count += 1
+ 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))
else:
committer = author
- parents = [p for p in repo.changelog.parentrevs(rev) if p >= 0]
+ parents = [repo[p] for p in repo.changelog.parentrevs(rev) if p >= 0]
if len(parents) == 0:
modified = c.manifest().keys()
print desc
if len(parents) > 0:
- print "from :%s" % (rev_to_mark(parents[0]))
+ print "from :%s" % (rev_to_mark(parents[0].rev()))
if len(parents) > 1:
- print "merge :%s" % (rev_to_mark(parents[1]))
+ print "merge :%s" % (rev_to_mark(parents[1].rev()))
for f in modified_final:
print "M %s :%u %s" % f
count += 1
if (count % 100 == 0):
print "progress revision %d '%s' (%d/%d)" % (rev, name, count, len(revs))
- print "#############################################################"
# make sure the ref is updated
print "reset %s/%s" % (prefix, ename)
- print "from :%u" % rev_to_mark(rev)
+ print "from :%u" % rev_to_mark(head.rev())
print
- marks.set_tip(ename, rev)
+ marks.set_tip(ename, head.rev())
def export_tag(repo, tag):
export_ref(repo, tag, 'tags', repo[hgref(tag)])
g_head = (head, node)
def do_list(parser):
- global branches, bmarks, mode, track_branches
+ global branches, bmarks, track_branches
repo = parser.repo
for bmark, node in bookmarks.listbookmarks(repo).iteritems():
tmp = encoding.encoding
encoding.encoding = 'utf-8'
- node = repo.commitctx(ctx)
+ node = hghex(repo.commitctx(ctx))
encoding.encoding = tmp
parser.next()
node = parser.repo.changelog.node(mark_to_rev(from_mark))
- parsed_refs[ref] = node
+ parsed_refs[ref] = hghex(node)
def parse_tag(parser):
name = parser[1]
data = fctx.data()
except error.ManifestLookupError:
data = ""
- content = data + "%s %s\n" % (hghex(node), tag)
+ content = data + "%s %s\n" % (node, tag)
return context.memfilectx(f, content, False, False, None)
p1 = tip.hex()
die('unhandled export command: %s' % line)
for ref, node in parsed_refs.iteritems():
+ bnode = hgbin(node)
if ref.startswith('refs/heads/branches'):
branch = ref[len('refs/heads/branches/'):]
- if branch in branches and node in branches[branch]:
+ if branch in branches and bnode in branches[branch]:
# up to date
continue
print "ok %s" % ref
author, msg = parsed_tags.get(tag, (None, None))
if mode == 'git':
if not msg:
- msg = 'Added tag %s for changeset %s' % (tag, hghex(node[:6]));
+ msg = 'Added tag %s for changeset %s' % (tag, node[:12]);
write_tag(parser.repo, tag, node, msg, author)
else:
fp = parser.repo.opener('localtags', 'a')
- fp.write('%s %s\n' % (hghex(node), tag))
+ fp.write('%s %s\n' % (node, tag))
fp.close()
print "ok %s" % ref
else:
continue
if peer:
- parser.repo.push(peer, force=force_push)
+ parser.repo.push(peer, force=force_push, newbranch=True)
+ remote_bmarks = peer.listkeys('bookmarks')
# handle bookmarks
for bmark, node in p_bmarks:
ref = 'refs/heads/' + bmark
- new = hghex(node)
+ new = node
if bmark in bmarks:
old = bmarks[bmark].hex()
if bmark == 'master' and 'master' not in parser.repo._bookmarks:
# fake bookmark
- pass
+ print "ok %s" % ref
+ continue
elif bookmarks.pushbookmark(parser.repo, bmark, old, new):
# updated locally
pass
continue
if peer:
- rb = peer.listkeys('bookmarks')
- old = rb.get(bmark, '')
+ old = remote_bmarks.get(bmark, '')
if not peer.pushkey('bookmarks', bmark, old, new):
print "error %s" % ref
continue
subprocess.call(cmd)
def main(args):
- global prefix, dirname, branches, bmarks
+ 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
url = args[2]
peer = None
- hg_git_compat = False
- track_branches = True
- force_push = True
-
- try:
- if get_config('remote-hg.hg-git-compat') == 'true\n':
- hg_git_compat = True
- track_branches = False
- if get_config('remote-hg.track-branches') == 'false\n':
- track_branches = False
- if get_config('remote-hg.force-push') == 'false\n':
- force_push = False
- except subprocess.CalledProcessError:
- pass
+ hg_git_compat = get_config_bool('remote-hg.hg-git-compat')
+ track_branches = get_config_bool('remote-hg.track-branches', True)
+ force_push = get_config_bool('remote-hg.force-push')
if hg_git_compat:
mode = 'hg'
if alias[4:] == url:
is_tmp = True
- alias = util.sha1(alias).hexdigest()
+ alias = hashlib.sha1(alias).hexdigest()
else:
is_tmp = False
if not is_tmp:
fix_path(alias, peer or repo, url)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
-
marks_path = os.path.join(dirname, 'marks-hg')
marks = Marks(marks_path)
+ 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'):