We want to set up a central repository, where several people contribute to a project and backups are easy, but allow complete local development when one is off-line. These are notes that help me remember how/what to do.
Links to sources and precompiled binaries are available from the Bazaar-NG site. As of today (2006-05-17) I find no binaries of the current version (0.8.2) for Debian. Thus, download the tar.gz, and uncompress, and do as root:
python2.4 setup.py install
If you only want to install for your user do:
python2.4 setup.py install --home /home/myuser
You'll also probably want to install the plugins bzrtools and bzrk (available also as deb packages or obtained via bzr branch or from sources), as well as difftools, show-paths and gannotate.
For the current bzr you can obtain the bzrtools source, the bzrk sources, difftools sources. (For instance, issuing the command "wget -nd http://people.ubuntu.com/~jbailey/snapshot/bzr/bzrtools_0.8" will leave the tar.gz in the current directory).
To get show-paths and gannotate:
bzr branch http://bzr.onembedding.com/bzr.win/plugins/show_paths/ bzr branch http://panoramicfeedback.com/opensource/bzr/gannotate/
To get latest difftools do:
bzr branch http://mysite.verizon.net/sward.dev/projects/bzr_difftools/
After decompressing or branching, move the directories (e.g., bzrtools) to ~/.bazaar/plugins or install system wide (python2.4 setup.py install). For those plugins that do not have a setup.py, just copy (i.e., do "cp -a") the directory under ~/.bazaar/plugins (for you user) or /usr/lib/python2.4/site-packages/bzrlib/plugins/ (system wide).
If using Debian GNU/Linux you will probably need to do "apt-get install python2.4-paramiko python2.4-cairo python2.4-crypto python2.4-gtk2 python2.4-numeric". (Some of these are needed not for bzr itself but for the plugins).
(Most of this based on an email from Robert Collins on 2006-05-05 answering my questions to the bazaar email list).
We assume we have some code in a "central repository" in a machine remote.server, in directory /Disk2/bzr-test-repo. Several people are working on that project. All of them will have a local repository on their machines (which, among other things, will allow them to use the revision control system fully even if disconnected from remote.server).
You work on your local machine, commit those changes to your local branch and, at the end of the day, or at certain important milestones, you save those changes back to the central repository (and thus make your newly edited code available to the rest of the people in the project).
You have permissions to access this machine and directory via ssh. ssh and sftp server are running in remote.server and you have the corresponding clients in your local machine.
"If you perform a checkout of this branch to your local machine, bzr will understand that this is a shared branch, and let you know when other people have done edits, and allow you to reconcile them locally."
(...) commit will commit directly to [the central repository] and is multi-user safe. If another user has committed before you did, you can just do a 'bzr update' and then do the commit again."
In your local machine:
mkdir ~/.bazaar cd .bazaar echo "email = MyName <myaddress@wherever.org>" > bazaar.conf
We assume a repository with branch(es) already exists. On your machine do (based on R. Collins' email):
# Create a checkout of the shared branch $ bzr checkout sftp://myself@remote.server/Disk2/bzr-test-repo boundbranch $ # Create a branch I'm going to work on $ bzr branch boundbranch localbranch2
Edit the files with your favourite editor
Check changes:
bzr status bzr diff
Commit:
bzr commit
commit can be used also to commit only some specific file(s)
How we have changed our repository:
bzr log bzr log --verbose bzr annotate onefile
In newer versions, or with some pluggins, other diffs (xxdiff, tkdiff, mgdiff, kompare, etc) might be available.
Other info:
bzr info
The plugins gannotate and bzrk (provides viz) are very nice:
bzr gannotate FILENAME bzr viz
(Again, from R. Collins' email):
# now we do a merge and publish it in the shared branch
$ cd ../boundbranch
# pickup any new work in the shared repository
$ bzr update
# now merge the changes you did in localbranch2
$ bzr merge ../localbranch2
# and commit them (after resolving any conflicts)
$ bzr commit -m 'Merge in feature-X'.
"That last commit will commit directly to
sftp://remote.server/Disk2/bzr-test-repo and is multi-user safe. If another
user has committed before you did, you can just do a 'bzr update' and
then do the commit again."
Conflicts can arise when we merge things back to the server, if bzr can not reconcile changes made by several people. See The Independant for examples of merging. See below, under Stable and development branches: fixing the same bug and dealing with conflicts for a couple of long examples including showing diffs, etc.
What we did above was:
Create a local repository (boundbranch) that is bound to a remote one.
Create a branch from the local repository to a second local repository (localbranch2) that is no longer bound to the remote one.
Do our coding and commiting in the localbranch2
When we want to send changes back to the remote server we:
4.1. Get latest changes from the remote repository (bzr update)
4.2. Merge the changes we made and the (possible) chages anybody else made.
4.3. From boundbranch commit our changes: recall boundbranch is bound to the remove server.
Notice that some of the above operations could be carried out "by hand" and using bzr push. See email from Matthieu Moy on 2006-05-05 in the bazaar-ng list.
(This follows an answer posted by Erik B�fors on 2006-05-05 to the bazaar-ng list).
Instead of creating localbranch2, which is a branch of a local repository that is bound to the remote, we can just work on boundrepository directly. The main difference is that the commits to boundrepository will need to use bzr commit --local. Once we want to commit to the remote we just do bzr commit. (It is a good idea to do bzr update first, then bzr status and then bzr commit; the update gets the possible changes from others, the status shows what has happened and possible conflicts).
So this option uses one fewer local repository. But we must remember to use --local for each local commit. (We could also set up an alias, which is a feature available in bzr 0.8).
An extremely useful feature of using version control with bzr (and some other systems) is that, if we fix a bug in one of our "branches", we can immediately incorporate that bug fix into another branch without any need for editing lots of files. This feature is particularly useful if we have a development branch and a stable branch of the same program. A bug can be fixed in one, and the changes merged into the other. (We will use kdiff3 here for dealing with conflicts).
################################################### ########## ############# ########## Cherry-picking works ############# ########## ############# ################################################### ## create a stable branch mkdir stableA cd stableA ## create a file, and add enough stuff to it (e.g., .emacs), ## so that a few changes do not screw up diffs and related echo -e line 1\\n line 2 \\n line 3 \\n line 4 > tmp cat tmp ../.emacs > file1 bzr init bzr add file1 bzr commit -m 'initial commit of file1' cd .. ## branch to devel bzr branch stableA develA ## do something in stable branch cd stableA sed -i 's/line 1/line 1 in file 1/' file1 bzr diff bzr commit -m 'add stuff to line 1' echo 'a new first line' | cat - file1 > tmp; mv tmp file1 bzr commit -m 'add new first line' ## do something else in devel cd .. cd develA sed -i 's/line 2/line 2 in devel/' file1 bzr diff bzr commit -m 'add stuff to line 2 in file devel' sed -i 's/line 4/line 4 in devel/' file1 bzr diff bzr commit -m 'add stuff to line 4 in file devel' echo 'last line' | cat file1 - > ftmp; mv ftmp file1 bzr commit -m 'added last line in devel' ## show diffs using kdiff3 bzr diff -r1..4 file1 --using kdiff3 ## Now the development and stable branches are different ## Cherrypick last change in devel? kdiff3 file1 ../stableA/file1 bzr log cd ../stableA bzr merge -r 3..4 ../develA bzr diff bzr commit -m 'Added the merge from devel' ## try again bzr merge -r 1..2 ../develA ## Humm, a conflict ## we could solve things, and do bzr resolve. ## save as file1.solved kdiff3 file1.BASE file1.OTHER file1.THIS cp file1.solved file1 bzr resolved file1 bzr commit -m 'the conflicting change' ## how does gannotate display changes? bzr gannotate file1 ## bzr viz ## of course, viz shows a different story ## depending on where you are; it shows a branch cd ../develA bzr viz
We could do similar things if both devel and stable came from a common trunk. But notice we need a minumum similarity so that bzr can correctly identify what should be merged. Otherwise, things will fail. For example:
################################################### ########## ############# ########## Cherry-picking doesn't ############# ########## work ############# ########## ############# ################################################### mkdir trunkB cd trunkB echo -e line 1\\n line 2 \\n line 3 \\n line 4 > file1 bzr init bzr add file1 bzr commit -m 'initial commit of file1' cd .. bzr branch trunkB stableB bzr branch trunkB develB ## do something in stable branch cd stableB sed -i 's/line 1/line 1 in file 1/' file1 bzr diff bzr commit -m 'add stuff to line 1' ## do something else in develB cd .. cd develB sed -i 's/line 2/line 2 in file 1/' file1 bzr diff bzr commit -m 'add stuff to line 2 in file devel' sed -i 's/line 4/line 4 in file 1/' file1 bzr diff bzr commit -m 'add stuff to line 4 in file devel' echo 'fifth line' | cat file1 - > ftmp; mv ftmp file1 bzr commit -m 'added line 5 in devel' ## Now the development and stable branches are different ## Cherrypick last change in devel? bzr log cd ../stableB bzr merge -r 3..4 ../develB ## nope, won't work
Many projects we work on are just single-person projects that we only keep on our hard drive (e.g., a LaTeX file for a presentation). It is very handy to have revision control here.
cd ~/somedirectory bzr init bzr add *
We might want to use .brzignore file to specify files to ignore (e.g., '.so', '.pyc', etc)
If you are new to bzr, you should definitely start by working through the Quick Hacking with Bazaar (the five minute introduction to Bazaar) and then the Introduction to Bzr.
A few very helpful documents that relate to issues covered in this document:
- Shared Repository tutorial: as it says, shared repositories, including features not mentioned here.
- The Independant: among other issues, deals with merging.
- CVS Intro: specially useful if you are used to CVS.
- Bzr for SVN: centralized development like in SVN.
| Date: | 2006-05-19 (4th revision) |
|---|---|
| Author: | Ramon Diaz-Uriarte <rdiaz at ligarto dot org> |