Random Stuff About Stuff

Git import old kind of related but not really history

December 01, 2015

So some of the projects I’ve work on for a while have had various version control systems used, VSS, SVN and now GIT. The fun here is not all imports have gone that well, there has been upgrades that happened in a different project because branches weren’t very good (VSS) or the project has be moved and renamed (SVN) so now that it’s landed in GIT I thought I try tie them togther in one repo, before they were always in the big giant repo.

The problem is as far as git is concerned they have nothing in common. The VSS is completely seperate and with SVN the SVN to GIT import doesn’t follow renames, so they are seperate too.

I had tried importing the history as seperate repo’s pull them all into one repo and merging them. That kind of works but is an unholy mess to look at.

So I decided to try again. Probably not the greatest idea it’s really going to mess with the commit hashes so not for something shared by lots of people.

So step 1 unmerge the previous merges So at the point just before the merge get the hash of that commit and create a branch from it

git checkout -b oldHistory 2708c62125fd29d2e752da349c221e274f2adf33

This branch should now be the old merge.

Step 2 So one option is to use git replace to chain the histories together. Seems like it might work But I think to do it right I need an empty commit at the start which I don’t alway have http://stackoverflow.com/questions/645450/insert-a-commit-before-the-root-commit-in-git

Allows you to add a commit at the start, seems to work quite well

# first you need a new empty branch; let's call it `newroot`
git checkout --orphan newroot
git rm -rf .

git commit --allow-empty -m 'root commit'
git rebase --preserve-merges --onto newroot --root master
git branch -d newroot

That messes up all the dates though… bummer so run

git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'

Magic.

Next up was trying to remove the old merges. Thought good ole rebase -i would in the easy option and I guess it was in the end but just doing

git rebase -i d0559ead5df7aea344fae4b1971419a1047916de

gave me all the commits in a linear line, way to many to go through and set manually.

But turns out all I was missing was —preserve-merges

git rebase --preserve-merges -i d0559ead5df7aea344fae4b1971419a1047916de

which had the merge listed as one commit so I could easily drop it.

Then I needed to replace the new blank commit with the end of the old commit, which should also be blank to make sure there aren’t any conflicts

git replace "5b4e4e2" "6577477"

Update So to make that change permanent in the history you can run

git filter-branch -f --tag-name-filter cat -- --all

Written by David Kerwick who lives and works Dublin as a Java Technical Lead.