David Ruttka

Engineering | Gaming | Improv | Storytelling | Music

A New Set of Lenses

| Comments

Those who know me know that I really love gaming, and in particular, game design. A desire to build new worlds and deliver the feelings of wonder that I’ve experienced through play are why I got into tech in the first place! I’m very enthusiastic about creating or remixing mechanics, defining core engagement loops, and balancing systems to force players to make choices that matter.

While I’ve constructed a few tabletop campaigns, designed some “escape” rooms for the family, started my secret (LOL) portfolio of designs, and dabbled in Unity, I have not yet channelled my enthusiasm into really “doing the thing.” I’ve recently decided that I’d get further if I put some more structure and concrete goals around my study. In the spring, I intend to take a formal game design certification course through the University of Washington. In the meantime, I’ve been doing some reading.

The Art of Game Design: A Book of Lenses

I’m very much enjoying The Art of Game Design: A Book of Lenses. The introduction alone struck me. Schell mentions working as an entertainer and as a software engineer at IBM before circling back around to game design. Given that I also pursued entertainment first and software engineering second, this certainly reminded me that it’s never too late to chase one’s dreams =)

I’ve been capturing copious notes and my own reflections in a personal OneNote, and now that I have the blog back up, I intend to play catch-up on sharing some of that very soon.

Reality is Broken

I’m also reading Reality Is Broken: Why Games Make Us Better and How They Can Change the World. This has renewed my thinking around serious games and meaningful play. I plan on making some time to look more closely at Gamers for Good, Games for Change, and MSU’s Meaningful Play.

Level Up

To round out a set of three, I’ve also got my hands on Level Up! The Guide to Great Video Game Design. I find that where the Art of Game Design is guiding the way I look at concepts and elements of my ideas, Level Up! is full of tips for more hands-on, practical execution. I’m looking forward to making more concrete use of that guidance.

Putting it all together

Everything I’m highly skilled at today, I was absolutely terrible at when I started. Please, (don’t) look at my Game of Life or Lemonade Stand from CS101! Ramping up and adapting quickly to new challenges has been a superpower, and in fact, I believe the gaming I did while growing up helped me develop it.

It’s perhaps a bit silly that I’ll spontaneously leverage this ability when it comes to ever-changing tech stacks but forget about it when it comes to what I really want to do. Maybe I’ve let myself believe that game design is too far outside the box, but no more. There’s only one way to find out how far I can go and how much I’ll really love it once I’m more seriously into the weeds. I feel that the resources above are going to help me focus my energy toward that end.

Are you a more seasoned game designer? Are there other resources or exercises you’d recommend? What are the “new player” levels and achievements to get the ball rolling? Let me know in the comments or on LinkedIn!

Are You a Grocer or an Airline?

| Comments

Cashier to aisle three

Raise your hand if you’ve played the chaotic game of choosing a grocery store checkout line. See yourself and your competition carefully assessing the number of customers, the number of items, the speed at which each item is being scanned and bagged. Revel in the memory of arriving just in time to join a line with only one customer ahead of you. Recall your despair when that customer experienced an issue that took a long time to resolve. See your rival from a much longer line get out the door before your first item is scanned. All the while, other customers keep jumping between lines, and store management has difficulty tracking pressure on the overall system.

Next in line, please

Now think about your experiences at an airport or the DMV. While it’s rare to find someone who enjoys waiting in these lines, take a moment to consider the flow of work through the system. There’s the set of people waiting, and there’s the set of people ready to serve them. When an associate finishes with one visitor, they call for the next in line. Visitors don’t need to guess or monitor which line moves more efficiently. There’s just the one, and they’ll be called when it’s their turn. If the system is moving too slowly, management can put more people at the counter without shuffling or rebalancing the queue. When the pressure ebbs, people can move back to other work, again without shuffling or rebalancing the queue.


When a frequent flier with the most elite status shows up and an airline wants to prioritize that person’s service, this causes little disruption to how work flows through the system (although it may disappoint those who are not so prioritized). Associates have been trained to call upon people from the prioritized queue first, and when it’s empty, the standard flow picks up right where it left off.

