]> git.donarmstrong.com Git - don.git/blob - posts/debbugs_merge_versions.mdwn
Make a post about how debbugs versions are merged
[don.git] / posts / debbugs_merge_versions.mdwn
1 [[!meta title="Debbugs Versioning: Merging"]] 
2
3 One of the key features of Debbugs,
4 the [bug tracking system Debian uses](https://bugs.debian.org), is its
5 ability to figure out which bugs apply to which versions of a package
6 by tracking package uploads. This system generally works well, but
7 when a package maintainer's workflow doesn't match the assumptions of
8 Debbugs, unexpected things can happen. In this post, I'm going to:
9
10 1. introduce how Debbugs tracks versions
11 2. provide an example of a merge-based workflow which Debbugs doesn't handle well
12 3. provide some suggestions on what to do in this case
13
14 # Debbugs Versioning
15
16 Debbugs tracks versions using a set of one or
17 more
18 [rooted trees](https://en.wikipedia.org/wiki/Tree_%28graph_theory%29#Forest) which
19 it builds from the ordering of debian/changelog entries. In the
20 simplist case, every upload of a Debian package has changelogs in the
21 same order, and each upload adds just one version. For example, in the
22 case of [dgit](https://packages.debian.org/dgit), to start with the
23 package has this (abridged) version tree:
24
25 [[!graph src="""
26 ranksep = 0.2;
27 rankdir = "LR";
28 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
29 edge [dir="back"];
30 "3.11"->"3.10"
31 "3.12"->"3.11"
32 """]]
33
34 the next upload, *3.13*, has a changelog with this version ordering:
35 `3.13 3.12 3.11 3.10`, which causes the *3.13* version to be added as
36 a descendant of *3.12*, and the version tree now looks like this:
37
38 [[!graph src="""
39 ranksep = 0.2;
40 rankdir = "LR";
41 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
42 edge [dir="back"];
43 "3.11"->"3.10"
44 "3.12"->"3.11"
45 "3.13"->"3.12"
46 """]]
47
48 dgit is being developed while also being used, so new versions with
49 potentially disruptive changes are uploaded to experimental while
50 production versions are uploaded to unstable. For example, the *4.0*
51 experimental upload was based on the *3.10* version, with the
52 changelog ordering `4.0 3.10`. The tree now has two branches, but
53 everything seems as you would expect:
54
55 [[!graph src="""
56 ranksep = 0.2;
57 rankdir = "LR";
58 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
59 edge [dir="back"];
60 "3.11"->"3.10"
61 "3.12"->"3.11"
62 "3.13"->"3.12"
63 "4.0"->"3.10"
64 """]]
65
66 # Merge based workflows
67
68 Bugfixes in the maintenance version of dgit also are made to the
69 experimental package by merging changes from the production version
70 using git. In this case, some changes which were present in the *3.12*
71 and *3.11* versions are merged using git, corresponds to a git merge
72 flow like this:
73
74 [[!graph src="""
75 ranksep = 0.2;
76 rankdir = "LR";
77 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
78 edge [dir="back"];
79 "3.11"->"3.10"
80 "3.12"->"3.11"
81 "3.13"->"3.12"
82 "4.0"->"3.10"
83 "4.1"->"4.0"
84 "4.1"->"3.12"
85 """]]
86
87 If an upload is prepared with changelog ordering `4.1 4.0 3.12 3.11
88 3.10`, Debbugs combines this new changelog ordering with the
89 previously known tree, to produce this version tree:
90
91 [[!graph src="""
92 ranksep = 0.2;
93 rankdir = "LR";
94 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
95 edge [dir="back"];
96 "3.11"->"3.10"
97 "3.12"->"3.11"
98 "3.13"->"3.12"
99 "4.0"->"3.12"
100 "4.1"->"4.0"
101 """]]
102
103 This looks a bit odd; what happened? Debbugs walks through the new
104 changelog, connecting each of the new versions to the previous version
105 if and only if that version is not already an ancestor of the new
106 version. Because the changelog says that *3.12* is the ancestor of
107 *4.0*, that's where the `4.1 4.0` version tree is connected.
108
109 Now, when *4.2* is uploaded, it has the changelog ordering (based on
110 time) `4.2 3.13 4.1 4.0 3.12 3.11 3.10`, which corresponds to this git
111 merge flow:
112
113 [[!graph src="""
114 ranksep = 0.2;
115 rankdir = "LR";
116 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
117 edge [dir="back"];
118 "3.11"->"3.10"
119 "3.12"->"3.11"
120 "3.13"->"3.12"
121 "4.0"->"3.10"
122 "4.1"->"4.0"
123 "4.1"->"3.12"
124 "4.2"->"4.1"
125 "4.2"->"3.13"
126 """]]
127
128 Debbugs adds in *3.13* as an ancestor of *4.2*, and because *4.1* was
129 not an ancestor of *3.13* in the previous tree, *4.1* is added as an
130 ancestor of *3.13*. This results in the following graph:
131
132 [[!graph src="""
133 ranksep = 0.2;
134 rankdir = "LR";
135 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
136 edge [dir="back"];
137 "3.11"->"3.10"
138 "3.12"->"3.11"
139 "3.13"->"4.1"
140 "4.0"->"3.12"
141 "4.1"->"4.0"
142 "4.2"->"3.13"
143 """]]
144
145 Which doesn't seem particularly helpful, because
146
147 [[!graph src="""
148 ranksep = 0.2;
149 rankdir = "LR";
150 node [fontsize=12,shape=box,margin=0.05,width=0.3,height=0.1];
151 edge [dir="back"];
152 "3.11"->"3.10"
153 "3.12"->"3.11"
154 "3.13"->"3.12"
155 "4.0"->"3.10"
156 "4.1"->"4.0"
157 "4.2"->"4.1"
158 """]]
159
160 is probably the tree that more closely resembles reality.
161
162
163 # Suggestions on what to do
164
165 *Why does this even matter?* Bugs which are found in *3.11*, and fixed
166 in *3.12* now show up as being found in *4.0* after the *4.1* release,
167 though they weren't found in *4.0* before that release. It also means
168 that *3.13* now shows up as having all of the bugs fixed in *4.2*,
169 which might not be what is meant.
170
171 To avoid this, my suggestion is to order the entries in changelogs in
172 the same order that the version graph should be traversed from the
173 leaf version you are releasing to the root. So if the previous version
174 tree is what is wanted, *3.13* should have a changelog with ordering
175 `3.13 3.12 3.11 3.10`, and *4.2* should have a changelog with ordering
176 `4.2 4.1 4.0 3.10`.
177
178 *What about making the BTS support DAGs which are not trees?* I think
179 something like this would be useful, but I don't personally have a
180 good idea on how this could be specified using the changelog or how
181 bug fixed/found/absent should be propagated in the DAG. If you have
182 better ideas, email me!
183
184
185
186 [[!tag debian tech debbugs]]