[lang]

Present Perfect

Personal
Projects
Packages
Patches
Presents
Linux

Picture Gallery
Present Perfect

ways in which git makes the opposite of sense to me

Filed under: Hacking,Python,Twisted — Thomas @ 14:05

2009-02-06
14:05

DISCLAIMER: I originally wrote this post 18 months ago but never posted it because it was unusually negative.

Recently, with GStreamer switching to git, and GNOME thinking of moving to it as well, I thought I'd pick the post back up and see if git had improved since writing it. For me, the most frustrating things about git are:

  • the user interface experience is the absolute worst of all of them since tla was around
  • there is no obvious way to do it - clearly shown by the 50 different git tutorials, and the myriads of git commands that are very similar-sounding and have strange descriptions that to the layman sound like they would do the same thing

Personally, I remain convinced that it would be easy to start a git hater's blog (much like the linux hater's one) and fill it with content, though I doubt that will stop me from using it in practice.

Feel free to rush to the defense of git, insult me, call me stupid, whatever you want! I just thought it'd be an interesting exercise to see if my frustrated vitriol from last time still held up.

I'll annotate each part with today's experience in italics, and finish off with a final git score.

Exhibit A:

[thomas@ana git]$ git init
Initialized empty Git repository in .git/
[thomas@ana git]$ mkdir t
[thomas@ana git]$ git add t
The following paths are ignored by one of your .gitignore files:
t (directory)
Use -f if you really want to add them.
[thomas@ana git]$ find . -name ".gitignore"

There is no .gitignore file, so what are you talking about ?

2009: this now actually works without problems. Score one for git! 1 out of 1 for git usability improvements.

Exhibit B:

[thomas@ana tmp]$ git clone gt clone
Initialized empty Git repository in /home/thomas/tmp/clone/.git/
fatal: 'gt': unable to chdir or not a git archive
fatal: The remote end hung up unexpectedly
fetch-pack from 'gt' failed.

Ok, so I have a typo. But this is how you choose to let me know ?
"unable to chdir" OR "not a git archive". Hey, YOU're the computer. And git, you're the program tracking these things, you can't tell the difference between a git archive and something that is not ? Why don't YOU tell me which of the two it is instead of failing to handle errors in a logical way.

Also, I have no idea how it knew that I was on the phone with my mom and my mom got angry at something I said and ended the conversation. Oh ,wait, that wasn't what you were referring to when talking about unexpected hangups ?

And I thought fatal meant fatal. Apparently the first fatal was not fatal enough to already stop, you prefer confusing me with another fatal. Which one of the two should I be fixing ?

Kudos though for cleaning up the failed creation of the clone repository.

Please, when I make this simple mistake, tell me only: "The repository 'gt' does not exist."

2009: behaviour exactly the same. 1 out of 2 for git usability improvements.

Exhibit C:

[thomas@ana clone]$ ls /usr/bin/git-* | wc
139     139    3158

Compared with

[thomas@ana clone]$ ls /usr/bin/e* | wc
69      69    1244

I would say that the Lobby For Commands In /usr/bin Starting With G has gone a little overboard here.

2009: only 131 commands left for git. In the interest of preserving my sanity I'm not even going to try figure out which ones got removed or replaced or folded. 1 out of 3 for git usability improvements.

Exhibit D

Maybe that last one was an unfair stab ? Maybe 139 binaries come for free anyway so I should not complain ? I wasn't sure either first. Until I took two random entries from there and ran:

[thomas@ana clone]$ git whatchanged -h
fatal: unrecognized argument: -h
[thomas@ana clone]$ git citool -h
usage: /usr/bin/git-citool
[thomas@ana clone]$

Care to guess how many of these binaries have no useful -h output ? I sure don't want to find out, there's 139 binaries to check. 130 of them have manpages though - I guess that could be one reason why git implements "git command" by having a binary "git-command" - how else are you going to document this monster ?

What I *really* wanted to do when finding this out is to find a command that would show me which files are not under version control and give that to me in the most easy to parse way. git status is something, but maybe one of those 138 other commands gives me something better ?

