Mar 28, 2024
13 min read

Improving Code Reviews with Storytelling

Improving Code Reviews with Storytelling

TLDR: At Doppler, we've enhanced our code reviews by weaving storytelling into git history, making reviews insightful and efficient. This approach, focusing on clear commit narratives, not only speeds up reviews but also fosters a culture of clarity, learning, and collaboration within our team.

Understanding the twists and turns in our code's journey isn't just helpful; it's a game changer. Sure, we all use git history to see what's changed, but there's so much more to it. It's like having a time machine that shows us not just the "what" but also the "how" and "why" behind each change. This isn't about making things more complicated; it's about clarifying them and helping us catch issues before they become problems.

Unveiling the Narrative Power of Git History

At Doppler, we're all about ensuring our code is as solid and secure as possible. We used to spend ages reviewing code to get it just right. But we've found a better way. By getting more innovative with how we use git history, we've turned it into our secret weapon for faster, more insightful reviews. It's like laying out our thought process on a map, making it easier for everyone to follow.

Starting out, it felt like a bit more work, rethinking how we commit our changes. But quickly, we saw the payoff. This approach helps us and our teammates understand the changes better, making our code faster to review, better quality, and more secure.

In this post, we're diving into how we shape our commit stories, why we focus on clear comments and commit messages, and the real difference this approach makes for us.

Crafting a Coherent Story: The Art of Commit Narration

One of the innovations for us has been treating our git history not just as a log but as a narrative—a story of our project’s development. It’s about making our commits work harder to tell the story of “how we got here,” which makes everyone’s life easier regarding reviews..

Setting the Stage with Rewriting Commits

Here’s how we do it: before we even think about hitting that pull request button, we take a step back and look at our commits. We ask ourselves, "How can we make this story clearer?" It starts with laying the groundwork—like setting the stage before the main act. This often means we rewrite our commits to start with the groundwork for significant changes without immediately implementing them. Such preparatory steps might include:

  • No-op refactors Small, non-functional adjustments that clean up the codebase, making subsequent changes more straightforward and less cluttered.
  • One-off fixes: Isolated corrections that address minor issues identified during the development of the feature or fix.
  • Structural groundwork: Introduction of new utilities, classes, or patterns without immediate application, setting the stage for their use in the feature or bug fix.

This approach isn’t about making more work for ourselves. It’s the opposite. It makes the next steps smoother and the whole thing easier to review because there’s a clear path from start to finish.

By organizing our commits this way, we’re making our PRs easier for others to understand and giving ourselves a chance to refine our work. Looking back over the commits, we often spot opportunities to simplify or improve the code that we might have missed the first time around.

Finding the right balance is critical. We aim for a narrative that’s rich in detail but still easy to follow. Too much information can be as confusing as too little. By focusing on clarity and relevance in each commit, we help our reviewers and ourselves navigate the development story without getting lost in the weeds.

Commit Narration Example

In the below example, we’re generating ‘workflow’ objects and we want to add a parameter to the creation request. There’s an opportunity to clean this code up a bit, so we’ll commit the changes in stages.

Let's start by cleaning up and refactoring this workflow creation into a loop.
Let's start by cleaning up and refactoring this workflow creation into a loop.
Next, we’ll make the necessary modifications to add parameters to our workflow creation.
Next, we’ll make the necessary modifications to add parameters to our workflow creation.
Finally, we’ll make the change to add the tag to our workflow objects.
Finally, we’ll make the change to add the tag to our workflow objects.

Could we have put this all in one commit? Of course! But this change narrative is much easier to understand, and if we make a mistake in our for-loop refactor, the reviewer is much more likely to identify it.

Mastering the Use of Comments and Commit Messages

Getting the balance right between comments in the code and the stories we tell through our commit messages has been transformative for us. So, what’s the right way to do it?

Code Comments: When and How to Use Them

We've all heard the saying, "Good code explains itself," but let's be honest—sometimes it's not so black and white. Here's where a well-placed comment can save the day. It's not about documenting every single line; it's about clarity when it's needed. Here's our take:

  • Clarifying Complex Logic: Even the best of us come across or write code that feels like a puzzle. Sometimes, code gets complicated, and it’s just not feasible to make it more readable for performance or other technical reasons. A comment that explains the "why" behind a piece of complex logic can be a lifesaver for the next person (which might be future you).
  • Explaining the "Why": Sometimes, the reason behind a decision isn't apparent from the code alone. That's when a comment can shed light on our rationale, especially for decisions that seem counterintuitive at first glance.

We strive to write code that speaks for itself but also know when to leave a breadcrumb trail of comments for those who come after us. It's about making our code as accessible and understandable as possible.

Commit Messages: Narrating the Development Journey

Comments explain the code and commit messages explain the change. They're our chance to tell the story of the development journey, one snapshot at a time. Here's how we approach them:

  • Conveying Intent: Each commit message is an opportunity to explain not just what changed but why. It's our way of providing context for the changes, offering a peek into our thought process.
  • Explaining the "How" and "Why": Beyond stating what changed, we dive into the how and the why of our changes. This isn't just about documenting our steps; it's about sharing our reasoning and the decisions behind our code.
  • Bridging Gaps with PR Comments: Sometimes, we want to flag things for our reviewers that don't fit neatly into code comments or commit messages. That's where pull request comments come in handy. They're perfect for highlighting considerations, temporary fixes, or future plans relevant to the review but don't belong in the codebase itself. However, consider that pull request comments are often harder to find later. They’re more like sticky notes rather than part of the story itself.

