Distributed development, the Linux kernel way
Mercurial allows various WorkingPractices. In this model the following roles are involved:
- subsystem maintainer
A few central developers do little more than inspect and integrate changes from others into their repositories. They publish their repositories regularly.
Individual subsystems are handled by subsystem maintainers. They perform development on those subsystems, and act as funnels for changes from other people who are working on those subsystems. They publish their repositories as they need to, and ask the central developers to pull their changes when they think it appropriate.
The unwashed masses typically contribute their changes to subsystem maintainers, who vet them and either accept or reject them.
Most people who have changes to merge "upstream" try to base their changes off recent versions of the repositories they are merging into. This reduces the likelihood of a merge conflict. Merge conflicts may cause maintainers to decline to take changes.
Repository lifetimes and types
In this model, most repositories tend to be short-lived. A typical developer might have several categories of repository:
- A recent copy of the "authoritative" repository.
- This is a "clean" copy that is in a working state and is used as reference to see the current upstream code.
- Having this tree makes local clones extremely fast (see below about creating "work-in-progress" trees).
- A few "incoming" trees, recent copies of those repos managed by subsystem maintainers.
- These are "dirty" trees, useful to get external input and tracking other contributor's development. Interesting changes can be later merged into the "outgoing" trees.
- It is often useful to setup a cron job to pull these trees regularly.
- Several ephemeral repositories that contain work in progress.
- These are like sandboxes to do local hacking. Commits here are frequent to consolidate them and make easy undoing non successful changes. If the resulting work has success all changes will be exported to the "outgoing" trees as a full changeset.
- A number of ephemeral repositories that contain changesets that have not yet been merged into subsystem maintainer's trees. (Aren't these a sort of "outgoing" trees oriented to maintainers?????)
- A handful of "outgoing" trees.
- These hold chunks of changes to be distributed to different people. They are again "clean" trees that that will eventually make their way to upstream (subsystem maintainers) or into the "authoritative" repository when a release is done.
Because there are many repositories "in flight" at one time, this model makes RepositoryNaming important.
At each point, changes are encouraged to be "clean", i.e. to be self-contained, and not include any changesets that were false starts. This prevents the change history from being cluttered with mistakes.
This adds some load to submitters, who must throw away their change history and generate clean patches. At least in the case of the Linux kernel, people do not appear to have found this overhead to be too onerous.