Star Trek: The Next Generation

I’ve had a long-standing affection for Star Trek: The Next Generation, since it used to be shown on TV right after I got home from school and I would watch it almost every day.  I must have seen every episode several times when I was younger, but it was only recently that I went back to rewatch them on DVD, partly out of curiosity to see how they would stand up.  I think it’s fair to say that a lot of these episodes haven’t aged well (or were dreadful even at the time), but there are still plenty of gems there. As much for my own reference as anything else, the table below marks which episodes I still thought were good after a gap of many years.

In the table, I’ve also added links to two series of reviews.  The first are Zack Handlen’s excellent reviews of every ST:TNG episode (linked from the initials “ZH” below), and I’ve also added his grade for each episode.  I’ve found myself agreeing with his reviews more often than not, and in a some cases the reviews are significantly more enjoyable than the episodes themselves.  The second set of links are to reviews by Wil Wheaton (who played Wesley Crusher) of some of the episodes from Season 1 - it’s interesting to hear his take on these very variable episodes, particularly since the writers were not good to him at all.

A few other random observations:

  • It’s often been said, but there are plenty of episodes that are completely carried by Patrick Stewart - he’s just fantastic.
  • Predictably, perhaps, given that I enjoyed Star Trek: Deep Space Nine and Battlestar Galactica, it seems that lots of my favourite episodes were written by Ronald D. Moore.
  • I hated the holodeck episodes when I was younger, and I still think they have no place in the series. There are any number of problems with the holodeck conceit from a science fiction point of view, and it very rarely adds anything to the story-telling.
  • The pastiches of other genres are dreadful, in particular the insultingly awful “Dixon Hill” parodies of Raymond Chandler. As a general rule, if you think you can write something in the style of Raymond Chandler, you have no idea what makes his books good. (See also the ridiculous Robert Altman version of the Long Goodbye.)

These other links might also be of interest if you enjoyed ST:TNG:

Summary Table of Episodes

The source for this table is the spreadsheet here and the HTML was generated from that with this script.

The key to this colours in this table is:

  • One of my favourites
  • An episode I liked
  • An episode I’m still undecided about
  • A quite missable episode

Season 1

1×01, 1×02 Encounter at Farpoint WP: The new starship Enterprise begins her maiden voyage by uncovering the mysteries of an advanced space station. The crew’s mission is threatened by an omnipotent being named Q, who puts them (and specifically, Captain Picard) on trial for the crimes of all humanity. ZH (B-) WW
1×03 The Naked Now WP: A mysterious, communicable contaminant causes the crew to experience symptoms similar to alcohol intoxication. ZH (D-) WW
1×04 Code of Honor WP: Lt. Yar is abducted by the leader of a people who abide by a strict code of honor, which requires her participation in a fight to the death. ZH (C-) WW
1×05 The Last Outpost WP: An unknown force immobilizes the Enterprise during the Federation’s first encounter with a new alien threat—the Ferengi. ZH (C-) WW
1×06 Where No One Has Gone Before WP: Warp efficiency tests send the Enterprise traveling far beyond known space, where the crew’s imagination takes on real form. First appearance of Eric Menyuk as The Traveler. ZH (B-) WW
1×07 Lonely Among Us WP: An alien entity possesses Dr. Crusher, Worf, and Picard while the Enterprise is transporting delegates from two feuding planets. ZH (C-) WW
1×08 Justice WP: Wesley breaks an idyllic world’s trivial law by accidentally stepping on flowers and faces the death sentence. ZH (C) WW
1×09 The Battle WP: A Ferengi captain returns the abandoned Stargazer to its former captain, Jean-Luc Picard. Picard, who experiences severe headaches, begins to relive the “Battle of Maxia” in which he lost the ship. Guest star Frank Corsentino as DaiMon Bok. ZH (C+) WW
1×10 Hide and Q WP: Q returns to the Enterprise to tempt Commander Riker into joining the Q Continuum with the lure of Q’s powers. ZH (C-) WW
1×11 Haven WP: Lwaxana Troi visits her daughter, Counselor Troi, and prepares her for an arranged marriage. ZH (D) WW
1×12 The Big Goodbye WP: A computer malfunction traps Picard, Data, and Beverly in a Dixon Hill holodeck program set in early 20th-century Earth. ZH (B-) WW
1×13 Datalore WP: The Enterprise crew finds a disassembled android identical to Data at the site of the Omicron Theta colony—where Data was found—which was destroyed by a life form dubbed “the Crystalline Entity.” The reassembled android, Lore, brings the Crystalline Entity to the Enterprise. ZH (B-) WW
1×14 Angel One WP: The Enterprise visits a world dominated by women to rescue survivors of a downed freighter. ZH (F) WW
1×15 11001001 WP: Bynars upgrade the Enterprise’s computers in spacedock. Riker and Picard become distracted by a surprisingly realistic holodeck character. ZH (B) WW
1×16 Too Short a Season WP: The Enterprise transports a legendary geriatric admiral who must once again negotiate a hostage situation involving a man from decades earlier in his career. The admiral is mysteriously growing younger; by the time the Enterprise arrives he is a young man. ZH (C+) WW
1×17 When The Bough Breaks WP: A planet formerly existing only in legend uncloaks and requests help from the Enterprise. Planet’s inhabitants are sterile and want to adopt children from the Enterprise—by force, if necessary. ZH (B) WW
1×18 Home Soil WP: The crew of the Enterprise discovers a crystalline lifeform with murderous intelligence that has been killing the scientists on a terraforming project. ZH (B+) WW
1×19 Coming of Age WP: While Wesley takes a Starfleet Academy entrance exam, the senior staff of the Enterprise are placed under investigation by Starfleet. ZH (C) WW
1×20 Heart of Glory WP: Fugitive Klingons seeking battle attempt to hijack the Enterprise, and ask Worf to join them. ZH (B+) WW
1×21 The Arsenal of Freedom WP: Trapped on the surface of an abandoned planet, an away team becomes unwitting participants in the demonstration of an advanced weapons system. ZH (C+) WW
1×22 Symbiosis WP: Picard tries to mediate a trade dispute between two neighboring planets, one of which is the sole supplier of a drug to treat the other’s apparently fatal disease. ZH (B) WW
1×23 Skin of Evil WP: An evil, tar-like creature holds Troi hostage on an alien world. During the rescue mission, one of the Enterprise crew is killed. ZH (C-) WW
1×24 We’ll Always Have Paris WP: Picard meets an old flame, whose husband has been affected by a dimensional experiment accident. ZH (B-) WW
1×25 Conspiracy WP: The strange behavior of high-ranking officers—which earlier prompted the investigation of the crew (in “Coming of Age”)—leads Picard to uncover a conspiracy within Starfleet. ZH (B) WW
1×26 The Neutral Zone WP: A derelict satellite is found containing cryonically frozen humans from the 21st century as the Enterprise is sent to investigate the destruction of outposts near Romulan space. ZH (C-) WW

Season 2

2×01 The Child WP: Dr. Pulaski joins the Enterprise while La Forge prepares the Enterprise to transport dangerous plague specimens; Deanna spontaneously becomes pregnant and gives birth to a mysterious child. ZH (D+) WW
2×02 Where Silence Has Lease WP: The Enterprise becomes trapped in a “hole in space”, where the crew encounter strange spatial phenomena and crewless ships materialising in and out of existence. The crew suspect they are akin to lab rats. ZH (B) WW
2×03 Elementary, Dear Data WP: After Data easily solves an ordinary Sherlock Holmes holodeck mystery, Geordi asks the computer to make a Holmes villain capable of defeating Data. The resultant Professor Moriarty soon becomes far more powerful than expected. ZH (B+) WW
2×04 The Outrageous Okona WP: The Enterprise is caught up in the schemes of a flamboyant space rogue on the run, while Data explores humor with the help of a holodeck comedian (played by Joe Piscopo). ZH (C-) WW
2×05 Loud As A Whisper WP: The Enterprise hosts a deaf, telepathic ambassador who mediates difficult peace negotiations with the assistance of his trio of telepathic interpreters. ZH (B-) WW
2×06 The Schizoid Man WP: A brilliant scientist and former mentor of Data’s creator, Dr. Ira Graves, cheats death by uploading his memories and personality into the android Data. ZH (C-) WW
2×07 Unnatural Selection WP: The Enterprise receives a distress call from the USS Lantree where the crew find all hands dead from, apparently, old age. The cause of the accelerated aging must be found before scientists on a research colony suffer the same fate. ZH (C+) WW
2×08 A Matter Of Honor WP: Riker is assigned to a Klingon vessel via an officer exchange program between the Federation and the Klingon Empire. ZH (A-) WW
2×09 The Measure Of A Man WP: When Data refuses orders to be dismantled for research purposes, a hearing is convened to determine if he is a legal citizen or property of the Federation. Guest stars Amanda McBroom as JAG Philippa Louvois. ZH (A-) WW
2×10 The Dauphin WP: The Enterprise hosts a young world leader and her mysterious chaperone. Wesley soon falls in love with the young leader. Guest stars Paddi Edwards as Anya. ZH (B) WW
2×11 Contagion WP: A dangerous alien computer virus runs rampant through the Enterprise after causing the destruction of her sister ship, the USS Yamato. ZH (B+) WW
2×12 The Royale WP: Riker, Worf, and Data investigate a structure on an icy gas giant. Inside, they find a casino reconstructed from a bad Earth novel. ZH (B) WW
2×13 Time Squared WP: Picard encounters his future self, when the Enterprise becomes caught in a time loop. ZH (A-) WW
2×14 The Icarus Factor WP: Riker’s estranged father visits to brief him on the command he has been offered, and Worf’s friends discover he is about to miss an important Klingon rite of passage. ZH (C+) WW
2×15 Pen Pals WP: Data befriends a child from a doomed planet, breaking the Prime Directive. ZH (B-) WW
2×16 Q Who WP: Q flings the Enterprise 7,000 light years beyond Federation space and introduces the ship and its crew to the deadly Borg. ZH (A) WW
2×17 Samaritan Snare WP: A group of seemingly dimwitted aliens, the Pakleds, kidnap Geordi to make their ship go. ZH (B-) WW
2×18 Up The Long Ladder WP: Picard must find a way to bring two radically incompatible cultures together, lest both of them face extinction. ZH (C) WW
2×19 Manhunt WP: Deanna’s mother seeks a new husband, and she has her eyes on Picard. ZH (C) WW
2×20 The Emissary WP: Worf’s former lover comes aboard Enterprise to help deal with a Klingon sleeper ship. ZH (B+) WW
2×21 Peak Performance WP: The Enterprise and USS Hathaway face off in simulated combat maneuvers. Data fails to beat a humanoid at a game of Strategema and experiences feelings of self-doubt. ZH (B+) WW
2×22 Shades Of Gray WP: Riker is poisoned by an alien plant and, as he lies comatose, he relives various memories of his life serving the Enterprise. (Clip show as a result of the 1988 Writers Guild of America strike.) ZH (F) WW

Season 3

3×01 Evolution WP: Nanites escape Wesley’s lab and form a collective intelligence, threatening an astrophysicist’s only chance at performing a stellar experiment. Guest star Ken Jenkins as Dr. Paul Stubbs. ZH (B) WW
3×02 The Ensigns of Command WP: Data must persuade a stubborn colony to evacuate their homeland under threat of a powerful and mysterious race. ZH (B+) WW
3×03 The Survivors WP: The Enterprise investigates the last two survivors of an annihilated world, as the entire surface has been transformed to dust except their one little garden and house. Guest stars John Anderson and Anne Haney as Kevin and Rishon Uxbridge. ZH (A) WW
3×04 Who Watches The Watchers WP: Deanna and Riker must rectify the damage done when two primitives from Mintaka III catch glimpse of a Federation observation team and eventually conclude that Captain Picard is a god. ZH (A) WW
3×05 The Bonding WP: A mysterious entity seeks to comfort a boy who has lost his mother in an accident on its planet. Guest star Gabriel Damon as Jeremy Aster. ZH (B+) WW
3×06 Booby Trap WP: The Enterprise falls victim to an ancient booby trap set to snare starships; while in an effort to find an escape, Geordi finds himself falling for the holodeck’s representation of a famous Federation engineer. Guest star Susan Gibney as Dr. Leah Brahms. ZH (B) WW
3×07 The Enemy WP: Geordi is trapped on a harsh planet with a hostile Romulan, and the two must work together to survive. ZH (A-) WW
3×08 The Price WP: Troi falls in love with a charismatic negotiator who vies for rights to a wormhole. But several different groups are after the wormhole as it may be the only known stable wormhole in existence. Guest star Dan Shor as Dr. Arridor. ZH (B-) WW
3×09 The Vengeance Factor WP: Riker exposes an assassin in the midst of critical peace talks. ZH (B) WW
3×10 The Defector WP: Determined to avert a war, a Romulan officer defects to warn Picard of his Empire’s invasion plans. ZH (A) WW
3×11 The Hunted WP: A genetically modified soldier reveals the social problems of a world hoping to join the Federation. Guest star James Cromwell as Prime Minister Nayrok. ZH (A) WW
3×12 The High Ground WP: Dr. Crusher is kidnapped by terrorists who need medical assistance as the technology employed in their attacks is detrimental to their own health. ZH (B-) WW
3×13 Déjà Q WP: The Q Continuum strips Q of his powers, and dumps him aboard the Enterprise. ZH (B+) WW
3×14 A Matter of Perspective WP: Riker is accused of murder, and the holodeck is used to reconstruct the events from different perspectives. ZH (B-) WW
3×15 Yesterday’s Enterprise WP: The Enterprise-C arrives from the past, causing a shift in reality—and the return of the deceased Tasha Yar. ZH (A) WW
3×16 The Offspring WP: Data creates a young gynoid, which he considers his daughter, “Lal”. But a Starfleet admiral arrives demanding she be removed from the Enterprise. Guest star Hallie Todd as Lal. ZH (A-) WW
3×17 Sins of the Father WP: Worf goes on trial to prove his father’s innocence after the Klingon High Council declares that Worf’s father is a traitor, and worked with the Romulans all along. ZH (A) WW
3×18 Allegiance WP: Aliens kidnap Picard and replace him with a duplicate, who sends the Enterprise to a pulsar. Meanwhile, the real Picard and three other captives try to escape from their prison. ZH (B) WW
3×19 Captain’s Holiday WP: Picard is convinced to take some much needed shore leave, but gets wrapped up in a woman’s treasure hunt. Guest star Max Grodenchik as Sovak. ZH (B) WW
3×20 Tin Man WP: A gifted telepath whom Deanna Troi once treated as a patient comes aboard to establish first contact with an unknown vessel near an unstable star before the Romulans do. ZH (B+) WW
3×21 Hollow Pursuits WP: Lt. Barclay’s use of the holodeck as an escape interferes with his duties. Meanwhile, the Enterprise suffers from mysterious and random malfunctions. ZH (B) WW
3×22 The Most Toys WP: An obsessed collector is determined to add Data to his private collection of unique items. Guest star Saul Rubinek as Kivas Fajo. ZH (A-) WW
3×23 Sarek WP: The Enterprise hosts Ambassador Sarek, but his deteriorating mental health causes unforeseen problems. ZH (A) WW
3×24 Ménage à Troi WP: The Ferengi kidnap Deanna, her mother and Riker. ZH (B) WW
3×25 Transfigurations WP: The Enterprise rescues a humanoid with amnesia and incredible healing powers. ZH (B-) WW
3×26 The Best of Both Worlds WP: Picard is kidnapped by the Borg, who begin their invasion of Federation space. ZH (A) WW

Season 4

