Skip to content

Git makes website maintenance easy too!

We’re gearing up to release our first program for the general public in quite some time, so we’re going to need a real website again, rather than the one-page placeholder that I put up several years ago.

The last time I had to design a website was before the turn of the century. I started with FrontPage (which we had as part of a copy of Microsoft Office from the era). It had a wonderful feature where it collaborated with some FrontPage extension on the server to update your site after any changes. I didn’t know enough to appreciate that at the time, and apparently at least some web hosts really don’t like it, because when we changed hosting companies a few years later the new one flatly refused to support it.

At that point we bought a copy of DreamWeaver. That was supposed to be the very best website editor, and it was quite expensive, but when I started using it I was REALLY disappointed. It seemed more primitive than even that aging copy of FrontPage, and required you to use the ancient and insecure FTP protocol to upload your work to your site.

Fast forward to the present.

Since GoddessJ and I are collaborating on the HTML/CSS stuff, I set up a Git repository on our internal office server (not the same machine as our web server) so we could keep our copies of the files synchronized, and the files would be automatically backed up with the rest of our source code repositories. As I finished that, it suddenly struck me that it should be possible to use Git to sync the files to the server too, right? That would have some major advantages over doing it manually or via something like DreamWeaver.

A web-search said that, if I had SSH access to the server and could run Git on it, then the answer was yes. :-D

The first problem was setting up SSH to access the web server properly. I’d already set it up for basic access, but it required manually entering a password each time; it needed to use public keys instead. (This is using Linux on the local system, where an always-available “keyring” program caches the SSH key password, which is different from a login password. Windows machines don’t have anything similar, so far as I know.)

I’d previously set up webserver as an alias to the web server in ~/.ssh/config, with the alternate port that our hosting company uses and some other configuration stuff it needed, so based on this page, all that was necessary was to copy the local key file (already on my machine) to the server. There was no SSH directory on the server yet, so after creating one (via mkdir ~/.ssh from an existing SSH session), this command uploaded it from the local machine…

scp ~/.ssh/id_dsa.pub webserver:~/.ssh/authorized_keys

…and then back to the existing SSH session to set the permissions…

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

We don’t have root access to the web server, so I didn’t try to chown the file to root as described. Despite that, it worked: now a simple ssh webserver takes me directly into the server. :-)

According to another page the search had turned up, the currently-preferred way to use Git to update a website is described here. The directions there worked like a charm: after following them, I tested it by making a slight modification to the index.html page, committing it to the local repository, then doing a git push web… and IT WORKED! The copy of Git on the server apparently used the post-receive hook set up in those instructions to check out the changes as soon as I uploaded them, because when I refreshed the index page in my browser, I could see the change! GoddessJ and the cats were quite startled when I let out a loud cheer. What can I say, I love it when technology works as advertised. ;-)

This setup will be a LOT better than using FTP. scp (the SSH secure-copy command) does the same things as FTP but securely, but you have to upload each changed file separately. With this, Git takes care of uploading everything (compression automatically included) and unpacking it to the proper directories on the server, and will only update the pages that have actually changed. You can also easily back up and restore the entire repository, via a single git clone command. With the main copy on our automatically-backed-up office server, it’s a pretty tough combination to beat.

If you’re setting up a web server, give it a try yourself. I’m pretty sure you’ll like it, especially if you’ve dealt with the other methods.

“DIY ‘Back to the Future’ hoverboard actually hovers”

Nice. I might even be tempted to buy something like that.

“RIP: Peak Oil – we won’t be running out any time soon”

It’s so hard to find a good, credible, looming disaster to panic about, and then those pesky scientists keep destroying the few that we manage to find. Runaway global warming keeps getting kicked in the teeth by inconvenient facts. Nuclear power disasters persistently refuse to be anywhere near as disastrous as people hope. Scientific advancement constantly fails to cause the end of the physical universe. Mother Nature is just too sentimental. And even God won’t even help.

You can’t even count on humans — hundreds of thousands of jihadist suicide attackers are just tauntingly refusing to blow themselves up on us, even when our governments go out of their way to give them reasons.

And now it looks like Peak Oil has joined the damp squib parade.

