Bzr

From HalfgeekKB
Jump to navigation Jump to search

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].


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

See #When Github gets sticky.

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:

  1. Use git clone to clone a branch ($BRANCH) of a Github repo ($GHURL) to a temporary local git repo ($LOCALGIT).
  2. Use bzr branch to create a branch ($LOCALBZR) of the temporary local git repo.
  3. 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"

See