4×01 The Best of Both Worlds, Part II WP: Picard is rescued from the Borg as the Enterprise races to save Earth. A great number of Starfleet ships are destroyed by the lone Borg ship, although an away team finally rescues Picard. Data interfaces with the half-Borg Picard and finds a way to shut down the Borg ship. Guest star Elizabeth Dennehy as Starfleet Commander Shelby. ZH (A) WW
4×02 Family WP: Picard visits his family in France and Worf’s human parents come aboard the Enterprise. ZH (A) WW
4×03 Brothers WP: Data is summoned by his creator Noonien Soong who is still alive, and they are joined by Lore. ZH (B+) WW
4×04 Suddenly Human WP: Picard must help a human boy, raised by aliens, to decide his fate. ZH (A-) WW
4×05 Remember Me WP: After an apparent failure of a warp-field experiment, people begin to disappear from the Enterprise with only Dr. Crusher remembering that they ever existed. ZH (B) WW
4×06 Legacy WP: Tasha Yar’s sister Ishara seeks to restore order on their conflict-ridden colony world. ZH (B) WW
4×07 Reunion WP: Worf’s ex-girlfriend returns, and along with Picard, the two mediate a Klingon power dispute and Worf discovers more family. ZH (B+) WW
4×08 Future Imperfect WP: Riker finds himself sixteen years in the future, his memory of the interim erased by a dormant virus. ZH (A-) WW
4×09 Final Mission WP: Wesley sets off on his final mission with the Enterprise accompanied by Picard, but they become stranded on a desert planet. ZH (B+) WW
4×10 The Loss WP: An unknown force captures the Enterprise and causes Deanna to lose her empathic powers. ZH (C+) WW
4×11 Data’s Day WP: Data gets dancing lessons from Dr. Crusher in preparation of Chief O’Brien’s wedding as the Enterprise brings Ambassador T’Pel to the Romulans for negotiations. ZH (B-) WW
4×12 The Wounded WP: A rogue Starfleet Captain jeopardizes the Cardassian peace treaty. ZH (A-) WW
4×13 Devil’s Due WP: A powerful mythic figure from a millennium ago returns to enslave a planet in accordance with a contract. However Picard is convinced she is an opportunistic charlatan. Guest star Marta DuBois as Ardra. ZH (B+) WW
4×14 Clues WP: The crew, with the exception of Data, is rendered unconscious for 30 seconds after going through a localized wormhole. However, various clues suggest they were unconscious for an entire day. ZH (B+) WW
4×15 First Contact WP: Riker is hospitalized during a botched pre-first contact mission. Xenophobia results in increasing hostility toward his presence. ZH (B+) WW
4×16 Galaxy’s Child WP: The Enterprise accidentally kills a space creature, and the crew rush to save its unborn offspring. Meanwhile, Geordi meets the engineer he fell in love with and finds to his shock, she’s nothing like the woman he encountered on the holodeck. Guest star Susan Gibney as Dr. Leah Brahms. ZH (C+) WW
4×17 Night Terrors WP: The Enterprise is trapped in a rift. The crew succumbs to REM sleep deprivation, while Deanna has a recurring nightmare. ZH (B) WW
4×18 Identity Crisis WP: Geordi transforms into an alien creature with strong instinct to return to its planet of origin. ZH (B+) WW
4×19 The Nth Degree WP: After an encounter with an alien probe Barclay experiences great leaps in confidence and intelligence. ZH (B) WW
4×20 Qpid WP: Q returns to test Picard’s love for an old flame. ZH (B-) WW
4×21 The Drumhead WP: A witchhunt ensues for suspected Romulan spies aboard the Enterprise. Guest star Jean Simmons as Rear Admiral Norah Satie. ZH (A) WW
4×22 Half a Life WP: Lwaxana Troi finally finds love, but discovers her man must undergo a ritualistic suicide. Guest star David Ogden Stiers as Timicin. ZH (B+) WW
4×23 The Host WP: Dr. Crusher falls in love with Odan, only to discover that Odan is a symbiote, which is implanted into Riker after his original host dies. Odan continues peace negotiations using Riker as a temporary host. ZH (B+) WW
4×24 The Mind’s Eye WP: The Romulans brainwash Geordi to carry out a covert mission. ZH (A) WW
4×25 In Theory WP: Data participates in a romantic relationship with a fellow crew member. ZH (B) WW
4×26 Redemption WP: Worf leaves the Enterprise to fight on behalf of Gowron in a Klingon civil war. ZH (A-) WW

Season 5

5×01 Redemption II WP: A fleet of 23 Federation ships blockades Romulan support to the Duras family, resulting in Gowron’s installation as Chancellor. ZH (B) WW
5×02 Darmok WP: Picard must learn to communicate with an alien captain who speaks in metaphors before a dangerous beast kills them both. Guest star Paul Winfield as Dathan. ZH (A) WW
5×03 Ensign Ro WP: After an attack on a Federation outpost, Picard is sent to locate a Bajoran terrorist, with the help of Ensign Ro Laren. ZH (A-) WW
5×04 Silicon Avatar WP: The crew, with the help of a scientist whose son lived on Data’s home world, attempt to communicate with the Crystalline Entity. ZH (B+) WW
5×05 Disaster WP: The Enterprise is without power, trapping Picard in a turbolift with three children and trapping others in various locations. Command of the bridge falls to Counselor Troi, who feels ill-prepared. ZH (B+) WW
5×06 The Game WP: Wesley visits the Enterprise, but finds the crew addicted to a mind-altering computer game. Guest star Ashley Judd as Robin Lefler. ZH (C) WW
5×07 Unification I WP: Spock is reported to have defected to the Romulans. Picard and Data travel to Romulus on a cloaked Klingon vessel to investigate. ZH (B) WW
5×08 Unification II WP: Spock attempts to unify the Vulcans and Romulans in peace, but falls into a Romulan trap. ZH (B) WW
5×09 A Matter of Time WP: A historian from the 26th century visits the Enterprise, while they help a planet prevent a nuclear winter. Guest star Matt Frewer as Berlinghoff Rasmussen. ZH (B) WW
5×10 New Ground WP: Worf tries to be a father to his son, Alexander, while the Enterprise helps to test a new propulsion technology. ZH (B-) WW
5×11 Hero Worship WP: Data saves the life of an orphaned boy, who begins to emulate him. ZH (B+) WW
5×12 Violations WP: An alien traveling aboard the Enterprise telepathically molests Troi and invades the minds of Beverly Crusher and William Riker. ZH (C+) WW
5×13 The Masterpiece Society WP: The Enterprise helps a far-flung eugenic human colony avoid destruction, but upsets its delicate balance by ending 200 years of isolation. ZH (B-) WW
5×14 Conundrum WP: The crew’s memory is erased, and they discover they are being manipulated into being the key part of a war. ZH (B+) WW
5×15 Power Play WP: Troi, O’Brien, and Data are possessed by entities who want control of the ship. ZH (B) WW
5×16 Ethics WP: Worf becomes paralyzed—and suicidal—and Dr. Crusher consults a risk-taking researcher to save his life. ZH (B-) WW
5×17 The Outcast WP: Riker falls in love with an androgynous person after rescuing some others trapped in “null space.” ZH (A) WW
5×18 Cause and Effect WP: The Enterprise becomes stuck in a causality loop, but the crew retain some memory of previous instances. Guest star Kelsey Grammer as Morgan Bateson. ZH (A) WW
5×19 The First Duty WP: Wesley is questioned over a Starfleet Academy flight-training accident. Guest star Ray Walston as Boothby. ZH (A) WW
5×20 Cost of Living WP: Deanna’s mother, Lwaxana, arrives to marry a man she has never met. Worf has difficulty rearing Alexander, which is exacerbated when Lwaxana takes the boy under her wing. ZH (C) WW
5×21 The Perfect Mate WP: Picard forces himself to resist the charms of a female empathic metamorph, who is sent to marry an alien leader as a peace offering. Guest star Famke Janssen as Kamala. ZH (B+) WW
5×22 Imaginary Friend WP: A child’s imaginary playmate takes on real form and threatens the well-being of the Enterprise. ZH (B-) WW
5×23 I Borg WP: The Enterprise rescues a Borg survivor, and Picard plans to use him as a weapon against his nemesis by exposing him to a computer virus. ZH (A-) WW
5×24 The Next Phase WP: A transporter accident traps Geordi and Ensign Ro out of phase; while the others plan their funeral they must find a way to reverse the process and save the Enterprise from destruction. ZH (A-) WW
5×25 The Inner Light WP: A space probe creates a telepathic tether and causes Picard to experience, in twenty-five minutes, a lifetime as a married man on a world that was destroyed a millennium ago. ZH (A+) WW
5×26 Time’s Arrow WP: A 500-year-old artifact is uncovered on Earth: Data’s severed head. The Enterprise investigates alien involvement in Earth’s past and Data fulfills his destiny. ZH (B-) WW

