Skip to content

Instantly share code, notes, and snippets.

@peterjc
Created August 24, 2011 02:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterjc/1167169 to your computer and use it in GitHub Desktop.
Save peterjc/1167169 to your computer and use it in GitHub Desktop.
Hack script to import selected folders from one git repository to another
#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