monotree术语含义及基于Git的项目组织方式咨询
Great question—this is a super common point of confusion when digging into large monorepo-style projects like the Linux kernel. Let’s break this down clearly, starting with what "tree" actually means in "monotree", then how to structure a project this way with Git.
What Does "Tree" Refer to in Linux’s Monotree?
First, let’s dispel the two misconceptions you and your friend debated:
It’s not about independent subfolder checkouts
While the Linux kernel has dozens of subdirectories (fs/,net/,arch/, etc.), these are not separate "trees" you can isolate and checkout on their own. The kernel’s components are deeply coupled—changes to memory management (mm/) can break file system logic, network stack code relies on core utilities, and so on. Even if you used Git’s sparse checkout orgit-subtreeto pull a single subfolder, it would be functionally useless without the rest of the kernel code.It’s not about forks of the master branch
Forks are just copies of the repository for individual/team development, but "monotree" has nothing to do with fork count. The "mono" in monotree emphasizes a single, unified code tree structure—not multiple disconnected trees across forks. Every fork is still a full copy of that single monotree.
So what is the "tree" here? It’s the single, cohesive directory tree that contains all of the project’s code within one Git repository. Greg Kroah-Hartman’s point about the kernel’s monotree is that unlike projects split across multiple repositories (e.g., microservices with separate repos for each service), every part of the kernel lives in one repo, under one root directory, sharing a single commit history, branch model, and build system.
How to Organize a Project as a Monotree with Git
If you want to structure your own project this way, follow these core principles:
Start with a single Git repository
Initialize one repo for your entire project, not multiple repos for different components. For example:git init my-monotree-project cd my-monotree-projectThen add all your subcomponents as subdirectories under the root (e.g.,
src/,docs/,tools/,core/)—no separate repos for each.Avoid splitting with submodules/subtrees (unless absolutely necessary)
Git submodules andgit-subtreeare useful for embedding external, independent projects, but a true monotree keeps all core code in the main repo. The Linux kernel rarely uses these because all its code is maintained as part of the single tree.Use a unified branch model
Maintain a single main branch (like the kernel’smainline) as the source of truth. All development happens in feature branches off this main tree, and changes are merged back into it—no separate branches for different subcomponents that live in their own repos.Build from the root
Create a single build system (Makefile, CMake, etc.) at the repo root that can compile/test the entire project. This works because all code is in the same tree, so dependencies between components are easy to define and resolve.Embrace cross-component changes
One of the biggest benefits of a monotree is that you can make changes across multiple subdirectories in a single commit. For example, if you need to update a core utility inutils/and adjust a feature inservices/that uses it, you can commit both changes together, keeping the history coherent.
Why the Linux Kernel Uses This Model
To tie back to Greg’s article: the kernel’s lack of a stable API is directly tied to its monotree structure. Since all code lives in one tree, developers can update internal APIs and adjust all dependent code in the same set of changes—no need to maintain a stable API for external repos to rely on. This allows the kernel to evolve quickly without being constrained by backward compatibility for third-party repo users.
内容的提问来源于stack exchange,提问作者Karsten