Season 6

6×01 Time’s Arrow, Part II WP: The Enterprise crew follow Data to San Francisco of the 1890s. The crew deals with Samuel Clemens (and run into Jack London), while trying to find a way to prevent aliens from interfering with 19th-century Earth. Guest star: Jerry Hardin as Samuel Clemens. ZH (D+) WW
6×02 Realm of Fear WP: Barclay must overcome his fear of the transporter to solve a mystery. ZH (B-) WW
6×03 Man of the People WP: A psychic ambassador uses Deanna’s mind to influence the outcome of his mission. ZH (C) WW
6×04 Relics WP: The Enterprise investigates a vessel that crashed on the surface of a Dyson sphere 75 years ago. An undegraded pattern is found in the transporter buffer, that of Mr. Scott. Feeling out of place and obsolete, Scotty agrees to return to his vessel with Geordi to help restore the logs, and they become the only hope when the Enterprise is accidentally pulled inside the sphere. ZH (A) WW
6×05 Schisms WP: Several members of the crew are abducted and experimented on while they sleep. ZH (B) WW
6×06 True Q WP: Q reveals a secret about a young woman from Kansas who is visiting the Enterprise. Guest star: Olivia D’Abo as Amanda Rogers. ZH (B+) WW
6×07 Rascals WP: A transporter malfunction turns Picard, Keiko, Ro and Guinan into children, who become the ship’s only hope when they are left aboard while the adult crew are forced to perform dangerous labor by Ferengi pirates. ZH (B-) WW
6×08 A Fistful of Datas WP: Data’s mind is connected to the ship’s computer, which creates unforeseen effects on the holodeck. ZH (B+) WW
6×09 The Quality of Life WP: Data observes self-guided “tools” used at a mining station display signs of sentience, and fights for their preservation, even risking Captain Picard’s life on the ground that it is unacceptable to kill one sentient being to save another. ZH (B+) WW
6×10 Chain of Command, Part I WP: Captain Jellico is assigned command of the Enterprise, while Picard is sent on a covert mission into Cardassian territory. Guest star: Ronny Cox as Edward Jellico. ZH (B+) WW
6×11 Chain of Command, Part II WP: Picard, having been captured, is tortured by a sadistic Cardassian interrogator (played by David Warner). ZH (A) WW
6×12 Ship in a Bottle WP: Barclay accidentally awakens Prof. Moriarty on the holodeck, who uses the powers at his disposal to coerce the crew into finding a way to allow him to leave the holodeck. Guest star: Daniel Davis as Professor Moriarty. ZH (A-) WW
6×13 Aquiel WP: Geordi falls for an alien Starfleet officer who is suspected of murder. Guest star Renee Jones as Aquiel Uhnari. ZH (C) WW
6×14 Face of the Enemy WP: Deanna is involuntarily recruited to assist in the transport of Romulan defectors across the border. ZH (B+) WW
6×15 Tapestry WP: An accident kills Picard, and he finds an afterlife with Q analyzing his past choices. ZH (A) WW
6×16 Birthright, Part I WP: Worf is told on Deep Space Nine his father is alive, and being held prisoner by the Romulans. Meanwhile an engineering experiment accidentally results in Data’s first dream. Guest star: James Cromwell as Jaglom Shrek. ZH (B+) WW
6×16 Birthright, Part II WP: Worf, now a prisoner, tries to teach the Klingon refugees the ways of the warrior. ZH (B) WW
6×18 Starship Mine WP: Thieves attempt to steal trilithium from Enterprise during a Baryon sweep at the Remmler Array, and Picard alone must thwart them. ZH (B) WW
6×19 Lessons WP: Picard becomes involved with a woman who is serving on the Enterprise, but he must send her into a dangerous mission. ZH (B+) WW
6×20 The Chase WP: Picard tries to solve an ancient genetic mystery uncovered by his archaeological mentor, and faces stiff competition. Guest star: Norman Lloyd as Richard Galen. ZH (B+) WW
6×21 Frame of Mind WP: Riker finds himself prisoner in an alien mental institution, which resembles scenes from Beverly’s play. ZH (A) WW
6×22 Suspicions WP: Dr. Crusher risks her career to solve the murder of Ferengi scientist Dr. Reyga and vindicate his research. ZH (B-) WW
6×23 Rightful Heir WP: Worf experiences a crisis of faith, and travels to a Klingon holy site where the mythic figure Kahless returns to lead the Klingon people. ZH (A) WW
6×24 Second Chances WP: Riker encounters a duplicate of himself created by a transporter malfunction stranded on a planet. “Thomas” vies for Deanna’s affections. ZH (B+) WW
6×25 Timescape WP: The Enterprise is caught in temporal stasis, and on the brink of destruction by a Romulan ship. ZH (B) WW
6×26 Descent WP: The crew encounter a group of Borg acting individually, and Data briefly experiences emotions. ZH (B) WW

Season 7

7×01 Descent, Part II WP: The Borg are being led by Lore. Data falls under his control by being fed negative emotions. ZH (B-) WW
7×02 Liaisons WP: Worf and Troi reluctantly play host to two Lyraan ambassadors, while Picard crashes in a shuttle with another Lyraan. He is rescued by a human female who exhibits strange behavior. ZH (B-) WW
7×03 Interface WP: Geordi tries to rescue his mother’s starship via a remotely controlled probe. ZH (C+) WW
7×04 Gambit, Part I WP: The Enterprise crew investigate the apparent murder of Captain Picard during an archaeological trip. Riker is kidnapped by mercenaries and finds Picard working as part of their crew. ZH (B) WW
7×05 Gambit, Part II WP: Picard and Riker help mercenaries collect archaeological artifacts to prevent an ancient Vulcan weapon falling into the wrong hands. ZH (B-) WW
7×06 Phantasms WP: Data experiences strange dreams, while the Enterprise has issues with its new Warp-core. But all is not as it seems. ZH (B+) WW
7×07 Dark Page WP: A psychic breakdown puts Lwaxana Troi in a coma, and Deanna works to save her life. Features a young Kirsten Dunst, playing the little girl Hedril. ZH (B-) WW
7×08 Attached WP: Reclusive aliens imprison Picard and Dr. Crusher on charges of espionage, and experimental implants linking their minds telepathically cause them to face their latent feelings for each other. ZH (B+) WW
7×09 Force of Nature WP: A pair of scientists show that warp drives are harming the fabric of space. ZH (B) WW
7×10 Inheritance WP: Data encounters a woman claiming to be his “mother”. ZH (B-) WW
7×11 Parallels WP: Worf finds himself randomly shifting between alternate realities. ZH (A-) WW
7×12 The Pegasus WP: Riker’s former Captain boards the Enterprise to retrieve the USS Pegasus. Picard investigates the circumstances of its loss and finds that there has been a cover-up. Features Terry O’Quinn as Admiral Eric Pressman. ZH (A-) WW
7×13 Homeward WP: Worf’s human foster brother violates the Prime Directive to save a doomed primitive race. ZH (C+) WW
7×14 Sub Rosa WP: Dr. Crusher attends her grandmother’s funeral, and takes on an unusual family tradition. ZH (D) WW
7×15 Lower Decks WP: Junior officers buck for promotion as one of them is assigned the dangerous task of helping a Cardassian spy. ZH (A) WW
7×16 Thine Own Self WP: Data loses his memory after retrieving radioactive fragments on a planet’s surface and endangers the humanoid settlement he encounters, while Deanna studies to become a bridge officer. ZH (B+) WW
7×17 Masks WP: The Enterprise finds an ancient library that recreates its civilization by taking possession of Data and transforming the ship. ZH (C) WW
7×18 Eye of the Beholder WP: Deanna investigates the suicide of a crewman and uncovers a murder that took place during construction of the Enterprise. ZH (C-) WW
7×19 Genesis WP: A routine medical treatment inadvertently creates a virus that begins to de-evolve the Enterprise crew while Picard and Data are on an away mission. This is the first and only episode to be directed by Gates McFadden, who plays Dr. Crusher. ZH (C-) WW
7×20 Journey’s End WP: Wesley considers his future, as the Enterprise is ordered to remove Native American colonists from a planet that is about to fall under Cardassian jurisdiction. Guest star Richard Poe as Gul Evek. Final appearance of Eric Menyuk as The Traveler. ZH (C) WW
7×21 Firstborn WP: Worf attempts to convince his son Alexander to embrace his warrior heritage. Guest star James Sloyan as K’mtar. ZH (C+) WW
7×22 Bloodlines WP: DaiMon Bok returns to exact revenge on Picard, by trying to kill the son Picard never knew he had. Guest star Lee Arenberg as DaiMon Bok. ZH (C+) WW
7×23 Emergence WP: The Enterprise becomes an emergent intelligence. ZH (B-) WW
7×24 Preemptive Strike WP: Ensign Ro graduates from advanced tactical training, and is sent by Picard to lure Maquis terrorists into a trap. Guest star Richard Poe as Gul Evek. ZH (A) WW
7×25 All Good Things… WP: Picard finds himself alternating between three time periods thanks to Q, with a spacetime distortion that threatens to destroy reality growing larger in the past, and smaller in the future. ZH (A) WW

