Traceback when running `bzr bundle .`

Bug #120588 reported by Dato Simó
4
Affects Status Importance Assigned to Milestone
Bazaar
Fix Released
Medium
Unassigned

Bug Description

Hello. This is reproducible for me on 0.16, 0.17rc1, and today's bzr.dev:

----------------------------------8<-------------------------------------
% b init foo && cd foo && echo foo >foo && b add foo && b ci -m foo && b bundle .
added foo
added foo
Committed revision 1.
bzr: ERROR: bzrlib.errors.ReadOnlyError: A write attempt was made in a read only transaction on LockableFiles(lock, file:///tmp/foo/.bzr/repository/)

Traceback (most recent call last):
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/commands.py", line 718, in run_bzr_catch_errors
    return run_bzr(argv)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/commands.py", line 679, in run_bzr
    ret = run(*run_argv)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/commands.py", line 375, in run_argv_aliases
    return self.run(**all_cmd_args)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/bundle/commands.py", line 157, in run
    base_branch.last_revision())
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/repository.py", line 364, in fetch
    return inter.fetch(revision_id=revision_id, pb=pb)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/decorators.py", line 163, in write_locked
    self.lock_write()
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/inter.py", line 100, in lock_write
    self._double_lock(self.source.lock_read, self.target.lock_write)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/inter.py", line 63, in _double_lock
    lock_target()
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/repository.py", line 252, in lock_write
    return self.control_files.lock_write(token=token)
  File "/home/adeodato/devel/bzr/bzr.dev/bzrlib/lockable_files.py", line 253, in lock_write
    raise errors.ReadOnlyError(self)
ReadOnlyError: A write attempt was made in a read only transaction on LockableFiles(lock, file:///tmp/foo/.bzr/repository/)

bzr 0.18.0dev0 on python 2.4.4.final.0 (linux2)
arguments: ['/home/adeodato/bin/bzr', 'bundle', '.']

** please send this report to <email address hidden>
---------------------------------->8-------------------------------------

Thanks.

 affects /products/bzr

Revision history for this message
John A Meinel (jameinel) wrote :

I can confirm that the steps reproduce it. I'm marking it Medium, though some may care more.

Basically because you supply a path ('.') it is trying to pull the latest revisions into the local repository, so that it can figure out what is new. However, at one point it realizes that the target is the source, so it re-uses the object. So when it goes to fetch between 2 objects it locks the source for 'read' and the target for 'write'. However, in this case, they are the same object, and the 'lock target write' is failing.

There are a few options:

a) Lock the target for write before we lock the source for read. You can always grab a read lock if you have a write lock, but you can't get a write lock with a read lock. This has the side effect that things will be locked, and then unlocked right away when it sees you already have the data.

b) Add a special case to the 'fetch()' code so that it sees they are the same object and knows it doesn't have to do anything before it tries to lock anything.

I think we don't do (a) right now because it makes sense to say "make sure I have the source ready before we start figuring out the target". But I don't think it really matters, we can do it the other way.

It is also possible that it is a layering problem. That high up we lock the source for read, and then much later on we lock the target for writing. Also, because of decorators, it may be difficult to untangle this. It might be easiest to define an "InterRepository" for the same object, which just defines everything as no-op. The "is_compatible()" check could just say:

return source is target

Changed in bzr:
importance: Undecided → Medium
status: Unconfirmed → Confirmed
Revision history for this message
John A Meinel (jameinel) wrote :

Oh, and it isn't very common to use a branch as its own target when deciding to generate a bundle, since this will always generate an empty bundle. But certainly we shouldn't generate a traceback.

We might also special case higher up in the cmd_bundle code, so that it recognizes when source is target, and doesn't try to fetch.

The standard command usage to not use a remote branch is:

bzr bundle -r X..Y > mybundle

AFAIK, using 2 revnos means it won't try to access the other branch.

Revision history for this message
Aaron Bentley (abentley) wrote :

The new bundle implementation doesn't have this problem.

Changed in bzr:
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.