Symlinks to repository branches don't work

Bug #48444 reported by Michael Ellerman
10
Affects Status Importance Assigned to Milestone
Bazaar
Confirmed
Medium
Unassigned
Breezy
Triaged
Low
Unassigned

Bug Description

current reproduction:

% cd ~/bzr/bzr.2.0
% ln -s ../trunk trunk
% bzr st trunk
bzr: ERROR: trunk is not in the same branch as trunk

Most other commands work.

----

If you create a branch inside a shared repository, then create a symlink to the branch from outside the repository, you can't operate on the symlink as if it's a branch. Perhaps this is unsupported, but IMHO it should work.

eg:

concordia ~$ bzr init-repo --trees test-repo
concordia ~$ bzr init test-repo/branch
concordia ~$ ln -s test-repo/branch
concordia ~$ ls -l branch
lrwxrwxrwx 1 michael michael 16 2006-06-05 11:15 branch -> test-repo/branch
concordia ~$ bzr st branch
bzr: ERROR: No repository present: u'/home/michael/branch/'

bzr.log:
opening working tree u'/home/michael/branch/'
not a branch in: u'/home/michael/' Not a branch: /home/michael/
not a branch in: u'/home/' Not a branch: /home/
not a branch in: '/' Not a branch: /
[ 9574] Mon 11:15:31.888 ERROR: No repository present: u'/home/michael/branch/'
Traceback (most recent call last):
  File "/home/michael/src/bzr/branches/mpe/bzrlib/commands.py", line 650, in run_bzr_catch_errors
    return run_bzr(argv)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/commands.py", line 612, in run_bzr
    ret = run(*run_argv)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/commands.py", line 246, in run_argv_aliases
    return self.run(**all_cmd_args)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/commands.py", line 622, in ignore_pipe
    result = func(*args, **kwargs)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/builtins.py", line 156, in run tree, file_list = tree_files(file_list)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/builtins.py", line 49, in tree_files
    return internal_tree_files(file_list, default_branch)
  File "/home/michael/src/bzr/branches/mpe/bzrlib/builtins.py", line 73, in internal_tree_files
    tree = WorkingTree.open_containing(file_list[0])[0]
  File "bzrlib/workingtree.py", line 356, in open_containing
  File "bzrlib/bzrdir.py", line 908, in open_workingtree
  File "bzrlib/workingtree.py", line 1736, in open
  File "bzrlib/workingtree.py", line 261, in __init__
  File "bzrlib/bzrdir.py", line 894, in open_branch
  File "bzrlib/branch.py", line 737, in open
  File "bzrlib/bzrdir.py", line 350, in find_repository
NoRepositoryPresent: No repository present: u'/home/michael/branch/'

Perhaps we should just be calling os.path.realpath() somewhere on the path we get from the user?

Tags: symlinks
Revision history for this message
John A Meinel (jameinel) wrote : Re: [Bug 48444] Symlinks to repository branches don't work

Michael Ellerman wrote:
> Public bug reported:
>
> If you create a branch inside a shared repository, then create a symlink
> to the branch from outside the repository, you can't operate on the
> symlink as if it's a branch. Perhaps this is unsupported, but IMHO it
> should work.
>

There is an alternate use case, which is why we currently do not support
this.

Here is the example: You have a normal standalone branch in 'branch',
and inside of it you have a symlink 'symlink', which points outside of
the branch. Let's say "branch/symlink => /etc/hosts"

cd branch
bzr status symlink

Which you call because you want to find out whether 'symlink' changed
(now it points to /etc/hosts.allow).

If you dereference the symlink, you will jump into '/etc', and then
tracking back upwards would leave you with no bzr branch.

The difficulty is that you can give a path to a branch, or to a file
inside of a branch. And you may want to dereference a symlink to a
branch, but you don't want to dereference a symlink to a file.

If you can come up with decent heuristics about when something should
work, we probably could support it. But for now, we explicitly try not
to dereference symlinks.