No, “cassette tape” hasn’t been removed from the Concise Oxford English Dictionary

I’ve seen many people link to a news story claiming that “cassette tape” has been removed from the Concise OED — this story appears to be complete nonsense,  and I’m genuinely intrigued as to how it got started.  Of course, none of the news stories that repeat this claim cite any source.  This is a minor example of a serious problem that Francis has blogged about.

TIME magazine is perhaps the highest profile publication to  make the claim, saying that “cassette tape” is being removed from the Oxford English Dictionary and referencing The Huffington Post as its only source.  Firstly, the TIME story is obviously nonsense taken literally, since the OED is a historical dictionary and words generally aren’t removed from its 20 volumes at all.  Other stories clarify that this is supposedly a scandal with the new (12th) edition of the Concise Oxford English Dictionary, which was released in August 2011 to a flurry of stories about the various entertaining new words that have been added to it.  The news stories about those words seem to be largely based on two blog posts (here and here) from Oxford University Press that discuss in general terms what has defined the COED over its 100 year history.  Neither of those posts mention anything about “cassette tape” being removed.  (I haven’t found any more official press release about this new edition online.)

Anyway, suspecting that this story was nonsense, I did the obvious thing and looked in the new 12th edition of the COED in a local bookshop.  Of course, cassette tape is still here:

So, my real question is: “Who is it that just invents this stuff?”

Ubuntu on the Sony Vaio VPCYB2M1E/S

tl;dr: This post describes how well Ubuntu GNU/Linux works on the Sony Vaio VPCYB2M1E since there’s otherwise not much information on the web about the hardware support for this model on Linux.  In summary, so far it seems that this is a good choice for running Ubuntu on so long as you use the 32-bit version, but these are still early days.

At the moment, looking for a new computer in the netbook space which runs Linux well is a rather frustrating exercise.  This is chiefly because:

  • The market moves fast, and often there’s little information on the web about Linux support for the models that are actually available in the shops.
  • Frustratingly, it seems that some companies change the hardware in their machines without changing the model number.
  • What random people on Ubuntu forums consider to count as “working well” can include “won’t suspend to RAM” or “ethernet doesn’t work”.
  • Most reviews of netbooks by technology journalists are written with a totally unhelpful set of assumptions, such as the  following:
    • They assume that you wouldn’t use a netbook as your main machine.  This might be true if you use Windows, but I used Ubuntu on the Samsung NC-10 as my main development machine for a long time.  Sure, it’s not the same experience as working on a powerful desktop system with multiple monitors, but you can get Real Work done quite happily nonetheless.
    • You see netbooks which are around the £400 price point denounced as “not knowing what they’re trying to be”, as if there aren’t customers who want the portability and battery life of a £200 netbook, but would be happy to pay a bit more for improved performance and a slightly better screen.  Their frequent suggestion that you might as well buy some powerful but bulky laptop for this money is completely missing the point.

Anyway, if you’re looking for one of these slightly-better-than-a-netbook machines to run Ubuntu on, you might consider the VPCYB2M1E - the Sony Vaio Y series that is available in the UK at the moment (summer 2011).  We believe that the “/S” at the end of the model number just means that it’s the silver rather than pink version.  This is based around the AMD E-350, so we initially chose to use the 64-bit version of Natty - however, due to some freezes that don’t seem to occur with the 32-bit flavour, we reinstalled with the 32-bit version.  (See below for more details.)

The specifications of this laptop can be found on Sony’s website.  The weight (at 1.46kg) is slightly more than I’d like, but the 1366 x 768 screen is very nice.

First we checked by booting from a live USB stick that enough of the hardware seemed to work (wireless, sound, graphics) that we were willing to risk wiping all the existing partitions and claiming all the disk space for Ubuntu.  On the second laptop I installed Natty alongside Windows 7, which worked fine.  (I note that the installation of Natty is very slick now.)

At the end of this post, we’ve include the output of “cat /proc/cpuinfo” and “lspci -v”, for those who are interested in the details.  There’s a summary of what we’ve tested so far below.  However, first a description of the only big problem we’ve seen so far:

I/O Related Freezes

When using rsync to copy large files onto this system, we found that the interface would freeze to a greater or lesser extent.  This seemed to be reproducible with any command that wrote a lot of data to disk (e.g. even dd from /dev/zero) but was only present on 64-bit installations, not 32-bit.  This problem is described here:

https://answers.launchpad.net/ubuntu/+source/linux/+question/159329

… and linked to a bug that might be related.  However, since this didn’t seem to be a problem with the 32-bit installation, we didn’t pursue it further.  (However, it should be still reproducible with the 64-bit Live USB stick.)

Ethernet

Works fine out-of-the-box

Wireless

Works out-of-the-box

Power Management

Suspend-to-RAM

Works out-of-the-box.  (When suspended, the power light glows bright orange, though, which is somewhat annoying.)

Hibernate (Suspend-to-Disk)

Works out-of-the-box

Special Keys

Work out-of-the-box

Sound

Speakers

Work out-of-the-box - pretty loud.  I’ve found on one occasion that the sound stopped working after a while and I had to reboot, but I need to investigate that more.

Microphone

Works out-of-the-box, a bit noisy, but we haven’t tried to change any of the mixer settings yet.

Graphics

With the default driver, some of the desktop effects flickered a great deal, and the desktop background showed some flickering. Installing the closed source ATI drivers (via the “Additional Drivers” in the System Settings) seems to have fixed this.

External monitor

- Not tested yet.  In particular we need to check how large a resolution it can drive.

Card Readers

The SD card reader and the slot for Sony’s memory sticks both work fine.

HDMI output

- Not tested yet.  (No HDMI monitor available.)

Webcam

Works out-of-the-box

Touchpad

Works fine out-of-the-box.  Changing the scrolling behaviour (from dragging on the right hand side to two-fingered scrolling) can be easily done with the mouse properties.

