Ways in which ‘Thomas’ appears the opposite of ’smart’ to me.

(original article)

(originally written the day after that article came out – I ended up posting snide comments on his blog, which was pretty dumb. I tend to do stupid things when I’m angry, and I’m not sure I did much good by telling the guy off on his own blog. Then again, in my slight defense, I was trying to prevent his blog from influencing people who don’t use git from being scared away. Of course, my nasty remarks probably pushed people the other way: “This is how the git community reacts to people who need help? What dicks.” So, a message to everyone – I don’t represent the git community, just my annoying little self)

When git first came out, it was hard. Really hard. Annoyingly hard. Linus made a decision, early on, to do the following for git:

  1. Make it fast
  2. Make it powerful
  3. Find other people to make it easy

And since, early on, it was just what he built (plus a few contributions from others), he got #1 and #2 down pat, but completely punted on #3.

Fair enough, whine whine, an app that is difficult to learn is completely useless (this is a pretty common vim complaint, mostly from people who never tried to learn vim).

But nowadays, git really isn’t hard. It is certainly easier than cvs, about as simple as svn, and it seems to be not that much different to me than mercurial and the like. Some of the commands have different names, but that is about it.

And that’s really the truth of it – it isn’t that git is difficult, it is that it does a few things differently, which also leads to another understandable complaint: the interaction model for a piece of software shouldn’t be “different” from other, similar pieces of software simply to be different.

But git really isn’t different for the sake of standing out.

That’s why I tend to get annoyed at the article I linked to at the beginning of this little rant – the guy is complaining that “git doesn’t do what I expect!”, when, in fact, his expectations are, well, retarded.

Let’s take his article, “exhibit” by exhibit:

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 ?

I can kinda understand this; it sucks when you make little typos that have annoying consequences. For the life of me, though, I have no idea what he intended to type. But there are two mitigating factors here:

First, nothing really “bad” happened, besides an empty git repo that was initialized (which you can promptly delete, if you don’t want it – git repros are entirely contained). It isn’t like mistyping rm -fr /foo/bar as rm -fr / foo/bar, which has extremely nasty consequences. Just a bit annoying.

Second, what is git supposed to do? The general command form is git clone <repo-location> <directory-to-put-it-in> – is git supposed to magically determine that “gt” looks a lot like “git“, so you probably mistyped the name of the command?

Of course, it does offer you the ability to, you know, figure out what the syntax of the command is. Or the first google search result for “git clone”, which is currently the man page for git-clone.

On to the next one:

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

His complaint here is literally that (in his older version of git), there are more commands that start with “git-” then there are commands that start with “e”.

First off, on the newer versions of git, the “git-” commands have been removed in favor of a single top-level “git” command, so things like “git-clone” are now invoked by typing “git clone”. Easy peasy, I imagine. On my mac, there are 5 commands that start with “git-”, and they aren’t in /usr/bin. In fact, I’m a bit surprised that, on his machine, it is installed in /usr/bin, and not /usr/local/bin(or, like my mac, /usr/local/git/bin). Anyways.

Second off, who the fuck cares how many commands start with “git-”? Does it hurt your ability to autocomplete other commands? No. Does it somehow “pollute” your namespace of commands? Maybe, which is why they removed the dashed version of the commands. But does it really matter?

Third, way to pick a letter that already has a low number of commands. On my mac, there are 27 “e” commands, but 78 “c” commands and 72 “g” commands (not including the git commands, which are in a different place). I don’t hear complaints about how most KDE programs start with a “k”, and how many gnome and gnu programs start with a “g”. And those commands actually do make it harder to find things, because different commands that start with a “g” really aren’t necessarily related to each other, whereas commands that start with “git-” really are.

Moving on.

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 ?

Sorry, what?

git help clone
git clone --help

Most commands accept --help, and most VCS have a “<toplevel> help <cmdname>" syntax, so what are you complaining about?

Oh, right, that -h doesn’t work here…just like it doesn’t work for other tools, where -h means human readable or something similar. Like, say, ls, which seems to be the only command you do understand.

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'

First off, if you “[resign yourself] to the black box approach” because “-h” doesn’t work, you deserve to fail. Seriously. If, when confused, you don’t turn to alternatives, like searching google, reading a tutorial (there are many), asking for help, or maybe using the smart part of your brain, you deserve to fail. Sorry.

git describe tells you the name of the most recent tag that is reachable from a commit. Since I’m guessing he has no tags, then there aren’t any reachable ones. The long hex string it spits out is the commit your repository is currently at. If you don’t understand that, then you should probably read up on how git works.

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]$

The extremely simple answer here is that, if you specify “-a”, which means “commit anything that appears to have changed”, you don’t specify a pathspec. In fact, that is exactly what the message is telling you – supplying paths with the “-a” argument is nonsensical. So don’t do it. In current versions of git, though, this is different. What you can do, now, is leave off the “-a” argument, and then it does exactly what you want. “git commit foobar.txt” skips the staging area and just commits foobar.txt. “git commit -a” skips the staging area and commits anything that appears to have changed.

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

Fail. “checkout” is a command you run, from within an active tree, to check out a different branch or path. “clone” is the command to clone a repository (which the guy obviously understood enough for Exhibit B, but has forgotten by the time Exhibit G came around).

—-

And there you have it

</endrant>

blog comments powered by Disqus