Continuous value streams

In my experience, when a product or service will ship in a continuous and iterative model, the business is best served by establishing the desired order of deliverables. Order, not priority. If the work is not high priority, then why are we doing it at all? (Thanks, Phil Japikse).

Having accomplished the ordering, the next step is to defer assigment until the last responsible moment, which is very often the moment when someone is actually available to execute it. Can you imagine being told, immediately upon arrival at the airport, which member of airline staff will check you in? What if that associate has a personal emergency and has to leave suddenly? Who serves you now, and more importantly, where do you fit into that person’s existing commitments? Instead, let teams continuously execute on the next value we wish to add to the system. Order the backlog such that the handful of “next right things” to deliver are right there on top, and let each team member pull the top item1 as soon as they’re free to take on new work.

Across multiple development teams, I’ve found a number of advantages to this model. Aside from simplifying assignment and facilitating dynamic adjustment to those “next right things,” it inherently dismantles the thinking that Person 1 always does X and Person 2 always does Y. While there’s certainly a place for subject matter expertise, the darker side of that coin manifests as knowledge silos and single points of failure. If the five top value-adds for the business are all in the domain of X, and we only have one person doing X, then our system is screaming at us: “It’s time for the team to crosstrain!” Better, in my opinion, to get ahead of that fire drill by thinking in terms of collective ownership all along the way.

What do you think? Where has this model worked for you, and in what cases does it fall apart? Let me know in the comments or LinkedIn!


  1. We’ve often said it doesn’t have to be the very first item. Maybe we allow looking three to five items down the list given a good justification. For example, someone is about to take time off and Item 3 is low hanging fruit they can easily tackle before departure. As always, put people first. The process should serve them, not the other way around.

UWP - Data Templates in Resource Dictionaries

| Comments

Lately, I’ve found myself looking into UWP development. Tonight I want to share a problem I ran into and a workaround that I found. I’ve created a repo that shows the step by step progression, and this blog post is meant to provide additional context around that.

Pre-emptive nitpickers note: for the sake of problem reduction, the code in this repo is not overly concerned with patterns, best practices, error checking, and so on

Some Background

In XAML, there’s the concept of a DataTemplate. This allows you to define what UI components or user controls are used when displaying certain objects inside of other content controls. A canonical example is a ListView.

Without Templates

By default, a ListView will just ToString() the object and put it on the screen. You can run this commit, or look at the screenshot below.

A ListView without a DataTemplate

Notice that the ListView says “DataTemplates.RedThing” and “DataTemplates.BlueThing” (i.e., the System.Type of each item) instead of any meaningful representation of the instance properties.

DataTemplate, Binding

In this commit we create a ResourceDictionary1 with a couple of DataTemplate definitions in it. We also merge that ResourceDictionary into the app resources in App.xaml, and create a ThingTemplateSelector to use one or the other based on the type of underlying Thing.

A ListView with a DataTemplate

I’m going to be very careful not to say this looks good, but it proves the technique. We can now let our designers have all the fun polishing the DataTemplate itself, and we’re good to go! Right?

What Are Tests? Baby, Don’t Hurt Me. Don’t Hurt Me. No More!

I have to say that whatever positives there might be with UWP, the unit testing story is not one of them. The vast majority of issues we’ve seen so far have boiled down to testability.

The next commit highlights one such example where our app runs run fine, but our unit test application crashes at startup. The error isn’t what I’d call helpful.

… test discovery output, a la deployment of application, etc., omitted …

A user callback threw an exception. Check the exception stack and inner exception to determine the callback that failed.

========== Run test finished: 0 run (0:00:04.9484062) ==========

If you debug the test to check the stack and inner exception, both are null. You may now flip your tables.

Update 6/30: After some discussion about this post, I realized it could be even clearer. In the original commits, the unit test was a UITestMethod that tested the template selector itself, making it seem like the problem was limited to testing UI concerns. Now, our unit test does nothing other than Assert.IsTrue(true) in a TestMethod. Let us all agree that one should always be able to Assert.IsTrue(true) without one’s unit tests crashing.

The Workaround

Of course, I neither force quit nor flipped tables in real life. I took a breath and decided to push through the pain. What I found was that our test project would not crash if I removed our equivalent of <local:ThingTemplates /> from the App.xaml.

In the final commit, you can see how our custom DataTemplateSelector takes care of instantiating the dictionary it needs itself. One might argue this is actually cleaner anyway. I’m not currently going to argue that point either way. All I’m going to say is, “Now we can put DataTemplates in a ResourceDictionary and still keep our unit tests, too!” That makes me a much happier camper.

1Note: The ResourceDictionary needs a code behind because we’re using x:Bind. This is a new alternative to Binding that lets you take advantage of static types. Leaving aside any debates on the merit of static types themselves, I feel that you might as well use ‘em if you got ‘em. I have not confirmed if the problems in the unit test project would also exist when using {Binding} and eliminating the code behind.

Templated Server Views With Hapi.js

| Comments

Today I realized I’ve overlooked a great feature of Hapi.js, so I figured I’d write a quick post about it.

What I Was Doing

For a server rendered view, I was doing this.

var jade = require('jade');
var fs = require('fs');
var template = jade.compile(fs.readFileSync(pathToTemplate));

// later on
return template(context);

This was fine for what I was doing at the time, since the rendered output was really part of a larger response, and was pretty much the only area in the system where such a thing was being done.

What I Was Doing Today

Instead of having some rendered output as part of a larger API response, I was creating a route that should actually return an HTML view. The above still works fine, but I could see a bit of friction coming in if this project has more views.

  • I would want to set the Content-Type, either through Hapi’s reply.header or reply.type. This could get repetitive.
  • The readFileSync and compile dance could get a bit repetitive or tedious.

What I Do Now

// During the server setup 
  engines: { 
    html: require('jade'),
    path: __dirname + '/templates'

// Later, in handlers
return reply.view('index', context);

Hapi takes care of reading, compiling, and applying the template as long as it’s in the configured path.

More information about what engines are supported and how to use other options can be found by reading up on Hapi’s vision plugin.

Committed to Good Commits: Atomic, Frequent Commits

| Comments

This is part of a series on good commits.

In this post, we’ll discuss atomicity and frequency. Remember that this series and the talk from which it came is a description of what has worked well for me, not a prescription of what will work well for you. It’s ok to do things differently.

Atomic Commits

By an atomic commit, I mean there’s just one reason for change included in the commit.

This Commit Is Not Atomic

Fix 4, 5, and 99

4 Adjust font sizes and colors
5 Changed the splash screen timeout from 1 sec to 5 sec
99 Implemented the new ruleset for discounts

4 and 5 are pretty small, so why not include them all in one commit? Here are a few reasons to think about.

  1. The commit message is not concise. The actual change description comes in the extended details, not the summary.
  2. None of these can be reverted without reverting the others1.
  3. None of these changes can be cherry-picked without the others2.
  4. This works against making frequent commits, which we’ll discuss shortly.

We can see some parallels with the debugging and troubleshooting concept of only turning one knob at a time. If you change three things and it gets better, you don’t know if it was one of them, a combination of two of them (which two?!), or all three working together. If all three are needed, then of course commit them as one cohesive unit. If not, consider keeping them separate3.

Why Not?

I’ve only heard two common arguments against this, and one is the same “habits” reason we’ve covered in almost every topic in the series.

The other is that the log gets much longer, and that’s certainly true. Whether this is a problem is another matter. I find that it’s often helpful to see a greater number of more granular commits in the log than to see a few gigantic ones. It’s more clear to me what changed when and why, especially since the message are more concise and specific. By the same token, it’s easier to search for a given commit.

There is one more option to keep in mind as you consider what works best for you. With some version control systems and branching strategies, you can have the best of both worlds. When the full history becomes irrelevant as a new feature reaches completion (i.e., in the future, we’ll only care that the feature was implemented, not about each step we took along the way), then you can squash the Work In Progress commits into a smaller set just before you merge them in.


If you’re making atomic commits, you’re probably also committing frequently.

It’s like undo/redo, but
– with named states
– across files
– without loss of the undo stack when the IDE or system restarts
– and you can jump back and forth multiple points at a time

It’s like saving your game right before the boss fight

I’ll usually commit each time I make forward progress toward my goal, or whenever I’m about to make a significant change across multiple files. This might mean I get one more test passing, or it might mean I’ve created something that “works” but needs to be refactored. The value in the commit is that no matter how bad I break things during the next step, there is zero effort to put things right. If I find myself down a terrible path, I just reset to HEAD, and I’m safe at home.

Depending on your branching strategy, you might even push your commits frequently so that you can get early feedback (from your peers and/or a build server). Contrast this with waiting until work is done, when feedback will often be withheld or ignored “to avoid the cost of rework”4.

So how frequently?

It depends ;) I certainly don’t think of it in terms of time. I think of it more in terms of progress versus risk. Do you have more value than you had before? Do you want to protect it as a known good state to which you can time travel later? Are you about to experiment with a wild idea or undergo a large refactoring? Consider whether there’s value in giving yourself a checkpoint, especially if your VCS supports squashing it later if you realize later that you didn’t need it.

