# named branches:
# git config --global remote-hg.track-branches false
#
-# If you don't want to force pushes (and thus risk creating new remote heads):
-# git config --global remote-hg.force-push false
-#
# If you want the equivalent of hg's clone/pull--insecure option:
# git config --global remote-hg.insecure true
#
return self.marks[rev]
def to_rev(self, mark):
- return self.rev_marks[mark]
+ return str(self.rev_marks[mark])
def next_mark(self):
self.last_mark += 1
return rev in self.marks
def get_tip(self, branch):
- return self.tips.get(branch, None)
+ return str(self.tips[branch])
def set_tip(self, branch, tip):
self.tips[branch] = tip
global prefix, marks, mode
ename = '%s/%s' % (kind, name)
- tip = marks.get_tip(ename)
- if tip and tip in repo:
+ try:
+ tip = marks.get_tip(ename)
tip = repo[tip].rev()
- else:
+ except:
tip = 0
revs = xrange(tip, head.rev() + 1)
if len(parents) > 1:
print "merge :%s" % (rev_to_mark(parents[1]))
- for f in modified_final:
- print "M %s :%u %s" % f
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 os.path.exists(path):
print "*import-marks %s" % path
print "*export-marks %s" % path
+ print "option"
print
def list_head(repo, cur):
global g_head, bmarks, fake_bmark
- if 'default' not in repo:
+ if 'default' not in branches:
# empty repo
return
- node = repo['default']
+ node = repo[branch_tip('default')]
head = 'master' if not 'master' in bmarks else 'default'
fake_bmark = head
bmarks[head] = node
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 repo.branchmap():
- heads = repo.branchheads(branch)
- if len(heads):
- branches[branch] = heads
-
for branch in branches:
print "? refs/heads/branches/%s" % gitref(branch)
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:
from_mark = parser.get_mark()
parser.next()
- rev = mark_to_rev(from_mark)
+ try:
+ rev = mark_to_rev(from_mark)
+ except KeyError:
+ rev = None
parsed_refs[ref] = rev
def parse_tag(parser):
p1 = tip.hex()
p2 = '0' * 40
- if not author:
- author = (None, 0, 0)
- user, date, tz = author
+ 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})
+ user, date_tz, {'branch' : branch})
tmp = encoding.encoding
encoding.encoding = 'utf-8'
return (tagnode, branch)
def checkheads_bmark(repo, ref, ctx):
- if force_push:
- return True
-
bmark = ref[len('refs/heads/'):]
if not bmark in bmarks:
# new bmark
ctx_old = bmarks[bmark]
ctx_new = ctx
if not repo.changelog.descendant(ctx_old.rev(), ctx_new.rev()):
- print "error %s non-fast forward" % ref
- return False
+ if force_push:
+ print "ok %s forced update" % ref
+ else:
+ print "error %s non-fast forward" % ref
+ return False
return True
continue
node = repo.changelog.node(rev)
- print "error %s non-fast forward" % p_revs[node]
- ret = False
+ 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
commoninc = fci(repo, remote, force=force)
common, _, remoteheads = commoninc
- if not force and not checkheads(repo, remote, p_revs):
+ if not checkheads(repo, remote, p_revs):
return None
cg = repo.getbundle('push', heads=list(p_revs), common=common)
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
else:
die('unhandled export command: %s' % line)
+ need_fetch = False
+
for ref, node in parsed_refs.iteritems():
- bnode = hgbin(node)
+ 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/'):
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))
# 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
+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):
global parsed_tags
global filenodes
global fake_bmark, hg_version
+ global dry_run
alias = args[1]
url = args[2]
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')
+ force_push = False
if hg_git_compat:
mode = 'hg'
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
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()