This week I’ve decided to put my work on Cool Cavemen’s concert videos aside, and work instead on refreshing our online store. After all, fans are requesting this, so I can’t escape my duty…
The theme the store is based on is Drupify, an adaptation of the RokWebify Joomla theme. All these themes are licensed under the GPL, so I have to share all my modifications with the community. This is a great opportunity to seriously experiment with Git (at last !).
Here is my plan:
- Make an exact copy of Drupify’s code base in my GitHub repository.
- Hack it in this playground.
- ???
- Profit !

Problem: Drupify lives in a CVS repository.
Solution: Git features a cvsimport command.
Before going further, we need to install cvsps. For MacPorts users, this is as simple as:
~$ sudo port install cvsps Password: ---> Computing dependencies for cvsps ---> Fetching cvsps ---> Attempting to fetch cvsps-2.1.tar.gz from http://arn.se.distfiles.macports.org/cvsps ---> Attempting to fetch cvsps-2.1.tar.gz from http://distfiles.macports.org/cvsps ---> Verifying checksum(s) for cvsps ---> Extracting cvsps ---> Applying patches to cvsps ---> Configuring cvsps ---> Building cvsps ---> Staging cvsps into destroot ---> Installing cvsps @2.1_1 ---> Activating cvsps @2.1_1 ---> Cleaning cvsps
Then we create a temporary copy of Drupify’s CVS repository:
~$ git cvsimport -a -k -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib -C drupify-copy contributions/themes/drupify Initialized empty Git repository in /Users/kevin/drupify-copy/.git/ parse error on user@server in pserver cvs rlog: Logging contributions/themes/drupify cvs rlog: Logging contributions/themes/drupify/css cvs rlog: Logging contributions/themes/drupify/images
The new Git repository automatically created is named drupify-copy. Here is how it looks like in GitX (notice tags and branches):

To keep things clean and tidy, I want to relocate all the content of this repository to a drupify-fork folder. Inspired by Pedro Melo, we’ll use the git filter-branch to do this job:
~$ cd drupify-copy drupify-copy$ git filter-branch -f --prune-empty --tree-filter ' mkdir -p /tmp/drupify-fork; mv $(ls -A) /tmp/drupify-fork; mv /tmp/drupify-fork drupify-fork ' -- --all Rewrite a9319cebb234c46cc8e0ada95ffb2cd81b87993c (17/17) Ref 'refs/heads/DRUPAL-5' was rewritten Ref 'refs/heads/DRUPAL-6--1' was rewritten Ref 'refs/heads/master' was rewritten Ref 'refs/heads/origin' was rewritten Ref 'refs/tags/DRUPAL-6--1-0' was rewritten
The command we just used alter all the commits, in a way that let Drupify act as if it was located, since the beginning of its history, in the drupify-fork sub-directory.
By default, filter-branch creates a backup of the tree using references prefixed by refs/original/:
drupify-copy$ git show-ref 4c33470f0f59bcfe7d0d88ee64945bb5625d6d02 refs/heads/DRUPAL-5 8930672eaf97eefa8f9d4ed9f5144f466a97728f refs/heads/DRUPAL-6--1 e5907fac0160febbd91f0cda73633b3e6eafa2a9 refs/heads/master e5907fac0160febbd91f0cda73633b3e6eafa2a9 refs/heads/origin af9786625a280930b532541722806739e221ebda refs/original/refs/heads/DRUPAL-5 a9319cebb234c46cc8e0ada95ffb2cd81b87993c refs/original/refs/heads/DRUPAL-6--1 328f3440e202ed72253974dbbbd45f39db23ea4a refs/original/refs/heads/master 328f3440e202ed72253974dbbbd45f39db23ea4a refs/original/refs/heads/origin 957bb22704bc8188c0421b68cbb2f52a3fdcdef6 refs/original/refs/tags/DRUPAL-6--1-0 ee44c42250a2552c1dbef2f7165d65179e1d19c6 refs/tags/DRUPAL-6--1-0
We’re not the only ones to not see through this mess. GitX seems to be confused too:

