return to OCLUG Web Site
A Django site.
July 23, 2010

Bart Trojanowski
Bart's Blog
» git 1.7.2 is out

Just announced is release of Git version 1.7.2.

Scanning through the ReleaseNotes the following look interesting:

  • git -c var=val will override config
  • git show :/pattern now uses regex
  • git no longer squelches if it doesn't find .git (useful when using in PS1)
  • git checkout --orphan name makes a new root branch (no parent)
  • git cherry-pick can now be given a list of refs
  • git log --decorate learned to colour more things

March 15, 2010

» dpanneur – your friendly DarkPAN/CPAN proxy corner store


There were two things I have wanted to do for some time now. The first was to come up with a way to quickly and easily set up a DarkPAN mirror so that we would have more control over our dependency chain at work. The second was to make a portable CPAN proxy service, so that I can always have access to my favorite modules, even if the machine I’m working on has no Internet access. Last week, I finally had a few ‘rount tuits’ to spend on this type of background itch, and the result is dpanneur (for dépanneur, French Canadian for convenience store).


As it stands, dpanneur is a very thin Catalyst application gluing together the goodiness of CPAN::Cache and MyCPAN::App::DPAN, and throwing in Git as the archive manager.

To get it running, first fetch it from Github

$ git clone git://

then check that you have all the dependencies

$ perl Makefile.PL

and run the script that will create the module repository

$ ./script/create_repo

For now, the module repository is hard-coded to be in the subdirectory cpan of dpanneur. A branch called proxy is created and checked out. Eventually, I’ll use GitStore to push newly fetched modules to the repository, but for the time being if dpanneur is to be used as a proxy, that branch must remain as the one being checked out.

All that is left is to fire up the server in whichever mode you prefer (single-thread test server would do nicely for now)

$ ./script/

and there you are, running your first dpanneur. Congrats! :-)

Using it as a caching proxy

You can use the server as a caching proxy, either for its own sake, or to seed the DarkPAN branches. To do that, you just have to configure your CPAN client to use http://yourmachine:3000/proxy:

$ cpan
cpan[1]> o conf urllist = http://localhost:3000/proxy
cpan[2]> reload index
cpan[3]> install Acme::EyeDrops
Running install for module 'Acme::EyeDrops'
Running make for A/AS/ASAVIGE/Acme-EyeDrops-1.55.tar.gz
Fetching with LWP:

As the modules are downloaded, they are also saved and committed within the repo

[dpanneur]$ cd cpan

[cpan (proxy)]$ git log -n 3
commit d065ad152f2204295334c5475104a3da517b6ae1
Author: Yanick Champoux <>
Date:   Wed Mar 10 20:32:52 2010 -0500


commit e8d2e83d1b16e2e0713d125f9a4bd2742681f859
Author: Yanick Champoux <>

Date:   Wed Mar 10 20:31:42 2010 -0500


commit 7e0b4b600bac8424c519199ee96dc56ffbb177eb
Author: Yanick Champoux <>
Date:   Wed Mar 10 20:30:47 2010 -0500


Using it as a DarkPAN server

There is not much more involved to enabling DarkPAN repos. All we have to do is to create a branch with the modules we want and have the ‘dpan’ utility bundled with MyCPAN::App::DPAN generate the right files for us.

To continue with the example of the previous section, let’s say that we want a DarkPAN branch containing Acme::EyeDrops, but not Acme::Bleach. Then we’d do

                        # only necessary if you are running
                        # the server while you work on the branch
[dpanneur]$ git clone cpan cpan-work   

[dpanneur]$ cd cpan-work

                        # branch just before we imported Acme::Bleach
[cpan-work (proxy)]$ git branch pictoral 7e0b4b600bac8424c519199ee96dc56ffbb177eb

[cpan-work (proxy)]$ git checkout pictoral
Switched to branch 'pictoral'

                        # cherry-pick the Acme::EyeDrops commit
[cpan-work (pictoral)]$ git cherry-pick d065ad152f2204295334c5475104a3da517b6ae1

                        # rebuild the module list
[cpan-work (pictoral)]$ dpan

                        # commit the new 02packages.details.txt.gz
[cpan-work (pictoral)]$ git add .
[cpan-work (pictoral)]$ git commit -m "dpan processing"

                        # push back to the mothership