I think all we have left is the end of the Mayan long-count calendar, and most people stubbornly refuse to believe that.

Come on guys, give us a break — our politicians need disasters to whip the masses into a frenzy. How else are they going to keep us scared and manipulable, and from noticing their hands constantly in our pockets?

“How to remove your Google Web History”

I did this (thanks for the early heads-up, Ploni), though I had a few problems getting to the history page. Once I managed it, I was appalled to see how much stuff they’d managed to associate with me… nothing damning, just massive amounts of it. If someone wanted to cause me problems, or wanted to know what I was up to, that list would probably give them some good clues.

If you’ve got any Google account, I suggest you at least take a look at what the company has on you. Up to you whether to remove it or not, but once you’ve seen it, I suspect you will.

“Laser used to cool semiconductor”

I can imagine the marketing blurb now: “Now with lazer cooling!” (Yes, I know laser is spelled wrong, but marketing guys are very fond of their Zs. Which might explain why it’s so tempting to sleep through most of their presentations, but I digress.)

With some work, this sort of thing might someday be employed to deal with CPU heat, leading to computing speeds that can only be managed today using cryogenic equipment. I pity the person whose super-laptop’s internal cooling laser suddenly dies though. ;-)

“Lesbian Necrophiliacs”

You don’t find an article whose title includes the phrase “Lesbian Necrophiliacs” too often. And it’s safe-for-work (and for my more prudish readers) too! ;-)

Even without the title, the article is pretty interesting. Cloning has apparently evolved lots of times over the history of Earth, but it’s almost always a death sentence: if every creature is the same, then their immune systems are likewise identical, and the first virus that evolves a way to overcome it has the whole species as a smörgåsbord. I hadn’t heard of these critters until I stumbled on this article, or I’d have wondered about them too.

“Crush! Kill! Destroy!”

Remember that one? It came from an episode of Lost in Space that I saw when I was maybe seven or eight, and it has stuck with me all these years. I even looked it up a little while back… apparently I’m not the only one it has stuck with.

Comments in Code

My nephew just introduced me to geek&poke, a web-comic that only true geeks could love. Needless to say, I’m lovin’ it. ;-)

While scanning through the recent strips, I ran across this one, which gave me a chuckle, and also got me thinking.

I’ve heard a lot of opinions on comments in programs over the last thirty years of developing software. They seem to be divided in to three camps. The first consists primarily of relatively new self-taught programmers, who think that comments (like documentation) are boring, unnecessary, and completely optional — after all, they understand their code, anyone wanting to use it should figure it out at a glance too! This type generally learns the folly of his ways the third or fourth time he has to go back and try to modify code that he wrote more than six months ago, and realizes to his dismay that without having the reasons why he did things that way fresh in his mind, he can’t understand it either. Unfortunately the vast majority of open-source developers are in this group.

The second is solely-college-educated developers, the ones who’d never even heard of a compiler until it was taught to them in a class. That type goes to the other extreme: every two-line function has to have its own twenty- or thirty-line comment header, describing when it was written, why it was needed, who wrote it, who approved it, who code-reviewed it, what each and every parameter is and is used for, what return values you can expect from it, and anything and everything else. This type either learns that all those comments are superfluous (and eventually graduates into the third camp), or has no real skill or interest in coding and just wants to get promoted to management as quickly as possible, where he forces everyone under him to adhere to that standard (because he has to read their work, and reading comments is soooo much easier than actually reading code — which is, I suspect, also the reason that college professors require that).

The third camp is where developers end up after lots of experience, after they realize that the code should be self-documenting. They pick their variable and function names in such a way that they don’t need documentation, anyone reading them can easily see what they’re used for. For these people, well-chosen names are the what, well-designed code is the how, and comments are reserved for the why — the reasons for things that can’t be determined from the code. As a very simple example, here’s an actual function copied directly from one of my programs:

