Bazaar fully supports the core operations of the centralized mode by using so-called bound branches. The checkout and update operations are implemented using dedicated commands in the context of bound branches. The commit operation works differently when used with bound branches, in order to enforce the requirements of the centralized mode.
In addition to the classic core operations of the centralized mode, Bazaar provides additional operations to easily turn the centralized mode on or off, which opens interesting new ways of combining centralized and decentralized elements in a workflow.
Bound branches are internally the same as regular branches; they differ only in a few configuration values—the bound
flag is set to true
, and bound_location
is set to the URL of another branch. We will refer to the bound location as the
master branch.
In most respects, a bound branch behaves just like any regular branch. However, operations that add revisions to a bound branch behave differently—all the revisions are first added in the master branch, and only if that succeeds, the operation is applied to the bound branch.
For example, the commit operation succeeds only if it can be applied to the master branch. Similarly, the push and pull operations on a bound branch will attempt to push and pull the missing revisions in the master branch first.
Since being bound to another branch is simply a matter of configuration, branches can be reconfigured at any time to be bound or unbound.
The checkout operation creates a bound branch with a working tree. This configuration is called a checkout in Bazaar. This is essentially the same as creating a regular branch and then binding it to the source branch it was created from. The term checkout is also used as a verb to indicate the act of creating a checkout from another branch.
Let's first create a shared repository to store our sample branches:
$ mkdir -p /sandbox $ bzr init-repository /sandbox/central Shared repository with trees (format: 2a) Location: shared repository: /sandbox/central $ cd /sandbox/central
You can check out from another branch by using the bzr checkout
command and by specifying the URL of the source branch. Optionally, you can specify the target directory where you want to create the new checkout. For example:
$ bzr checkout http://bazaar.launchpad.net/~bzrbook/bzrbook-examples/hello-start trunk
You can confirm that the branch configuration is a checkout by using the bzr info
command:
$ bzr info trunk Repository checkout (format: 2a) Location: repository checkout root: trunk checkout of branch: http://bazaar.launchpad.net/~bzrbook/bzrbook-examples/hello-start/ shared repository: .
The first line of the output is the branch configuration, in this case a "Repository checkout", because we created the checkout inside a shared repository. Outside a shared repository, the configuration is called simply "Checkout". For example:
$ bzr checkout trunk /tmp/checkout-tmp $ cd /tmp/checkout-tmp/ $ bzr info Checkout (format: 2a) Location: checkout root: . checkout of branch: /sandbox/central/trunk
In both the cases the checkout of branch
line indicates the master branch that this one is bound to.
Performing a checkout using Bazaar Explorer can be a bit confusing, because the buttons and menu options labeled Checkout... use a special mode of the checkout operation called "lightweight checkouts". Lightweight checkouts are very different from branches; we will explain them in Chapter 8, Using the Advanced Features of Bazaar.
Use the Branch view to checkout from a branch:
In the From: textbox, enter the URL of the source branch. In the To: textbox, you can either type the path to the directory where you want to create the checkout, or click on the Browse button and navigate to it. Make sure to select the Bind new branch to parent location box, in order to make the new branch bound to the source branch:
After you click on OK, the Status box will show the bzr
command that was executed and its output. For example:
Run command: bzr branch https://code.launchpad.net/~bzrbook/bzrbook-examples/hello-start /sandbox/central/trunk2 --bind --use-existing-dir Branched 6 revisions. New branch bound to https://code.launchpad.net/~bzrbook/bzrbook-examples/hello-start
Click on Close to return to the status view, which shows the content of the working tree exactly in the same way as in the case of regular branches.
The Status view does not indicate whether the branch of the current working tree is bound or not. On the other hand, the repository view uses different icons to distinguish these configurations:
Bound branches are shown with a computer icon, and unbound branches are shown with a folder icon.
The purpose of the update operation is to bring a bound branch up-to-date with its master branch. If there are pending changes in the working tree, they will be reapplied after the branch is updated. If the incoming changes conflict with the pending changes in the working tree, the operation may result in conflicts.
As collaborators work independently in parallel, it is very common and normal that a bound branch is out of date due to the commits done by other collaborators. In such a state, the commit operation would fail, and the bound branch must be updated first before retrying to commit.
Similar to a pull operation, the update operation copies the missing revision data to the repository and updates the branch data to be the same as the master branch.
If there are pending changes in the working tree at the time of performing the update, they are first set aside and reapplied at the end. During this step conflicts may happen, the same way as during a merge operation.
You can bring a bound branch up-to-date with its master branch by using the
bzr update
command. To demonstrate this, let's first create another checkout based upon an older revision:
$ cd /sandbox/central $ bzr checkout trunk -rlast:3 last-3 $ cd last-3 $ bzr missing --line ../trunk You are missing 2 revisions: 6: Janos Gyerik 2013-03-03 updated readme 5: Janos Gyerik 2013-03-03 added python and bash impl
That is, our new checkout is two revisions behind the trunk. Let's bring it up to date:
$ bzr update +N hello.py +N hello.sh M README.md All changes applied successfully. Updated to revision 6 of branch /sandbox/central/trunk
The missing revisions are added to the branch, and the necessary changes are applied to the working tree, resulting in identical branches:
$ bzr missing ../trunk Branches are up to date.
To bring a checkout up-to-date with its master, you can either click on the large Update button in the toolbar, or navigate to Bazaar | Collaborate | Update Working Tree.... in the menu.
The user interface does not take any parameters; the operation is applied immediately and its result is shown similar to the command-line interface.
An interesting alternative use of the update operation is to reset the working tree to a past state, by specifying a revision by using the -r
or --revision
options. For example:
$ cd /sandbox/central/trunk $ bzr update -r3 -D .bzrignore M README.md -D hello.py -D hello.sh All changes applied successfully. Updated to revision 3 of branch http://bazaar.launchpad.net/~bzrbook/bzrbook-examples/hello-start
This may seem similar to using bzr revert
, but in fact it is very different. The changes applied to the working tree will not be considered pending changes. Instead, the working tree is marked as out of date with its master, effectively preventing commit operations in this state:
$ bzr status working tree is out of date, run 'bzr update'
Another difference from the
revert
command is that we cannot specify a subset of files; the
update
command is applied to the entire working tree.
This operation works on unbound branches too. Since an unbound branch can be thought of as being its own master, the update
command without a revision
parameter simply restores it to its latest revision.
The commit operation works in the same way as it does with unbound branches, however, in keeping with the main principles of the centralized mode, Bazaar must ensure that the commit is performed in two branches—first in the master branch, followed by the bound branch.
The commit operation in the master branch succeeds only if it is at the same revision as the bound branch. Otherwise, the operation fails, and the bound branch must first be synchronized with its master branch using the update operation.
In Bazaar Explorer, the Commit view shows an additional explanation when committing in a bound branch, as a kind reminder that the operation will be performed on the master branch first, keeping the local and master branches in sync:
The centralized mode is simple and easy to work with in general, except for the update operation. The update operation can be problematic when there are too many pending changes in the working tree, and the central branch has evolved too far since the last time the bound branch was synchronized.
Fortunately, a few simple practices can greatly reduce or mitigate the potential conflicts that may arise during update operations:
3.15.219.130