Why not?

A lot of people worry that this will cause destabilization.

This is a very valid concern if committing means that it affects the whole team instead of just you5. If your commits only live locally until you push them to the server, or if your pushed commits will be isolated in a topic branch, then you’re only affecting yourself.

If the commits (or check-ins) are into a shared mainline, then yes, frequently adding your half-baked work in progress can indeed break builds and impact your team. However, there are ways around breaking your team and benefits to earlier integration. You will have to integrate at some point, and delaying that will only make it harder at the end. Do a check-in dance. Find out earlier what’s going to break, and it’ll be easier to correct your course before getting too far down the wrong path6.


Again, this is what has worked for me and my teams. It might not be best for everyone. It might not even be best for me…just the best I’ve found yet. Please do share the pros and cons of any alternatives that have worked well for you.


  1. To be clear, you could manually revert them piece by piece by paying careful attention to what changes went with what commit. I’m talking about a quick, automatic revert, as when using git revert.
  2. To cherry-pick or not to cherry-pick is another topic. All I’m saying here is that if you were to cherry-pick, three changes come with that commit.
  3. If you’ve already made several changes before realizing they should be separate, can look at git add -p to selective stage and commit portions of changed files instead of all of them. The danger would be that if you separate things that actually needed to be together, one of the commits might actually be unbuildable. When (if ever) that’s acceptable is another topic.
  4. Transitioning from code reviews when work is considered complete to an ongoing, collaborative discussion as soon as work begins is incredibly powerful.
  5. And your pair(s).
  6. If you are isolating work in topic branches, you’re guarding against destabilization of the mainline, but you’re opening yourself up to the pain of delayed integration. You don’t see conflicts or incompatible semantic changes until you merge. One solution is to regularly incorporate the mainline into your branch (e.g., rebasing or merging master) to see and resolve these problems earlier. Of course, this doesn’t solve the case where Topic A and Topic B are both compatible with master, but not with each other. We will talk more about these tradeoffs in a future post about branching strategies.

What You Think vs. What You Know

| Comments

Me: Have you checked the closet?
5yo: No, I know it’s not there.
Me: But have you checked the closet?
5yo: Nooooo. I know it isn’t there.
Me: I hear you, but I want to know if you’ve actually looked.
(wife comes back with the missing shirt)
Me: Was it in the closet?
Wife: Yep.

As a result, we had a good discussion about the differences between knowing and thinking. It boiled down to these points.

  1. You didn’t know. You thought. There’s a difference.
  2. Not knowing is OK. It’s just one more thing you can learn.
  3. Indeed, smart people don’t know everything. They know there’s more to learn.
  4. Smart people consider helpful suggestions.
  5. Being adamant that you know when you don’t really know can make problems harder to solve.
  6. Just because someone says they know doesn’t mean that they know. Trust, but verify.
  7. Smart people test what they think until they know.
  8. Again, always, always remember that it’s ok to be wrong.