But according Jakub NarÄ™bski on the Git mailing-list, we can safely removes Git’s backups:
drupify-copy$ rm -Rf .git/refs/original drupify-copy$ git gc --prune=now Counting objects: 106, done. Delta compression using up to 2 threads. Compressing objects: 100% (88/88), done. Writing objects: 100% (106/106), done. Total 106 (delta 40), reused 0 (delta 0)
After the cleaning, references are back to normal:
drupify-copy$ git show-ref 4c33470f0f59bcfe7d0d88ee64945bb5625d6d02 refs/heads/DRUPAL-5 8930672eaf97eefa8f9d4ed9f5144f466a97728f refs/heads/DRUPAL-6--1 e5907fac0160febbd91f0cda73633b3e6eafa2a9 refs/heads/master e5907fac0160febbd91f0cda73633b3e6eafa2a9 refs/heads/origin ee44c42250a2552c1dbef2f7165d65179e1d19c6 refs/tags/DRUPAL-6--1-0
We can then fire up GitX to get the ultimate proof that the relocation operation didn’t change anything, but the base folder (and SHA hashes):

It’s time to import all this code in our main repository. First, get a local copy of our public GitHub code base:
drupify-copy$ cd ~$ git clone git@github.com:kdeldycke/kev-code.git Initialized empty Git repository in /Users/kevin/kev-code/.git/ remote: Counting objects: 5, done. remote: Compressing objects: 100% (3/3), done. remote: Total 5 (delta 0), reused 0 (delta 0) Receiving objects: 100% (5/5), done.
Now let’s include our temporary drupify-copy as a tracked remote repository:
~$ cd kev-code/ kev-code$ git remote add drupify ../drupify-copy kev-code$ git fetch drupify warning: no common commits remote: Counting objects: 106, done. remote: Compressing objects: 100% (48/48), done. remote: Total 106 (delta 40), reused 106 (delta 40) Receiving objects: 100% (106/106), 61.62 KiB, done. Resolving deltas: 100% (40/40), done. From ../drupify-copy * [new branch] DRUPAL-5 -> drupify/DRUPAL-5 * [new branch] DRUPAL-6--1 -> drupify/DRUPAL-6--1 * [new branch] master -> drupify/master * [new branch] origin -> drupify/origin From ../drupify-copy * [new tag] DRUPAL-6--1-0 -> DRUPAL-6--1-0
As you can see, all the little particularities of the remote repository are well tracked (HEAD, branches and tags are there):
kev-code$ git remote show drupify
* remote drupify
Fetch URL: ../drupify-copy
Push URL: ../drupify-copy
HEAD branch (remote HEAD is ambiguous, may be one of the following):
master
origin
Remote branches:
DRUPAL-5 tracked
DRUPAL-6--1 tracked
master tracked
origin tracked
Local ref configured for 'git push':
master pushes to master (local out of date)
Another way to check this is to list all tracked remote branches:
kev-code$ git branch -r drupify/DRUPAL-5 drupify/DRUPAL-6--1 drupify/master drupify/origin origin/HEAD -> origin/master
It’s time to merge all our tracked remote code (from drupify-copy) in our local repository (kev-code). The branch I’m interested in is DRUPAL-6--1, as it holds the latest Drupify code for Drupal 6.x:
kev-code$ git merge drupify/DRUPAL-6--1 Merge made by recursive. drupify-fork/README.txt | 16 + drupify-fork/css/editor_content.css | 7 + drupify-fork/css/index.html | 1 + drupify-fork/css/template_ie.css | 55 +++ drupify-fork/drupify.info | 11 + drupify-fork/images/arrow.png | Bin 0 -> 278 bytes drupify-fork/images/bg.png | Bin 0 -> 315 bytes drupify-fork/images/bottom-bg.png | Bin 0 -> 583 bytes drupify-fork/images/col-divider.png | Bin 0 -> 200 bytes drupify-fork/images/emailButton.png | Bin 0 -> 454 bytes drupify-fork/images/favicon.ico | Bin 0 -> 1150 bytes drupify-fork/images/footer-bg.png | Bin 0 -> 544 bytes drupify-fork/images/footer-l.png | Bin 0 -> 593 bytes drupify-fork/images/footer-r.png | Bin 0 -> 592 bytes drupify-fork/images/footer-rocket.png | Bin 0 -> 3391 bytes drupify-fork/images/header-bg.png | Bin 0 -> 638 bytes drupify-fork/images/header-l.png | Bin 0 -> 430 bytes drupify-fork/images/header-r.png | Bin 0 -> 444 bytes drupify-fork/images/indent1.png | Bin 0 -> 214 bytes drupify-fork/images/indent2.png | Bin 0 -> 214 bytes drupify-fork/images/indent3.png | Bin 0 -> 214 bytes drupify-fork/images/indent4.png | Bin 0 -> 214 bytes drupify-fork/images/index.html | 1 + drupify-fork/images/menu-bg.png | Bin 0 -> 343 bytes drupify-fork/images/menu-bullet.png | Bin 0 -> 933 bytes drupify-fork/images/menu-divider.png | Bin 0 -> 200 bytes drupify-fork/images/pdf_button.png | Bin 0 -> 482 bytes drupify-fork/images/printButton.png | Bin 0 -> 467 bytes drupify-fork/logo.png | Bin 0 -> 27829 bytes drupify-fork/node.tpl.php | 31 ++ drupify-fork/page.tpl.php | 173 ++++++++++ drupify-fork/screenshot.png | Bin 0 -> 11289 bytes drupify-fork/style.css | 593 +++++++++++++++++++++++++++++++++ drupify-fork/template.php | 10 + 34 files changed, 898 insertions(+), 0 deletions(-) create mode 100644 drupify-fork/README.txt create mode 100644 drupify-fork/css/editor_content.css create mode 100644 drupify-fork/css/index.html create mode 100644 drupify-fork/css/template_ie.css create mode 100644 drupify-fork/drupify.info create mode 100644 drupify-fork/images/arrow.png create mode 100644 drupify-fork/images/bg.png create mode 100644 drupify-fork/images/bottom-bg.png create mode 100644 drupify-fork/images/col-divider.png create mode 100644 drupify-fork/images/emailButton.png create mode 100644 drupify-fork/images/favicon.ico create mode 100644 drupify-fork/images/footer-bg.png create mode 100644 drupify-fork/images/footer-l.png create mode 100644 drupify-fork/images/footer-r.png create mode 100644 drupify-fork/images/footer-rocket.png create mode 100644 drupify-fork/images/header-bg.png create mode 100644 drupify-fork/images/header-l.png create mode 100644 drupify-fork/images/header-r.png create mode 100644 drupify-fork/images/indent1.png create mode 100644 drupify-fork/images/indent2.png create mode 100644 drupify-fork/images/indent3.png create mode 100644 drupify-fork/images/indent4.png create mode 100644 drupify-fork/images/index.html create mode 100644 drupify-fork/images/menu-bg.png create mode 100644 drupify-fork/images/menu-bullet.png create mode 100644 drupify-fork/images/menu-divider.png create mode 100644 drupify-fork/images/pdf_button.png create mode 100644 drupify-fork/images/printButton.png create mode 100644 drupify-fork/logo.png create mode 100644 drupify-fork/node.tpl.php create mode 100644 drupify-fork/page.tpl.php create mode 100644 drupify-fork/screenshot.png create mode 100644 drupify-fork/style.css create mode 100644 drupify-fork/template.php
We can remove the attached drupify repository and its local drupify-copy source:
kev-code$ git remote rm drupify kev-code$ cd .. ~$ rm -rf ./drupify-copy
At this stage, here is what our repository looks like:

To keep all the details that were created by git cvsimport, we can add by hand all the missing refs. The only difference with the original ones is that I unified the namespace with a drupify/ prefix:
kev-code$ git update-ref refs/heads/drupify/DRUPAL-6--1 8930672 kev-code$ git update-ref refs/heads/drupify/master e5907fa kev-code$ git update-ref refs/heads/drupify/origin e5907fa kev-code$ git tag drupify/DRUPAL-6--1-0 DRUPAL-6--1-0 kev-code$ git tag -d DRUPAL-6--1-0 Deleted tag 'DRUPAL-6--1-0'
And finally, we can contemplate our work:

This let me work cleanly on the CVS branch I wanted to in the first place. But there is one missing thing: all other tracked remote branches were not merged properly. I really wanted to import all of them (especially the DRUPAL-5 branch), to keep a perfect copy of the original CSV tree. But I failed to find a way. Does anyone have a clue ?