John
=:->

Revision history for this message
David Allouche (ddaa) wrote :

A long time ago, I tried to get that fixed. The patch stayed in my branch for a while, and was posted for merge a couple of times, but it never happened. That was before the review process was set up.

The basic idea is that symlinks should be traversed for every path step except for the final one. So we retain the ability to operate explicitly on symlink files, while being able to traverse them.

Attaching a patch, which is almost certainly hopelessly bitrotten, but illustrate the point.

Another important case, is to fail properly when a tree contains a symlink to a directory and the use tries to operate on a name below that symlink. That should work using the realname if the ultimate file is in the tree, and that should fail if it's outside the tree. I do not know if my patch handles this case.

Revision history for this message
David Allouche (ddaa) wrote : relpath-symlink.patch

Traverse symlinks except for the last path segment, so we retain the ability to explicitely reference symlinks.

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

I need to review David's patch, because it looks like it will also fix bug 32669.

Another possible fix is to do:
dirpath, basename = os.path.split(path)
os.path.join(os.path.normpath(dirname), basename)
Which should canonicalize the directory, without modifying the basename. Should be the same effect as manually traversing all but the last symlink.

Changed in bzr:
assignee: nobody → jameinel
Revision history for this message
John A Meinel (jameinel) wrote :

still needs progress (0.12?)

Revision history for this message
F.R.@.N.K (frank-iceshop) wrote :

Any news on this topic?

Revision history for this message
Martin Pool (mbp) wrote :

Even with the fix for bug 128562, "st LINK_TO_BRANCH" still fails with

bzr: ERROR: bar is not in the same branch as bar

Revision history for this message
John A Meinel (jameinel) wrote : Re: [Bug 48444] Re: Symlinks to repository branches don't work

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

Martin Pool wrote:
> Even with the fix for bug 128562, "st LINK_TO_BRANCH" still fails with
>
>
> bzr: ERROR: bar is not in the same branch as bar
>

It might work to use:

wt, relpath = WT.open_containing(dereference_path(file_list[0]))
                                 ^^^^^^^^^^^^^^^^

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkxAUdcACgkQJdeBCYSNAAPGlgCfcORflUamX2HY33zNR+yScfgE
63sAoJpAto9kuxLlI5EH840nAoCfyAzd
=KvXP
-----END PGP SIGNATURE-----

Martin Pool (mbp)
Changed in bzr:
status: Confirmed → In Progress
assignee: John A Meinel (jameinel) → Martin Pool (mbp)
Martin Pool (mbp)
description: updated
Jelmer Vernooij (jelmer)
tags: added: symlinks
Revision history for this message
John A Meinel (jameinel) wrote :

I'm guessing this might be an inverse bug to bug #32669
Specifically, 32669 wants "bzr add tree/link-to-tree2" to add link-to-tree2 as a new entry in "tree". However this bug wants us to treat "bzr st link-to-tree2" as though we were running "bzr st tree2".
I don't know that we can cleanly handle both cases at the same time. The only thing that comes to mind is if the last portion of a path is a symlink, to walk back up and see if you find a containing WT and treat that path differently in the two cases.
Alternatively, there is always the "link" vs "link/" syntax that seems to handle some of these ambiguities.

Note that this bug does still exist:

$ ln -s b2 fake-b2
$ bzr st b2
added:
  foo
$ bzr st fake-b2
bzr: ERROR: Path "/home/jameinel/dev/,tmp/fake-b2" is not a child of path "/home/jameinel/dev/,tmp/b2"

Martin Pool (mbp)
Changed in bzr:
assignee: Martin Pool (mbp) → nobody
status: In Progress → Confirmed
Jelmer Vernooij (jelmer)
tags: added: check-for-breezy
Jelmer Vernooij (jelmer)
tags: removed: check-for-breezy
Changed in brz:
status: New → Triaged
importance: Undecided → Low
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

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