Verbosity Ahead. You could stop reading here and be fine.

Smart Doesn’t Mean You Know Everything

My 5yo is incredibly smart, and there’s no parental bias coloring that statement =) The problem is when her confidence transitions into a need to be the smartest person in the room. She often joins an ongoing conversation with, “Well, actually, it’s (fill in the blank).” Sometimes, she’s technically correct, but is missing the point. Other times, she has drawn an incorrect conclusion, but it’s amusingly logical based on the data that she has. Then, there are the times when she’s just making noise, trying to avoid looking like a person who doesn’t know something. As the old saying goes, it’s usually better to remain silent and appear ignorant than to speak up and remove all doubt.

This isn’t just my five year old. Many professionals (not excluding myself) do this because they confuse being vocal with looking smart, and they conflate being silent with appearing confused or uninformed. Sometimes we even chime in with something that isn’t even relevant, but it’s a data point that proves I Know Thingstm!

The other danger in thinking you know everything is that you lose the appetite to learn and improve. Knowing that you can’t even know how much you don’t know keeps you reading, keeps you experimenting, and keeps you pushing for even better ways to do things. Accepting that you’ve learned all there is to learn keeps you stuck doing whatever you’re doing. You may be the #1 ranked expert at frobbing the wizbangs, while everyone else has realized that wizbangs don’t even need to be frobbed anymore.

Smart People Accept Help

Just as my 5yo wouldn’t check the closet, many professionals refuse to accept a suggestion because they are sure that it’s wrong. As time passes and it becomes the last possible thing to try, it turns out to be the solution.

Consider that your team is probably trying to be helpful, so they probably have reason to believe that the idea is worth a shot. Why not consider what they’re offering? In the worst case, you spend ten seconds opening a closet. In the best case, you have your shirt.

My discussion with a 5yo put it a little something a little like this

Remember that we’re trying to be helpful, not trying to waste your time or patronize1. Listen.

Do Not Present Guesses As Facts

We hear a lot about how interrupting a dev is the worst thing you can do. Let’s consider that there might be something worse. You could send them on a wild goose chase by presenting a guess as if it was a vetted root cause analysis.

Guess liberally, but be clear that you’re guessing. Do not present your guesses as data. – @druttka

What if we took my kid’s confident statement of knowing the shirt wasn’t there at face value? The shirt would still be “lost”. We professionals often present our own guesses as facts. I can think of many times that a bug report came with a full analysis of when it started happening, why it was happening now, and what we needed to change to fix it. After a few hours of tunnel vision2, it was discovered that everything we “knew” was wrong. The timeline was off, the root cause didn’t even exist, and the proposed change was impossible because the code to change didn’t exist either.

The tunnel vision could have been avoided, and time saved, if the briefing had included a simple, humble, “I think”. Then the ideas would have been considered as ideas instead of taken as facts.

Test Assumptions

This brings us to the fundamental truth that we should always test assumptions. We all know the old saying that goes with this one, but we often forget to put it into practice. I’ve been trying to incorporate the following ideas into my thought process.

First, I try to remember to say “I think” if I just think3. If I do have evidence or reasoning, I try to remember to say “because (evidence or reasoning).” This helps the other person take what I’m saying for what it’s worth, not as hard truth. I also ask them to confirm what I’m saying, since I could be wrong.

Second, I add a silent “I think” to what others tell me unless or until they say “because (evidence or reasoning).” Even when they present evidence or reasoning, I try to hold off on accepting it as truth until I can confirm it in the same way I’d expect them to confirm anything I told them.

Third, I’m getting more liberal with asking “How do we know that?” It works well in combination with the point above because it prompts a person to voice their evidence or reasoning. Then we can vet it together. For example, if I sit down to pair with someone who has been investigating a problem, they might say, “We know this is being called.” I will usually be the kind of person who asks how we know it’s called4. If the response is “Because we see this text on a button changing,” I will be the kind of person who asks “Is that the only thing that changes the button text?” I’m aware that this could come across as annoying, but it’s often followed by “Oh…”. The realization is not always directly related, but sending the train of thought down the right track is still a positive outcome.