bool isValidGregorianDate(int year, int month, int day) {
    if (year == 0) return false; // 1 BCE is followed by 1 CE.
    if (month < 1 || month > 12) return false;
    if (day < 1 || day > highestValidDay(year, month)) return false;

    // Due to Pope Gregory's reform in 1582, ten days are missing from the
    // Gregorian calendar, as compared to the Julian calendar in use before
    // that. There's no way to properly calculate which days unless you also
    // know the location, because different places adopted the change in
    // different years. All you can say for certain is that somewhere
    // between ten and thirteen days get skipped somewhere between 1582 and
    // 1923. This function will assumes that those changes happened in 1582,
    // so that Thursday, 4 October 1582 on the Julian calendar was followed
    // by Friday, 15 October 1582 on the Gregorian.
    if (year == 1582 && month == 10 && day > 4 && day < 15) return false;
    return true;
}

First, notice the function name, isValidGregorianDate. If you were reading through the code and saw a function with that name, it would be pretty bloody obvious what the purpose of it is, and any comments to that effect would represent valuable time wasted. Ditto for the parameters year, month, and day — between the names themselves and the context of the function name, their purpose is self-evident. If you want to know the valid ranges, they’re pretty obvious from the code itself, just in case you weren’t familiar with the Gregorian calendar.

Next, notice the first line within the function. If it were uncommented you might wonder why year zero isn’t accepted by the function, but a tiny little comment directly after it explains it — there is no year zero in the Gregorian calendar, and here’s why. Also notice the second and third lines, which have no comments because they’re self-explanatory, thanks in great part to a call to another self-descriptive function, highestValidDay (which calls another self-descriptive function, isLeapYear). An inexperienced developer would see that these functions would never be called from anywhere else and put the code for them right into isValidGregorianDate, with or without comments to explain what it’s doing and why, but that would be a distraction from the purpose of isValidGregorianDate. By separating them and giving them very descriptive names, none of that is necessary.

Finally, there’s the huge nine-line comment, which describes the reason for the one line of code immediately following it. Lots of care was lavished on the description for that one line, because a reader who isn’t intimately familiar with the history of the Gregorian calendar wouldn’t know that stuff — and that reader just might be the developer who wrote the code, some time later when he’s forgotten all of the details.

Out of curiosity, I scanned a dozen source-code files from my current project, counting the number of lines and the number of true comments (skipping commented-out code lines and TODO comments which are meant to catch my attention when I go searching for things that still need work). Out of 3,645 lines in those twelve files, there are 87 comments, mostly little one-liners tacked onto the end of the line they’re commenting (like “so it will call Update” or “otherwise it’s constant”), but occasionally detailed four- or six- or ten-line comments like the one shown in the example above. I don’t know how that measures up to anyone else’s code, but it’s fairly average for my own.

If you’re a developer, you’re probably wondering just how I could possibly know what lines will need comments when someone else looks at the function. The answer is easy enough: as I’m developing the code, I also read it as if I’m seeing it for the first time, and if any questions occur to that side of my brain, I add a comment to answer them. It’s something you pick up with enough experience, and I don’t know of any shortcut to it except knowing what you’re aiming for.

The basic thing to remember is that you’re not writing code for the compiler, you’re writing it for the human readers who comes after you. The compiler can understand literally millions of variations on a single function. Practically all of those would be gibberish to a human trying to debug or modify the function. If you need any more encouragement, keep in mind that that later someone might be you.

“The Pirate Bay torrents printable 3D objects”

Ever since I read Neal Stephenson’s The Diamond Age, I’ve been wondering what would happen when anyone could download a set of plans and print their own, for example, Star Wars toys. And more to the point, what would happen when those plans could be pirated.

Anything digital can easily be copied; the Internet is one huge digital copy machine. And anything that people want will be copied. There’s no effective way to prevent or police it, and I doubt there every can be. LucasFilm made a fortune on the Star Wars films, but (as I understand it) many times that on cheaply-made plastic toys from them — I had several myself when I was a kid. Lego continues to make money hand over fist, for a product that anyone with a RepRap could churn out by the thousands without thinking.

That sort of thing simply couldn’t happen in an age where anyone can download free (official, stolen, or knockoff) plans, or create their own, and have their own home 3D printer create whatever it is they want. Right now the products from such devices look pretty crude, but it wouldn’t take much interest from the masses to drive their creators to improve them.

When they do… well, life is going to be interesting for the Lego Corporation and any would-be LucasFilms.

“Ambient Field Conditioner audiophile insanity”

Some people have a lot more money than sense.