The Problem: Git Rigour Fatigue
When developing a large feature, writing 'Good Commits' is hard. Good Commits follow a clean narrative: define types, add DB functions, server CRUD, client API, client UI. This allows reviewers to step through your pull request in small, scoped bites.
But real development is messy. You end up with: define types, add DB functions, WIP test code, server CRUD, client API and UI, fix DB function, fix UI bug, refactor CRUD, fix another UI bug. Latter commits overwrite earlier work, breaking the story. Maintaining this discipline over the entire lifecycle is exhausting — that's 'git rigour fatigue'.
The Solution: Jujutsu's 'Laundry Pile' Technique
Jujutsu (jj) already makes it easier to hop around commits and iterate quickly. Commands like jj absorb and jj squash -i help, but they have downsides: absorb assigns changes based on which previous commit most recently touched those files, which sometimes doesn't match the intended owner; squash can lead to merge conflict hell if boundaries aren't clean.
Here's a better approach, demonstrated by the author: create your ideal commit history first, then fill it with changes by sorting a messy 'everything commit' at the end.
Step-by-Step Example
Visualize commits as colored boxes: red for type definitions, blue for UI, etc. Initially, your work is a mess — red and blue mixed, red touched in multiple places.
- Create empty, ideal commits using
jj new:
This creates a chain of empty commits with your desired structure.jj new -B messy-first -m 'red' jj new -A red -m 'blue' # ... continue for each logical commit
-
Squash all real work into one 'everything' commit:
jj squash --from messy-first..messy-last --into messy-firstNow one commit contains all changes.
-
Sort changes into the right commits using
jj squash -i:jj squash -i --from messy-first --into redThis opens an interactive hunk picker. Select only the red changes to move them into the 'red' commit. Repeat for blue, etc.
-
Result: The 'everything' commit becomes empty, and each ideal commit contains only its intended changes. No conflicts because the final state of the everything commit is guaranteed conflict-free.
Why This Is Better Than Alternatives
- Compared to
jj split: With split, if you miss a hunk that should have been in 'red', you have to split again and squash. This technique lets you sort the easiest hunks first without worrying about sequencing. - Compared to
jj squash -ias you go: Creating a new 'fix red and green' commit and interactively squashing it might break your 'blue' commit if it touches affected files. Doing it all at the end avoids that because the everything commit is the final, conflict-free state.
Downsides
- No guarantee that every intermediate commit compiles. If your team requires every commit to be buildable, this workflow may not suit you.
- The author hasn't named the technique — 'Doing Commits Like A Big Pile Of Laundry' is a candidate.
Practical Advice
For large features, this workflow is far easier than maintaining strict git rigour throughout development. It allows you to make improvised commits with temp debugging state and tidy up in one sweep at the end. Give it a try on your next feature branch.


