Not following symlinks causes weird bugs

John Arbash Meinel john at arbash-meinel.com
Fri Mar 9 19:29:17 GMT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Well, I just found one of the reasons we want to always fully
dereference symlinks to branches. And we need to use the dereferenced
value when searching for the repository.

On IRC I was working with 'jabrah', and it turned out they have 2 shared
repositories, one controlled, and one shared between users. I'm
paraphrasing the names, but this is the idea:

mainline/
  .bzr/repository
  stable
  dev

users/
  .bzr/repository
  user1
  user2
  stable => ../mainline/stable
  dev => ../mainline/dev

So basically, on the 'users' directories, they have a symlink over to
the main repository.

The idea is that users could do a checkout of "users/mainline" and they
would get a readonly copy of the official mainline. (It was marked with
a different set of permissions).

However, what was happening, is that when people would commit, it ended
up putting the revisions in users/.bzr/repository, rather than putting
it into mainline/.bzr/repository.

With the net effect that doing:

bzr checkout users/stable

would work, but doing

bzr checkout mainline/stable

would fail with a 'no-such-revision' error.


For now, I've changed their setup to use a BranchReference rather than
using a real symlink. But this was certainly the source of a lot of
confusion (for me, and for them).

The best I can come up with, is that once BzrDir finds out that there
*is* a bzrdir at a location, it should then change the transport over to
a realpath() version of it. And then continue to search for things like
repositories from the realpath version.

The patch would look something like:
=== modified file 'bzrlib/bzrdir.py'
- --- bzrlib/bzrdir.py    2007-03-06 12:28:18 +0000
+++ bzrlib/bzrdir.py    2007-03-09 19:28:11 +0000
@@ -569,6 +569,7 @@
         while True:
             try:
                 result = BzrDir.open_from_transport(a_transport)
+                a_transport = a_transport.make_absolute()
                 return result, urlutils.unescape(a_transport.relpath(url))
             except errors.NotBranchError, e:
                 pass

(this is in BzrDir.open_containing)

And then Transports would need to define 'make_absolute()' or maybe
'make_realpath()' or something like that.

That would give us reasonable support for 'bzr add symlink' while still
making sure we have the canonical location for a branch.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFF8bWNJdeBCYSNAAMRAhrBAJ9EEU4PFMyi+CpJdNyV4plRSbgGJgCgxU7W
/KBtZnnntdIG++0ZSBwrQck=
=XAfw
-----END PGP SIGNATURE-----



More information about the bazaar mailing list