Kubuntu 10.10 on Sony Vaio VPC-S12C5E

Here are some (old) notes regarding the installation of Kubuntu on my Sony Vaio VPC-S12C5E.

First I have to tell you that everything is working fine and out of the box with Kubuntu 10.10. This include: Bluetooth, HDMI out (tested with a Full-HD monitor), Sound out, VGA, USB, CD Burning, WiFi, Networking, Keyboard backlight & SD Card reader.

The only annoying thing in 10.10 is the non-responding touchpad. But a fix can be found on Ubuntu forums:

  1. Edit /etc/default/grub to include GRUB_CMDLINE_LINUX="i8042.nopnp"
  2. Run sudo update-grub
  3. Reboot

Now about the laptop itself: construction quality is below my previous MacBook (cheap plastic instead of aluminum) and battery autonomy is not impressive. A bios update seems to address the latter. Haven’t done it yet as it requires to re-install Windows (*sigh*). But overall that’s a good lightweight machine to get things done, especially with its 8 Gb of RAM, 4 cores and a SSD ! :)

Pushing Git to Subversion: the case of WordPress plugin repository

Some weeks ago I moved my e107 Importer project from a big fat Git repository to its own.

Then I wanted to have my plugin to be available on WordPress.org. In fact, this list is the tip of WordPress plugin hosting solution. It means that if you want to have your plugin there, you have to push your code in WordPress’ big Subversion repository. And that’s when I realized I had to sync my Git repository to Subversion…

This article details how I managed to push to Subversion all my developments activity taking place in Git.

Before going further: be careful ! It’s really easy to mess things up. After all, we’re trying to push code on a public Subversion repository. We must be certain of what we are doing here. Risks of deleting stuff that are not ours are great.

The simulation

To prevent any big mistake, we’ll test our commands on a local subversion repository.

Let’s create one:

$ rm -rf svn-repo
$ svnadmin create ./svn-repo

Now we’ll launch a local Subversion server with a minimal config:

$ sed -i 's/# password-db = passwd/password-db = passwd/' ./svn-repo/conf/svnserve.conf
$ echo "kevin = kevin" >> ./svn-repo/conf/passwd
$ kill `ps -ef | grep svnserve | awk '{print $2}'`
$ svnserve --daemon --listen-port 3690 --root ./svn-repo

To test our server, let’s checkout a local working copy from it:

$ rm -rf svn-working-copy
$ svn co svn://localhost:3690 svn-working-copy
$ cd svn-working-copy/
$ svn info

To simulate an already active Subversion repository, we’ll make a first commit with a structure mimicking WordPress’ plugin repository:

$ mkdir -p e107-importer/{trunk,branches,tags}
$ svn add *
$ svn commit -m "Create a WordPress-like repository structure" --username kevin
$ svn up
$ svn info

Now that we have a place to hack, we can experiment on Git side. We start with a copy of my plugin repository:

$ cd ..
$ rm -rf e107-importer
$ git clone git@github.com:kdeldycke/e107-importer.git
$ cd e107-importer

Thanks to git-svn, we can attach a remote Subversion repository:

$ git svn init --trunk=e107-importer/trunk --branches=e107-importer/branches --tags=e107-importer/tags --username kevin  svn://localhost:3690

Get get a copy of Subversion’s content:

$ git svn fetch
r1 = d969aa9a11684a1cd2ba0b3eab0a3ee72a62af51 (refs/remotes/trunk)

Now we will rebase our whole Git tree to Subversion’s trunk:

$ git rebase trunk

According gitg, the result of this is 2 parallel trees:

  • the first is the untouched original tree;
  • the other start on the trunk branch and continue with a copy of the original tree, and is the result of the rebase.

But the latter has a problem: my initial commit and all my tags are squashed. I tried several methods to rebase my whole Git tree onto the local trunk branch while keeping these. But I failed.

I resigned myself and passed over this. After all, the initial commit played its role, by taking care of this corner-case.

As for the tags, I just re-added them by hand. I forced their creation, as Git keeps them attached to the original parallel tree:

