Welcome to my blog. Have a look at the most recent posts below, or browse the tag cloud on the right. An archive of all posts is also available.
(Debian) packaging and Git.
The big picture is as follows. In my view, the most natural way to
work on a packaging project in version control [1] is to have an
upstream branch which either tracks upstream Git/Hg/Svn, or imports of
tarballs (or some combination thereof, and a Debian branch where both
modifications to upstream source and commits to stuff in ./debian are
added [2]. Deviations from this are mainly motivated by a desire to
export source packages, a version control neutral interchange format
that still preserves the distinction between upstream source and
distro modifications. Of course, if you're happy with the distro
modifications as one big diff, then you can stop reading now gitpkg
$debian_branch $upstream_branch and you're done. The other easy case
is if your changes don't touch upstream; then 3.0 (quilt) packages
work nicely with ./debian in a separate tarball.
So the tension is between my preferred integration style, and making
source packages with changes to upstream source organized in some
nice way, preferably in logical patches like, uh, commits in a
version control system. At some point we may be able use some form of
version control repo as a source package, but the issues with that are
for another blog post. At the moment then we are stuck with
trying bridge the gap between a git repository and a 3.0 (quilt)
source package. If you don't know the details of Debian packaging,
just imagine a patch series like you would generate with git
format-patch or apply with (surprise) quilt.
From Git to Quilt.
The most obvious (and the most common) way to bridge the gap between
git and quilt is to export patches manually (or using a helper like
gbp-pq) and commit them to the packaging repository. This has the
advantage of not forcing anyone to use git or specialized helpers to
collaborate on the package. On the other hand it's quite far from the
vision of using git (or your favourite VCS) to do the integration that
I started with.
The next level of sophistication is to maintain a branch of
upstream-modifying commits. Roughly speaking, this is the approach
taken by git-dpm, by gitpkg, and with some additional friction
from manually importing and exporting the patches, by gbp-pq. There
are some issues with rebasing a branch of patches, mainly it seems to
rely on one person at a time working on the patch branch, and it
forces the use of specialized tools or workflows. Nonetheless, both
git-dpm and gitpkg support this mode of working reasonably well [3].
Lately I've been working on exporting patches from (an immutable) git
history. My initial experiments with marking commits with git notes
more or less worked [4]. I put this on the back-burner for two
reasons, first sharing git notes is still not very well supported by
git itself [5], and second Gitpkg maintainer Ron Lee convinced me to
automagically pick out what patches to export. Ron's motivation (as I
understand it) is to have tools which work on any git repository
without extra metadata in the form of notes.
Linearizing History on the fly.
After a few iterations, I arrived at the following specification.
The user supplies two refs upstream and head. upstream should be suitable for export as a
.orig.tar.gzfile [6], and it should be an ancestor of head.At source package build time, we want to construct a series of patches that
- Is guaranteed to apply to upstream
- Produces the same work tree as head, outside
./debian - Does not touch
./debian - As much as possible, matches the git history from upstream to head.
Condition (4) suggests we want something roughly like git
format-patch upstream..head, removing those patches which are
only about Debian packaging. Because of (3), we have to be a bit
careful about commits that touch upstream and ./debian. We also
want to avoid outputting patches that have been applied (or worse
partially applied) upstream. git patch-id can help identify
cherry-picked patches, but not partial application.
Eventually I arrived at the following strategy.
Use git-filter-branch to construct a copy of the history upstream..head with ./debian (and for technical reasons .pc) excised.
Filter these commits to remove e.g. those that are present exactly upstream, or those that introduces no changes, or changes unrepresentable in a patch.
Try to revert the remaining commits, in reverse order. The idea here is twofold. First, a patch that occurs twice in history because of merging will only revert the most recent one, allowing earlier copies to be skipped. Second, the state of the temporary branch after all successful reverts represents the difference from upstream not accounted for by any patch.
Generate a "fixup patch" accounting for any remaining differences, to be applied before any if the "nice" patches.
Cherry-pick each "nice" patch on top of the fixup patch, to ensure we have a linear history that can be exported to quilt. If any of these cherry-picks fail, abort the export.
Yep, it seems over-complicated to me too.
TL;DR: Show me the code.
You can clone my current version from
git://pivot.cs.unb.ca/gitpkg.git
This provides a script "git-debcherry" which does the history linearization discussed above. In order to test out how/if this works in your repository, you could run
git-debcherry --stat $UPSTREAM
For actual use, you probably want to use something like
git-debcherry -o debian/patches
There is a hook in hooks/debcherry-deb-export-hook that does this at
source package export time.
I'm aware this is not that fast; it does several expensive operations. On the other hand, you know what Don Knuth says about premature optimization, so I'm more interested in reports of when it does and doesn't work. In addition to crashing, generating multi-megabyte "fixup patch" probably counts as failure.
Notes
This first part doesn't seem too Debian or git specific to me, but I don't know much concrete about other packaging workflows or other version control systems.
Another variation is to have a patched upstream branch and merge that into the Debian packaging branch. The trade-off here that you can simplify the patch export process a bit, but the repo needs to have taken this disciplined approach from the beginning.
git-dpm merges the patched upstream into the Debian branch. This makes the history a bit messier, but seems to be more robust. I've been thinking about trying this out (semi-manually) for gitpkg.
See e.g. exporting. Although I did not then know the many surprising and horrible things people do in packaging histories, so it probably didn't work as well as I thought it did.
It's doable, but one ends up spending about a bunch lines of code on duplicating basic git functionality; e.g. there is no real support for tags of notes.
Since as far as I know quilt has no way of deleting files except to list the content, this means in particular exporting upstream should yield a DFSG Free source tree.
In April of 2012 I bought a ColorHug colorimeter. I got a bit discouraged when the first thing I realized was that one of my monitors needed replacing, and put the the colorhug in a drawer until today.
With quite a lot of help and encouragment from Pascal de Bruijn, I finally got it going. Pascal has written an informative blog post on color management. That's a good place to look for background. This is more of a "write down the commands so I don't forget" sort of blog post, but it might help somebody else trying to calibrate their monitor using argyll on the command line. I'm not running gnome, so using gnome color manager turns out to be a bit of a hassle.
I run Debian Wheezy on this machine, and I'll mention the packages I used, even though I didn't install most of them today.
Find the masking tape, and tear off a long enough strip to hold the ColorHug on the monitor. This is probably the real reason I gave up last time; it takes about 45minutes to run the calibration, and I lack the attention span/upper-arm-strength to hold the sensor up for that long. Apparently new ColorHugs are shipping with some elastic.
Update the firmware on the colorhug. This is a gui-wizard kindof thing.
% apt-get install colorhug-client % colorhug-flashSet the monitor to factory defaults. On this ASUS PA238QR, that is brightness 100, contrast 80, R=G=B=100. I adjusted the brightness down to about 70; 100 is kindof eye-burning IMHO.
Figure out which display is which; I have two monitors.
% dispwin -\?Look under "-d n"
Do the calibration. This is really verbatim from Pascal, except I added the
ENABLE_COLORHUG=trueand-d 2bits.% apt-get install argyll % ENABLE_COLORHUG=true dispcal -v -d 2 -m -q m -y l -t 6500 -g 2.2 test % targen -v -d 3 -G -f 128 test % ENABLE_COLORHUG=true dispread -v -d 2 -y l -k test.cal test % colprof -v -A "make" -M "model" -D "make model desc" -C "copyright" -q m -a G testLoad the profile
% dispwin -d 2 -I test.iccIt seems this only loads the x property
_ICC_PROFILE_1instead of_ICC_PROFILE; whether this works for a particular application seems to be not 100% guaranteed. It seems ok for darktable and gimp.
It's spring, and young(ish?) hackers' minds turn to OpenCL. What is the state of things? I haven't the faintest idea, but I thought I'd try to share what I find out. So far, just some links. Details to be filled in later, particularly if you, dear reader, tell them to me.
Specification
LLVM based front ends
Mesa backend
Rumours/hopes of something working in mesa 8.1?
- r600g is merged into master as of this writing.
- clover
Other projects
- SNU This project seems be only for Cell/ARM/DSP at the moment. Although they make you register to download, it looks like it is LGPL.
I've been experimenting with a new packaging tool/workflow based on marking certain commits on my integration branch for export as quilt patches. In this post I'll walk though converting the package nauty to this workflow.
Add a control file for the gitpkg export hook, and enable the hook: (the package is already 3.0 (quilt))
% echo ':debpatch: upstream..master' > debian/source/git-patches % git add debian/source/git-patches && git commit -m'add control file for gitpkg quilt export' % git config gitpkg.deb-export-hook /usr/share/gitpkg/hooks/quilt-patches-deb-export-hookThis says that all commits reachable from master but not from upstream should be checked for possible export as quilt patches.
This package was previously maintained in the "recommend topgit style" with the patches checked in on a seperate branch, so grab a copy.
% git archive --prefix=nauty/ build | (cd /tmp ; tar xvf -)More conventional git-buildpackage style packaging would not need this step.
Import the patches. If everything is perfect, you can use qit quiltimport, but I have several patches not listed in "series", and quiltimport ignores series, so I have to do things by hand.
% git am /tmp/nauty/debian/patches/feature/shlib.diffMark my imported patch for export.
% git debpatch +export HEADgit debpatch listoutputs the followingafb2c20 feature/shlib Export: true makefile.in | 241 +++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 136 insertions(+), 105 deletions(-)The first line is the subject line of the patch, followed by any notes from debpatch (in this case, just 'Export: true'), followed by a diffstat. If more patches were marked, this would be repeated for each one.
In this case I notice subject line is kindof cryptic and decide to amend.
git commit --amendgit debpatch liststill shows the same thing, which highlights a fundemental aspect of git notes: they attach to commits. And I just made a new commit, sogit debpatch -export afb2c20 git debpatch +export HEADNow
git debpatch listlooks ok, so we trygit debpatch exportas a dry run. In debian/patches we have0001-makefile.in-Support-building-a-shared-library-and-st.patch series
That looks good. Now we are not going to commit this, since one of our overall goal is to avoid commiting patches. To clean up the export,
rm -rf debian/patchesgitpkg masterexports a source package, and because I enabled the appropriate hook, I have the following% tar tvf ../deb-packages/nauty/nauty_2.4r2-1.debian.tar.gz | grep debian/patches drwxr-xr-x 0/0 0 2012-03-13 23:08 debian/patches/ -rw-r--r-- 0/0 143 2012-03-13 23:08 debian/patches/series -rw-r--r-- 0/0 14399 2012-03-13 23:08 debian/patches/0001-makefile.in-Support-building-a-shared-library-and-st.patchNote that these patches are exported straight from git.
I'm done for now so
git push git debpatch push
the second command is needed to push the debpatch notes metadata to the origin. There is a corresponding fetch, merge, and pull commands.
More info
Example package: bibutils In this package, I was already maintaining the upstream patches merged into my master branch; I retroactively added the quilt export.
I have been in the habit of using R to make e.g. histograms of test scores in my courses. The main problem is that I don't really need (or am too ignorant to know that I need) the vast statistical powers of R, and I use it rarely enough that its always a bit of a struggle to get the plot I want.
racket is a programming language in the scheme family, distinguished from some of its more spartan cousins by its "batteries included" attitude.
I recently stumbled upon the PLoT graph (information visualization kind, not networks) plotting module and was pretty impressed with the Snazzy 3D Pictures.
So this time I decided try using PLoT for my chores. It worked out pretty well; of course I am not very ambitious. Compared to using R, I had to do a bit more work in data preparation, but it was faster to write the Racket than to get R to do the work for me (again, probably a matter of relative familiarity).

#lang racket/base (require racket/list) (require plot) (define marks (build-list 30 (lambda (n) (random 25)))) (define out-of 25) (define breaks '((0 9) (10 12) (13 15) (16 18) (19 21) (22 25))) (define (per-cent n) (ceiling (* 100 (/ n out-of)))) (define (label l) (format "~a-~a" (per-cent (first l)) (per-cent (second l)))) (define (buckets l) (let ((sorted (sort l <))) (for/list ([b breaks]) (vector (label b) (count (lambda (x) (and (<= x ( second b)) (>= x ( first b)))) marks))))) (plot (list (discrete-histogram (buckets marks))) #:out-file "racket-hist.png")
It seems kind of unfair, given the name, but duplicity really doesn't like to be run in parallel. This means that some naive admin (not me of course, but uh, this guy I know ;) ) who writes a crontab
@daily duplicity incr $ARGS $SRC $DEST
@weekly duplicity full $ARGS $SRC $DEST
is in for a nasty surprise when both fire at the same time. In particular one of them will terminate with the not very helpful.
AttributeError: BackupChain instance has no attribute 'archive_dir'
After some preliminary reading of mailing list archives, I decided to
delete ~/.cache/duplicity on the client and try again. This was
not a good move.
- It didn't fix the problem
- Resyncing from the server required decrypting some information, which required access to the gpg private key.
Now for me, one of the main motivations for using duplicity was that I could encrypt to a key without having the private key accessible. Luckily the following crazy hack works.
A host where the gpg private key is accessible, delete the
~/.cache/duplicity, and perform some arbitrary duplicity operation. I didduplicity clean $DEST
UPDATE: for this hack to work, at least with s3 backend, you need to specifify the same arguments. In particular omitting --s3-use-new-style will cause mysterious failures. Also, --use-agent may help.
- Now rsync the ./duplicity/cache directory to the backup client.
Now at first you will be depressed, because the problem isn't fixed yet. What you need to do is go onto the backup server (in my case Amazon s3) and delete one of the backups (in my case, the incremental one). Of course, if you are the kind of reader who skips to the end, probably just doing this will fix the problem and you can avoid the hijinks.
And, uh, some kind of locking would probably be a good plan... For now I just stagger the cron jobs.
As of version 0.17, gitpkg ships with a hook called quilt-patches-deb-export-hook. This can be used to export patches from git at the time of creating the source package.
This is controlled by a file debian/source/git-patches.
Each line contains a range suitable for passing to git-format-patch(1).
The variables UPSTREAM_VERSION and DEB_VERSION are replaced with
values taken from debian/changelog. Note that $UPSTREAM_VERSION is
the first part of $DEB_VERSION
An example is
upstream/$UPSTREAM_VERSION..patches/$DEB_VERSION
upstream/$UPSTREAM_VERSION..embedded-libs/$DEB_VERSION
This tells gitpkg to export the given two ranges of commits to debian/patches while generating the source package. Each commit becomes a patch in debian/patches, with names generated from the commit messages. In this example, we get 5 patches from the two ranges.
0001-expand-pattern-in-no-java-rule.patch
0002-fix-dd_free_global_constants.patch
0003-Backported-patch-for-CPlusPlus-name-mangling-guesser.patch
0004-Use-system-copy-of-nauty-in-apps-graph.patch
0005-Comment-out-jreality-installation.patch
Thanks to the wonders of 3.0 (quilt) packages, these are applied
when the source package is unpacked.
Caveats.
Current lintian complains bitterly about debian/source/git-patches. This should be fixed with the next upload.
It's a bit dangerous if you checkout such package from git, don't read any of the documentation, and build with debuild or something similar, since you won't get the patches applied. There is a proposed check that catches most of such booboos. You could also cause the build to fail if the same error is detected; this a matter of personal taste I guess.
I use a lot of code in my lectures, in many different programming languages.
I use highlight to generate HTML (via ikiwiki) for web pages.
For class presentations, I mostly use the beamer LaTeX class.
In order to simplify generating overlays, I wrote a perl script hl-beamer.pl to preprocess source code. An htmlification of the documention/man-page follows.
NAME
hl-beamer - Preprocessor for hightlight to generate beamer overlays.
SYNOPSIS
hl-beamer -c // InstructiveExample.java | highlight -S java -O latex > figure1.tex
DESCRIPTION
hl-beamer looks for single line comments (with syntax specified by -c) These comments can start with @ followed by some codes to specify beamer overlays or sections (just chunks of text which can be selectively included).
OPTIONS
-c commentstring Start of single line comments
-k section1,section2 List of sections to keep (see @( below).
-s number strip number spaces from the front of every line (tabs are first converted to spaces using Text::Tabs::expand)
-S strip all directive comments.
CODES
@( section named section. Can be nested. Pass -k section to include in output. The same name can (usefully) be re-used. Sections omit and comment are omitted by default.
@) close most recent section.
@< [overlaytype] [overlayspec] define a beamer overlay. overlaytype defaults to visibleenv if not specified. overlayspec defaults to +- if not specified.
@> close most recent overlay
EXAMPLE
Example input follows. I would probably process this with
hl-beamer -s 4 -k encodeInner
Sample Input
// @( omit
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.Scanner;
// @)
// @( encoderInner
private int findRun(int inRow, int startCol){
// @<
int value=bits[inRow][startCol];
int cursor=startCol;
// @>
// @<
while(cursor<columns &&
bits[inRow][cursor] == value)
//@<
cursor++;
//@>
// @>
// @<
return cursor-1;
// @>
}
// @)
BUGS AND LIMITATIONS
Currently overlaytype and section must consist of upper and lower case letters and or underscores. This is basically pure sloth on the part of the author.
Tabs are always expanded to spaces.
Before I discovered you could just point your browser at
http://search.cpan.org/meta/Dist-Name-0.007/META.json to automagically
convert META.yml and META.json, I wrote a script to do it.
Anyway, it goes with my "I hate the cloud" prejudices :).
use CPAN::Meta; use CPAN::Meta::Converter; use Data::Dumper; my $meta = CPAN::Meta->load_file("META.yml"); my $cmc = CPAN::Meta::Converter->new($meta); my $new=CPAN::Meta->new($cmc->convert(version=>"2")); $new->save("META.json");
I recently decided to try maintaining a Debian package (bibutils) without committing any patches to Git. One of the disadvantages of this approach is that the patches for upstream are not nicely sorted out in ./debian/patches. I decided to write a little tool to sort out which commits should be sent to upstream. I'm not too happy about the length of it, or the name "git-classify", but I'm posting in case someone has some suggestions. Or maybe somebody finds this useful.
#!/usr/bin/perl use strict; my $upstreamonly=0; if ($ARGV[0] eq "-u"){ $upstreamonly=1; shift (@ARGV); } open(GIT,"git log -z --format=\"%n%x00%H\" --name-only @ARGV|"); # throw away blank line at the beginning. $_=<GIT>; my $sha=""; LINE: while(<GIT>){ chomp(); next LINE if (m/^\s*$/); if (m/^\x0([0-9a-fA-F]+)/){ $sha=$1; } else { my $debian=0; my $upstream=0; foreach my $word ( split("\x00",$_) ) { if ($word=~m@^debian/@) { $debian++; } elsif (length($word)>0) { $upstream++; } } if (!$upstreamonly){ print "$sha\t"; print "MIXED" if ($upstream>0 && $debian>0); print "upstream" if ($upstream>0 && $debian==0); print "debian" if ($upstream==0 && $debian>0); print "\n"; } else { print "$sha\n" if ($upstream>0 && $debian==0); } } } =pod =head1 Name git-classify - Classify commits as upstream, debian, or MIXED =head1 Synopsis =over =item B<git classify> [I<-u>] [I<arguments for git-log>] =back =head1 Description Classify a range of commits (specified as for git-log) as I<upstream> (touching only files outside ./debian), I<debian> (touching files only inside ./debian) or I<MIXED>. Presumably these last kind are to be discouraged. =head2 Options =over =item B<-u> output only the SHA1 hashes of upstream commits (as defined above). =back =head1 Examples Generate all likely patches to send upstream git classify -u $SHA..HEAD | xargs -L1 git format-patch -1
This wiki is powered by ikiwiki.