(answer after some random command 'bisecting': git ls-files --others)

2009: behaviour has changed, but is still unhelpful

[thomas@ana git]$ git whatchanged -h
fatal: bad default revision 'HEAD'
[thomas@ana git]$ git citool -h

The last one now pops up a TK dialog box that says "couldn't open /usr/share/git-gui/lib/tclIndex": no such file or directory. 1 out of 4 for git usability improvements.

Exhibit E:

In my quest to figure out what some git commands do without wading through the man pages, I've resigned myself to the black box approach.


[thomas@ana clone]$ git describe
fatal: cannot describe '02d3a05f1e9710f9a6683ed8a62c9bd2ff3680a8'

For once I must side with git on this one. I have no way to describe that hex string either.

2009: output changed, but equally unhelpful:

fatal: Not a valid object name HEAD

Still inclined to side with git, I don't name my objects HEAD either. 1 out of 5 for git usability improvements.

Exhibit F:
I'm following this simple tutorial and it suggests that git has a slightly different model for committing. Most VCS systems have you "add" paths to tell the VCS you want to track them. Git seems to have something in addition - it has "files that it tracks", "files that it tracks and is going to commit in the next changeset", and "files that it doesn't track". git add then seems to be used to add to "the next changeset", and as a result also add it to "files that it tracks". A little confusing, but OK. So basically, to do a commit, you must add files to the commit.

The tutorial explains that you can do both at once by using git commit -a. Obviously the two step process of committing was so unintuitive that they made an option do to both, and the tutorial thinks this shortcut is important enough to mention.

Except that this happens:

[thomas@ana git]$ touch 1
[thomas@ana git]$ git commit 1
error: pathspec '1' did not match any file(s) known to git.
Did you forget to 'git add'?
[thomas@ana git]$ git add 1
[thomas@ana git]$ git commit 1
Created commit 79e67c26b27c80f7f0ddc37293cbc022f932c968
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1
[thomas@ana git]$ touch 2
[thomas@ana git]$ git commit -a 2
Paths with -a does not make sense.
[thomas@ana git]$

I guess I should be lucky it didn't call me stupid outright. It may not make sense to you, git, but I guess this is how my intuition works when I read your tutorial and you've already made it clear to me that you're not planning to have your help or usage output to be helpful or useful or for that matter even be period.

As a hint, here's what I expect to happen when I run git commit -a 2:

  1. git adds the file 2 to the next commit
  2. git commits the change to file 2

That wasn't so hard to make sense of now, was it ?

2009: slightly different behaviour. First off, the actually helpful suggestion from before (did you forget to add 1) is now gone. Why ? The second part is still the same, exactly as is. 1 out of 6 for git usability improvements (and actually a step back).

Exhibit G:

[thomas@otto git]$ ls /home/thomas/tmp/git/repo/.git/
branches/    description  hooks/       objects/
config       HEAD         info/        refs/
[thomas@otto git]$ git checkout /home/thomas/tmp/git/repo
fatal: Not a git repository

What do you mean, not a git repository ? I gave you one argument that clearly is a repository. Could you try and tell me what is wrong in a way that us humans can read ?

2009: different error:

[thomas@ana git]$ git checkout /home/thomas/tmp/git
error: pathspec '' did not match any file(s) known to git.

I'm guessing I should be giving it an additional argument. Hey, wouldn't that be a nice understandable error message instead ? 1 out of 7 for git usability improvements.

Exhibit H:

gitk is in Tk. Tk !!! 1991 called and they ... Oh never mind, not even going there. No, really. Start it up and click on 'File'. Then move the mouse pointer to 'Edit'. Is it just me, expecting the logical thing to happen, while nothing happens at all ? At a guess, this behaviour was probably for those people who were logging in to a remote X server over a 300 baud modem.

2009: still the same. To be fair, the application is actually pretty useful, you'd almost forgive it being written in tk. Still, 1 out of 8 for git usability improvements.

If you're still here, feel free to point out where git's behaviour really was my fault. I'm all for learning more about why things are the way they are. I'm just not convinced at all yet that git has made huge inroads on the usability level as its defenders often claim when discussing git vs. bzr.

Scrolling LED Marquee part two

Filed under: Hacking,Python,Twisted — Thomas @ 10:39

10:39

Following up on a previous post, I've been writing some code to do useful things with my scrolling LED marquee.

It gave me a chance to try my hand at implementing another protocol in Twisted, and it was a pleasurable experience. I still firmly believe that Twisted's code and design combines so much knowledge about these things that I will now never have to have in my life because I can rely on it being designed properly for the task.

I got it working quite quickly, reusing some activatestate code for a feedparser, and now I have my marquee following a bunch of feeds like StackOverflow's python tags, SlashDot and VRT news.

Here is a link to the video of the marquee showing (old) news from slashdot (using Cortado to watch it), or a link to a playlist to open in a player, or a link to the Ogg file directly.

I had the original version working over the serial port, but these days a serial port is a hassle. The marquee also included a USB plug which has a built-in serial port, and it didn't work out of the box with that. After some fiddling I realized that for some reason, over USB the replies of the device (which sends 'ACK' to acknowledge) come in separate packets (sometimes two, sometimes three, one per letter). It was simple to fix in the protocol implementation, and that's where Twisted's levels of abstraction really shine - a simple fix in one location at exactly the right logical level.

Last night I added a quick and dirty hack to have it also display what song Elisa is playing. I should start worrying about managing the marquee's different pages now so that it can easily mix different information sources.

Oh yeah, the code. Not sure you'd find anything interesting there if you don't actually have a scrolling marquee, but here it is. If you have a similar device, I'd be happy to help you out get this set up and add support for it.

And if any Twisted people want to comment and help me improve my probably poorly implemented protocol, comments appreciated!

I get such a kick…

Filed under: Flumotion,Python — Thomas @ 18:21

2009-01-20
18:21

... out of watching Flumotion's interface for the streamer components when a big event is going on. The platform's launching streamers all over, and as soon as a new one starts, you just see the numbers flying up. Look, another one just started, and in its first minute it went up to 280 connections, and still climbing. For a 500 kbit/sec stream that means it goes from 0 to 140 Mbit/sec on that machine just for this stream.

We jumped up in a few hours to a good 14 Gbit/sec, which is still climbing.

The event in question, of course, is one of hope for the future - Obama's inauguration - streamed with Python, Twisted, and GStreamer.

GStreamer, appsink and CRC32

Filed under: GStreamer,Hacking,Python — Thomas @ 10:50

2009-01-07
10:50

Slowly flexing my GStreamer muscles again in preparation for a real application.

Yesterday I wanted something that allowed me to calculate CRC's of decoded audio files, to be able to calculate the CRC of a ripped file.

There's a few ways to do this using GStreamer, none of them code-free.

I assume the 'correct' way would be to write a filter element that calculates the CRC as buffers come in. In the olden days this would involve a lot of boiler plate code in C, and a small processing function.

Today, in C, this would be easier, since you could probably simply subclass basetransform.

You could write either in Python as well these days.

Then there's the 'get data out of GStreamer' approach. This used to be done using identity and the handoff signal.

