1
by Chris Lamb
Import upstream version 0.2+bzr31 |
1 |
=======================
|
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
2 |
Implementation notes |
1
by Chris Lamb
Import upstream version 0.2+bzr31 |
3 |
=======================
|
4 |
||
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
5 |
Revision format |
6 |
===============
|
|
7 |
||
8 |
The format of trac "revs" is in flux. |
|
9 |
Currently the following guidelines are used: |
|
10 |
||
11 |
- A revision as Trac sees is always consists of a branch name followed |
|
12 |
by a comma and some string identifying the revision. The branch name |
|
13 |
is important, as Trac thinks of the repository as a single tree, so |
|
14 |
a revision id by itself wouldn't give us an absolute path in that |
|
15 |
tree if there were multiple branches containing that revision.
|
|
16 |
||
17 |
- If there is only a single branch at the root of the directory
|
|
18 |
configured as the bzr repository in Trac, then no branch name will
|
|
19 |
be included in revision strings. In this case, simple revision
|
|
20 |
numbers will work as Trac links, too. Maybe a future version of
|
|
21 |
trac-bzr will allow users to configure a "default branch" to obtain
|
|
22 |
simple revision names even when dealing with multiple branches.
|
|
23 |
||
24 |
- When generating revision strings, we prefer (dotted) revision
|
|
25 |
numbers over bzr revision identifiers. Only when the revision in
|
|
26 |
question hasn't been merged into that branch yet we emit a revision |
|
27 |
id instead. Usually people should never encounter such revisions |
|
28 |
trough Trac links, and we might simply reject them in the future, |
|
29 |
but for now they're handled in this fashion. |
|
30 |
||
31 |
- Wenn accepting revision strings, we accept both dotted revision
|
|
32 |
numbers and revision identifiers.
|
|
33 |
||
34 |
- Some characters are special to Trac, and shouldn't be part of a |
|
35 |
revision as Trac sees it. These include ``/`` and ``@``. For this |
|
36 |
reason, slashes in the branch name are replaced by commas, and |
|
37 |
revision identifiers will always be url-quoted. Branch names |
|
38 |
containing commas or percent signs will be url-quoted as well, which |
|
39 |
will ensure backwards compatibility with versions that used ot |
|
40 |
url-quote slashes and colons, so we have to url-unquote branch |
|
41 |
paths. |
|
42 |
||
43 |
- It seems that Trac takes care of quoting special characters, percent |
|
44 |
signs in particular, when generating links, and will unquote them |
|
45 |
before handing them to Trac. If you find an indication to the |
|
46 |
contrary, it might be a bug in Trac. |
|
47 |
||
48 |
Miscellaneous
|
|
49 |
=============
|
|
50 |
||
51 |
- trac wants to have a total ordering on revs. If one of the two |
|
52 |
revisions to be compared is an ancestor of the other, then we can |
|
53 |
compare them using the revision graph. bzrlib provides |
|
54 |
``Graph.is_ancestor`` for a one-way comparison. It internally uses |
|
55 |
``Graph.heads``, which we can use to get both ways at once. If the |
|
56 |
two branches are uncomparable using the partial ordering given by |
|
57 |
the ancestry graph, we compare them using timestamps instead. In the |
|
58 |
presence of a clock skew, this can lead to inconsistent results: if |
|
59 |
*a* is ancestor of *b* but *a* has a later timestamp than *b*, and |
|
60 |
if *c* is uncomparable to either, then by ancestry copparison |
|
61 |
*a* < *b* but by time comparison *b* < *c* < *a*. |
|
1
by Chris Lamb
Import upstream version 0.2+bzr31 |
62 |
|
63 |
- trac occasionally compares path values, which means we have to be |
|
64 |
careful about "normalizing" those. Currently the format is the one |
|
65 |
bzr hands us: always omit the starting "/" (which makes the root ""). |
|
66 |
What trac uses for svn is "/" for the root, "foo/bar" for everything |
|
67 |
else. Hopefully it will cope with our usage. trac also occasionally |
|
68 |
passes a None path, which is taken as meaning the root (""). |
|
69 |
(Example of where this bit in the past: if Node.get_history changes |
|
70 |
the path it returns trac interprets this as a move, even if we do not |
|
71 |
pass the corresponding constant. This means that if the Node is |
|
72 |
constructed from a non-normalized path starting with a "/" and we switch |
|
73 |
to a path with no starting "/" when the node *content* first changes |
|
74 |
trac picks it up as a move.) |
|
75 |
Again trac may pass in a normalized path, so make sure normalizing twice |
|
76 |
is safe. Notice that we do not always normalize passed in paths, since |
|
77 |
bzr should handle anything trac hands us. We just need to make sure |
|
78 |
everything that escapes back to trac is normalized. |
|
79 |
||
80 |
- trac wants the revision log of a dir to include what happens to its |
|
81 |
contents. bzr only notices changes to the dir itself (renames and moves |
|
82 |
of the dir, not its contents). |
|
83 |
||
84 |
One case where this is very important is get_previous of the root |
|
85 |
node. Since you can't rename or move the root this simply does not |
|
86 |
exist for bzr. Trac uses this to get the previous revision to |
|
87 |
display a changeset, so we really need to do this in the trac (svn) |
|
88 |
way. |
|
89 |
||
90 |
Another case is the revision attribute of BzrDirNode. If we pick the |
|
91 |
entry.revision for that we do not see the changes in subdirectories |
|
92 |
in the directory listings (as people expect from bzr/svn). If we |
|
93 |
pick the revisiontree revision id (which is the one the user is |
|
94 |
using to find us) then all subdirectories get the same log message |
|
95 |
(the one of the most recent commit to the tree, not to something |
|
96 |
under that subdir). |
|
97 |
||
98 |
Performance
|
|
99 |
===========
|
|
100 |
||
101 |
Constructing a BzrDirNode is slow because it walks its children to |
|
102 |
determine the right "most recent" revision. Because it is pretty |
|
103 |
common to iterate over the children afterwards and we need to |
|
104 |
determine their most recent revision anyway we cache those values |
|
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
105 |
(``BzrDirNode.revcache``). Speeds up the source browser in a directory |
1
by Chris Lamb
Import upstream version 0.2+bzr31 |
106 |
with a couple of subdirs. |
107 |
||
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
108 |
``BzrDirNode.get_history`` is a bit slow and pretty memory-hungry. Again |
1
by Chris Lamb
Import upstream version 0.2+bzr31 |
109 |
the need to manually pick up changes to children is the root cause. |
110 |
It has to construct full inventories and/or deltas between revisions |
|
111 |
to pick up changes to children, while for the other node types we just |
|
112 |
have to open the "versionedfile" for that particular file. |
|
113 |
||
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
114 |
Probably the most questionable optimization is keeping branches locked |
115 |
for the whole request. This provides a *very* noticable speed boost by |
|
116 |
keeping the branch locked for the entire web request (try timing a |
|
1
by Chris Lamb
Import upstream version 0.2+bzr31 |
117 |
"log" of the root dir, which pulls in a hundred BzrChangesets). And at |
118 |
a glance it looks like trac was designed with this thing in mind: it |
|
119 |
has a close method for "closing the connection". Unfortunately it does |
|
120 |
not actually call this method... We have a __del__ method to try to |
|
121 |
improve the chance the branch is unlocked, and bzr has one too, and |
|
122 |
this seems to be working so far. It is probably not really reliable |
|
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
123 |
though. And care has to be taken to avoid uncollectable cycles with |
124 |
objects containing __del__ methods, as this would cause serious memory |
|
125 |
leaks. |
|
1.1.1
by Jelmer Vernooij
Import upstream version 0.2+bzr45 |
126 |
|
127 |
Testsuite
|
|
128 |
=========
|
|
129 |
||
130 |
The testsuite can be run using one of the many Python testsuite runners. |
|
131 |
A good one is "trial" from the Twisted folks. To use it, run: |
|
132 |
||
133 |
$ trial tracbzr |
|
134 |
||
1.1.3
by Jelmer Vernooij
Import upstream version 0.3.0 |
135 |
.. vim: ft=rst |
136 |
||
137 |
.. emacs |
|
138 |
Local Variables: |
|
139 |
mode: rst |
|
140 |
End: |