Difference between revisions of "Working with Bazaar"

From Inkscape Wiki
Jump to navigation Jump to search
(update workflow to protect linearity of bzr log)
Line 103: Line 103:
* No special server is needed to publish a branch. You can push branches to anywhere, including simple FTP shares. In our scenario, Launchpad works like a central repository, but it's not required to publish everything there.
* No special server is needed to publish a branch. You can push branches to anywhere, including simple FTP shares. In our scenario, Launchpad works like a central repository, but it's not required to publish everything there.
* You create branches locally. To simulate creating a SVN-style branch on Launchpad, you need to create a local branch, push it, then bind it to the pushed location.
* You create branches locally. To simulate creating a SVN-style branch on Launchpad, you need to create a local branch, push it, then bind it to the pushed location.
* In some cases it is possible to create subrevisions. When two branches with a common parent are merged, all commits to one of them since the time they diverged will be grouped into one revision. To avoid this, when committing your work to trunk, you should merge from your branch into trunk and push the trunk, rather than merging trunk into your work and pushing your branch as the new trunk.


==Using branches==
==Using branches==

Revision as of 22:52, 28 December 2009

Bazaar concepts

It is assumed that you are familiar with the basic concepts of version control, like working copy, committing, updating, conflicts. There will be a section that explains the basic functionality soon.

  • Branch is a working copy of the project's code. Typically you use one branch per set of related changes, for example a new output extension. Once your work is finished, you merge your branch into a larger project. Initially, there is only one branch, the trunk; all other branches are its (probably indirect) descendants. To create a new branch, you have to copy an existing one.
  • Checkout is a copy of code contained in a branch that is not stored on your computer (a remote branch). Committing to a checkout will immediately apply the changes to the remote branch. Commits will not succeed if somebody else
  • When branches A and B have a common ancestor branch but each contain changes not present in the other, they have diverged. For example, when you work on an improved rectangle tool in your own branch and at the same time somebody else applies a PDF export bugfix to the trunk, your rectangle tool branch becomes diverged from the trunk.
  • Trunk is the main branch, which represents cutting-edge working code. You should start from it when doing any new development.
  • Merge is the process of reconciling changes made between two branches since they diverged. This operation is asymmetric. When you merge A into B, all changes made to A since it was branched from B are applied to B. A is not changed. When you work on some feature, you typically work in a branch, periodically merging the trunk into your branch (to sync up with the latest changes), then you merge your work into the trunk. Merging is similar to applying a patch - it only changes your working copy. To apply a merge, you need to commit the changes it introduced. Merging un-diverges branches.
  • Repository is a place where branches of a project are stored. Having a shared repository reduces the storage requirements of multiple branches of one project. Instead of O(number of branches) space, they take roughly O(size of changes).
  • Bind is the process of converting a non-diverged local branch into a checkout.
  • Push is the process of publishing an exact copy (a mirror) of your branch in some other location. The difference between pushing and checkouts is that a checked out remote branch is updated every time you commit, while a pushed remote branch is updated only when you push to it. You can only push to a branch if the mirror has not diverged from your local copy. This can happen if more than 1 person can push to the same location.
  • Pull is the process of creating a local exact copy (mirror) of a branch, in principle a reverse of pushing.

First steps

First you need to tell Bazaar your name. This will appear on all your commits. You should use your real e-mail, but you can obfuscate it if you are afraid of spam.

Obfuscated e-mail example:

$ bzr whoami "John Q. Public <john dot q dot public at-sign bigmail dot com>"

Unobfuscated e-mail example:

$ bzr whoami "John Q. Public <john.q.public@bigmail.com>"

If you have an account on launchpad and want to commit changes there, you need to specify your launchpad login:

$ bzr launchpad-login johnq

Then fetch Inkscape's trunk

$ bzr branch lp:inkscape

Using a decentralized workflow

In this case you will be working locally until you are ready to publish your changes. This is the way git works by default.

NOTE: this workflow has been updated to avoid the "other people's commits become subrevisions of your commit" problem.

Get Inkscape's code

$ bzr branch lp:inkscape myproject

Now work:

$ cd myproject
<work work work>
$ bzr commit -m "Some changes"
<more work work work>
$ bzr commit -m "More changes"
<create new file>
$ bzr add new-file.c

Now, you need to merge your changes into a local copy of the trunk. If you don't have one, do (in the directory containing myproject):

 $ bzr branch lp:inkscape trunk
 $ cd trunk

If you already have one on hand, make sure it's up to date:

 $ cd trunk
 $ bzr pull

Now that you have a local copy of the current trunk:

 $ bzr merge ../myproject
 $ bzr commit -m'added my feature'
 $ bzr push

Using a centralized (SVN-like) workflow

In this case, every commit that you make is immediately sent to the central repository. There are two ways of achieving this:

SVN-style checkout

Get the latest Inkscape code as a checkout, rather than a branch:

