5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
1 |
#################################### |
2 |
Developer guide to bzrlib transports |
|
3 |
#################################### |
|
4 |
||
5 |
This guide describes the `Transport` classes that Bazaar uses for most |
|
6 |
local and remote file access. (Working tree files are the major |
|
5346.2.3
by Martin Pool
review feedback on transport docs |
7 |
exception (`bug 606249 <https://bugs.launchpad.net/bzr/+bug/606249>`). |
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
8 |
|
9 |
||
10 |
Handling symlinks |
|
11 |
################# |
|
12 |
||
13 |
A symlink creates an alias where files or directories can be accessed by a |
|
5346.2.3
by Martin Pool
review feedback on transport docs |
14 |
different name. Symlinks are useful but raise a few annoying cases for |
15 |
bzr. |
|
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
16 |
|
5346.2.3
by Martin Pool
review feedback on transport docs |
17 |
It's important to have tests for symlinks but these tests can't run on |
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
18 |
Windows, so you need eg :: |
19 |
||
20 |
_test_needs_features = [tests.SymlinkFeature] |
|
21 |
||
22 |
or :: |
|
23 |
||
24 |
self.requireFeature(tests.SymlinkFeature) |
|
25 |
||
26 |
Bazaar versions symlinks as objects in their own right, whose content is |
|
5346.2.3
by Martin Pool
review feedback on transport docs |
27 |
the path they point to. bzr doesn't care whether a versioned |
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
28 |
symlink is absolute or relative; or whether it points inside or outside |
5346.2.3
by Martin Pool
review feedback on transport docs |
29 |
the working tree; or whether its referent exists or not. In Unix the |
30 |
target of a symlink is a byte string; bzr treats this as a Unicode string |
|
31 |
in the filesystem encoding (`osutils._fs_enc`). |
|
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
32 |
|
33 |
So when we say ``bzr add symlink``, this should always add the symlink to |
|
34 |
its containing working tree, and never dereference the symlink. |
|
35 |
||
36 |
However, ``bzr add symlink/file`` shouldn't add ``file`` as a child of |
|
37 |
``symlink``. (Symlinks don't have files underneath them: they may point to |
|
38 |
a directory which contains children, but if the symlink was pointed |
|
39 |
somewhere else those children would be unaffected.) This could either add |
|
40 |
the file in its containing working tree, or fail outright. |
|
41 |
||
42 |
One interesting case for this is :: |
|
43 |
||
44 |
bzr add ~/dev/bug123/a.c |
|
45 |
||
46 |
where ``~/dev`` is actually a symlink to ``/srv/dev/joe/``. In this case |
|
47 |
clearly the user does want us to follow the symlink to open the tree. |
|
48 |
||
49 |
As of bzr2.2, when we open a `WorkingTree`, we typically immediately |
|
50 |
compute its real path and store that as ``.basedir``, but `BzrDir` stores |
|
51 |
its apparent path. (This may not be the best thing.) |
|
52 |
||
53 |
||
5346.2.2
by Martin Pool
Mention dereference_path |
54 |
Useful functions |
55 |
---------------- |
|
56 |
||
57 |
`bzrlib.osutils.dereference_path` does the commonly useful operation of |
|
58 |
resolving the directory part of a path, but leaving the filename |
|
59 |
untouched. In other words :: |
|
60 |
||
61 |
ln -s x a |
|
62 |
ln -s y x/b |
|
63 |
dereference_path('a/b') => 'x/b' |
|
64 |
||
65 |
||
5346.2.1
by Martin Pool
Add some developer docs about symlinks and transports towards bug 192859 |
66 |
Relative paths beyond symlinks |
67 |
------------------------------ |
|
68 |
||
69 |
Another interesting case is when a control directory contains a relative |
|
70 |
path, perhaps from a branch to its master or from a working tree to its |
|
71 |
branch. If it contains ``../`` parts as it typically will, these may have |
|
72 |
different effects depending on whether they're looked up relative to the |
|
73 |
real path or the apparent path given by the user. It may be that some |
|
74 |
users expect different behaviours at different times. |
|
75 |
||
76 |
Resolving the path relative to the real directory makes it somewhat more |
|
77 |
consistent with what you would see by in a shell entering that directory |
|
78 |
and then opening the given name. It may also make things more consistent |
|
79 |
when there are multiple links to the same bzrdir. However it may cause |
|
80 |
problems when using a transport that hides symlinks. |
|
81 |
||
82 |
We could possibly handle this by doing less path arithmetic and asking the |
|
83 |
OS or server to open the path including ``..`` and other relative |
|
84 |
elements, but that might cause other problems. HTTP servers may do their |
|
85 |
own path arithmetic before passing it to the OS. |
|
86 |
||
87 |
||
88 |
Transports that hide symlinks |
|
89 |
----------------------------- |
|
90 |
||
91 |
On local, sftp and bzr+ssh transports, we can directly see symlinks as |
|
92 |
symlinks. Over http (and ftp?) they're expanded by the server and we |
|
93 |
cannot detect them. This can cause problems when bzr follows relative |
|
94 |
paths because typically we will join the paths, and we may do this |
|
95 |
inconsistently with how the server, which can see the symlinks, would do. |
|
96 |
||
97 |
||
98 |
Symlinks and ChrootTransports |
|
99 |
----------------------------- |
|
100 |
||
101 |
bzr has an internal concept of a `ChrootTransport` that locks access into |
|
102 |
a particular directory. Symlinks should not break out of a chroot jail |
|
103 |
which implies they should be expanded and checked within bzrlib. |
|
104 |
(At least as long as the transport lets us see the symlink; otherwise it |
|
105 |
may not be possible.) |
|
106 |
||
107 |
||
108 |
.. vim: ft=rst sw=4 |