Created
December 2, 2016 05:00
-
-
Save glandium/56a61454b2c3a1ad2cc269cc91292a56 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import atexit | |
import os | |
import shutil | |
import subprocess | |
from cinnabar.git import ( | |
FastImport, | |
Git, | |
git_dir, | |
GitProcess, | |
sha1path, | |
) | |
from cinnabar.githg import ( | |
GitCommit, | |
git_hash, | |
) | |
from cinnabar.helper import GitHgHelper | |
from cinnabar.util import ( | |
init_logging, | |
one, | |
progress_iter, | |
) | |
from tempfile import mkdtemp | |
git_dir = os.path.abspath(git_dir) | |
clone = mkdtemp(prefix='.cinnabar.', dir=git_dir) | |
atexit.register(lambda: shutil.rmtree(clone)) | |
init_logging() | |
GitProcess('clone', '--mirror', '--share', git_dir, clone, | |
stderr=open(os.devnull, 'w')).wait() | |
repo = 'https://github.com/glandium/gecko-dev' | |
print 'Fetching cinnabar metadata from %s' % repo | |
pwd = os.path.abspath('.') | |
os.chdir(clone) | |
GitProcess('fetch', repo, 'cinnabar').wait() | |
input = Git.resolve_ref('FETCH_HEAD') | |
ref = 'refs/cinnabar/metadata' | |
fast_import = FastImport() | |
fast_import.send_done() | |
fast_import._real_proc = GitProcess( | |
'fast-import', '--quiet', stdin=subprocess.PIPE, | |
config={'core.ignorecase': 'false'}, | |
env={'GIT_DIR': git_dir}) | |
fast_import.write('feature force\nfeature ls\nfeature done\n') | |
for line in Git.iter('ls-tree', '-r', input): | |
mode, typ, sha1, path = line.split() | |
Git._replace[path] = sha1 | |
metadata = list(Git.iter('rev-parse', '%s^@' % input)) | |
changesets = list(Git.iter('rev-parse', '%s^@' % metadata[0])) | |
for sha1 in Git._replace.itervalues(): | |
if sha1 in changesets: | |
changesets.remove(sha1) | |
mark = fast_import.new_mark() | |
commit = GitCommit(metadata[0]) | |
with fast_import.commit( | |
ref=ref, | |
parents=changesets, | |
mark=mark, | |
message=commit.body): | |
pass | |
changesets = mark | |
print 'Importing git2hg, manifests and replace metadata' | |
def refs(): | |
yield metadata[3] | |
for sha1 in Git._replace.values(): | |
yield sha1 | |
for line in Git.iter('log', '%s^@' % metadata[1], '--format=%H^{tree}'): | |
yield line | |
GitProcess('pack-objects', '--revs', '--all-progress', | |
os.path.join(git_dir, 'objects', 'pack', 'pack'), | |
stdin=refs()).wait() | |
cs = set(Git.iter('rev-list', '%s^@' % metadata[0])) | |
marks = {} | |
mn = set() | |
for line in progress_iter('Finalizing %d manifests', | |
Git.iter('rev-list', '--reverse', '--parents', | |
'--topo-order', '%s^@' % metadata[1])): | |
parents = line.split() | |
sha1 = parents.pop(0) | |
try: | |
commit = GitCommit(sha1) | |
except: | |
print sha1 | |
raise | |
mark = fast_import.new_mark() | |
with fast_import.commit( | |
ref=ref, | |
message=commit.body[:40], | |
parents=(marks[p] for p in parents), | |
mark=mark) as c: | |
c.filemodify('git', commit.body[40:], typ='tree') | |
c.filemodify('hg', commit.tree, typ='tree') | |
marks[sha1] = mark | |
mn.add(commit.body[:40]) | |
manifests = fast_import.new_mark() | |
with fast_import.commit( | |
ref=ref, | |
parents=(marks[p] for p in Git.iter('rev-parse', '%s^@' % metadata[1])), | |
mark=manifests): | |
pass | |
hg2git = fast_import.new_mark() | |
with fast_import.commit( | |
ref=ref, | |
mark=hg2git) as c: | |
prev = None | |
for line in progress_iter('Importing %d hg2git metadata', | |
Git.iter('ls-tree', '-r', metadata[2])): | |
mode, typ, sha1, path = line.split() | |
node = path.replace('/', '') | |
if node in mn or sha1 in cs: | |
c.filemodify(path, sha1, typ='commit') | |
elif path.endswith('.meta'): | |
meta = Git.cat_file('blob', sha1) | |
data = Git.cat_file('blob', prev) | |
c.write('M %s inline %s\n' % (c.MODE['regular'], path[:-5])) | |
c.cmd_data('\1\n' + meta + '\1\n' + data) | |
c.filedelete(path) | |
else: | |
prev = sha1 | |
c.filemodify(path, sha1) | |
with fast_import.commit( | |
ref=ref, | |
parents=(changesets, manifests, hg2git, metadata[3])): | |
for path, sha1 in Git._replace.iteritems(): | |
c.filemodify(path, sha1, typ='commit') | |
for path, sha1 in Git._replace.iteritems(): | |
fast_import.write('reset refs/cinnabar/replace/%s\nfrom %s\n\n' | |
% (path, sha1)) | |
fast_import.close() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment