Building simplicidade.org: notes, projects, and occasional rants

Merging two unrelated repositories

I keep a repository for operations-style stuff. Server configurations, Puppet recipes, old CFEngine stuff, the works.

But for some idiotic reason long lost in time, my DNS setup was in a totally unrelated repository. This didn't make that much sense. Even more stupid: other stuff, unrelated to DNS, was also stored in there.

So I had:

  • a oss/ repo with the good and clean stuff to configure all the servers I manage;
  • a dns/ repo with all the DNS configuration stuff, and a bunch of other unrelated configurations.

And the goal: merge the history of the network/dns/ directory in the dns/ repo to the dnssrv/ directory of the oss/ repo.

Like this:

# create a copy of my dns/ repo
git clone dns dns_work && cd dns_work

# remove everything except the network/dns/ directory
git filter-branch --prune-empty --subdirectory-filter network/dns -- --all

# move stuff back to the dnssrv/ directory
git filter-branch -f --prune-empty --tree-filter '
   mkdir -p .dnssrv;
   mv * .dnssrv;
   mv .dnssrv dnssrv
' -- --all

# make sure we clean all the cruft
git gc --aggressive

# ok, prepare to merge
cd ../oss && git remote add dns ../dns_work && git fetch dns

# Merge...
git merge dns/master

# Remove the cruft
git remote rm dns && git gc --aggressive

And with that, all the history of my DNS work is merged back into the oss/ repo in the proper directory.

As a final step, I need to remove the network/dns commits from the dns/ repo:

# prepare...
cd ../dns

# Remove the old directory and any empty commits lying around
git filter-branch -f --prune-empty --tree-filter 'rm -rf network' HEAD

# Cleanup
git gc --aggressive

Done.

One of the common complaints I hear about git is that it allows you to rewrite the history. Although this operation can be very damaging in a repository that is heavily cloned, banning, or making history rewriting a second-class operation feels like banning hammers because you can harm yourself. Git is a tool, and it should make complex, but at times useful operations like this, easy or at least possible.