OCTOBER 7, 2023

In software development, tools are everything. They can either empower or hinder your workflow, and one tool that frequently divides developers is Git. While Git has undoubtedly transformed version control and collaboration with its open-source, free, and distributed nature, it can also be a source of frustration. After years of wrestling with Git's intricacies and obscure features, I made the bold decision to transition away from it, a move that brought much-needed clarity to my workflow, allowing me to focus on the essence of software development: writing code and delivering value.

The Problem with Git

Git, as powerful as it is, lacks the user-friendliness that many developers desire. It's often likened to the HTTP Rest API—abstract, enigmatic, and open to myriad interpretations. Just like diverse opinions surround HTTP Rest, Git's extensive feature set often leaves developers bewildered, creating an environment ripe for collaboration chaos.

A clear sign of Git's complexity lies in the multitude of aliases, settings, and commands that one must commit to memory. Countless hours are squandered in the quest for Git documentation to decipher how to undo an operation with git reflog or correctly name branches. Tasks like creating branches, pushing changes, managing pull requests, addressing reviews, and re-pushing can become a labyrinthine ordeal. These seemingly endless steps disrupt your workflow, forcing you to think before juggling between multiple tasks simultaneously.

Git is mostly pretty “easy” to use, when you know how to use it

Git is mostly pretty “easy” to use, when you know how to use it

But perhaps the most egregious issue with Git is the time it consumes—time that should be dedicated to coding and delivering value. Its convoluted processes are a recipe for a catastrophic loss of productivity. It's not merely about the quantity of work completed, but also the quality and speed of delivery. It's the mental toll of grappling with a tool that can often feel like it's working against you.

Embrace Trunk-Based Development Period

Throughout my software development journey, I've explored a diverse array of tools and platforms, from GitLab to the occasionally perplexing Azure DevOps. Regardless of the specific tool or platform, one recurring issue became abundantly clear: Gitflow, the standard workflow, is inherently and irrefutably flawed.

Git flow description by javatpoint

Git flow description by javatpoint

While the world of version control and collaboration tools presents a variety of options, the core issue lies in how we manage branches—a workflow that fosters confusion when dealing with production hotfixes, features, releases and the intricate process of merging them.

My definitive solution to this conundrum is the adoption of the trunk-based development model. This model advocates for streamlined development through a singular main branch, complemented by downstream branches corresponding to major and minor versions. This approach offers the flexibility needed to efficiently release patches and minor features without the complications of multiple primary branches.

Simple example of trunk based development

Simple example of trunk based development

Trunk-based development simplifies the workflow by eliminating the unnecessary complexities associated with numerous primary branches. It streamlines the process, making hotfix management more efficient and ensuring a more cohesive and agile approach to software delivery.

Building Efficiently with Stacked Pull Requests

During my transformative journey, I stumbled upon the stack-based workflow while collaborating on projects within Meta. This innovative approach, coupled with the powerful tools like ghstack, completely revolutionized my code management and collaboration methodology.

A stacked pull request (PR) is a meticulously structured hierarchy of PRs that seamlessly build upon each other, creating a coherent chain. Each PR within the stack represents a distinct feature or bug fix. This approach brings order and efficiency to the development process, allowing individual developers to focus on their specific features without becoming lost in a torrent of code changes. The result? A streamlined and focused workflow with simplified code reviews, testing, and code merging processes.

An extreme way to break feature into small mergeable tasks

An extreme way to break feature into small mergeable tasks

But what does this workflow look like in practice? Before Git introduced the git rebase —update-refs flag, managing a chain of PRs was even more bewildering. However, the advent of Sapling SCM, an open-source version of Meta's internal code management system, has made it incredibly user-friendly. Sapling SCM offers a few essential features: the client CLI, the elegant Interactive Smartlog (with a VSCode extension), and the ReviewStack web tool that enhances GitHub's diff review process.

Sapling Interactive Smarlog interface on Visual Studio Code

Sapling Interactive Smarlog interface on Visual Studio Code