Mercurial > hg-git
view __init__.py @ 0:06366111af3c
initial import of the hg-git bridging extension for mercurial
author | Scott Chacon <schacon@gmail.com> |
---|---|
date | Fri, 20 Feb 2009 18:27:51 -0800 |
parents | |
children | 0e55a2ecac87 |
line wrap: on
line source
# git.py - git server bridge # # Copyright 2008 Scott Chacon <schacon at gmail dot com> # also some code (and help) borrowed from durin42 # # This software may be used and distributed according to the terms # of the GNU General Public License, incorporated herein by reference. '''push and pull from a Git server This extension lets you communicate (push and pull) with a Git server. This way you can use Git hosting for your project or collaborate with a project that is in Git. A bridger of worlds, this plugin be. ''' # # Stage One - use Git commands to do the import / pushes, all in one big uggo file # # Stage Two - implement the Git packfile generation and server communication # in native Python, so we don't need Git locally and don't need # to keep all the git repo data around. We should just need a SHA # mapping - since everything is append only in both systems it should # be pretty simple to do. # # just importing every damn thing because i don't know python that well # and I have no idea what I actually need from mercurial import util, repair, merge, cmdutil, commands, error, hg, url from mercurial import extensions, ancestor from mercurial.commands import templateopts from mercurial.node import nullrev, nullid, short from mercurial.i18n import _ import os, errno import subprocess def gclone(ui, git_url, hg_repo_path=None): ## TODO : add git_url as the default remote path if not hg_repo_path: hg_repo_path = hg.defaultdest(git_url) if hg_repo_path.endswith('.git'): hg_repo_path = hg_repo_path[:-4] hg_repo_path += '-hg' subprocess.call(['hg', 'init', hg_repo_path]) clone_git(git_url, git_path(hg_repo_path)) import_git_heads(hg_repo_path) def gpull(ui, repo, source='default', **opts): """fetch from a git repo """ lock = wlock = None try: lock = repo.lock() wlock = repo.wlock() ui.write("fetching from the remote\n") git_fetch() import_git_heads() # do the pull finally: del lock, wlock def gpush(ui, repo, dest='default', **opts): """push to a git repo """ lock = wlock = None try: lock = repo.lock() wlock = repo.wlock() ui.write("pushing to the remote\n") # do the push finally: del lock, wlock def git_path(hg_path=None): return os.path.join(hg_path, '.hg', 'git-remote') def clone_git(git_url, hg_path=None): git_initialize(git_path(hg_path), git_url) git_fetch(git_path(hg_path)) def git_initialize(git_path, git_url): # TODO: implement this in pure python - should be strait-forward subprocess.call(['git', '--bare', 'init', git_path]) oldwd = os.getcwd() os.chdir(git_path) subprocess.call(['git', 'remote', 'add', 'origin', git_url]) os.chdir(oldwd) def git_fetch(git_path, remote='origin'): # TODO: implement this in pure python # - we'll have to handle ssh and git oldwd = os.getcwd() os.chdir(git_path) subprocess.call(['git', 'fetch', remote]) os.chdir(oldwd) def git_push(): # find all the local changesets that aren't mapped # create git commit object shas and map them # stick those objects in a packfile and push them up (over ssh) def import_git_heads(hg_path=None): # go through each branch # add all commits we don't have locally # write a SHA<->SHA mapping table # update the local branches to match return subprocess.call(['hg', 'convert', git_path(hg_path), hg_path]) commands.norepo += " gclone" cmdtable = { "gclone": (gclone, [ #('A', 'authors', '', 'username mapping filename'), ], 'Clone a git repository into an hg repository.', ), "gpush": (gpush, [('m', 'merge', None, _('merge automatically'))], _('hg gpush remote')), "gpull": (gpull, [], _('hg gpull [--merge] remote')), }