The new, approved, API-stable way is to do this using appsink, one of two elements (with a helper library, of which I don't yet see the point) recently moved to gst-plugins-base.

Using appsink is probably the approach that involves the least code to write. You can set up a pipeline, set it to PLAYING, and just pull buffers in a blocking fashion (which is easier code to write, but harder to slap a GUI on later)

Here's the example code. You might note that there is an ugly try/except which I suspect is some bad handling inside gst-python or pygtk for errors during signal handling/emission.

It is a deceptively simple way to get data out of a pipeline and processed, and I'm glad we have a guaranteed way of doing this sort of operation now for the many people who want to dip their toes into GStreamer instead of diving in. I do hope they will at least consider the full dive still though.

Side note 1: GStreamer heads are free to share their opinion on what *should* be the correct way for data analysis operations like this. Years of brainwashing still lead me to believe that the answer would be 'write a filter element'.

Side note 2: I've been toying with the idea of making a python class for 'asynchronous operations' that would wrap a GObject main loop doing the processing, and implementations can then subclass and implement some simple methods. This would make it easy to attach that operation to a GUI element (for example, a progress bar) automatically, or adapt it into a linear, blocking operation for command line applications. I can't imagine this would be a novel idea, I'm sure someone else has done this already, anyone know what I'm talking about or have any suggestions ?

Lustrum

Filed under: Fluendo,GStreamer,Hacking,Life,Music,Python,Spain — Thomas @ 19:10

2008-11-28
19:10

Hard to believe that next week it will be Five Full Years I live and work in Barcelona.

It seems like only yesterday that I closed the door on the empty house I then shared with three good friends, and drove our truck through the icy mist on to a new life. That night where we had no place to live I passed by my grandmother's house for dinner, a few hours late. My grandmother's not here anymore. Neither is her house. At least part of her floor is now the floor of my apartment.

Originally we planned to give it a try and see after a year. And then one turned into two, then two-and-a-half, and now five.

When I left there wasn't even a company yet to give me a contract. Now we're three companies, and our fifth move has taken us to an office of around 50 people now, and already people are complaining again about space. Par for the course.

I also guess I never actually publically informed about my move from Fluendo to Flumotion - it was just a logistical confirmation of a practical situation. Today Julien is managing Fluendo (the GStreamer/codecs/DVD company), and Elisa was always managed by Lionel anyway. And Flumotion is a full-blown commercial company.

Meanwhile, after a bit of a hiatus on my GStreamer involvement, I am slowly coming back to my plans of using GStreamer - the plans I had originally when I discovered GStreamer more than 7 years ago. I just reread my first post the mailing list, from April 10th 2001 - at least it wasn't a completely stupid question.

My original plan was to write some code that would play your music just like a radio would. Nicely mixed, correctly levelled, a good flow between songs, and playing what you like to hear. An extension of the thesis project I did a long time ago which I used in our student radio at the time.

But GStreamer being what it was at the time, I got sucked into the vortex and didn't really work on these ideas for a long time. I took a quick stab at it during 0.8 in the form of gst-python's gst.extend.jukebox which worked quite well already on the mixing front, but when it got ported to 0.10 using gnonlin it just never worked for me and was left abandoned.

So third time's a charm. After close to 10 years of random hacking, it's about time to decide on one good personal project to invest my time in before life takes over. And this time I think I want to write something that not only Linux people can use. I want to write something that my friends can use too, and that means it has to work on Windows.

My motivation comes from being annoyed at not being able to listen to my music the way I should want to. I've been lax at ripping my new CD's over the last 5 years, and a 300 CD backlog to show for it. My automatic playlists reflect my tastes of five years ago, and only once in a while do I bother to get some new tracks on one of my three computers or my Nokia, to which I then listen only in certain conditions. And every player I deal with annoys me to some extent. And none of them do any kind of decent crossfading, if at all.

I'm not promising anything yet, and I'm only at the beginning, but my experience makes me a happier hacker, advancing quicker from the idea to the code stage than way back when. That's a nice feeling. Over a few two hour nightly sessions, I've put together some code that analyzes tracks, calculates RMS and attack/decay envelopes, and puts together a half decent mix. I've written a simple example using gnonlin which allows me to pre-listen these mixes, playing 5 seconds of the first track alone, then the mix, then 5 seconds of the second track alone.

This makes it a lot easier to evaluate different mixing strategies, making them easier to tune later on. I'll have a fun plane trip with my laptop, earphones, and three batteries.

If you happen to be adventurous and interested, you can always check out the repository and play around a bit and see if it can mix your tracks at all.

So, I'm celebrating my Lustrum of Fluendo and Barcelona with a bit of code for a new project!

Sadly, the names I was considering a few years ago were already taken - pyjama is now a jamendo python application (mine would have been Just Another Music Application - in Python), and Orpheus, which also exists. So for now I recycled a name of a previous project that handled another aspect of the problem.

8 hours of plane hacking baby! Here I go.

« Previous PageNext Page »
picture