Potentially Useful

Writing boring posts is okay

The design of everyday programs

in: Programming Data Science tagged: Design Git

Several fellow researchers at the FAA have backgrounds in cognitive neuroscience and are new to applied research. We recently started a book club through the South Jersey chapter of the Human Factors and Ergonomics Society to learn more about human factors and user experience research. Our first reading was The Design of Everyday Things by Don Norman, and it’s already influenced how I think about design. Norman focuses on how designers can apply concepts from psychology to the design of “things”, but these lessons apply to any interaction—such as the use of the popular revision control system (RCS) Git.

Git was created to meet the needs of programmers working on the Linux operating system. Other interfaces are available for it, but it primarily exists as a collection of command-line utilities; this strongly informs its design. People typically associate design with graphical and physical interfaces (e.g. web pages and control panels), but good design helps everything. Command-line arguments and prescribed sequences of separate commands are “design decisions”, and poor decisions have made Git harder to use.

In The Design of Everyday Things, Norman stresses the importance of conceptual models. Norman defines a conceptual model as “an explanation, usually highly simplified, of how something works.” A “highly simplified” conceptual model isn’t exactly right but it’s good enough to get the job done. People don’t need to know how the accelerator pedal of a car changes the flow of air and fuel to the engine; it suffices to understand that pressing the pedal makes the engine—and therefore the car—go faster. However, bad models cause problems, and people who are new to Git are likely to have a poor conceptual model of the program.

Users who’ve switched to Git from another RCS (e.g., CVS or Subversion) are accustomed to systems that use a central repository; the repository is “home” to the code and programmers sync their work to it. In contrast, Git is designed for decentralized work; each programmer has their own full repository and merges their code with everybody else’s. While a conceptual model based on a central repository is inappropriate for Git, users without previous RCS experience are in even more trouble. Most follow a sequence of commands learned by rote with little intuition about how the system works. In the case of Git, bad mental models cause users to make mistakes that they can’t fix (see Oh Shit, Git! for common examples).

xkcd on Git: users just memorize commands
xkcd on Git: users just memorize commands

In the open source community, the solution to bad mental models is tell users that they need a better understanding of how the system works. When I shared my frustrations with experienced Git users, they recommended that I read the free online book Pro Git by Scott Chacon and Ben Straub. The book did alleviate my frustrations, but I also spent a lot of time reading about inner workings of Git that aren’t relevant to my work. It was like learning how internal combustion engines work just to find out which pedal makes a car go faster.

The key to bringing good design to command-line programs lies in understanding users’ mental models. Instead of expecting users to learn the details of how a program works, developers should focus on helping them build a simple “good enough” conceptual model. In their book, Chacon and Straub introduce excellent metaphors for several concepts in Git, but follow these with details about the system. Good introductory documentation would focus on these metaphors and save the detail for users who need it; Git’s documentation is notoriously useless for non-expert users (the Git man page generator parodies the experience of reading Git’s docs).

Developers should also understand how people learn to use their systems. Norman calls the signals that tell people how they can interact with things “signifiers”. A command-line program will necessarily rely on textual signifiers, and developers should focus on making them easy to find and understand. For example, the “git-status” command does a good job of explaining what actions users can perform on files in their working directory, but doesn’t explain what these actions mean (and this is arguably the most user friendly of Git’s commands). Git also uses many of the same commands as CVS and Subversion, but from the perspective of the user they often serve different functions in each system. We can consider a well-known command such as “checkout” to be a signifier; it’s bad design that it does something different in Git vs. Subversion.

Developers must understand that any interface they create for their program is design work, and that good design will make their program easier to use. Norman warns readers that “designers are not typical users”; developers should take note. The time users spend learning the intricacies of a program would be better spent using it.