Hardware Details

$ lspci -v
00:00.0 Host bridge: Advanced Micro Devices [AMD] Pavilion DM1Z-3000 Host bridge
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 0

00:01.0 VGA compatible controller: ATI Technologies Inc Device 9802 (prog-if 00 [VGA controller])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, fast devsel, latency 0, IRQ 44
    Memory at e0000000 (32-bit, prefetchable) [size=256M]
    I/O ports at 3000 [size=256]
    Memory at f0200000 (32-bit, non-prefetchable) [size=256K]
    Expansion ROM at <unassigned> [disabled]
    Capabilities: <access denied>
    Kernel driver in use: fglrx_pci
    Kernel modules: fglrx, radeon

00:01.1 Audio device: ATI Technologies Inc Device 1314
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, fast devsel, latency 0, IRQ 42
    Memory at f0244000 (32-bit, non-prefetchable) [size=16K]
    Capabilities: <access denied>
    Kernel driver in use: HDA Intel
    Kernel modules: snd-hda-intel

00:04.0 PCI bridge: Advanced Micro Devices [AMD] Device 1512 (prog-if 00 [Normal decode])
    Flags: bus master, fast devsel, latency 0
    Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
    I/O behind bridge: 00002000-00002fff
    Memory behind bridge: f0100000-f01fffff
    Capabilities: <access denied>
    Kernel driver in use: pcieport
    Kernel modules: shpchp

00:06.0 PCI bridge: Advanced Micro Devices [AMD] Device 1514 (prog-if 00 [Normal decode])
    Flags: bus master, fast devsel, latency 0
    Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
    Memory behind bridge: f0000000-f00fffff
    Capabilities: <access denied>
    Kernel driver in use: pcieport
    Kernel modules: shpchp

00:11.0 SATA controller: ATI Technologies Inc SB7x0/SB8x0/SB9x0 SATA Controller [AHCI mode] (rev 40) (prog-if 01 [AHCI 1.0])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 19
    I/O ports at 3118 [size=8]
    I/O ports at 3124 [size=4]
    I/O ports at 3110 [size=8]
    I/O ports at 3120 [size=4]
    I/O ports at 3100 [size=16]
    Memory at f024c000 (32-bit, non-prefetchable) [size=1K]
    Capabilities: <access denied>
    Kernel driver in use: ahci
    Kernel modules: ahci

00:12.0 USB Controller: ATI Technologies Inc SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (prog-if 10 [OHCI])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 18
    Memory at f024b000 (32-bit, non-prefetchable) [size=4K]
    Kernel driver in use: ohci_hcd

00:12.2 USB Controller: ATI Technologies Inc SB7x0/SB8x0/SB9x0 USB EHCI Controller (prog-if 20 [EHCI])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 17
    Memory at f024a000 (32-bit, non-prefetchable) [size=256]
    Capabilities: <access denied>
    Kernel driver in use: ehci_hcd

00:13.0 USB Controller: ATI Technologies Inc SB7x0/SB8x0/SB9x0 USB OHCI0 Controller (prog-if 10 [OHCI])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 18
    Memory at f0249000 (32-bit, non-prefetchable) [size=4K]
    Kernel driver in use: ohci_hcd

00:13.2 USB Controller: ATI Technologies Inc SB7x0/SB8x0/SB9x0 USB EHCI Controller (prog-if 20 [EHCI])
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 17
    Memory at f0248000 (32-bit, non-prefetchable) [size=256]
    Capabilities: <access denied>
    Kernel driver in use: ehci_hcd

00:14.0 SMBus: ATI Technologies Inc SBx00 SMBus Controller (rev 42)
    Subsystem: Sony Corporation Device 9082
    Flags: 66MHz, medium devsel
    Kernel driver in use: piix4_smbus
    Kernel modules: sp5100_tco, i2c-piix4

00:14.2 Audio device: ATI Technologies Inc SBx00 Azalia (Intel HDA) (rev 40)
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, slow devsel, latency 64, IRQ 16
    Memory at f0240000 (64-bit, non-prefetchable) [size=16K]
    Capabilities: <access denied>
    Kernel driver in use: HDA Intel
    Kernel modules: snd-hda-intel

00:14.3 ISA bridge: ATI Technologies Inc SB7x0/SB8x0/SB9x0 LPC host controller (rev 40)
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, 66MHz, medium devsel, latency 0

00:14.4 PCI bridge: ATI Technologies Inc SBx00 PCI to PCI Bridge (rev 40) (prog-if 01 [Subtractive decode])
    Flags: bus master, 66MHz, medium devsel, latency 64
    Bus: primary=00, secondary=03, subordinate=03, sec-latency=64

00:18.0 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 0 (rev 43)
    Flags: fast devsel

00:18.1 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 1
    Flags: fast devsel

00:18.2 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 2
    Flags: fast devsel

00:18.3 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 3
    Flags: fast devsel
    Capabilities: <access denied>
    Kernel driver in use: k10temp
    Kernel modules: k10temp

00:18.4 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 4
    Flags: fast devsel

00:18.5 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 6
    Flags: fast devsel

00:18.6 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 5
    Flags: fast devsel

00:18.7 Host bridge: Advanced Micro Devices [AMD] Family 12h/14h Processor Function 7
    Flags: fast devsel

01:00.0 Ethernet controller: Atheros Communications AR8131 Gigabit Ethernet (rev c0)
    Subsystem: Sony Corporation Device 9082
    Flags: bus master, fast devsel, latency 0, IRQ 43
    Memory at f0100000 (64-bit, non-prefetchable) [size=256K]
    I/O ports at 2000 [size=128]
    Capabilities: <access denied>
    Kernel driver in use: atl1c
    Kernel modules: atl1c

02:00.0 Network controller: Atheros Communications Inc. AR9285 Wireless Network Adapter (PCI-Express) (rev 01)
    Subsystem: Foxconn International, Inc. Device e017
    Flags: bus master, fast devsel, latency 0, IRQ 18
    Memory at f0000000 (64-bit, non-prefetchable) [size=64K]
    Capabilities: <access denied>
    Kernel driver in use: ath9k
    Kernel modules: ath9k

$ cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 20
model           : 1
model name      : AMD E-350 Processor
stepping        : 0
cpu MHz         : 800.000
cache size      : 512 KB
physical id     : 0
siblings        : 2
core id         : 0
cpu cores       : 2
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 6
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt arat npt lbrv svm_lock nrip_save pausefilter
bogomips        : 3192.53
TLB size        : 1024 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

processor       : 1
vendor_id       : AuthenticAMD
cpu family      : 20
model           : 1
model name      : AMD E-350 Processor
stepping        : 0
cpu MHz         : 800.000
cache size      : 512 KB
physical id     : 0
siblings        : 2
core id         : 1
cpu cores       : 2
apicid          : 1
initial apicid  : 1
fpu             : yes
fpu_exception   : yes
cpuid level     : 6
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt arat npt lbrv svm_lock nrip_save pausefilter
bogomips        : 3192.05
TLB size        : 1024 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate

Official Kindle subscription to The Guardian

It seems that finally The Guardian have an official Kindle version, that you can subscribe to here:

The Guardian and The Observer [Kindle Edition]

A subscription costs a very reasonable £9.99 per month, and like all the official Kindle periodicals, it appears on your device automatically if wireless is enabled.  It looks as if they’ve done a very nice job - I’d encourage anyone who was regularly using my unofficial Guardian for Kindle project to subscribe to the official version.  As well as the convenience of automatic delivery, you get more complete content (since a number of articles aren’t available for free via the Guardian’s API) and bigger photos for each story.  In addition, with newspapers in general struggling these days, it’s good to be able to support them by paying for this service.

Where does this leave my unofficial version?  My plan is to leave in place the system that generates the web-hosted version each day, but prominently link to the official version on that page.  The version generated from the Guardian’s API might be occasionally useful for people, and I think the project is of interest in its own right - figuring out how to generate Kindle books and then periodicals was hard work, and it’s still a satisfying project to have got working so well in the end.  Even masthead images now work, thanks to a tip from Marco Arment!  (Again I should thank Dominic Evans for figuring out how to switch from generating books to periodicals, and his other contributions.)

