Defeating Git Rigour Fatigue with Jujutsu

For many developers, the ideal pull request is a curated narrative: a sequence of logical, atomic commits that guide a reviewer through the implementation—starting with type definitions, moving to database functions, and ending with the UI. In practice, however, maintaining this "rigour" during the heat of development is exhausting.

Most of us fall into a pattern of "mayhem commits": a mix of feature work, bug fixes, and refactors all piled into a few messy changesets. While tools like git rebase -i or jj absorb exist to clean this up, they often introduce their own friction, such as merge conflicts or imprecise change assignments. This is known as "git rigour fatigue"—the mental tax of trying to keep a clean history while simultaneously solving a complex technical problem.

The "Big Pile of Laundry" Workflow

To combat this fatigue, a more relaxed approach can be adopted using Jujutsu (jj), a version control system that treats the working copy as a first-class commit. Instead of trying to maintain a perfect history during development, this workflow suggests embracing the mess and tidying it up in one sweep at the end.

The Process

  1. Embrace the Mayhem: Develop your feature normally. Create improvised commits, include temporary debugging state, and don't worry about where specific changes land. You'll likely end up with a series of messy, overlapping commits.
  2. Define the Ideal State: Once the feature is complete, create the "skeleton" of your ideal history. Use jj new to create empty commits with the descriptive titles you wish you had (e.g., "define types", "add DB functions", "server CRUD").
  3. Consolidate the Mess: Squash all your actual development commits into a single "everything commit."
  4. Distribute the Changes: Use jj squash -i to interactively move changes from the "everything commit" into your idealized skeleton commits. You pick out the "red" changes (types) and move them to the types commit, then the "blue" changes (UI) to the UI commit, and so on.

By the end of the process, the "everything commit" is empty, and your history is perfectly structured for the reviewer.

Why This Beats Traditional Methods

Compared to jj split or standard interactive rebasing, this "laundry" method offers several advantages:

  • Reduced Conflict Risk: Because you are moving changes from a final, stable state into a new history, you avoid the intermediate merge conflicts that often plague jj squash -i when used iteratively during development.
  • Lower Cognitive Load: You don't have to decide which commit a change belongs to while you are in the flow of coding. You only perform the "sorting" task once, at the end.
  • Flexibility: It is easier to sort the simplest hunks first without worrying about how it affects the sequencing of the rest of the history.

Trade-offs and Counterpoints

As with any workflow, this approach is not without its drawbacks. A primary concern is that intermediate commits may not compile. If your team requires every single commit in a PR to pass CI and be buildable, this method may be a dealbreaker, as you are sorting by logical category rather than chronological dependency.

Community discussions around this topic highlight a broader debate on the value of "Good Commits."

The Case for the "Clean History"

"Jujutsu's approach to treating the working copy as a commit solves so many common friction points with Git rebase workflows." — @danborn26

For these users, the ability to treat the VCS as a tool for storytelling makes the review process significantly more efficient.

The Case for the "Squash and Merge"

Conversely, some argue that the effort spent crafting a perfect history is wasted if the team simply squashes the entire PR into one commit upon merging.

"I have finally embraced squashing PRs and realized I wasted my youth trying to write Good Commits." — @drdrey

Others point out that a perfectly clean history can actually be less useful for debugging, as it strips away the evolutionary context of how a design was reached.

Final Thoughts

Whether you use Git or Jujutsu, the goal is to reduce the friction between writing code and recording its history. While some prefer the discipline of atomic commits from the start, and others prefer the total erasure of history via squashing, the "Big Pile of Laundry" approach provides a middle ground: the freedom to be messy during creation, with the power to curate the narrative afterward.

Sources