$ git tag -f "e107-importer-0.1" 728ec8689d13350bbfc1f2d9dc17dda2b8a8fdbf
$ git tag -f "e107-importer-0.2" 8049b92265a41f594e97020bae6f3aa74b6a7fb1
$ git tag -f "e107-importer-0.3" 9505aa0656ba61f39cd6cb91c76c1e7279c68473
$ git tag -f "e107-importer-0.4" 0da2d61239c9a9549d197737518705912fd4982d
$ git tag -f "e107-importer-0.5" 561d35b5d1b4d2c35e13c76a3f2a41689c96e991
$ git tag -f "e107-importer-0.6" c6de1a2bf60cad054c5420eab2f30f190092fb68
$ git tag -f "e107-importer-0.7" 6ad4d4a67e8b84da31565383e5eed6ceb5b7d2b2
$ git tag -f "e107-importer-0.8" 47b8efdc82132027b139a2f214f119cee1e9c06c
$ git tag -f "e107-importer-0.9" a82f5d0814db7cf6ac7a1ac171b30c300e1a91d4

Now we are ready to push the code to the remote Subversion repository:

$ git svn dcommit

Things seems to have worked, as if you go back to your local copy of the simulated remote SVN, you’ll get all your code base and its history:

$ cd ..
$ cd svn-working-copy
$ svn up
$ svn log

If commit order is preserved, dates are not, because unlike Git, Subversion only track the commit date, not the author’s date. This is sad but expected.

But here I was hoping that Git-svn was smart enough to create tags automatically. They weren’t, and my tags folder remained empty. That may be due to the nature of tags in Subversion, which are just branches. I don’t know. At the end I just decided to create tags by hand on Subversion side:

$ svn copy svn://localhost:3690/e107-importer/trunk@2  svn://localhost:3690/e107-importer/tags/0.1 -m "Tag e107-importer 0.1"
$ svn copy svn://localhost:3690/e107-importer/trunk@4  svn://localhost:3690/e107-importer/tags/0.2 -m "Tag e107-importer 0.2"
$ svn copy svn://localhost:3690/e107-importer/trunk@5  svn://localhost:3690/e107-importer/tags/0.3 -m "Tag e107-importer 0.3"
$ svn copy svn://localhost:3690/e107-importer/trunk@6  svn://localhost:3690/e107-importer/tags/0.4 -m "Tag e107-importer 0.4"
$ svn copy svn://localhost:3690/e107-importer/trunk@8  svn://localhost:3690/e107-importer/tags/0.5 -m "Tag e107-importer 0.5"
$ svn copy svn://localhost:3690/e107-importer/trunk@9  svn://localhost:3690/e107-importer/tags/0.6 -m "Tag e107-importer 0.6"
$ svn copy svn://localhost:3690/e107-importer/trunk@10 svn://localhost:3690/e107-importer/tags/0.7 -m "Tag e107-importer 0.7"
$ svn copy svn://localhost:3690/e107-importer/trunk@11 svn://localhost:3690/e107-importer/tags/0.8 -m "Tag e107-importer 0.8"
$ svn copy svn://localhost:3690/e107-importer/trunk@12 svn://localhost:3690/e107-importer/tags/0.9 -m "Tag e107-importer 0.9"

Real life push to WordPress repository

Now that our commit simulation worked somehow, we can perform them in the real world.

First, initialize a copy of the Git repository:

$ rm -rf e107-importer-git
$ git clone git@github.com:kdeldycke/e107-importer.git e107-importer-git

Let’s attach Subversion to Git:

$ cd e107-importer-git
$ git svn init --trunk=trunk --branches=branches --tags=tags http://plugins.svn.wordpress.org/e107-importer

Here you might want to do a git svn fetch as we did before. But this will take a while. Especially on WordPress plugin repository, as Git will browse all SVN revisions (more than 330.000 currently).

To speed things up, and following a tip from Nicolas Kuttler, we’ll search for the revision we’re interested in (the start of our plugin subfolder life), then fetch from here:

$ svn log --limit 1 http://plugins.svn.wordpress.org/e107-importer
------------------------------------------------------------------------
r333566 | plugin-master | 2011-01-17 17:09:40 +0100 (Mon, 17 Jan 2011) | 1 line

adding e107-importer by Coolkevman
------------------------------------------------------------------------
$ git svn fetch -r333566
r333566 = b850438a98c26a8f55ee2ddd7bdf8816d0390a1b (refs/remotes/trunk)

And now we can send our massive payload, after rebasing our master branch to SVN’s trunk:

$ git rebase trunk
$ git svn dcommit --username=Coolkevman

We can then contemplate our work in the official WordPress plugin repository.

There is one problem though: git-svn has left empty folders because of renaming. Let’s fix this:

$ svn rm http://plugins.svn.wordpress.org/e107-importer/trunk/bbcode -m "Git-svn doesn't delete empty folders on move." --username=Coolkevman

Last thing to do is to tag our old versions on Subversion, as we did in our simulation:

$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336229 http://plugins.svn.wordpress.org/e107-importer/tags/0.1 -m "Tag e107-importer 0.1"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336231 http://plugins.svn.wordpress.org/e107-importer/tags/0.2 -m "Tag e107-importer 0.2"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336232 http://plugins.svn.wordpress.org/e107-importer/tags/0.3 -m "Tag e107-importer 0.3"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336233 http://plugins.svn.wordpress.org/e107-importer/tags/0.4 -m "Tag e107-importer 0.4"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336235 http://plugins.svn.wordpress.org/e107-importer/tags/0.5 -m "Tag e107-importer 0.5"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336236 http://plugins.svn.wordpress.org/e107-importer/tags/0.6 -m "Tag e107-importer 0.6"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336237 http://plugins.svn.wordpress.org/e107-importer/tags/0.7 -m "Tag e107-importer 0.7"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336238 http://plugins.svn.wordpress.org/e107-importer/tags/0.8 -m "Tag e107-importer 0.8"
$ svn copy http://plugins.svn.wordpress.org/e107-importer/trunk@336239 http://plugins.svn.wordpress.org/e107-importer/tags/0.9 -m "Tag e107-importer 0.9"

But this mean I had to clean up tags too, to remove the remaining empty folder.

Pushing new commits

All of the above only works with an newly created plugin structure on WordPress plugin repository. What if we want to push new commits to Subversion once we’ve already pushed part of our Git history ?

First, let’s make our life miserable and delete all our local repositories:

$ cd ..
$ rm -rf e107-importer-git

Now, if we replay the steps above, the git rebase trunk command will ends with loads of conflicts. The procedure is different this time and is explained by Ikke.

This involves Git’s graft:

$ git clone git@github.com:kdeldycke/e107-importer.git e107-importer-git
$ cd e107-importer-git
$ git svn init --trunk=trunk --branches=branches --tags=tags http://plugins.svn.wordpress.org/e107-importer
$ git svn fetch -r333566
$ git show-ref trunk
$ git log --pretty=oneline master | tail -n1
$ echo `git log --pretty=oneline master | tail -n1 | cut -d ' ' -f 1` `git show-ref trunk | cut -d ' ' -f 1` >> .git/info/grafts
$ git svn dcommit

The last command will not end well, with Git complaining about unmerged differences. This is likely due to my additional commit removing the empty folder left by git-svn. Fortunately Git suggest something in its log:

If you are attempting to commit  merges, try running:
  git rebase --interactive --preserve-merges  refs/remotes/trunk
Before dcommitting

Well, that’s what I exactly did:

$ git rebase --interactive --preserve-merges refs/remotes/trunk
$ git svn dcommit

And it magically fixed the issue ! :)

I’m quite happy now to have a clearly identified workflow to push my Git updates to Subversion ! :)

Trapped in Freedom: live at Garage Café

Some weeks ago I was at a local bar to see Trapped in Freedom. This band is composed of friends, and is also a side project involving Jimy Wong from Cool Cavemen, again as a drummer. This was a perfect excuse to test my brand new Tamron SP AF 17-50mm f/2.8 XR Di-II VC LD IF lens.

Some days after shooting I sent my raw footages to the band, which decided to publish a preview of their song “Chicken Fighter” on YouTube. Here is the video:

They also released “Incoming” some days ago:

All of these were shots in 1080p at 23.976 fps with a shutter speed of 1/50. Lens was set to manual focus as usual, and stayed wide open at f/2.8, with optical stabilization (“VC” in Tamron’s jargon) on.

I think the white balance was set to tungsten. I don’t remember what was the ISO setting. Maybe set to automatic. I really don’t remember. Should have drink less. Either that or changing my video workflow. After all, keeping these .THM files is a good idea, as these contain the video metadatas that can’t be put in the .MOV files produced by Canon.

Finally, if the music is good, the sound is awful as it was captured without any special care, with the embedded camera microphone. Now I really have to invest money and time to upgrade my sound recording gear and skills. Canon EOS 7D‘s Automatic Gain Control (AGC) really starts to be limiting (pun intended)…

Moving a Git sub-tree to its own repository

Coming from Subversion (and with Plone collective repository structure in mind), I’ve recently moved all my tiny software projects in a big standalone Git repository (named kev-code). Now that I figured out that GitHub allows you to create unlimited amount of repositories, as long as they are open-source public projects, it make sense to emancipate some of my projects to their own repository. How do I move a sub-tree to its own repository ? That’s what I talk about in this article.

First, there is an automated way of performing this task with git-subtree. You should try it first. For some reasons I didn’t investigate, git-subtree didn’t worked for me. So I’ll explain now how I did it by hand.

The idea is to revisit the history of my bloated Git repository and massively delete everything that is not related to the sub-folder I’m looking to export. In this case, I try to make a dedicated repository for my e107 importer for WordPress.

Let’s start by getting a local copy of my source repository:

git clone git@github.com:kdeldycke/kev-code.git
cd scripts

Then I’ll use the filter-branch action with a combination of find and rm to remove everything except the source code of my plugin:

git filter-branch --prune-empty --tree-filter 'find ./ -maxdepth 1 -not -path "./e107*" -and -not -path "./wordpress-e107*" -and -not -path "./.git" -and -not -path "./" -print -exec rm -rf "{}" \;' -- --all

Instead of the command above, I could have use the --subdirectory-filter option (as suggested by jamessan on Stack Overflow):

git filter-branch --prune-empty --subdirectory-filter e107-importer -- --all

But this doesn’t work in my case as my e107 Importer plugin didn’t started its life straight in a dedicated folder. So this command squash some of the history I want to preserve.

At this point I’m left with this following history:

This looks pretty good, as all the history of my plugin is kept in order. But tags unrelated to my plugin are still there. Let’s remove them:

git tag -d coolkevmen-0.3 cool-blue-0.1 sapphire-0.1 sapphire-0.2 sapphire-0.3 sapphire-0.4

Now there is some commits polluting my history. These are left-overs of git-modules additions. I tried to removed them, but it didn’t worked. Also left in the history are unwanted merges and empty commits from an old CVS import. To clean this up, I started an interactive rebase:

git rebase --interactive init

There, using my text editor, I deleted the entries corresponding to these unrelated commits (namely c21a840, 0dc1d76, 37473a8 and c6f9f64), and hoped Git will be smart enough to reconstruct a clean history:

Luckily, it worked for me. If Git complain about such abuse, you may ignore warnings and force it to continue:

git rebase --continue

Now that we only have a clean sub-tree, let’s create a dedicated local Git repository to receive our branch:

cd ..
mkdir e107-importer
cd e107-importer
git init

Add a temporary origin hooked on our source repository:

git remote add origin ../kev-code

And import the master branch we carefully crafted (including tags):

git pull --tags origin master

Now we can create on GitHub the new repository that will receive our exported project:

It’s time to push our changes. Let’s replace our temporary origin to the new GitHub repository we just created:

git remote rm origin
git remote add origin git@github.com:kdeldycke/e107-importer.git
git push origin master --force --tags

So now we have a copy of the sub-tree of my plugin into its own repository. That’s great, but there is still some stuff to clean-up.

First, we will rewrite the repository to look as if the ./e107-importer sub-folder had been its project root since the beginning:

git filter-branch --tree-filter 'test -d ./e107-importer && mv ./e107-importer/* ./ || echo "No folder found"' -- --all

Then, I’ve altered some commit messages to fix inconsistencies due to sub-folder removal:

git filter-branch --msg-filter 'sed "s/Move the script to a dedicated folder/Rename script/g"' -- --all

Finally, at the bottom of the history, I still have my initial commit (a personal habit of mine when I initialize my Git repositories). But its date was updated by the first filter-branch call. Let’s set its date back to epoch:

git filter-branch --force --env-filter \
  'if [ $GIT_COMMIT = a2a5c05aed893fdd10250b724eb6a54bc6e7f122 ]
     then
       export GIT_AUTHOR_DATE="Thu, 01 Jan 1970 00:00:00 +0000"
       export GIT_COMMITTER_DATE="Thu, 01 Jan 1970 00:00:00 +0000"
   fi' -- --all

We can now send our latest changes to the remote GitHub repository by forcing a push:

git push --force

Last thing we have to do, is to remove the plugin code from the fat source repository (I don’t like duplicates). But that’s another story for another article…