'git-remote-bzr' is the semi-official Bazaar bridge from the Git project, once installed, it allows you to clone, fetch and push to and from Bazaar repositories as if they were Git ones:
git clone "bzr::lp:ubuntu/hello"
To enable this, simply add the 'git-remote-bzr' script anywhere in your
$PATH
:
wget https://raw.github.com/mnauw/git-remote-bzr/master/git-remote-bzr -O ~/bin/git-remote-bzr chmod +x ~/bin/git-remote-bzr
That’s it :)
Obviously you will need Bazaar installed.
At present, this "working copy"/fork adds the following features (and I would prefer it is indeed rather a "working copy" to be appropriately merged upstream):
-
eliminates a number of limitations as mentioned below
-
avoids clutter of
refs/bzr/…
by keeping these implementation details really private -
more robust and efficient fetching
See sections below or sidemarked notes for more details.
Remember to run git gc --aggressive
after cloning a repository, specially if
it’s a big one. Otherwise lots of space will be wasted.
The oldest version of Bazaar supported is 2.0. Older versions are not tested.
Bazaar’s UI can clone only branches, but a repository can contain multiple branches, and 'git-remote-bzr' can clone both.
For example, to clone a branch:
git clone bzr::bzr://bzr.savannah.gnu.org/emacs/trunk emacs-trunk
And to clone the whole repository:
git clone bzr::bzr://bzr.savannah.gnu.org/emacs emacs
The second command would clone all the branches contained in the emacs repository, however, it’s possible to specify only certain branches:
git config remote-bzr.branches 'trunk, xwindow'
Some remotes don’t support listing the branches contained in the repository, in which cases you need to manually specify the branches, and while you can specify the configuration in the clone command, you might find this easier:
git init emacs git remote add origin bzr::bzr://bzr.savannah.gnu.org/emacs git config remote-bzr.branches 'trunk, xwindow' git fetch
Limitations of the remote-helpers' framework apply. In particular, these commands don’t work:
-
git push origin :branch-to-delete
-
git push origin old:new
(it will push 'old') (patches available) -
git push --dry-run origin branch
(it will push) (patches available)
Actually, scratch the limitations above ascribed to the remote-helpers framework. They are not limitations of the framework, but are due to how the original implementation of 'git-remote-bzr' interacts with it. Using the remote-helpers framework in only a slightly different way has none of the above limitations. See the relevant section below for more details.
There are other 'git-remote-bzr' projects out there, do not confuse this one, this is the one distributed officially by the Git project:
For a comparison between these and other projects go here.
The mentioned limitations are indeed
limitations of the export
capability of
gitremote-helpers(1)
framework. However, the framework also supports a push
capability and when this
is used appropriately in the remote helper the aforementioned limitations do not apply.
In the case of export
capability, git-core will internally invoke git-fast-export
and the helper will process this data and hand over generated changesets to Bazaar.
In the case of push
capability, git informs the helper what (refs) should go where,
and the helper is free to ponder about this and take the required action, such as
to invoke git-fast-export
itself (with suitable options) and process its output
the same way as before (and over to Bazaar).
And so;
-
git push origin :branch-to-delete
will (mostly) deletebranch-to-delete
on remote (within some bzr limitations) -
git push --dry-run origin branch
will not touch the remote (or any local state, except for local helper proxy repo) -
git push origin old:new
will pushold
ontonew
in the remote
Other than removing the limitations as mentioned above, a number of issues (either so reported in issue tracking or yet unreported) have been addressed here, e.g. creating a branch if needed when pushing, not creating several bzr revision-ids for same git commit, speeding up import of branches, etc
For example, the refs/bzr/…
refs are really an implementation detail
that need not clutter up the (visible) ref space. So, in as much as they
are still relevant, these are now kept elsewhere out of sight.
More importantly, a significantly more efficient workflow is achieved using one set of shared marks files for all remotes. The practical consequence is that fetching from a newly added remote bzr repo does not require another (lengthy) complete import (as the original clone) but will only fetch additional revisions (if any). The same goes for subsequent fetching from any bzr remote; what was fetched and imported from some remote need not be imported again from another. Operating in this shared mode also ensure pushing identical revisions to several remote branches, rather than coming up with a separate revision-id for each branch a commit is pushed to.
The transition to using shared marks-files will happen mostly automatically, but for good measure it is advisable to fetch first from remotes (prior to any subsequent pushing).