summaryrefslogtreecommitdiff
path: root/contrib/remote-helpers
diff options
context:
space:
mode:
authorFelipe Contreras <felipe.contreras@gmail.com>2013-05-25 02:29:50 (GMT)
committerJunio C Hamano <gitster@pobox.com>2013-05-28 15:02:04 (GMT)
commit19a8cefc44b216db5cf8faf790d197c85db6395e (patch)
treef5f7fe1765b6bf5f2399c6218d5ade85e264b448 /contrib/remote-helpers
parent4f37bdbdb6229931c464b99eb9f6e198de01d0a7 (diff)
downloadgit-19a8cefc44b216db5cf8faf790d197c85db6395e.zip
git-19a8cefc44b216db5cf8faf790d197c85db6395e.tar.gz
git-19a8cefc44b216db5cf8faf790d197c85db6395e.tar.bz2
remote-hg: implement custom checkheads()
The version from Mercurial is extremely inefficient and convoluted, this version achieves basically the same, at least for our purposes. No functional changes. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'contrib/remote-helpers')
-rwxr-xr-xcontrib/remote-helpers/git-remote-hg52
1 files changed, 49 insertions, 3 deletions
diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg
index c2c1cb8..7eb809b 100755
--- a/contrib/remote-helpers/git-remote-hg
+++ b/contrib/remote-helpers/git-remote-hg
@@ -12,7 +12,7 @@
# 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
+from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions, discovery, util
import re
import sys
@@ -86,6 +86,11 @@ def hgref(ref):
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)
@@ -854,6 +859,42 @@ def write_tag(repo, tag, node, msg, author):
return tagnode
+def checkheads(repo, remote, p_revs):
+
+ remotemap = remote.branchmap()
+ if not remotemap:
+ # empty repo
+ return
+
+ new = {}
+
+ for node in p_revs:
+ ctx = repo[node]
+ branch = ctx.branch()
+ if not branch in remotemap:
+ # new branch
+ 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
+
+ raise Exception("non-fast-forward")
+
def push_unsafe(repo, remote, parsed_refs, p_revs):
force = force_push
@@ -862,7 +903,8 @@ def push_unsafe(repo, remote, parsed_refs, p_revs):
commoninc = fci(repo, remote, force=force)
common, _, remoteheads = commoninc
- # TODO checkheads
+ if not force:
+ checkheads(repo, remote, p_revs)
cg = repo.getbundle('push', heads=list(p_revs), common=common)
@@ -991,7 +1033,7 @@ def main(args):
global track_branches, force_push, is_tmp
global parsed_tags
global filenodes
- global fake_bmark
+ global fake_bmark, hg_version
alias = args[1]
url = args[2]
@@ -1026,6 +1068,10 @@ def main(args):
parsed_tags = {}
filenodes = {}
fake_bmark = None
+ try:
+ hg_version = tuple(int(e) for e in util.version().split('.'))
+ except:
+ hg_version = None
repo = get_repo(url, alias)
prefix = 'refs/hg/%s' % alias