20181027

Extracting part of the FreeBSD tree

Extacting the history CTM into its own

In the early days of the FreeBSD project, CTM provided a competitive advantage to the project by allowing those that weren't completely connected to the internet. CTM provided convenient way to get the sources via mag tape or mail (sometimes over UUCP links which were popular at the time).

Recently, the notion of removing from ctm from came up. Maybe it's a good idea, maybe it isn't a good idea. I thought it would be nice to know how hard it would be to extract the history of ctm into its own repo. So, I set out to see how hard it would be. Turns out, git makes it easy.

Initial setup

First, clone a tree.
git clone https://github.com/freebsd/freebsd
Next, we need to remove everything except ctm:
git filter-branch --prune-empty --subdirectory-filter usr.sbin/ctm
This will leave a repo with the complete history and a ctm directory at the top level. We're done, right?

Well, not so fast. We actually aren't done. There's a lot of crap still in the tree. Despite saying to get rid of empty commits, there are empty commits. Most of them are from merges to the tree that didn't actually touch ctm, but were merged and git has all of those in the tree.

Rebasing to clean away the sins

So, how do we clean this up? By rebasing of course. So, to make things easy, I tagged the first version in the new repo with a tag. I used 'base'. I also tagged the tip of master after the prune with 'orgmaster' in case I needed to start over (which I've not detailed here, but I'll just say it came in handy).
git rebase -i base master
Now, if you try this, it won't work. All the merges and cvs2svn 'fixups' are a problem. After a bit of trial and error, I figured out the list of things to remove from the todo list. Then I learned there was an easier way to find this list
git log --merges
will show the merges that still remain in the tree. Remove them from the todo list and then let the rebase proceed. There's likely a clever shell-script that can do all this, but I've not written one.

Sanity check

The sanity check step is easy. Diff the checked-out ctm repo with the freebsd repo's usr.sbin/ctm tree:
diff -ur ctm freebsd/usr.sbin/ctm
and it should be identical.  If not, you need to redo prior steps until it is done.

Pushing the result

So I created a new repo on github (in bsdimp/ctm).
git remote add upstream https://github.com/bsdimp/ctm
And then push it upstream:
git push upstream master
and you should be done. https://github.com/bsdimp/ctm should now have a repo that you can look at and have it match your local tree.

Next Steps

let the pull requests come in :)