[cpan-work (pictoral)]$ git push origin pictoral

And that’s it. Now point the cpan client to http://yourmachine:3000/pictoral, and you’ll get the limited mirror.

cpan[1]> o conf urllist http://localhost:3000/pictoral
cpan[2]> reload index

cpan[3]> i Acme::EyeDrops
Strange distribution name [Acme::EyeDrops]
Module id = Acme::EyeDrops
    CPAN_USERID  ASAVIGE (Andrew J. Savige &lt;>)
    CPAN_FILE    A/AS/ASAVIGE/Acme-EyeDrops-1.55.tar.gz
    UPLOAD_DATE  2008-12-02
    MANPAGE      Acme::EyeDrops - Visual Programming in Perl
    INST_FILE    /usr/local/share/perl/5.10.0/Acme/

cpan[4]> i Acme::Bleach
Strange distribution name [Acme::Bleach]
No objects found of any type for argument Acme::Bleach

February 27, 2010

Bart Trojanowski
Bart's Blog
» serving http content out of a git repo

While preparing for my Git Workshop for Flourish Conf, I thought about serving files over http directly out of a git repo.

Here is a short shell script that I came up with: git-serv.cgi.

It takes request URLs like http://domain/examples/dir/file and looks up the objects in a bare git repository in /home/git/examples.git. It looks only on the master branch, and nothing is ever checked out. If it finds a tree object, it prints the file listing at that point in the tree. If the object is a blog, it dumps the contents. Otherwise some error is reported.

The other way to achieve something similar would be to use a hook script, like what I used with my resume post-update hook.

February 25, 2010

Bart Trojanowski
Bart's Blog
» pimped out zsh prompt

Here is yet another update to the series. I've updated my git prompt again, now using the zsh 4.3.7 built in vcs_info module. This time the motivation came from Zsh Prompt Magic article. Here is what it looks like now:

zsh git prompt

Everything is now self contained in one file: S60_prompt. Grab it and source it into your zsh config.

The features are:

  • name of current branch,
  • git repo state (rebase, am, bisect, merge, etc),
  • markers indicating staged/unstaged changes,
    • little 1 after branch name indicates dirty working tree,
    • little 2 after branch name indicates staged changes,
  • highlight depth decended into the repository on the right,
  • show failure of commands via prompt background change,
  • show command/insert mode when using vi mode (set -o vi).

[Read More]

January 16, 2010

Bart Trojanowski
Bart's Blog
» pimping out git log

I got playing with git log and ended up creating this alias:

    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative

Which adds a git lg command that is a prettier version of git log --oneline.

[Read More]

» using git workflows to avoid loosing intermediate changes

A few days ago a buddy, Jean, had stumbled into a problem caused by infrequent committing to his git repository. Committing after the feature is implemented is common when working with tools like SVN... but we have multiple workflows available to us under git to manage frequent commits.

[Read More]

» using WIP branches to save every edit

I am experimenting with a new workflow to help solve the problem of lost work between commits. As described in my previous post, there are already several ways to deal with keeping track of frequent edits. The only problem is that they all involve dedication and extra effort.

[Read More]

July 14, 2009

Bart Trojanowski
Bart's Blog
» importing an old project into git

I have recently been asked to revive an old project. Way back when I used to use bk for tracking changes. But today, I don't even have a working bk tree.

Moving the history to git is easiest done by taking the tarballs I've published and creating a commit per tarball.

Below is a simple script that will do just that.

[Read More]

July 2, 2009

Bart Trojanowski
Bart's Blog
» Why pick Git?

Someone on the Git LinkedIn group asked "why pick Git?". I started writing a response on LinkedIn but quickly realized I had more to say on the topic than I'd care to leave behind closed doors of LinkedIn.

If you already use Git, none of the stuff I talk about below will surprise you. But if this sparks your interest see my Git talk.

[Read More]

June 23, 2009

Bart Trojanowski
Bart's Blog
» bringing git-format-patch to bzr

It should be of no surprise to readers of this blog that I am a fan of Git. If you know me, you will also know that I am no fan of Bzr.

I was working on something today and wanted to export a patch... you know, like git format-patch does. Well, bzr does not seem to have an equivalent.

[Read More]

June 11, 2009

Bart Trojanowski
Bart's Blog
» Scott Chacon smacks git around

I came across a RailsConf talk given by Scott Chacon last month. As previously, his git work is really good. His presentation style has also guided my Git the basics talk which I gave about a year ago.

Anyway, I want to summarize what I learned from Scott's presentation...

[Read More]

June 9, 2009

Bart Trojanowski
Bart's Blog
» git-vim hacking

I did some hacking on my fork on git-vim. I am impressed how well things work. motemen, the upstream author, did a really great job setting things up.

I've been mostly tyoing with command handling and completion this evening. I want to make that I could type :git diff ma<tab> and have it do the rigth thing... it seems to work.

Next, I need to integrate my other git hacks and also others that seem interesting. I should also see if I can get the upstream author to consider including any of it.

May 17, 2009

Dave O'Neill
» Converting vimblog to ikiwiki

Until today, this blog ran on vimblog, a hand-rolled minimal script for displaying blog entries. In the last year or so, though, I've become a convert to git, and so what I really want to do is edit my posts on any system, commit them to a git repository, push to a remote and have them end up as blog entries on my server. Fixing vimblog to do this would have been more work than I want to deal with, but thankfully ikiwiki exists, and can do most of what I need.

So, as of now, this blog is in ikiwiki. To get there, I followed (more or less, since I'm documenting after-the-fact) these steps:


May 1, 2009

Bart Trojanowski
Bart's Blog
» splitting files out of a commit

I previously wrote on splitting patches with git. This is very similar but deals with removing a file from a commit.

[Read More]

April 1, 2009

Bart Trojanowski
Bart's Blog
» how old are these files in git?

A freind asked me how he could check the age of a file in his git repository. I came up with this:

    % git ls-files | xargs -n1 -i{} git log -1 --pretty=format:"%ci {}" -- {}
    2007-04-11 11:39:31 -0400 .gitignore
    2008-10-18 10:52:27 -0400 Xdefaults

It walks through all the files tracked by git and prints the time stamp of the last commit that modified that file.

Git rocks!

March 9, 2009

Ian Ward
excess - News
» Ottawa Python Authors Group Meeting

The Ottawa Python Authors Group is having a meeting tomorrow (Monday) and Michael Soulier will be presenting talks on concurrency in Django, and an Introduction to Git. It has been a while since the last meeting and this promises to be a good one.

November 12, 2008

Bart Trojanowski
Bart's Blog
» splitting patches with git

Here is a really cool workflow using git...

Say you have several commits (you can think of them as patches for this exercise) in your current repository and want to split one into multiple parts. There could be various reaons like upstream request, only want to release part of it, remove debug code, etc.

Anyway, there is one commit in your unpublished history that needs to be split.

[Read More]

October 24, 2008

Bart Trojanowski
Bart's Blog
» git-svn strangeness

As awesome as git-svn is, I had it fail today with this message:

    Last fetched revision of refs/remotes/branches/foo was r19307, but we are about to fetch: r19307!

To which I said: "WTF?". I still don't know what it means, but I can share with you how I recovered it.

It turns out that git-svn is quite capable of recovering from this. You just have to remove its meta-data for the offending branch, and resync with SVN.

    rm -f .git/svn/branches/foo/.rev_*
    git svn fetch

I actually had multiple branches in this bad state -- but not all of them -- and I had to repeat it for all those that it complained about.

UPDATE: I upgraded to git v1.6.0.2 and the problem went away.

September 15, 2008

Bart Trojanowski
Bart's Blog
» installilng git man pages quickly

I just upgraded git to get a fix for a diff buffer overflow. I built the git binaries, but this box is too slow to rebuild the man pages.

Fortunately those are already prebuilt in a separate branch. One way to install them without rebuilding them locally is to:

    # in a clone of git://

    git archive --format=tar origin/man | sudo tar -x -C /usr/share/man/ -vf -

... with which I don't have to rebuild man pages locally. Git rocks!

August 1, 2008

Bart Trojanowski
Bart's Blog
» Git Screencast

Ian Ward posted a screencast of my Git intro talk. Thanks Richard for doing the audio, Ian for doing the screencast and post production, and Jay for hosting us.

Update: Richard took some photos of the OGRE meeting. Thanks.