Skip to content
Snippets Groups Projects
Commit d6c443a91b18 authored by Scott Chacon's avatar Scott Chacon
Browse files

refactored the git handling stuff out into another class

parent 9150a8f9d1f2
No related branches found
No related tags found
No related merge requests found
......@@ -9,6 +9,14 @@
(Dulwich library)
= Lossless Two Way =
We need to store data that Git records that Merc does not in a git/extra_data file. This would be parents over two and committer information (author will be mapped to Hg committer). This way two Hg developers can collaborate without the Git transport messing up the local commits.
Each Git commit should be reproducable as a Merc ID and vice versa on any system.
= ISSUES =
* currently sorts by date, though it should be sorting topologically. if it gets to a commit where we haven't processed it's parents, it will probably fuck up.
May need to use bookmarks extension to do everything better.
* Cloning from a Git Repository *
......
......@@ -34,6 +34,7 @@
import os, errno, sys
import subprocess
import dulwich
from git_handler import GitHandler
def gclone(ui, git_url, hg_repo_path=None):
## TODO : add git_url as the default remote path
......@@ -50,7 +51,8 @@
dulwich.repo.Repo.init_bare(git_hg_path)
# fetch the initial git data
git_fetch(dest_repo, git_url)
git = GitHandler(dest_repo, ui)
git.fetch(git_url)
# checkout the tip
# hg.update(ui, dest_repo)
......@@ -60,34 +62,7 @@
def gpull(ui, repo):
dest_repo.ui.status(_("pulling from git url\n"))
def git_fetch(dest_repo, git_url):
dest_repo.ui.status(_("fetching from git url\n"))
git_fetch_pack(dest_repo, git_url)
def git_fetch_pack(dest_repo, git_url):
from dulwich.repo import Repo
from dulwich.client import SimpleFetchGraphWalker
client, path = get_transport_and_path(git_url)
git_dir = os.path.join(dest_repo.path, 'git')
r = Repo(git_dir)
graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
f, commit = r.object_store.add_pack()
refs = client.fetch_pack(path, r.object_store.determine_wants_all, graphwalker, f.write, sys.stdout.write)
f.close()
commit()
r.set_refs(refs)
def get_transport_and_path(uri):
from dulwich.client import TCPGitClient, SSHGitClient, SubprocessGitClient
for handler, transport in (("git://", TCPGitClient), ("git+ssh://", SSHGitClient)):
if uri.startswith(handler):
host, path = uri[len(handler):].split("/", 1)
return transport(host), "/"+path
# if its not git or git+ssh, try a local url..
return SubprocessGitClient(), uri
commands.norepo += " gclone"
cmdtable = {
"gclone":
......@@ -102,4 +77,4 @@
_('hg gpush remote')),
"gpull":
(gpull, [], _('hg gpull [--merge] remote')),
}
\ No newline at end of file
}
import os, errno, sys
import dulwich
from dulwich.repo import Repo
from dulwich.client import SimpleFetchGraphWalker
from hgext import bookmarks
from mercurial.i18n import _
class GitHandler(object):
def __init__(self, dest_repo, ui):
self.repo = dest_repo
self.ui = ui
git_dir = os.path.join(self.repo.path, 'git')
self.git = Repo(git_dir)
def fetch(self, git_url):
self.ui.status(_("fetching from git url: " + git_url + "\n"))
self.export_git_objects()
self.fetch_pack(git_url)
self.import_git_objects()
def fetch_pack(self, git_url):
client, path = self.get_transport_and_path(git_url)
graphwalker = SimpleFetchGraphWalker(self.git.heads().values(), self.git.get_parents)
f, commit = self.git.object_store.add_pack()
try:
determine_wants = self.git.object_store.determine_wants_all
refs = client.fetch_pack(path, determine_wants, graphwalker, f.write, sys.stdout.write)
f.close()
commit()
self.git.set_refs(refs)
except:
f.close()
raise
def import_git_objects(self):
self.ui.status(_("importing Git objects into Hg\n"))
# import heads as remote references
todo = []
done = set()
convert_list = []
for head, sha in self.git.heads().iteritems():
todo.append(sha)
while todo:
sha = todo.pop()
assert isinstance(sha, str)
if sha in done:
continue
done.add(sha)
commit = self.git.commit(sha)
convert_list.append(commit)
todo.extend([p for p in commit.parents if p not in done])
convert_list.sort(cmp=lambda x,y: x.commit_time-y.commit_time)
for commit in convert_list:
print "commit: %s" % sha
self.import_git_commit(commit)
print bookmarks.parse(self.repo)
def import_git_commit(self, commit):
# check that parents are all in Hg, or no parents
print commit.parents
pass
def export_git_objects(self):
pass
def check_bookmarks(self):
if self.ui.config('extensions', 'hgext.bookmarks') is not None:
print "YOU NEED TO SETUP BOOKMARKS"
def get_transport_and_path(self, uri):
from dulwich.client import TCPGitClient, SSHGitClient, SubprocessGitClient
for handler, transport in (("git://", TCPGitClient), ("git+ssh://", SSHGitClient)):
if uri.startswith(handler):
host, path = uri[len(handler):].split("/", 1)
return transport(host), "/"+path
# if its not git or git+ssh, try a local url..
return SubprocessGitClient(), uri
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment