= Bazaar Theory = This article attempts to give an in introduction to distributed VCS in order to explain [wiki:BazaarWorkflow HelenOS Bazaar workflow]. == Revision Graph == Unlike with a centralized VCS the revision history is not linear, but instead it is a directed acyclic graph. Each node in the graph represents a revision (or equivalently it represents a changeset). The nodes are connected by arrows. Exactly one node has no parents (the initial commit). Every other node has one parent (regular changeset) or two parents (merge changeset). The two parents are not equal. When you merge in Bazaar, you always merge to the current branch (we will note it as ''left parent'') from another branch (''right parent''). There is also always at least one node which has no children. Every such node is called ''head''. In a Bazaar branch there is usually just one head. If you start from the head and go against the direction of arrows, always following the left parent if there are two, until the initial commit, you will traverse the ''main branch'' of the repository (this is what {{{bzr log}}} shows you). The main branch of the central repository is called the ''mainline''. Every Bazaar branch can have a different head. This also means that the main branch of ''A'' may be different from the main branch of ''B'' (although they may represent identical source trees). As long as the set of revisions in repository ''A'' is a subset of the revisions in repository ''B'', you can pull from ''B'' to ''A''. If the revisions ''A'' form a superset of revisions in ''B'', you can push from ''A'' to ''B''. As long as ''A'' and ''B'' have some common ancestor, you can merge from one to another or vice versa. == Pushing and Pulling == Generally speaking, the effect of a push from ''A'' to ''B'' (or pull from ''B'' to ''A'', which is the same) is to introduce into ''B'' all changesets from ''A'' which are not already there. In Bazaar this can only be done if the resulting repository contains only one head (such as when ''A'' contains a merge changeset has the head of ''B'' as one of its parents). The push or pull operation in Bazaar, however, has one more effect. ''B'' will get a new head... the head of ''A''. This is the reason why you must not push from a (diverged) feature branch to the main repository. The main repository would inherit your repository's head and your feature branch would become the mainline (and the history of your branch will become the history of the mainline), which is very bad. == Merging == In a general distributed VCS a merge changeset consists of the references to its two parents and, possibly, a patch that resolves merge conflicts. A merge operation consists of creating the merge changeset. In Bazaar, however, a repository can only have one head. This means you cannot get to the situation you would expect before merging (two heads). Thus, the merge operation in Bazaar works with the current repository as the left argument and another repository as the right argument. It actually consists of two operations: * pulling necessary changesets from the other repository and * creating a merge changeset with the current head as the left parent and the head of the other repository as the right parent. After this Bazaar will let you resolve possible conflicts and commit the merge changeset. We end up with a valid Bazaar branch that has only one head. == Merging Mainline Changes to a Feature Branch == This is easy since you have direct access to your repository. You simply go there and run {{{bzr merge}}} with the main repository as the argument. == Merging a Feature Branch into the Mainline == Since it is not possible to merge directly to the central repository ''M'', we must do the following in order to merge our private branch in ''A'': First create a clone ''M,,C,,'' of ''M'' with {{{bzr branch}}}. Then merge ''A'' into ''M,,C,,''. This means we take the mainline in ''M,,C,,'' as the left parent and the feature branch in ''A'' as the right parent. In the end the main branch in ''M,,C,,'' will be a superset of the main branch in ''M'' (the mainline). Now we are free to push from ''M,,C,,'' to ''M''.