Created
August 24, 2011 02:31
-
-
Save peterjc/1167169 to your computer and use it in GitHub Desktop.
Hack script to import selected folders from one git repository to another
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
#Copyright 2011 Peter Cock, released under GPL v3 licence | |
# | |
#Hack script to extract files in selected directories in one git | |
#repository and apply them to another repository using a potentially | |
#different directory structure. | |
# | |
#This written in Python and needs the git library, I used 0.3.2 RC1 | |
#https://github.com/gitpython-developers/GitPython | |
# | |
#I assume when run both repositories are clean (no untracked files, | |
#uncommitted changes etc) and are in the branches of interest. That | |
#means in my case a fresh new branch in the destination repo. | |
# | |
#This was written to extract from GFF code for Biopython from | |
#https://github.com/chapmanb/bcbb/tree/ (master branch) | |
#to a branch of the main Biopython repository, | |
#https://github.com/chapmanb/bcbb/tree/ | |
# | |
#TODO - Commits deleting files probably don't work (untested) | |
import os | |
import subprocess | |
import time | |
from git import Repo | |
source = "/Users/peterjc/repositories/bcbb" | |
dest = "/Users/peterjc/repositories/biopython" | |
source_repo = Repo(source) | |
dest_repo = Repo(dest) | |
directory_map = { | |
"gff/BCBio/GFF": "Bio/GFF", | |
"gff/Tests": "Tests/", | |
} | |
assert not source_repo.bare | |
assert not source_repo.is_dirty() | |
assert not dest_repo.is_dirty() | |
def apply_patch(original_commit): | |
hash = str(original_commit) | |
author = '"%s <%s>"' % (original_commit.author.name, original_commit.author.email) | |
print hash, author | |
print str(original_commit.message).strip().split("\n",1)[0].strip() | |
original_patch = source_repo.git.show(source_commit, "--", *directory_map.keys()) | |
patch = original_patch.rstrip("\n") + "\n" | |
for pre in [" a/", " b/"]: | |
for old, new in directory_map.iteritems(): | |
patch = patch.replace(pre+old, pre+new) | |
os.chdir(dest) | |
h = open("%s.patch" % hash, "w") | |
h.write(patch) | |
h.close() | |
h = open("%s.txt" % hash, "w") | |
for line in original_commit.message.strip().split("\n"): | |
h.write(line.strip() + "\n") | |
h.close() | |
#print patch | |
print "Patch and message prepared" | |
return_code = os.system("patch -p 1 -i %s.patch" % hash) | |
assert not return_code, return_code | |
print os.getcwd() | |
print "Patch applied" | |
files = [] | |
for line in patch.split("\n"): | |
if line.startswith("+++ b/"): | |
files.append(line[6:].strip()) | |
for f in files: | |
print f | |
assert os.path.isfile(f), f | |
dest_repo.git.add(f) | |
dest_repo.git.commit("--author", author, | |
"-F", "%s.txt" % hash, | |
"--date", original_commit.authored_date) | |
print "Done" | |
selected_commits = list(source_repo.head.commit.iter_parents(paths=directory_map.keys()))[::-1] | |
for source_commit in selected_commits: | |
print source_commit, time.asctime(time.gmtime(source_commit.committed_date)) | |
print "Working..." | |
for source_commit in selected_commits: | |
apply_patch(source_commit) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment