Plan backwards, look forward

A good novelist makes every piece of the story essential to the final resolution. Each event described in the book leads up to one big finale. That’s a good narrative.

We like to see the past in that light. We like to believe everything happens for a reason, and that reason is to get things where they are right now. “It was good this guy broke up with me, because I wouldn’t be who I am now otherwise.” Like the present circumstances are superior somehow to all the alternatives that don’t exist. It was all meant to be, we like to believe.

Kanban suggests we apply this model to the future.

“The first rule of kanban is that the later process goes to the earlier process to pick up products” ~ Taichii Ohno

That is, pull model: start with the customer demand. Figure out what we must do to meet that (deploy), what is the prerequisite for that (testing), what is the prereq for that (code), and so on down a forking chain. Anything not in demand by the next step in the process is busywork. If repairing your development environment is needed to write the code effectively, then it is not yak shaving. If you’re distracted by all the code formatting options, that is the non-work that seeps in to distract us from the end goal.

This is harder than we think. It’s harder because it is not the way the real world works. The Gulf of Mexico doesn’t suck water from the Mississippi River, and the river’s tributaries don’t pull rain down from the sky. This is not how the past works either: all those “it was meant to be” warm fuzzies are a coping mechanism to help us accept the past. Causality runs forward in time. Things are the way they are because they got that way. Everything happens for a reason – usually a million reasons – and every one of those reasons existed before the result. Not after.

Yet, the first rule of Kanban is right. When we’re aiming for something, when we’re building our project’s narrative, we can set up the causalities. Plan backwards, work forwards. If we aren’t careful and deliberate, then our work will emanate from our current situation, as reality does. Water will flow down the path of least resistance. We’ll have pretty colors in our IDE and a feature that no one asked for. Conscious effort can direct our flow.

And be careful to check over and over that our destination is still where we most want to go. Check, re-aim, and proceed down the shortest path from the new-here to the new-there. Otherwise we’re back to Waterfall.

Our project history may never read like a good novel, because we should change our minds on the best ending, and we don’t go back and edit the first chapters. Yet, if we think about it that way – how can all the characters on my team be important to the final solution? – we might get somewhere faster, and be part of a story bigger than ourselves.

Looking across the lines

Looking at other cultures, finding differences, can teach us about ourselves.

One example from business: in the US we rate managers on results. Quarterly or annual metrics measure an employee’s value. In contrast, many Asian countries give managers years to build a strong market position. Recognizing the distinction between short-term and long-term results, we can stop taking for granted that obviously the best way to evaluate a person is by this year’s numbers.

In programming, we can learn from other languages and their cultures. As a Java developer, I learned from Haskell that we can get way more out of the type system if we take the time to be more specific than String or Int. The Haskell community teaches that we can do better than testing a few examples. I learned from Ruby that code can be more expressive without curly braces. Ruby teaches the importance of careful, intuitive API design; in dynamically typed languages we like to remember or guess method names. The Ruby community teaches that the important part of coding is the people, both the people who use the programs and the people who write them.

Experiencing diverse cultures can help us question what we thought we knew, and grow as people and programmers.



Git: Checkout multiple branches at the same time

With git, source code lives in a single working directory. When we switch from one branch to another, git rearranges our files for us. Usually this keeps things simple, but now and then I wish for two copies of the code.

Do you ever want to run a big fat suite of tests in one branch while working on code in another branch? I do! This requires two different versions of the code on the filesystem at the same time.

Before you go making another copy of the whole repository, consider this solution: write a version of the for-testing branch to a temporary place outside of your working directory. Run the tests over there, leaving the real local repository available for work as usual.

1. Create a temporary directory. Maybe /Users/me/somewhere
2. Go to your git repository, to the project root directory. Now run this command:

git archive branchypoo | tar –xC /Users/me/somewhere

git archive takes the whole source tree from branchypoo, tars it up, and writes the result to stdout.
tar –x extracts the files from stdin
-C means “do the extraction over in this directory.”

Now you’re clear to run tests over in /Users/me/somewhere, and your local repository is ready for real work.

Thanks to JørgenE for this trick!


The original post used three steps:

0. Commit or stash any changes you have lying around. (important!)

1. Create a temporary directory. Maybe /Users/me/some/where/else

2. Go to your git repository, to the project root directory. Now run this crazy command, and don’t forget the dot at the end:

git –work-tree=/Users/me/some/where/else checkout branch-of-interest .

–work-tree=/Users/me/some/where/else tells git to act like your working directory is in some other location.
checkout writes the specified version of the specified files into your (modified) working directory. Note that checkout behaves differently when given a filepath; if you leave that out, checkout will change your current branch and not give you all the files.
branch-of-interest is a branch name, or any commit identifier.
says “I’m done naming commits, here come some paths to files”
. chooses the current directory, including all subdirectories and so on.

The whole command means “Write all the files, as they currently exist on branch-of-interest, into this directory over here (and my staging area).” The staging-area bit is unfortunate. If there’s a way to tell checkout to skip that, I’d like to know it.

3. Fix your staging area. git status will tell you that you have a bunch of changes to be committed, and a bunch of other changes. Tell it to forget about that stuff in the staging area.

git reset

Now you’re clear to run tests over in /Users/me/some/where/else, and your local repository is ready for real work.