remote-hg: implement custom push()

The one from mercurial does a ton of things we are not interested in, and we need some special modifications which are impossible otherwise. Most of the code is borrowed from Mercurial, and cleaned up, but should be functionally the same for our purposes, except that multiple heads are not detected. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Felipe Contreras committed May 24, 2013 at 21:29 UTC 4f37bdbdb6229931c464b99eb9f6e198de01d0a7
1 file changed +42 -2
contrib/remote-helpers/git-remote-hg
+42 -2
@@ -12,7 +12,7 @@
12 # For remote repositories a local clone is stored in
13 # "$GIT_DIR/hg/origin/clone/.hg/".
14
15 -from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions
15 +from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions, discovery
16
17 import re
18 import sys
@@ -854,6 +854,46 @@ def write_tag(repo, tag, node, msg, author):
854
855 return tagnode
856
857 +def push_unsafe(repo, remote, parsed_refs, p_revs):
858 +
859 + force = force_push
860 +
861 + fci = discovery.findcommonincoming
862 + commoninc = fci(repo, remote, force=force)
863 + common, _, remoteheads = commoninc
864 +
865 + # TODO checkheads
866 +
867 + cg = repo.getbundle('push', heads=list(p_revs), common=common)
868 +
869 + unbundle = remote.capable('unbundle')
870 + if unbundle:
871 + if force:
872 + remoteheads = ['force']
873 + return remote.unbundle(cg, remoteheads, 'push')
874 + else:
875 + return remote.addchangegroup(cg, 'push', repo.url())
876 +
877 +def push(repo, remote, parsed_refs, p_revs):
878 + if hasattr(remote, 'canpush') and not remote.canpush():
879 + print "error cannot push"
880 +
881 + if not p_revs:
882 + # nothing to push
883 + return
884 +
885 + lock = None
886 + unbundle = remote.capable('unbundle')
887 + if not unbundle:
888 + lock = remote.lock()
889 + try:
890 + ret = push_unsafe(repo, remote, parsed_refs, p_revs)
891 + finally:
892 + if lock is not None:
893 + lock.release()
894 +
895 + return ret
896 +
897 def do_export(parser):
898 global parsed_refs, bmarks, peer
899
@@ -919,7 +959,7 @@ def do_export(parser):
959 continue
960
961 if peer:
922 - parser.repo.push(peer, force=force_push, newbranch=True, revs=list(p_revs))
962 + push(parser.repo, peer, parsed_refs, p_revs)
963
964 # update remote bookmarks
965 remote_bmarks = peer.listkeys('bookmarks')