$ bzr checkout lp:inkscape

Now work as in SVN:

 <do work>
$ bzr commit
 <error, someone else has changed things>
$ bzr update
 <check all is okay>
$ bzr commit

If you add new files, add them to version control with bzr add file. You can recursively add all new files by writing simply bzr add in the top level directory.

Binding a BZR branch

Get Inkscape's code the regular bzr way:

$ bzr branch lp:inkscape

Then transform your banch into a checkout:

$ cd inkscape
$ bzr bind lp:inkscape

Now work as in SVN:

 <do work>
$ bzr commit
 <error, someone else has changed things>
$ bzr update
 <check all is okay>
$ bzr commit


Differences from SVN

  • Commits will fail if your checkout is not up to date, even if there would be no conflicts.
  • The revision number is an attribute of the working tree, not of individual files. It is not possible to have different portions of the working tree at different revisions.
  • bzr commit file works like svn commit file && svn update project-root. After a successful partial commit, the entire tree's revision is increased by 1.
  • No special server is needed to publish a branch. You can push branches to anywhere, including simple FTP shares. In our scenario, Launchpad works like a central repository, but it's not required to publish everything there.
  • You create branches locally. To simulate creating a SVN-style branch on Launchpad, you need to create a local branch, push it, then bind it to the pushed location.
  • In some cases it is possible to create subrevisions. When two branches with a common parent are merged, all commits to one of them since the time they diverged will be grouped into one revision. To avoid this, when committing your work to trunk, you should merge from your branch into trunk and push the trunk, rather than merging trunk into your work and pushing your branch as the new trunk.

Using branches

This will asumme this directory layout:

inkscape
 +-trunk
 |  +-doc
 |  +-share
 |  +-src
 |  +-po
 |  +-...
 +-my-branch
 +-some-other-branch

Repository setup

If you are working on several things at once, it's better to use one branch per feature. Here is how to work with branches.

  • Create a shared repository for your branches. This brings significant space savings if you have several branches, but is not mandatory: bzr init-repo --rich-root inkscape. This will create the directory inkscape, which will contain a shared repository used by all branches within it, in the rich root format. This is the format currently used by our Launchpad repository - if you choose another format, you might not be able to push your branches to Launchpad. Enter the directory just created: cd inkscape
  • Create a new branch: bzr branch lp:inkscape my-branch. This will retrieve the main branch of Inkscape and put it in the subdirectory my-branch.
  • Make changes. Commit them locally using bzr commit. Note that this doesn't touch the trunk on Launchpad; you are only committing to your local repository.
  • If somebody else modified the trunk, resync with it: bzr merge (merging will automatically use the parent branch if none is specified)

Publishing branches on Launchpad

To publish branches on Launchpad, you have to add an SSH key to your account. You can generate a key using the program ssh-keygen.

When you added a key to your account, you can now use the Launchpad integration features.

  • First you have to log in: bzr launchpad-login launchpad-username. You need to use your username, not your display name.
  • Publish your branch on Launchpad: bzr push lp:~launchpad-username/inkscape/my-branch. Of course if you're working with a different project, substitute inkscape with its Launchpad name.
  • The push location will be saved. To update the branch on Launchpad, write <ttbzr push after your commits.
  • If you want to always commit directly to the remote branch on Launchpad, write bzr bind lp:~launchpad-username/inkscape/my-branch after the initial push. This will convert your local branch into a checkout of the remote branch.

Merging branches into trunk

Way A: commit to a checkout of the trunk. This requires a trunk checkout, but for some people is more logical.

  • Navigate to a checkout of the trunk.
  • Execute bzr merge branch-url. This will modify the files to receive the changes from the specified branch but will not modify the trunk.
  • After verifying the changes (e.g. compile the program and see whether it doesn't crash on startup), execute bzr commit to apply the changes from the merge to the trunk.

Way B: merge from trunk, then push. It doesn't require a trunk checkout, but it may be less obvious what is happening.

  • Navigate to the branch you want to merge.
  • Execute bzr merge trunk-location, where trunk-location might be your local trunk checkout or lp:inkscape
  • Verify the changes, then execute bzr commit.
  • Push to trunk: bzr push lp:inkscape

Local branching

Naturally, all this also works locally. For example, when you're in the inkscape directory, you can write bzr branch trunk export-dialog to create a new branch of the trunk called export-dialog, where you'll work only on improving the export dialog. Similarly, you can merge between local branches.

Best Practicals for Inkscape Project

Registering Bugfixes

Launchpad will automatically mark a bug "Fix Available" (rather than "Fix Committed") once somebody commits using the flag --fixes, e.g. (if you fix those two bugs in one commit):

bzr commit --fixes lp:123456 --fixes lp:123457 -m 'patch description'

Then, bugs can be changed automatically from "Fix Available" to "Fix Released"

Read more: "Changing the state in Launchpad while committing in Bazaar"

External links