Combining insightful comments with descriptive commit messages gives us a richer narrative around our git history. This doesn't just make reviews smoother; it turns our codebase into a learning tool, encouraging best practices and fostering a culture of transparency and teamwork. It's about building a bridge between the code we write today and the understanding we'll need tomorrow.

Streamlining Reviews: The Benefits of a Narrative Approach

Adopting a narrative approach to our git history and focusing on clear, informative comments and commit messages has revolutionized how we do code reviews. It's turned what used to be a chore into a journey through the thought processes of our team members, making everything more efficient and insightful.

Commit-by-Commit Review: A Guided Journey

One of our biggest wins has been the ability to review code commit by commit. This method lets us walk through the development story in the way we ideally wanted it to unfold, understanding not just what changed but why. It’s like reading a book chapter by chapter, where each commit adds to the story. This strategy has some clear benefits:

  • Increase Review Efficiency: Breaking down the review into smaller, focused chunks makes it easier to spot issues and understand new features. It’s less overwhelming than looking at a massive list of changes all at once and helps us provide more constructive feedback.
  • Enhance Comprehension: By seeing the logic unfold step by step, we better understand the codebase and the changes being introduced. It’s like being in the developer’s shoes, seeing the problems and solutions evolve.

Refinement and Simplification

When forced to organize our thoughts and work into coherent stories, it encourages us to look critically at our code. This often leads us to refine and simplify our solutions. We're not just coding; we're curating our work, which leads to better outcomes.

If we wish to count lines of code, we should not regard them as 'lines produced' but as 'lines spent.'
Edsger Dijkstra

This quote really hits home for us. It reminds us that every line of code is an investment, and by focusing on crafting our git history, we're ensuring we spend those lines wisely.

The Educational Value

Beyond making reviews more efficient, this narrative approach has turned our git history into a valuable learning resource. New team members can dive into the history to understand the evolution of our projects, seeing first-hand how and why decisions were made. It’s an ongoing knowledge base rich with real-world solutions and reasoning.

Fostering a Culture of Quality and Collaboration

We're building a culture that values quality and collaboration by prioritizing clarity and narrative in our code and commits. Reviews have transformed from simple quality checks into team-wide learning and improvement opportunities. We’re not just catching bugs but sharing knowledge and building a collective understanding of our projects.

Navigating the Challenges: Overcoming Obstacles in Narrative Commit Histories

Embracing a narrative approach in managing our git history has been hugely beneficial but hasn't been without its hurdles. Like any good story, there are twists and challenges along the way.

Learning Curve for New Engineers

For new folks or anyone not used to manipulating git history, rewriting commits to tell a more straightforward story can seem daunting. The commands and concepts, like rebase and squash, might initially feel like a foreign language.

  • Solution: We’ve found that it can be helpful to incorporate git training sessions focused on these techniques into the onboarding process for new engineers. Pair programming sessions, where newcomers can get hands-on experience with the support of more seasoned team members, have also been invaluable. It’s all about demystifying the process and showing that it’s just another tool in our toolkit.

Balancing Clean History with Traceability

We want our git history to tell a story, but we don’t want it to become War and Peace. Finding the right level of detail can be a balancing act. Too much and we overwhelm the reader; too little and we lose the narrative.

  • Solution: Encouraging the team to find that sweet spot between detail and brevity has been vital. We’ve developed guidelines that help everyone understand what’s useful to include and what might be better left out. Grouping minor but related changes into a single commit has helped us maintain a clear narrative without sacrificing detail.

Embracing Continuous Improvement

Adopting a narrative approach is a journey, not a destination. It’s about continuous learning and improvement, both individually and as a team. Staying open to new ideas and refining our process is part of our DNA.

  • Solution: Regular retrospectives where we discuss what’s working and what’s not have been crucial. It’s a safe space where everyone can share their experiences and suggest improvements, and together, we evolve our approach.

Navigating these challenges has been a learning experience for us all. But by facing them together, we’ve not only improved our git history management but also strengthened our team. It’s been a journey of growth, and the benefits—clearer communication, better code, and a more cohesive team—are well worth the effort.

Final Thoughts: Integrating Storytelling into Your Code Review Process

As we've woven storytelling into the fabric of our code review process, we've seen firsthand how powerful it can be. It's transformed our approach, turning what could be a dry, technical task into a rich narrative journey that improves our code and deepens our team's understanding and collaboration.

A Powerful Yet Flexible Approach

This narrative method has proven itself to be incredibly potent, offering a structured yet insightful way to tackle the complexities of software development. But it's not a rigid formula; it's a flexible approach that can be adapted to fit any team's unique dynamics and needs. The key lies in recognizing the value of the story behind the code and finding the best way to share that story within your team's context.

The Value of Storytelling in Code

Storytelling in code does more than streamline reviews; it enriches our development culture, fostering a mindset focused on clarity, intentionality, and shared understanding. By encouraging engineers to see their contributions as part of a larger narrative, we've cultivated a more thoughtful and reflective approach to coding. This perspective helps elevate our work from mere lines of code to meaningful chapters in an ongoing story of innovation and improvement.

Looking Ahead

If you're considering integrating storytelling into your code review process, remember that the goal is to enhance collaboration, learning, and continuous improvement within your team. It's about making the code review process more efficient, engaging, and educational for everyone involved.

We encourage you to experiment with our approach and adapt it to meet your team's specific needs and challenges. And as you do, share your experiences and insights with the broader community. Our industry's collective wisdom and evolving practices are built on such contributions, helping us all grow and improve together.

Have any questions or want to chat about your engineering strategies with us? Send an email to chandler.mayo@doppler.com.

Enjoying this content? Stay up to date and get our latest blogs, guides, and tutorials.

Related Content

Explore More