I guess the tl;dr on all of this is that problems can be more easily solved if we are careful to separate what we know from what we think. All the rest would flow naturally in a healthy, functioning team.


  1. If this is not the case, you might need a new team.
  2. I’ve talked more about tunnel vision in problem solving here and here. Will covers it here.
  3. I was once given advice that “I think” is a bad thing to say. Lacks commitment, looks weak, etc. I have come to respectfully disagree.
  4. Did we log something? Set a breakpoint? Make a change and see it reflected on the next run?

If It’s Good for You, Good for You!

| Comments

tl;dr: We need to stop telling others that they’re doing it wrong just because they’re doing it differently. Different things work for different people; we should at least consider that other paths exist, even if we choose not to take them.

Y’all Be Jokin’ On Me

The other day, I saw this meme:

The instance of the tweet that I saw had about 9001 comments from both sides of the estimation debate that proved the point of the meme itself. My initial reaction was, “Yes! This observation is both humorous and valid. Often, people do indeed respond with great scepticism and dismissal when someone suggests exploring a new methodology!” The replies quickly transformed my feelings into something along the lines of “Stop arguing on Twitter about why everyone needs to do it your way!”

Different Strokes

As I said above, to me it wasn’t really about whether estimates or no estimates is the best way to do things. It was about the way people (not isolated to developers) insist that their way is the only way, and everyone else is an idiot who has never been successful with anything in their lives. It’s about how simply suggesting that an alternate path exists is treated as the incoherent babbling of a mad person.

So many are convinced that what works for them and their team is the one true way, and anyone doing something else must be converted. To such a mind, there is no need to try something else, or to even acknowledge that something else exists. Methodology, language, framework, tabs vs. spaces, and even source control1 somehow become matters of great urgency.

What if we focused instead on the value being delivered and the problems being solved? What if it’s ok to eat mashed potatoes with either a spoon or a fork, as long as the food is making it into the mouth?


There are certainly cases where a new technology, a new methodology, or a different source control solution can yield significant, objectively measurable improvements. There are certainly patterns which can wreak havoc on a system or compromise privacy and security. In such cases, of course we should share that knowledge. However, there are ways to make such sharing effective, and there are ways to ensure that no one takes you seriously.

Ways To Make A Point, Ranked, Edited For Length and To Make A Point

(1) References to case studies, production systems
(2) Side by side demo solutions, real world scenario
(3) Side by side code examples, contrived scenario
(4) Prose describing hypothetical situations

(9001) Popularity contest
(10001) Get really loud
(11001) Get really snarky
(NaN) Call the other person stupid

What If They Still Won’t Listen?!

Well, if we’re going to start a Dark Knight reference, we might as well wrap up with one. Symmetry!

Please do calmly, respectfully highlight of the pitfalls of pattern / framework / methodology X and how Y mitigates said pitfalls. If a person insists on moving forward with X, you’ve done the best you can. It is not your job to change a stubborn, irrational person into a thoughtful, logical one. If the dangers are real, then they’ll eventually be bitten by their willful ignorance, and maybe they’ll want to revisit the discussion. If not, then maybe those dragons you were seeing weren’t such a big deal after all, and you’ve avoided fighting over something irrelevant.

Admittedly, this is a bit more complex if it’s happening within your own team. In that case, if the dragons come, they’re eating you too. Even if they don’t come, there’s a weird air of conflict hanging around. This post was focused more on arguing with people you don’t work with about things that will not impact you. I might cover team dynamics in the future, or you can feel free to share thoughts on that (or anything else) in the comments section below2.


1: I’m probably definitely guilty of getting a bit evangelical about Git, but honestly, that kind of falls under the “Truly, Objectively Better” bit ;)

2: Just remember to keep the theme of this post in mind when commenting =p

