Migrate n git repositories to a single repository with subdirectories

After my time at 42's final admissions test, the "piscine" I had a lot of one off repos hanging around. Their grading system is tightly coupled with their private Git server "Vogsphere" (named after the Vogon homeworld from, surprise "Hitchhiker's Guide to the Galaxy").

One of the great things about 42 in addition to being free as in beer, it's also free as in software. Any and all code you write while at 42 is owned by you.

So while I'm empowered to share my code, I didn't want to make a bunch of single serving repos that are intrinsically connected[1].

Unfortunately, a normal merge here wouldn't have done it, as every repo was placed in it's own root, and our grading scheme had a lot of overlap (e.g., the first solution to any problem set was always in a directory named ex01). And it was important to me to keep Git history intact.

What to do?

These requirements sent me down a great rabbit hole, learning much more about Git than when I started (including 'tree-ish' notation, along with subtleties and contrasts of git-merge and git-pull).

But the piece that really drove it together was a pretty clever answer from Stack Overflow that used git-merge with the ours strategy and --no-commit, combined with git-read-tree to nest the pre-existing repos as subdirectories.

for i in {0..9}
do repo=foo$i
    git remote add -f $repo ../path/to/$repo
    git merge -s ours --no-commit $repo/master --allow-unrelated-histories
    git read-tree --prefix=$repo/ -u $repo/master;
    git commit -m "Migrate $repo from vgs to github";
    git remote rm $repo;

1 - In hindsight I should have used Github Organizations, which would have been much easier, but where's the fun in that?

On Social Coding

I spent hours turning these squares green...