~ubuntu-branches/debian/sid/trac-bzr/sid

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: