Paris rough cuts
Unless you are Hemmingway or Kerouac, no-one cares where you have been
or what you did do on your travels. Therefore, I’ll keep myself short,
but reasonably complete.
General impressions
WLAN at the hotel (Ibis Berthier) is possible, but not seriously: 0.25€/min
will make the thing cost 360€ a day; various ads all around the
city sell you a flatrate for net and phone and digital tv for about
30€ a month.
There generally is high quality typography all around, something I
don’t notice in Germany. However, their use of italics on road
signs just sucks.
The Metro and RER guy that introduced loops into their system deserves
to be slapped, it’s hard to imagine a better way to confuse foreigners.
French motorways are great—straight on and with just about no traffic,
doesn’t hurt too much they are turnpiked.
There are nice Chinese girls all around. :-)
Day One
Arrival at about two o’clock, led by GPS (which doesn’t know about
some private motorway exits…).
Sacré Cœur: IMO ugly, boring from a cultural point, far too many
tourists. Has vending machines in the back part of the church
(Notre Dame, too). Seen children that blow the candles out.
Montmartre is ideal for vendors of scratchpads; else there are
artists that use them or try to, generally ugly tourism, but lesser
visited parts are actually very beautiful and aesthetic; this can,
however only be appreciated after experiencing the ugliness.
(Probably my first appreciation of Paris.)
Dinner at some Chinese shop, where the soley owner put your chosen
meal in various microwaves to warm it up. Turns out this is a
popular way of running a Chinese restaurant. Not bad, but not
exciting, the idea is more interesting than the taste.
Day Two
Arc de Triomphe, the watch(wo)men at the Tomb of the Unknown Soldier
do not have rifles.
Champs-Éllysée, nice for a shopping tour
Louvre, we didn’t visit it due to lack of time, but it’s very
nice architectonically—not only the glass pyramid, but also
the entrance hall and other things below the ground.
Centré Pompidou, didn’t visit either, but in afterthought I’d
probably have liked to—appears to be the center of contemporary
art in Paris, together with the IRCAM next to it.
Tour Eiffel, at night. Good (and probably best free) view from
Trocadero. The tower sparkles every full hour—highly hokum.
Dinner at Pizza Hut. (Pretty hard to find a good meal for a reasonable
price in Paris.)
Day Three
Left river bank of the Seine, always good for a walk.
Notre Dame, finally a nice cathedral.
Musée d’Orsay, didn’t visit as well; the queue was “short”, but
still wrapping several times.
Lafayette, nice view from the roof over the city and the Opera.
The dome and general style of the main hall needs to be mentioned
too. Checked CD prices there, seems they are cheaper in Germany;
even the cheap CDs cost more than 9.99€.
Tour Eiffel at day, haven’t been on top, however. Amazing construction,
and pretty lightweight. The watchmen have automatic rifles.
Saint-Germain-des-Prés.
Quartier Latin, I really liked that part of Paris—despite
a lot of people, it keeps a certain attractive atmosphere.
Dinner at Quartier Latin: Spaghetti Carbonara. Nice italian-style
restaurant.
Day Four
Gare Austerlitz, still trying to figure why we went there.
Jardin des Plantes, nice botanical garden with lots of museums around.
Rue Mouffetard, the market there had not as much action as expected.
Pantheon, haven’t been inside.
Sorbonne, a central university of Paris.
Jardin Luxembourg, nice garden too; we couldn’t find the
snow-white elephant, though.
Tour Montparnasse, great panoramic view from the 56th and 59th
floor. Worth a visit. Also interesting they check the tickets
once you are up there…
Dinner at Pizza Hut. (Did I tell you how hard it’s to find a dinner
in Paris!?)
Day Five
- Return journey, drive was okay, but of course took a bit longer
than the journey there because of the traffic at daytime. As soon
as we were on German ground again, congestion started—amazing.
All in all, it was a pleasant five days in Paris, I can only recommend
it. However, avoid the places where a lot of tourists usually
go—they mostly suck and aren’t worth the time.
NP: Pearl Jam—Gone
Off to Paris
Early tomorrow morning, I’ll be heading to
Paris for holiday till April 21. I’m
uncertain about open-WiFi in Paris, so don’t expect mail activity, IRC
or other net stuff. Maybe I’ll get some hacking done, we’ll see.
For now, I just hope I have enough podcasts to survive the 10 hour
drive… but I’m looking forward to one week of baguettes, croissants
and people speaking a gay language. :-D
chris blogs and Anarchaia resume publishing on April 22, have a lot of
fun. I guess I have something to tell when I’m back.
NP: Wir sind Helden—Denkmal
My DVCS wishlist
After last week’s intermezzo with Git, my
curiosity for distributed version control systems (DVCS) reinflamed
again. I also imported the Ruby CVS history into
Monotone, which has a pretty fast
CVS importer, and Mercurial,
which CVS importer seamt to be even faster
(cvs20hg),
but unfortunately is not complete yet. However, Mercurial also can
import from Git, so I went that way.
My projects will continue to be kept in
Darcs for near future, but so far no DVCS really
could convince me. Wondering about which lacked what, I thought it
would be useful to write up what I want to have. So far, I tried:
Darcs,
Git/Cogito,
Mercurial and
Monotone. I also dabbled into
Bazaar (seems to be discontinued),
Bazaar-NG,
FastCST (seems to be
discontinued) and SVK (IMO just a hack).
So, here is my wishlist (roughly ordered in decreasing importance):
Prefer file storage over patch storage, it’s just easier to deal
with in practice. It took be a long time to figure this out, but I
actually think it’s the more pragmatic solution. I noticed this
when I saw how the Git repository just merged with the Gitk
repository, even if both didn’t share a single revision. Darcs, on
the other hand, even had problems doing merges which were factually
the same, but just couldn’t be arranged the right way. The theory
of patches sounds nice, but it doesn’t work out.
Note that this doesn’t exclude diff storage, this of course should
be done to save disk space and bandwidth.
Provided by: Bazaar-NG (I think), Git/Cogito, Mercurial, Monotone.
Revisions need to be identified by a globally unique identifier, e.g.
a SHA1-hash or a GUID.
Provided by: Bazaar (theoretically), Bazaar-NG, Darcs, Git/Cogito,
Mercurial, Monotone.
Revision storage should be implemented as write-once files. Once a
file has been written, it should not be touched afterwards. This
eases incremental backup and generally improves safety.
Alternatively, if files are append-only, this is acceptable too.
Changing files leaves a bad taste. (It’s okay for index files and
other unessential information.)
Provided by: Bazaar, Darcs, Git/Cogito, Mercurial.
File permissions must be saved, at least the executable bit. Also,
the VCS shouldn’t touch the contents of the files at all (no
newline conversion, no keywords by default).
Provided by: Bazaar, Bazaar-NG, Git/Cogito, Mercurial, Monotone.
Easy setup of repositories: Setting up a new repository needs to be
possible with a single command, usually that’s xxx init—it will
turn the current directory into a fresh repository (or even import
the files of the current directory, as Cogito does).
Provided by: Bazaar-NG, Darcs, Git/Cogito, Mercurial.
Support multiple heads of development in a single repository.
This encourages microbranching and eases incremental development without
keeping loads of working directories around.
Provided by: Git/Cogito, Mercurial [Added 22apr2006, thanks
to Daniel Néri for noticing], Monotone.
It has to be possible to export patches with full metadata (e.g. renames)
as ASCII files, e.g. to send via mail or share in other ways. It
needs to support binary files, too. (Think of contributing graphics
to a game.)
Provided by: Bazaar-NG, Darcs (very good), Git/Cogito (no binary,
renames partly), Mercurial (bundles, but they are not ASCII, renames
partly), Monotone (packets, good).
It needs to be possible to contribute patches via mail.
This is the way most non-regular commiters send patches.
Provided by: Bazaar-NG, Darcs, Git/Cogito, Mercurial, Monotone.
Serving repositories over dumb HTTP: This is essential to allow
people easily setting up repositories on their cheap webspace.
Systems that require CGIs would be acceptable too, here (Mercurial
without old-http); opening new ports isn’t. It doesn’t need to be
the most efficient way of accessing, but must not be unreasonably
inefficient.
Provided by: Bazaar-NG, Bazaar (slow), Darcs, Git/Cogito, Mercurial,
Monotone (soon).
I definitely need good Emacs integration, preferably with
DVC, alternatively, a good
standalone-mode can be enough too.
Provided by: Bazaar (DVC), Bazaar-NG (DVC), Darcs (own, partly DVC),
Git/Cogito (own, DVC), Mercurial (own, DVC), Monotone (own).
It needs to provide a GUI repository viewer that can show change history
as a tree and diffs for each revision. I’ve found such a tool
indispensably since I’ve discovered Gitk, especially if you
microbranch a lot.
Provided by: Bazaar-NG, Git/Cogito, Mercurial (hack), Monotone.
It needs a good and fast tool to import CVS trees. I’ve found
this absolutely needed to convert legacy repositiories and capture
the history of older projects locally.
Provided by: Git/Cogito (git-cvsimport, parsecvs), Mercurial
(cvs20hg, partly), Monotone (own, very good).
A library to access all features of the VCS from other tools.
If a very comprehensive set of commands is available, this will
be acceptable too.
Provided by: Bazaar (shell), Bazaar-NG (Python), Darcs (shell, XML),
Git/Cogito (shell, very good), Mercurial (Python), Monotone (Lua, shell).
If you find any mistakes or misattribution, please post a comment and
I’ll correct it.
Writing a good DVCS is not that hard in theory, but very hard in
practice—not only for technical reasons. Implementing DVCS is a
community effort, I’d even state it’s pointless today to start yet
another VCS, unless you are a celebrity that already has a big
community behind (cf. Git).
NP: The Smiths—You Just Haven’t Earned It Yet Baby
Tracking the Ruby CVS with Git
$ du -h ~/projects/Git/ruby.git/
29M /Users/chris/projects/Git/ruby.git/
Amazing, but true: above directory contains the whole history of the
Ruby CVS—from January
1998 until today, in less than 30 megabytes. That’s 9325 commits and
about 44332 different file versions.
How is this possible? I used Git, the version
control system that was written to keep the Linux source, which is
“designed to handle absolutely massive projects with speed and
efficiency”. And most of the parts are actually pretty efficient and
fast.
Not among them is importing from CVS. Not yet, at least. Git includes
a Perl script, git-cvsimport which essentially works like that:
Checkout each revision from CVS, commit to Git, checkout the next revision,
commit again, water, rinse and repeat.
Hopelessy slow, especially if the CVS is remote. So let’s fix that,
we make a local CVS mirror first. Luckily, the Ruby CVS supports
cvsup, which is essentally like a fast rsync
for CVS repositories, but also can be used to mirror complete
CVSROOTs. Unluckily, this is not documented at the Ruby CVS page.
However, with help from Shugo Maeda, I was able to locally mirror the
Ruby CVS. You need a cvsup file like this:
*default base=/Users/chris/mess/current/cstest/sups
*default compress delete use-rel-suffix
*default release=cvs
*default host=cvs.ruby-lang.org
*default prefix=/Users/chris/mess/current/cstest/ruby
# Ruby and other modules
cvs-src
Adjust the paths to your local needs, of course. Then, you need to
fetch cvsup. If you are lucky, your distribution will have it
packaged, else you need to bootstrap a Modula 3 compiler(!) to compile
it. Have fun. *sigh* (The compiler is pretty quick, though.)
Anyway, at the end of the day, I had my local CVS mirror—let the
experiments start.
git-cvsimport
depends on cvsps, a tool to analyze
CVSROOTs and figure the actual revisions. This is needed because CVS
is a bunch of clunky shit that has no conscience of its commits. After
that, an almost endless loop of checkout and commit will start. If
you want to try it yourself, get a fast computer, a fast, big disk and
an efficient file-system. No, doing it on an iBook with only a few
gigs free and HFS+ is not a good idea. Actually, it took four days,
and I had to do it stepwise.
There could be a better solution in the future,
parsecvs
by Keith Packard of X.org fame. It’s in very early alpha stage, and
will need even more disk space as of now, but ought to be a lot faster
in the future. At least one can hope.
After this, you’ll have a Git controlled tree full of the actual file
revisions, it’s hard to estimate how big it would be. To make the
handy file shown above, you need to pack the tree. For this, you run:
git repack -d
This will compute a few minutes/hours/days and spit out a nice file,
of about 70 megabytes in size. If you want the handy file above, you
either need to figure out how to patch git repack to pass the
optimization options --window=50 --depth=50 to git-pack-objects,
or call the latter low-level tool directly. This way, you’ll get the handy
file. Higher argument values will slow down the process a lot, and
not result in packages that are maybe half a megabyte smaller. I
tried.
The great thing about git-cvsimport is that it can work
incrementally, so once we have the pack, we can update directly from
Ruby CVS—the changes are small if you do that regularily. For this,
I included a small script in the pack, update-ruby-git:
git-cvsimport -d :pserver:anonymous@cvs.ruby-lang.org:/src \
-k -u -v -m -p -Z,9 ruby
Run this script regularily to keep your tree recent. You don’t need
the CVSROOT or cvsup anymore.
Now, how is this all of this useful? Obviously, you enjoy all the
benefits Git provides for your daily hacking: atomic actions,
distributed development, zero cost (almost!) branches and good merges.
Also, you have the nice gitk
repository browser that allows you to keep track of recent
development. Since you can fetch every file at every revision easily,
it’s just a matter of time someone starts datamining… “how many
percents of Ruby are really written by matz”?
You can use
git bisect
to find bugs in Ruby by marking some revision as good, some as bad,
and let Git figure which revision you try next to find the faulty
patch.
And if you really want to use CVS, you even can emulate a CVS server
(read and write!), with git-cvsserver. Isn’t that impressive?
I probably will make the pack available on the net, but I haven’t yet
found a good way to allow others to efficiently (and incrementally)
fetch it… hopefully more about that later.
NP: Meat Puppets—Up on the Sun