I’ve summarized what I’ve learned so far about generating periodicals using Kindlegen in this Stack Overflow answer, and I’ll update that if I find out anything new.

A short introduction to git

I gave a short talk at work that was intended to be a sound introduction to the basics of using git, and wrote a tutorial document to go along with that. In case that is of wider interest, I’ve now put a copy of the tutorial online. It is deliberately limited in scope at the moment, but I’d be interested in what people think of this style of introduction.

Making an encrypted partition on a USB drive

On Ubuntu or Debian, it’s really simple to create an encrypted partition on a newly-purchased USB mass storage device.  In my case, I had bought a 1TB hard drive which had very mixed reviews, some people saying their drives had failed very early.  I wanted to be able to return the drive under warranty if it broke without worrying about personal data.

It turns out that if you want to reformat a partition on an external USB drive so that it’s encrypted, this is just a matter of doing the following:

sudo luksformat -t ext4 /dev/partitiondevice

…. where /dev/partitiondevice is the device for the drive partition you want to overwrite.  Obviously, this will destroy everything that was previously on that partition.

I like to use a proper filesystem for USB mass storage devices, but if you leave out the -t ext4 then the default is to use VFAT.

When you next plug in that drive, you’ll be prompted to enter the password that you picked when creating the partition - if you type that correctly, the drive will be mounted and usable.  (If you mistype it, you’re not given another chance to enter the password, so you’ll need to go to the command line and do: gvfs-mount -d /dev/partitiondevice to try again.)

One small thing is that the mount point in /media will be based on a UUID by default, but if you set the ext4 partition label, it’ll be mounted under that name in /media/ instead.  To do this, starting from when your disk is mounted, you can run mount without parameters to find the unencrypted device name and then unmount it and change the label:

$ umount /dev/mapper/udisks-luks-uuid-b7bbb2c8-etc
$ e2label /dev/mapper/udisks-luks-uuid-b7bbb2c8-etc topsekrit

If you unplug and plug in the disk again, it should be mounted on /media/topsekrit

Missing git hooks documentation

One part of git’s documentation that is particularly lacking is that on the subject of hooks.  In particular, that page doesn’t explain:

  • What the current working directory is when the hooks run.
  • Which helpful environment variables are set in the environment when the hooks are run.

These omissions are particularly irritating since the current directory is not consistent across the different hooks, and the setting of the GIT_DIR environment variable can cause some very surprising results in some situations.

So, I did some quick tests to find what the behaviour of git 1.7.1 is for each of these hooks, for both bare and non-bare repositories where appropriate.  (If I were more confident about the details of these, I would try to contribute a documentation patch, but that’s probably best done by someone who knows the code well.)

applypatch-msg
post-applypatch
pre-applypatch

(Tested with “git am” in a working tree - it cannot be used with a bare repository for obvious reasons.)

The current directory is the top level of the working tree.  The following environment variables are set:

  • GIT_AUTHOR_DATE, e.g. set to ‘Sat, 9 Apr 2011 10:13:24 +0200′
  • GIT_AUTHOR_NAME, e.g. set to ‘Ada Lovelace’
  • GIT_AUTHOR_EMAIL, e.g. set to ‘whoever@whereever’
  • GIT_REFLOG_ACTION is set to ‘am’

Note that GIT_DIR is not set.

pre-commit
prepare-commit-msg
commit-msgt
post-commit

(Tested with “git commit” in a working tree - it cannot be used with a bare repository.)

The current directory is the top level of the working tree.  The following environment variables are set:

  • GIT_DIR is set to ‘.git’
  • GIT_INDEX_FILE is set to ‘.git/index’

post-checkout

(Tested with “git commit” in a working tree - it cannot be used with a bare repository.)

The current directory is the top level of the working tree.  The following environment variables are set:

  • GIT_DIR is set to ‘.git’

pre-receive
update
post-receive
post-update

These hooks can be run either in a bare or a non-bare repository.  In both cases, the current working directory will be the git directory.  So, if this is a bare repository called “/src/git/test.git/”, that will be the current working directory - if this is a non-bare repository and the top level of the working tree is “/home/mark/test/” then the current working directory will be “/home/mark/test/.git/”.

In both cases, the following environment variable is set:

  • GIT_DIR is set to ‘.’

With a working tree, this is unexpectedly awkward, as described in Chris Johnsen’s answer that I linked to earlier.  If only GIT_DIR is set then this comment from the git man page applies:

Note: If --git-dir or GIT_DIR are specified but none of --work-tree, GIT_WORK_TREE and core.worktree is specified, the current working directory is regarded as the top directory of your working tree.

In other words, your working tree will also be the current directory (the “.git” directory), which almost certainly isn’t what you want.

pre-auto-gc

(Not tested yet.)

Summary

I think the (quite obvious) lesson from this is just:

  • Always test your hooks carefully, probably starting with a script that just echos the current working directory and GIT_DIR.

A related tip is that since the rules about GIT_DIR / --git-dir and GIT_WORK_TREE / --work-tree / core.worktree are so complex, I follow the rule of thumb that if you need to set either one, set both, and make sure you set them to an absolute path.

In case you’re interested, the test hook I used for this was just:

#!/bin/bash
echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

git: Too Many Topic Branches

Another couple of git tips, that might conceivably be useful to someone somewhere :)

git makes it so easy to create topic branches, that it’s easy to lose track of which branches were for what. Here are a couple of recipes that might help with this:

Order branches by last commit date

I often want to order my branches according to how recently I was working on them. We can approximate that by saying we’d like to order the branches by the commit date of each branch tip, and you can do that with git for-each-ref --sort=committerdate. For example, the shell script:


for C in $(git for-each-ref --sort=committerdate refs/heads --format='%(refname)')
do
    git show -s --format="%ci $C" "$C"
done

… produces output like this:

...
2011-02-23 18:57:01 -0500 refs/heads/trainable-seg-gui
2011-03-09 11:25:38 +0100 refs/heads/snt-swing-menus3
2011-03-11 00:44:37 +0100 refs/heads/master

Show branches that introduced changes to particular paths

If that doesn’t turn up the branch I’m looking for, it might be useful to just list those branches that made changes to particular paths (with respect to master). Here’s a similar example of how to do this, in this case looking for all those branches that introduced changes to the path src-plugins/Simple_Neurite_Tracer:


P="src-plugins/Simple_Neurite_Tracer"
for C in $(git for-each-ref --sort=committerdate refs/heads/ --format='%(refname)')
do
    git diff master..."$C" --quiet -- "$P" || echo $C
done

… which produces output like this:

...
refs/heads/sholl-analysis
refs/heads/for-rebasing
refs/heads/sholl-analysis-wip
refs/heads/sholl-analysis-wip2
...

Ordering branches by the last time the branch was changed

This came up in a Stack Overflow question - sometimes you might want to know when the branch pointer was last changed, not the date of the last commit. Jefromi’s answer provides a nice recipe that you could alter to order the branches in that way.

An asymmetry between git pull and push

Although git is an excellent system, which has certainly changed my way of working for the better, occasionally one comes across an inconsistency that seems bizarre. In case you don’t want to read the whole of this post, the one sentence summary would be, “By default, git push origin will update branches on the destination with one with the same name on the source, instead of using the association defined by git branch --track, which git pull origin would use — the config option push.default can change this behaviour.” However, for a more detailed explanation, read on…

Suppose someone has told you that they’ve pushed a topic branch to GitHub that they’d like you to work on. Let’s say that you’ve set up a remote called github for that repository, and the branch there is called new-feature2.  With a recent git (>= 1.6.1) you can just do git fetch and then:

git checkout -t github/new-feature2

… which will create a branch in your repository called new-feature2 based on github/new-feature2, and set various config options to associate your new-feature2 branch with github/new-feature2.  It will also checkout that new branch so that you can start working on it.  However, let’s suppose that you want to give your branch a more helpful name - let’s say that’s “add-menu”.  Then you might instead do:

git checkout -t -b add-menu github/new-feature2

… which has the same effects to the previous command, except for giving the branch a different name locally.  The config options that will have been set by that command are:

branch.add-menu.remote=github
branch.add-menu.merge=refs/heads/new-feature2

The detailed semantics of these config options are given in the branch.<name>.remote and branch.<name> merge sections of git config’s documentation, but, for the moment, just understand that this sets up an association between your local add-menu branch, and the new-feature2 branch on GitHub.

This association makes various helpful features of git possible - for example, this is how you get this nice information from git status:

$ git status
# On branch add-menu
# Your branch is ahead of 'github/new-feature2' by 5 commits.

It’s also the mechanism by which, when you’re on the add-menu branch, typing:

$ git pull github

… will cause git to run a git fetch, and then merge github/new-feature2 into your add-menu branch.  That’s all very helpful.

So, what happens when you want to push your changes back to the upstream branch?  You might hope that because this association exists in your config, then typing any of the following three commands while you’re on the add-menu branch would work:

  1. git push github add-menu
  2. git push github
  3. git push
  4. git push github HEAD

However, with the default git setup, none of these commands will result in new-feature2 being updated with your new commits on add-menu.  What does happen instead?

1. [wrong] git push github add-menu

In this case git push parses add-menu as a refspec.  “refspecs” are usually of the form <src>:<dst>, telling you which local branch (src) you’d like to update the remote branch (def) with.  However, the default behaviour if you don’t add :<dst>, as in this example, is explained in here:

If :<dst> is omitted, the same ref as <src> will be updated.

So the command is equivalent to git push github add-menu:add-menu, which will create a new branch called add-menu on GitHub rather than updating new-feature2.

2. [wrong] git push github

In this case, the refspec is omitted.  The documentation for git push again explains what happens in this case:

The special refspec : (or +: to allow non-fast-forward updates) directs git to push “matching” branches: for every branch that exists on the local side, the remote side is updated if a branch of the same name already exists on the remote side. This is the default operation mode if no explicit refspec is found (that is neither on the command line nor in any Push line of the corresponding remotes file---see below).

… so the new commits on your add-menu branch won’t be pushed.  However, the changes for every other branch for which there’s a matching name in your repository on GitHub will be!

2. [wrong] git push

Again, we can find in the documentation for git push what happens if we miss out the remote as well:

git push: Works like git push <remote>, where <remote> is the current branch’s remote (or origin, if no remote is configured for the current branch).

In our example case, branch.add-menu.remote is set to github, so the behaviour in this case will be the same as in the previous one, i.e. probably not what you want.

4. [wrong] git push github HEAD

Thanks to David Ongaro for suggesting adding this fourth wrong command. The git push documentation explains that this is:

A handy way to push the current branch to the same name on the remote.

In other words, in this example, that will end up being the same as git push github add-menu:add-menu, again creating an unwanted add-menu branch in the remote repository.

So how should you push?

The simplest option, which will work everywhere, is just to specify both the source and destination parts of the refspec, i.e.:

git push github add-menu:new-feature2

That means that you have to remember what the remote name should be, but it’s the least ambiguous way to push a branch, and in any case it’s a good idea to understand how to use refspecs more generally.

However, another alternative (available since git version 1.6.3) is to set the push.default config variable.  The documentation for this in the git config man page is:

push.default: Defines the action git push should take if no refspec is given on the command line, no refspec is configured in the remote, and no refspec is implied by any of the options given on the command line. Possible values are:

  • nothing - do not push anything.
  • matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default.
  • tracking - push the current branch to its upstream branch.
  • current - push the current branch to a branch of the same name.

So if you set push.default to tracking with one of:

$ git config push.default tracking # just for the current repository
$ git config --global push.default tracking # globally for your account

… then when you’re on the add-menu branch, git push github will update new-feature2 on GitHub with your changes in add-menu, and no other branches will be affected.

The commit message that introduced this change suggests that the reason that this option was introduced was exactly to avoid the kind of confusion I’ve described above:

When “git push” is not told what refspecs to push, it pushes all matching branches to the current remote. For some workflows this default is not useful, and surprises new users. Some have even found that this default behaviour is too easy to trigger by accident with unwanted consequences.

Personally, I don’t actually use this option, since I use git on so many different systems it would be more confusing to have different settings for push.default on some of them.  However, I hope it’s useful for some people, and it’s a shame that this behaviour couldn’t reasonably be made the default at this stage.

Update: Thanks to David Ongaro, who points out below that since git 1.7.4.2, the recommended value for the push.default option is upstream rather than tracking, although tracking can still be used as a deprecated synonym. The commit message that describes that change is nice, since it suggests that there is an effort underway to deprecate the term “track” in the context of setting this association with the upstream branch in a remote repository. (The totally different meanings of “track” in git branch --track and “remote-tracking branches” has long irritated me when trying to introduce git to people.)

The Guardian on your Kindle

Update: It is now possible to buy an official subscription to The Guardian and The Observer. The rest of this post is now largely of historical interest if you just want The Guardian on your Kindle, but I’ve left the rest of the content unchanged for people who are interested in how I generated my unofficial version.


If you just want a copy of today’s copy of The Guardian or The Observer for you Kindle, you can download one from this automatically generated page.  This post describes the script that generates that generates the file and the motivation for it.

Since moving to Switzerland, I’ve found that I really miss being able to get The Guardian in the morning on my way into work.  Unfortunately, reading the website on a phone (or any other device) is no substitute if you’re relying on data over the mobile phone networks - one really wants all the articles cached for fast navigation through the paper.  The solution for this should be my shiny new Kindle, but sadly subscriptions to The Guardian aren’t available in the Kindle store.  (There are many other papers available.)  Fortunately, The Guardian has an excellent API for accessing its content, and the lovely interface produced by Phil Gyford for reading the paper in a cleaner interface suggested that I could similarly generate a bare bones version of the paper for my Kindle.  I believe that this is permitted under the terms and conditions of the Guardian Open Platform, since I’m (a) including the advertisement linked to from each article, (b) linking back to the original article and (c) acknowledging that the data is supplied by that service.  If I’ve misunderstood, and in fact this is not allowed, please let me know.

To generate a book in the Kindle’s preferred format, you have to generate a .opf file describing the contents of the book, which refers to other files describing its text, images, structure, etc.  Then you can run a binary called “kindlegen” to generate a .mobi archive from those files that will work on your Kindle.  (The samples in the kindlegen archive and the Amazon Kindle Publishing Guidelines are quite sufficient to figure out how to do this.)  My script to generate the .opf and supporting files is far from elegant, but I’m very happy with the results that it produces - it’s a really lovely reading experience.  You can use the normal page forward / back buttons to go from page to page, while the left and right buttons on the five-way skip to the next article’s headline.  This means you can skip quickly through the articles that you aren’t interested in, but each article you do want to read is presented very clearly on the amazing eInk display:

There are a few articles for which the API won’t return the text, saying that rights for redistribution are not available - I’m still including the other metadata for these article and the link to the original article, so that you know what’s missing:

At the end of each article is the advertisement image that’s included - this is to comply with the requirements of the Guardian Open Platform:

You can download the generated .mobi file for today’s Guardian (or The Observer on Sunday) from this page:

A Kindle version of today’s Guardian or Observer

You can bookmark that page in your Kindle’s web browser. Then, whenever you select the bookmark and then “Reload”, then it’ll be refreshed with a link to that day’s generated edition of the newspaper for your Kindle, which you can download straight from that page.

If you’re interested in this project, or have any comments or suggestions, you can contact me by email at:

"mark" followed by a dash, then "guardian" then "kindle" then an "at" sign then longair dot net

… or leave a comment below.  The script for generating this version of The Guardian is available at github.