Maiao is a command-line tool that turns each of your git commits into its own pull request. It reached the front page of Hacker News on 26 August 2026 with 99 points and 62 comments, mostly because it now works across GitHub, GitLab, Gitea, Forgejo and Bitbucket instead of GitHub alone. The idea behind it is not new. It is how Gerrit has worked for years, and the argument it started says a lot about why code review still frustrates people.
You run one command, git review, and Maiao does the rest.
What the tool actually does
Say you have three commits sitting on your branch. A normal git push plus a pull request bundles all three into one review. A reviewer opens it and sees every change at once, mixed together.
Maiao creates three pull requests instead, and points each one at the last:
PR #1 → main
PR #2 → PR #1
PR #3 → PR #2
That shape is what people mean by a stack. Each commit gets reviewed on its own, and each one only shows the change it actually made. If your first commit renames a function across forty files and your second commit fixes a real bug, the reviewer never has to dig the bug fix out from under the rename.
When PR #1 merges, Maiao rebases the rest of the stack automatically. You do not go back and repoint anything by hand.
Change-Id, and why the tool needs it
This is the part worth understanding, because it explains both how Maiao works and what people dislike about it.
Git commits do not have stable identities. A commit hash is computed from the commit's content and its parent, so the moment you rebase or amend, the hash changes. As far as git is concerned, you now have a different commit. That is fine for git, and useless for a review tool trying to remember which pull request belongs to which change.
Gerrit solved this years ago by adding a line to the commit message:
Fix timezone handling in the export job
Change-Id: I8f4c9a2e1b7d3f05a6c8e9b0d1f2a3b4c5d6e7f8
That Change-Id is generated once by a commit-msg hook and then survives everything. Rebase the commit, amend it, cherry-pick it onto a different branch, and the Change-Id stays put. Maiao borrows the same hook, then uses the ID to keep each commit tied to its pull request across every rewrite.
It also means git commit --fixup works the way you would hope. The fixup lands on the right commit, the right pull request updates, and the stack below it stays where it is.
Not everyone likes this. In the Hacker News thread, nh2 argued that injecting metadata into commit messages is friction you should not have to accept. The alternative offered was Reviewable.io, which works with ordinary git branches and no commit rewriting. It is a fair objection. The Change-Id is a permanent marker in your project's history, added to serve a tool.
Where it runs
Support is uneven, and the README is honest about it:
| Forge | Status |
|---|---|
| GitHub | Full, including GitHub's own native stacks API |
| GitLab | Stacks auto-detected, capped at 20 merge requests |
| Gitea, Forgejo, Codeberg | Works, with WIP-prefix support |
| Bitbucket Cloud | Supported |
Known hosts are detected automatically. Self-hosted instances need configuring. On older GitHub Enterprise versions the native stacks feature is skipped silently, and you fall back to plain branch-based stacking, which still works.
The tool is written in Go and released under the MIT licence.
Why it matters
Review quality falls off a cliff as diffs get bigger. Anyone who has been sent a two thousand line pull request knows what happens next: the reviewer skims it, approves it, and hopes. Splitting that into six reviewable pieces is a real fix, not a stylistic preference.
There is a second benefit that came up repeatedly in the thread, and it is the one Gerrit users miss most when they leave. mtlynch pointed out that Gerrit shows you what changed since your last review by default. On GitHub you have to edit the URL by hand to get the same incremental view. When a pull request goes through five rounds of feedback, that difference decides whether round five takes two minutes or twenty.
Maiao does not fix GitHub's review interface. What it fixes is the size of the thing you are asked to review.
The disagreement
The thread did not settle into agreement, and the split is worth reading before you adopt anything.
On the supporting side, steveklabnik described one review per commit as simply standard practice in the stacked-diffs world. verall argued the model only really proves itself on teams of ten to twenty active committers, where review throughput becomes the bottleneck. jdub made the case that features which mix a refactor, a migration and a dependency bump are exactly the ones that need to be split apart.
The objections were just as direct. chrisweekly argued that forcing commits to equal pull requests puts unfair pressure on how you commit, and that a substantial feature might reasonably contain a dozen commits that belong together. NamlchakKhandro was blunter, calling one PR per commit "crazy town". synergy20 asked the practical question underneath all of it: why bother, when a normal GitHub or Gitea pull request already gets the job done?
Even supporters conceded a weakness. shubhamjain praised Gerrit's review model and said in the same breath that its user experience is terrible, which is roughly why most teams never tried it.
There was also a workflow objection. tclancy asked whether this purity depends on force-pushing amended commits every time you forget something. adastra22 answered that force-pushing only happens before a change lands on main. After that, fixes are ordinary new commits like anywhere else.
Why the project moved to a new home
Maiao was built at Adevinta, the classifieds group behind sites like Marktplaats and Subito. In 2024 Adevinta was taken private by a consortium led by Permira and Blackstone. Maintainers left, and the original repository went quiet.
The version people are using now is a community fork under the Runetes organisation. joaoqalves, a maintainer and former Adevinta engineer, explained the move in the thread and made two design points worth repeating. Maiao deliberately adds almost no new commands, so there is no maiao new stack to learn. And you can adopt it alone, without your team switching to anything.
The thread also confirmed that Maiao predates GitHub's own stacked pull requests, which entered public preview on 30 July 2026. Rather than compete with it, Maiao now uses the native API where it exists and falls back to branches where it does not.
What happens next
GitHub's native stacked pull requests are still in preview, and how good they get will decide how much of Maiao's job remains. If GitHub eventually shows incremental diffs between review rounds, the strongest argument for the Gerrit model loses much of its force on that platform.
The multi-forge angle is harder to copy. GitLab, Gitea, Codeberg and Bitbucket users have no native stacking coming, so a tool that treats them all the same has room to stay useful.
Whether a community fork holds together after its corporate sponsor walks away is the open question. That is not a technical problem, and no amount of Go code answers it.
The point underneath all of this
Strip away the tooling argument and one belief is left standing: a diff you can read in a single sitting gets reviewed properly, and a diff you cannot read gets waved through. Stacked pull requests are one way of enforcing that. Smaller commits are another. Reading the diff carefully is the part no tool does for you.
That belief is not specific to code. Anyone comparing two versions of a contract, a spreadsheet or an exported report runs into the same wall. That is why our text comparison tool highlights changes line by line, instead of handing you two documents and wishing you luck. The format changes. The problem does not.
Frequently Asked Questions
What is Maiao?
Maiao is an open-source command-line tool that creates one pull request per git commit and stacks them in order, so each change is reviewed on its own. It is written in Go, licensed under MIT, and maintained as a community fork by the Runetes organisation.
What is Gerrit-style code review?
Gerrit-style review means one commit equals one review. Instead of bundling many commits into a single pull request, each commit is proposed, reviewed and approved separately. Gerrit, originally built at Google for the Android project, popularised the model.
What is a Change-Id in git?
A Change-Id is a unique identifier added to a commit message by a commit-msg hook. Because a commit's hash changes whenever you rebase or amend it, review tools need something stable to track the change by. The Change-Id survives every rewrite, so the tool always knows which review a commit belongs to.
Does Maiao work with GitLab and Gitea?
Yes. It supports GitHub, GitLab, Gitea, Forgejo and Codeberg, and Bitbucket Cloud. GitLab stacks are auto-detected up to twenty merge requests. Known hosts are recognised automatically, while self-hosted instances need to be configured.
How is Maiao different from GitHub's stacked pull requests?
GitHub's own stacked pull requests entered public preview on 30 July 2026 and only work on GitHub. Maiao is older, works across several forges, and uses GitHub's native API where it is available. It also tracks commits by Change-Id, which GitHub's feature does not do.
Do I need my whole team to use it?
No. According to maintainer joaoqalves, Maiao is designed for individual adoption. It uses ordinary git commit and adds almost no new commands, so you can use it while colleagues carry on as before.
Why do some developers dislike this workflow?
Two objections come up most. Requiring one pull request per commit puts pressure on how you structure commits, and a large feature may contain commits that only make sense together. The second is that Change-Id injects tool-specific metadata into your project's permanent history.
Sources
- runetes/maiao — project repository, README and documentation
- Hacker News discussion, 26 August 2026 — 99 points, 62 comments