Why Doesn’t Cordova Run Windows Run the 8.1 App?

| Comments

A few years ago, I did a (very intro level) talk on PhoneGap. Recently, I’ve been getting back into Cordova for serious business — wow, have we come a long way =)

One of the things that caused me a bit of friction was that cordova run windows wasn’t working how I expected. It kept trying to run the 8.0 target of the universal app instead of the 8.1 target.

I was working around this by opening the .sln in Visual Studio and explicitly running the 8.1 project. I’d prefer not to do this.

Today I finally took a minute to search for a solution, and I found what I needed to do.

By default build command produces two packages: Windows 8.0 and Windows Phone 8.1. To upgrade Windows package version from 8.0 to 8.1 the following configuration setting must be added to configuration file (config.xml). <preference name='windows-target-version' value='8.1' />

Thanks, Sergey!

A Set of Fresh Eyes

| Comments

The other day, I saw my wife looking at a recipe book and writing in a notebook. She often looks at these books when making meal plans and grocery lists, so I didn’t think much of it. Many minutes later, she was still writing. I looked closer and realized that she was copying recipes by hand. “Have you considered taking a picture and emailing it?” The look of realization spread over her face, and we had a laugh. It turns out that she had considered scanning it, but our scanner isn’t a flatbed.

It struck me as another great example of why team communication is so powerful. She had come up with a reasonable solution, but when it didn’t work out, a narrow focus on that solution caused her to overlook a working alternative. My teammates have often found me in a similar state and gotten me rolling again with a simple “Have you considered…?”1 I immediately see the light and can usually see exactly how my initial idea put me on a train of thought that made me miss it.2

Feel free to share some times you remember when a set of fresh eyes was all it took to see a better way.3


1: I’d like to think that I return the favor from time to time.

2: In addition, I usually facepalm myself.

3: Pairing can make this process continuous, but that’s for another post.

Committed to Good Commits: Work Item Association

| Comments

This is part of a series on good commits.

Ok, Mr. Anderson

Work Item Association

Another way to enhance your commits is to associate them to work items. This can help everyone on the team – present and future – understand what’s going on with the project.

What Are You Doing?

One of the most common problems I see during code reviews is that reviewers do not have a proper context for what they’re reviewing. Things devolve into something on par with copy editing with no feedback on the plot. At best, bad loops or off by one errors get caught, but there are no guarantees that the changes are covering all of the intended acceptance criteria.

What if the author could give the reviewers a pointer to something that explained what they were trying to accomplish? Something that was already on record in a shared system? Something like a work item?

How Did We Fix That?

Another great advantage of associating commits to work items is to jog memories when the ghosts of crushed bugs come back to haunt the team.

Have you ever come across a problem and thought, “This seems familiar. We fixed something like this a while ago. I just can’t remember how…”

Or, “This is a regression of what we fixed a few weeks ago, but I don’t remember exactly what we did to fix it.”

What if you could look at the old bug and know exactly which commits resolved the issue? What if you could just grep a git log for an issue number?

Test Case Generation

It can also help a test team understand what areas are at risk for regression if they know what code is changing. Put commit information on the bug when you resolve it so that they can review the changes.

Common Arguments

  1. “We don’t use issue tracking.”1 In this case, you can use the extended commit message to provide a lot of details of what your change is attempting to do.
  2. “I forgot!” This, like many things in this series, is just a matter of habit. The team can hold each other accountable, or you can find a way to enforce it via policy.
  3. “Takes too long!” Again, like many things in this series, compare it to the time spent on the change itself and to the time that will be wasted later (looking things up, discussing the intent of the code review, etc.). Seconds on hours is blue on black2.


What do you think? Is adding this extra information to the public record of your project history valuable? If not, why not? If so, what other benefits have I missed? What else can we do to make it more natural for our teams?

1: I will hold my tongue on asking, “Why the hell not?!”

2: Remember that things can be automated. My teams have used server side hooks in the past so that if the message matched, for example, ^GEM:\d+, we’d automatically associate to the Gemini issue. Think about what works best for your team.