Bzr
Template:Unix Bazaar (invoked using the shell command bzr) is a distributed version control system "sponsored by Canonical Ltd., designed to make it easier for anyone to contribute to free and open source software projects."[1].
Contents
Cheatsheet
Help!
bzr help commandname
Initialization
init
To create a completely new, empty project dir "foo":
bzr init foo
If the directory "foo" contains a project already and just needs versioning added:
cd foo bzr init bzr add .
checkout
To check out a "checkout"/working tree (bzr terminology for a working copy) of an existing branch:
# co = checkout bzr co fooFrom [fooTo]
If there is no fooTo, the last fragment of fooFrom is used.
branch
To start an entirely new branch copied from an existing branch:
# branch = get = clone bzr branch fooFrom [fooTo]
The arguments are basically identical to those for checkout.
Unlike checkout, this is intended to create an extended history that forks from the original.
Examination
status
Version status of files:
bzr status
log
Revision log:
bzr log [files...]
diff
Compare current to last committed:
bzr diff [files...]
Compare a file between revisions 1 and 3:
bzr diff -r1..3 [files...]
info
Branch information:
bzr info
cat
Get the contents of a file (optionally from revision 3):
bzr cat [-r3] file > foo-file.out
Version ops
add
Add files to set of versioned files:
bzr add [--dry-run] [--no-recurse] [files...]
Any directories are traversed unless --no-recurse. --dry-run will list what would be added without doing the adding. If no files are given, . (current dir) is assumed.
rm
Remove files from set of versioned files:
# rm = remove = del bzr rm [--keep | --force] [files...]
By default bzr will delete the files iff they can be recovered trivially with revert. --keep removes the file from versioning but leaves the working copy. --force removes the file from versioning and the working copy even if it is nontrivial to recover.
ci
Check a revision of files into the repository:
# ci = commit = checkin bzr ci [files...] [-m message]
If files is omitted, the entire tree is used. If -m is omitted, your default editor is used to record the revision message.
uncommit
If the last commit was a mistake (and optionally the last non-mistake was revision 3):
bzr uncommit [location] [-r3]
revert
To revert files to the last committed revision (or optionally to revision 3):
bzr revert [files...] [-r3]
Files edited manually are backed up with a tail first.
Merging
merge
Merging works by attempting to apply changes that were made to another branch to the current working tree.
bzr merge ../foo.dev.branch
pull
To copy changes from another (non-divergent) branch, making this a mirror of that:
bzr pull fooFrom
up
To merge back the most recently committed code to this working copy:
# up = update bzr up
resolve
Merges, updates, and so forth result in marked conflicts. After conflicts are resolved manually:
bzr resolve [files...]
If no files are given, bzr will try to automatically figure out what has been resolved. It may or may not succeed.
Publishing
push
To copy changes from this working tree to another (non-divergent) branch:
bzr push fooTo
send
To e-mail (or optionally just create) a merge directive (an archive that contains a series of revision changes):
bzr send [-o ../foo-updates.patch]
export
Exporting produces a snapshot of the To export the current revision (or optionally revision 3) to another file or directory:
bzr export [-r3] ../fooOut [branch|subdir]
If fooOut has an extension like .tar, .tar.bz2, or .zip, the destination will be an archive file of the suggested type. Otherwise, the destination will be a directory. (Use the --format option to override.)
Install a plugin
As described elsewhere, the general rule is to find the thing on Launchpad and branch it into your local plugins, stripping the bzr- prefix and substituting _ for -.
In general
cd ~/.bazaar/plugins && bzr branch lp:bzr-example-plug example_plug
Install bzr-git
cd ~/.bazaar/plugins &&
bzr branch lp:bzr-git git
But note that dulwich must also be installed.
# If you don't have easy_install or pip yet, this installs easy_install to a user-local path
# In the case of my cygwin, it was ~/.local/bin/easy_install
wget https://bootstrap.pypa.io/ez_setup.py -O - | python - --user
easy_install dulwich==0.9.1
# or pip install dulwich==0.9.1
Using bzr with github
Feel like you're missing out on the whole forking social development thing? Like markdown a whole lot and frustrated that Launchpad doesn't use it? Here's how to share code with a zillion of your friends without converting them.
Before proceeding, ensure that you're up on your SSH keys/credentials for github.
Caveats
Hangs
Submodules
No submodules yet. You'll have to learn git for that.
The URL
Previously, a more detailed translation of the repo URL was needed, but the current version of bzr-git allows almost the same format as git itself.
Get the SSH URL of the desired repo. It looks like this:
git@github.com:someuser/somerepo.git
You need to add a branch qualifier to the end (unlike in git, in bzr a working copy corresponds to exactly one branch). Suffix the URL with ,branch=master
, replacing master with the desired branch name.
The result is
git@github.com:someuser/somerepo.git,branch=master
Internally, this URL is normalized to bzr's own form, which resembles the following:
git+ssh://git@github.com/someuser/somerepo.git,branch=master
Exists on local, new on github
If the bzr branch you want to use already exists locally, create the new repo on github and be sure "Initialize this repository with a README" is unchecked. If it doesn't exist locally and you create the repo on github with a README, follow the #Exists_on_github advice instead.
From the root of the local bzr branch, do:
bzr dpush --remember URL
using master
as the branch name.
If this worked, your content has been pushed.
Branch
Do
bzr branch URL somerepo
If the somerepo parameter is omitted, the name of the destination is the name of the git branch.
Pushing
Use dpush
where you'd normally use push
. This indicates that the push targets a non-bzr repo.
Pushing a new branch
Use dpush
but also provide a URL qualified with the new branch's name. Use --remember
to mark the URL as the new parent.
bzr --remember git@github.com:someuser/somerepo.git,branch=new-branch-name
When Github gets sticky
It seems as though Github works differently enough from normal git that some (or all) bzr-git commands do most of their job, then hang (for about 10 minutes, I estimate) before successfully completing. They usually do complete eventually, but you don't have time for this nonsense. Here are my workarounds:
dpush (to an existing or new branch)
If it's a dpush, in my experience you can get away with getting it up to the hanging point and then terminating bzr. Use the website to ensure that the changes were uploaded correctly.
Branching
This has historically worked for me without hanging, but today I'm having difficulties. Here's how to work around it with git.
export TEMP=$HOME/tmp
export PARENT=$HOME/prj
#export PARENT="`pwd`"
export BRANCH=master
export GHUSER=someuser
export GHREPO=somerepo
export GHURL="git@github.com:$GHUSER/$GHREPO.git"
export LOCALGIT="$TEMP/$GHREPO"
export LOCALBZR="$PARENT/$GHREPO"
git clone --branch "$BRANCH" "$GHURL" "$LOCALGIT" &&
bzr branch "$LOCALGIT" "$LOCALBZR" &&
(
cd "$LOCALBZR" &&
bzr pull --remember "$GHURL,branch=$BRANCH"
)
This script does a sequence of three things:
- Use
git clone
to clone a branch ($BRANCH) of a Github repo ($GHURL) to a temporary local git repo ($LOCALGIT). - Use
bzr branch
to create a branch ($LOCALBZR) of the temporary local git repo. - Use
bzr pull --remember
to update the bzr branch's configured parent ($GHURL,branch=$BRANCH
). (This also does a no-op pull. It's less complicated and error-prone than doing some sort of stream edit on branch.conf.)
At least once, the branch somehow didn't include a working tree, so I also had to run
bzr co
from inside the branch.
Weird database version conflict problem
There's a certain problem that recurs for me that may have something to do with a version upgrade of bzr-git. In this situation, committing and pushing may result in an error message about 'tdb' and may or may not still succeed.
The right way
The right way to fix this is to install python-tdb (that is, libtdb with python bindings).
The workaround
I don't know why I hadn't figured out the above immediately; it should have been the first thing I tried.
That said, the following workaround may be helpful in situations where the .bzr is too screwy to commit or push but somehow is still able to be branched.
Branch a new temporary copy of the branch, copy the old branch.conf to the new branch to fix the push/parent information, and then replace the old .bzr directory with the new one. This corrects the .bzr directory without clobbering any files that were in progress or non-versioned.
export OLDBRANCH="GEDA-Machinery"
export TEMPBRANCH="tmp-$OLDBRANCH"
tar cvf "$OLDBRANCH-pre-fix-backup.tar" "$OLDBRANCH"
bzr branch "$OLDBRANCH" "$TEMPBRANCH"
cp "$OLDBRANCH"/.bzr/branch/branch.conf "$TEMPBRANCH"/.bzr/branch/branch.conf
rsync -avz --delete "$TEMPBRANCH"/.bzr/ "$OLDBRANCH"/.bzr/
rm -rf "$TEMPBRANCH"