
Maiao Brings Stacked Code Review to the Rest of Git Hosting
Maiao brings a Gerrit-style stacked review workflow to GitHub, GitLab, Gitea, Forgejo, Bitbucket Cloud, and Cursor Origin. Here is why turning every commit into its own dependent PR or MR matters—and where the workflow still needs careful handling.
The biggest problem with pull requests is not pull requests themselves. It is the tendency to use one enormous PR as a container for an entire feature.
That makes review slower, feedback broader, and the relationship between individual changes harder to see. Maiao takes a different approach: it turns each commit in a branch into its own pull request or merge request, then links those reviews together as a stack.
The community fork at runetes/maiao was published yesterday, August 25, 2026. It continues development from adevinta/maiao, whose original maintainers are no longer at Adevinta and whose upstream repository is no longer actively maintained.
The project is not inventing stacked diffs. The useful part is making the workflow available across several hosting providers without requiring a team to move to Gerrit or adopt a separate review platform.
The core idea: review the changes in sequence
Imagine a feature split into three commits:
git commit -m "Add user authentication"
git commit -m "Add authorization middleware"
git commit -m "Add admin endpoints"With Maiao, running git review creates three dependent reviews:
- The authentication change targets
main. - The authorization change targets the first PR or MR.
- The admin endpoints change targets the second PR or MR.
Each commit becomes a reviewable unit, but the complete feature still exists as a connected chain.
That distinction matters. A conventional feature branch often presents reviewers with the accumulated diff from the branch to the default branch. Even when the commits are logically separated, the review interface can encourage people to treat the work as one large object.
A stack makes the order explicit. Reviewers can start at the base change, understand what later commits depend on, and focus on one logical change at a time.
A stack is not just a smaller pull request. It is a dependency graph for review.
That is the real value. Maiao is not merely automating PR creation; it is preserving the structure of the work between Git commits and the hosting provider's review objects.
Why this is more than a Git alias
The git review command handles several pieces of coordination that are easy to get wrong by hand:
- It creates one PR or MR per commit.
- It establishes parent-child dependencies between those reviews.
- It tracks commits with Change-IDs through the Gerrit
commit-msghook. - It supports fixups using
git commit --fixup. - It detects when earlier reviews merge and updates the remaining stack.
- It rebases the stack when upstream changes need to be incorporated.
- It identifies the hosting provider from the repository's remote URL.
That last point is especially practical. A workflow tool that works only for one forge is easy to ignore if a team maintains repositories across different platforms. Maiao supports GitHub, GitLab, Gitea, Forgejo and Codeberg, Bitbucket Cloud, and Cursor Origin in beta.
For known hosts—including github.com, gitlab.com, codeberg.org, bitbucket.org, and origin.cursor.com—provider detection happens from the remote URL. For self-hosted instances, Maiao prompts on first use and stores the selection in git config maiao.provider.
This is the kind of detail that determines whether a tool survives contact with real repositories. The workflow should not begin with a configuration scavenger hunt.
The provider support is useful, but not symmetrical
The supported providers do not all expose the same capabilities. Maiao smooths over some differences, but it does not make the platforms identical.
GitHub supports pull requests, API-based draft or work-in-progress state, and native stacks through explicit registration. GitLab supports merge requests, uses a title prefix for drafts, and can auto-detect stacks from the target branch, up to 20 merge requests. Gitea and Forgejo/Codeberg support pull requests and use a WIP: title prefix, but do not have native stacks. Bitbucket Cloud supports pull requests, but does not support the draft or work-in-progress state through Maiao. Cursor Origin is marked beta and supports API-based draft state plus a parentPullNumber relationship.
Those differences are not a footnote. They define how much of the workflow is visible in the provider's own interface.
Where a platform has native stack support, Maiao can register the relationship directly. Where it does not, the tool relies on branch-based stacking and the relationships it can represent through the provider's existing review model.
That is a sensible design choice. A cross-provider tool should provide a consistent workflow without pretending that every backend has the same API or review semantics.
GitHub Stacks are treated as an enhancement, not a requirement
The GitHub integration is designed to degrade gracefully.
When two or more pull requests are pushed, Maiao probes the GitHub Stacks API. That capability check is cached for 24 hours. If the feature is available, the pull requests are registered as a native stack. On older GitHub Enterprise instances where it is unavailable, Maiao skips native registration and continues with branch-based stacking.
This behavior can be controlled with maiao.useNativeStack:
git config maiao.useNativeStack auto
git config maiao.useNativeStack true
git config maiao.useNativeStack falseThe default is auto, which uses native stacks when available and skips them otherwise. Setting it to true always attempts registration and warns when the capability is unavailable. Setting it to false disables native stack registration entirely.
I like this approach because it separates the workflow from the platform feature. Native stacks can improve the experience, but they should not become a hard dependency for creating and maintaining a stack.
That is an important principle for developer tooling: platform-specific enhancements should make the common path better, not make the basic path fragile.
Fixups are where the workflow starts paying off
Stacked review is most useful when review feedback can be applied without destroying the shape of the work.
Maiao supports the standard Git fixup flow:
git commit --fixup <sha>The exact mechanics are less interesting than the model behind them. A reviewer can comment on a specific change, the author can create a fixup for that commit, and the stack retains a clear connection to the original unit under review.
This is preferable to treating every round of feedback as an unrelated patch piled onto the end of the branch. The more a branch evolves through review, the more important it becomes to preserve intent: which commit introduced the behavior, which commit corrected it, and which later changes depend on it.
Maiao's Change-ID tracking also borrows a useful idea from Gerrit. The identifier stays associated with the logical change even as commits are amended or rebased. That gives the tool a stable way to track commits across the operations that stacked workflows require.
The result is a review process that maps more closely to how experienced engineers already try to structure changes: small logical units, ordered dependencies, and focused corrections.
The trade-off is operational complexity
Stacked diffs are not automatically better. They trade one kind of complexity for another.
A large pull request is cognitively expensive for reviewers. A stack distributes that complexity across several smaller reviews, but now the author and reviewers must understand ordering, dependencies, rebases, and merge behavior.
That means teams need conventions. A commit should represent a coherent change, not an arbitrary slice created only to make the stack longer. The order should make sense. A later commit should genuinely depend on the earlier one. If the stack becomes a sequence of unrelated changes, the structure stops helping.
There is also a social constraint: every reviewer needs to understand that a child PR or MR may not make sense in isolation. The stack is the unit of delivery, while each commit is the unit of review. Those are related, but they are not identical.
Maiao can automate the mechanics. It cannot decide whether a commit boundary is meaningful.
Automation can preserve a good change structure. It cannot create one from a tangled branch.
This is why I would not introduce Maiao by telling a team to split every feature into as many commits as possible. That produces review fragmentation, not focused review. The better rule is simpler: make each commit explain one logical step in the feature, then stack those steps when they have real dependencies.
The community-fork question matters
The repository's maintenance status should be part of the evaluation, not buried in the installation notes.
runetes/maiao is explicitly a community fork. The original maintainers are no longer at Adevinta, and the upstream repository is no longer actively maintained. The fork continues development under the runetes/maiao repository and is released under the MIT License, with details in DISCLAIMER.md.
That does not make the project unusable. It does mean teams should evaluate it like any other community-maintained developer tool, especially if it will sit in the path between local Git state and multiple hosting-provider APIs.
Before adopting it broadly, I would check the project's contribution and maintenance activity, test the workflow against the providers the team actually uses, and make sure developers understand how native and branch-based stacks differ. The documentation includes separate material for getting started and for the tool's technical details and architecture, which is the right place to dig into those questions.
The project is free and open source, but free does not mean costless. The real cost is learning the workflow and maintaining confidence that the integration behaves correctly as repositories, branches, and provider capabilities change.
Where Maiao fits
Maiao occupies an interesting middle ground.
Gerrit makes stacked review a central part of its model, but adopting Gerrit is a significant organizational and platform decision. Dedicated stacked-diff tools can provide a polished experience, but they add another service or workflow layer. Maiao instead puts the command in Git and sends the resulting reviews to the provider a team already uses.
That makes it appealing for teams that like the discipline of stacked diffs but do not want to replace GitHub, GitLab, or another forge.
It is also a good fit for developers who work across providers. The same high-level command can create and manage reviews on different platforms, while provider-specific features remain optional where available.
The strongest argument for Maiao is not that it makes pull requests disappear. It makes the relationship between commits and pull requests explicit.
That is a small conceptual change with large practical consequences. Reviewers get smaller units. Authors get a structured way to respond to feedback. Teams get a cleaner path from a sequence of local changes to a sequence of dependent reviews.
The next question is whether a team is willing to treat commit structure as part of the review design. If the answer is yes, Maiao is worth trying—not because stacked diffs are fashionable, but because they force a feature to reveal its shape before that shape gets buried inside one oversized PR.