2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
1 |
Choosing a shared repository layout |
2 |
=================================== |
|
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
3 |
|
4 |
Bazaar is designed to give you flexibility in how you layout branches inside a shared repository. |
|
5 |
This flexibility allows users to tailor Bazaar to their workflow, |
|
6 |
but it also leads to questions about what is a "good" layout. |
|
7 |
We present some alternatives and give some discussion about the benefits of each. |
|
8 |
||
9 |
One key point which should be mentioned is that any good layout should somehow highlight |
|
10 |
what branch a "general" user should grab. In SVN this is deemed the "``trunk/``" branch, |
|
11 |
and in most of the layouts this naming convention is preserved. Some would call this |
|
12 |
"``mainline``" or "``dev``", and people from CVS often refer to this as "``HEAD``". |
|
13 |
||
14 |
||
15 |
"SVN-Style" (``trunk/``, ``branches/``) |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
16 |
--------------------------------------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
17 |
|
18 |
Most people coming from SVN will be familiar with their "standard" project layout. |
|
19 |
Which is to layout the repository as:: |
|
20 |
||
21 |
repository/ # Overall repository |
|
22 |
+- trunk/ # The mainline of development |
|
23 |
+- branches/ # A container directory |
|
24 |
| +- foo/ # Branch for developing feature foo |
|
25 |
| ... |
|
26 |
+- tags/ # Container directory |
|
27 |
+- release-X # A branch specific to mark a given release version |
|
28 |
... |
|
29 |
||
30 |
With Bazaar, that is a perfectly reasonable layout. |
|
31 |
It has the benefit of being familiar to people coming from SVN, |
|
32 |
and making it clear where the development focus is. |
|
33 |
||
34 |
When you have multiple projects in the same repository, |
|
35 |
the SVN layout is a little unclear what to do. |
|
36 |
||
37 |
||
38 |
``project/trunk`` |
|
39 |
~~~~~~~~~~~~~~~~~ |
|
40 |
||
41 |
The preferred method for SVN seems to be to give each project a top level directory for a layout like:: |
|
42 |
||
43 |
repository/ # Overall repository |
|
44 |
+- project1/ # A container directory |
|
45 |
| +- trunk/ # The mainline of development of project1 |
|
46 |
| +- branches/ # A container directory |
|
47 |
| +- foo/ # Branch for developing feature foo of project1 |
|
48 |
| ... |
|
49 |
| |
|
50 |
+- project2/ # Container for project2 |
|
51 |
+- trunk/ # Mainline for project2 |
|
52 |
+- branches/ # Container for project2 branches |
|
53 |
||
54 |
||
55 |
This also works with Bazaar. |
|
56 |
However, with Bazaar repositories are cheap to create |
|
57 |
(a simple ``bzr init-repo`` away), and their primary benefit is when the |
|
58 |
branches share a common ancestry. |
|
59 |
||
60 |
So the preferred way for Bazaar would be:: |
|
61 |
||
62 |
project1/ # A repository for project1 |
|
63 |
+- trunk/ # The mainline of development of project1 |
|
64 |
+- branches/ # A container directory |
|
65 |
+- foo/ # Branch for developing feature foo of project1 |
|
66 |
... |
|
67 |
||
68 |
project2/ # A repository for project2 |
|
69 |
+- trunk/ # Mainline for project2 |
|
70 |
+- branches/ # Container for project2 branches |
|
71 |
||
72 |
||
73 |
``trunk/project`` |
|
74 |
~~~~~~~~~~~~~~~~~ |
|
75 |
||
76 |
There are also a few projects who use this layout in SVN:: |
|
77 |
||
78 |
repository/ # Overall repository |
|
79 |
+- trunk/ # A container directory |
|
80 |
| +- project1 # Mainline for project 1 |
|
81 |
| +- project2 # Mainline for project 2 |
|
82 |
| ... |
|
83 |
| |
|
84 |
+- branches/ # Container |
|
85 |
+- project1/ # Container (?) |
|
86 |
| +- foo # Branch 'foo' of project1 |
|
87 |
+- project2/ |
|
88 |
+- bar # Branch 'bar' of project2 |
|
89 |
||
90 |
||
91 |
A slight variant is:: |
|
92 |
||
93 |
repository/ # Overall repository |
|
94 |
+- trunk/ # A container directory |
|
95 |
| +- project1 # Mainline for project 1 |
|
96 |
| +- project2 # Mainline for project 2 |
|
97 |
| ... |
|
98 |
| |
|
99 |
+- branches/ # Container |
|
100 |
+- project1-foo/ # Branch 'foo' of project1 |
|
101 |
+- project2-bar/ # Branch 'bar' of project2 |
|
102 |
||
103 |
I believe the reason for this in SVN, is so that someone |
|
104 |
can checkout all of "``trunk/``" and get the all the mainlines for all projects. |
|
105 |
||
106 |
This layout can be used for Bazaar, but it is not generally recommended. |
|
107 |
||
108 |
1) ``bzr branch/checkout/get`` is a single branch at a time. |
|
109 |
So you don't get the benefit of getting all mainlines with a single command. [1]_ |
|
110 |
||
111 |
2) It is less obvious of whether ``repository/trunk/foo`` is the ``trunk`` of project |
|
112 |
``foo`` or it is just the ``foo`` directory in the ``trunk`` branch. |
|
113 |
Some of this confusion is due to SVN, because it uses the same "namespace" |
|
114 |
for files in a project that it uses for branches of a project. |
|
115 |
In Bazaar, there is a clear distinction of what files make up a project, versus |
|
116 |
the location of the Branch. (After all, there is only one ``.bzr/`` directory per branch, |
|
117 |
versus many ``.svn/`` directories in the checkout). |
|
118 |
||
119 |
.. [1] Note: `NestedTreeSupport`_ can provide a way to create "meta-projects" which |
|
120 |
aggregate multiple projects regardless of the repository layout. |
|
121 |
Letting you ``bzr checkout`` one project, and have it grab all the necessary |
|
122 |
sub-projects. |
|
123 |
||
2481.1.3
by Robert Collins
Add the performance roadmap rationale. |
124 |
.. _NestedTreeSupport: http://bazaar-vcs.org/NestedTrees |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
125 |
|
126 |
||
127 |
Nested Style (``project/branch/sub-branch/``) |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
128 |
--------------------------------------------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
129 |
|
130 |
Another style with Bazaar, which is not generally possible in SVN |
|
131 |
is to have branches nested within each-other. |
|
132 |
This is possible because Bazaar supports (and recommends) creating repositories |
|
133 |
with no working trees (``--no-trees``). |
|
134 |
With a ``--no-trees`` repository, because the working files are not intermixed with |
|
135 |
your branch locations, you are free to put a branch in whatever namespace you want. |
|
136 |
||
137 |
One possibility is:: |
|
138 |
||
139 |
project/ # The overall repository, *and* the project's mainline branch |
|
140 |
+ joe/ # Developer Joe's primary branch of development |
|
141 |
| +- feature1/ # Developer Joe's feature1 development branch |
|
142 |
| | +- broken/ # A staging branch for Joe to develop feature1 |
|
143 |
| +- feature2/ # Joe's feature2 development branch |
|
144 |
| ... |
|
145 |
+ barry/ # Barry's development branch |
|
146 |
| ... |
|
147 |
+ releases/ |
|
148 |
+- 1.0/ |
|
149 |
+- 1.1.1/ |
|
150 |
||
151 |
The idea with this layout is that you are creating a hierarchical layout for branches. |
|
152 |
Where changes generally flow upwards in the namespace. It also gives people a little |
|
153 |
corner of the namespace to work on their stuff. |
|
154 |
One nice feature of this layout, is it makes branching "cheaper" because it gives you |
|
155 |
a place to put all the mini branches without cluttering up the global ``branches/`` namespace. |
|
156 |
||
157 |
The other power of this is that you don't have to repeat yourself when specifying more detail in the |
|
158 |
branch name. |
|
159 |
||
160 |
For example compare:: |
|
161 |
||
162 |
bzr branch http://host/repository/project/branches/joe-feature-foo-bugfix-10/ |
|
163 |
||
164 |
Versus:: |
|
165 |
||
166 |
bzr branch http://host/project/joe/foo/bugfix-10 |
|
167 |
||
168 |
||
169 |
Also, if you list the ``repository/project/branches/`` directory you might see something like:: |
|
170 |
||
171 |
barry-feature-bar/ |
|
172 |
barry-bugfix-10/ |
|
173 |
barry-bugfix-12/ |
|
174 |
joe-bugfix-10/ |
|
175 |
joe-bugfix-13/ |
|
176 |
joe-frizban/ |
|
177 |
||
178 |
Versus having these broken out by developer. |
|
179 |
If the number of branches are small, ``branches/`` has the nice advantage |
|
180 |
of being able to see all branches in a single view. |
|
181 |
If the number of branches is large, ``branches/`` has the distinct disadvantage |
|
182 |
of seeing all the branches in a single view (it becomes difficult to find the |
|
183 |
branch you are interested in, when there are 100 branches to look through). |
|
184 |
||
185 |
Nested branching seems to scale better to larger number of branches. |
|
186 |
However, each individual branch is less discoverable. |
|
187 |
(eg. "Is Joe working on bugfix 10 in his feature foo branch, or his feature bar branch?") |
|
188 |
||
189 |
One other small advantage is that you can do something like:: |
|
190 |
||
191 |
bzr branch http://host/project/release/1/1/1 |
|
192 |
or |
|
193 |
bzr branch http://host/project/release/1/1/2 |
|
194 |
||
195 |
To indicate release 1.1.1 and 1.1.2. This again depends on how many releases you have |
|
196 |
and whether the gain of splitting things up outweighs the ability to see more at a glance. |
|
197 |
||
198 |
||
199 |
Sorted by Status (``dev/``, ``merged/``, ``experimental/``) |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
200 |
----------------------------------------------------------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
201 |
|
202 |
One other way to break up branches is to sort them by their current status. |
|
203 |
So you would end up with a layout something like:: |
|
204 |
||
205 |
project/ # Overall layout |
|
206 |
+- trunk/ # The development focus branch |
|
207 |
+- dev/ # Container directory for in-progress work |
|
208 |
| +- joe-feature1 # Joe's current feature-1 branch |
|
209 |
| +- barry-bugfix10 # Barry's work for bugfix 10 |
|
210 |
| ... |
|
211 |
+- merged/ # Container indicating these branches have been merged |
|
212 |
| +- bugfix-12 # Bugfix which has already been merged. |
|
213 |
+- abandonded/ # Branches which are considered 'dead-end' |
|
214 |
||
215 |
||
216 |
This has a couple benefits and drawbacks. |
|
217 |
It lets you see what branches are actively being developed on, which is usually |
|
218 |
only a small number, versus the total number of branches ever created. |
|
219 |
Old branches are not lost (versus deleting them), but they are "filed away", |
|
220 |
such that the more likely you are to want a branch the easier it is to find. |
|
221 |
(Conversely, older branches are likely to be harder to find). |
|
222 |
||
223 |
The biggest disadvantage with this layout, is that branches move around. |
|
224 |
Which means that if someone is following the ``project/dev/new-feature`` branch, |
|
225 |
when it gets merged into ``trunk/`` suddenly ``bzr pull`` doesn't mirror the branch |
|
226 |
for them anymore because the branch is now at ``project/merged/new-feature``. |
|
227 |
There are a couple ways around this. One is to use HTTP redirects to point people |
|
228 |
requesting the old branch to the new branch. ``bzr`` >= 0.15 will let users know |
|
229 |
that ``http://old/path redirects to http://new/path``. However, this doesn't help |
|
230 |
if people are accessing a branch through methods other than HTTP (SFTP, local filesystem, etc). |
|
231 |
||
232 |
It would also be possible to use a symlink for temporary redirecting (as long as the symlink |
|
233 |
is within the repository it should cause little trouble). However eventually you want to |
|
234 |
remove the symlink, or you don't get the clutter reduction benefit. |
|
235 |
Another possibility instead of a symlink is to use a ``BranchReference``. It is currently |
|
236 |
difficult to create these through the ``bzr`` command line, but if people find them useful |
|
237 |
that could be changed. |
|
238 |
This is actually how `Launchpad`_ allows you to ``bzr checkout https://launchpad.net/bzr``. |
|
239 |
Effectively a ``BranchReference`` is a symlink, but it allows you to reference any other URL. |
|
240 |
If it is extended to support relative references, it would even work over http, sftp, |
|
241 |
and local paths. |
|
242 |
||
243 |
.. _Launchpad: https://launchpad.net |
|
244 |
||
245 |
||
246 |
Sorted by date/release/etc (``2006-06/``, ``2006-07/``, ``0.8/``, ``0.9``) |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
247 |
-------------------------------------------------------------------------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
248 |
|
249 |
Another method of allowing some scalability while also allowing the |
|
250 |
browsing of "current" branches. Basically, this works on the assumption |
|
251 |
that actively developed branches will be "new" branches, and older branches |
|
252 |
are either merged or abandoned. |
|
253 |
||
254 |
Basically the date layout looks something like:: |
|
255 |
||
256 |
project/ # Overall project repository |
|
257 |
+- trunk/ # General mainline |
|
258 |
+- 2006-06/ # containing directory for branches created in this month |
|
259 |
| +- feature1/ # Branch of "project" for "feature1" |
|
260 |
| +- feature2/ # Branch of "project" for "feature2" |
|
261 |
+- 2005-05/ # Containing directory for branches create in a different month |
|
262 |
+- feature3/ |
|
263 |
... |
|
264 |
||
265 |
This answers the question "Where should I put my new branch?" very quickly. |
|
266 |
If a feature is developed for a long time, it is even reasonable to copy a |
|
267 |
branch into the newest date, and continue working on it there. |
|
268 |
Finding an active branch generally means going to the newest date, and |
|
269 |
going backwards from there. (A small disadvantage is that most directory |
|
270 |
listings sort oldest to the top, which may mean more scrolling). |
|
271 |
If you don't copy old branches to newer locations, it also has the disadvantage |
|
272 |
that searching for a branch may take a while. |
|
273 |
||
274 |
Another variant is by release target:: |
|
275 |
||
276 |
project/ # Overall repository |
|
277 |
+- trunk/ # Mainline development branch |
|
278 |
+- releases/ # Container for release branches |
|
279 |
| +- 0.8/ # The branch for release 0.8 |
|
280 |
| +- 0.9/ # The branch for release 0.9 |
|
281 |
+- 0.8/ # Container for branches targeting release 0.8 |
|
282 |
| +- feature1/ # Branch for "feature1" which is intended to be merged into 0.8 |
|
283 |
| +- feature2/ # Branch for "feature2" which is targeted for 0.8 |
|
284 |
+- 0.9/ |
|
285 |
+- feature3/ # Branch for "feature3", targeted for release 0.9 |
|
286 |
||
287 |
||
288 |
Some possible variants include having the ``0.9`` directory imply |
|
289 |
that it is branched *from* 0.9 rather than *for* 0.9, or having the ``0.8/release`` |
|
290 |
as the official release 0.8 branch. |
|
291 |
||
292 |
The general idea is that by targeting a release, you can look at what branches are |
|
293 |
waiting to be merged. It doesn't necessarily give you a good idea of what the |
|
294 |
state of the branch (is it in development or finished awaiting review). |
|
295 |
It also has a history-hiding effect, and otherwise has the same benefits |
|
296 |
and deficits as a date-based sorting. |
|
297 |
||
298 |
||
299 |
Simple developer naming (``project/joe/foo``, ``project/barry/bar``) |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
300 |
-------------------------------------------------------------------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
301 |
|
302 |
Another possibly layout is to give each developer a directory, and then |
|
303 |
have a single sub-directory for branches. Something like:: |
|
304 |
||
305 |
project/ # Overall repository |
|
306 |
+- trunk/ # Mainline branch |
|
307 |
+- joe/ # A container for Joe's branches |
|
308 |
| +- foo/ # Joe's "foo" branch of "project" |
|
309 |
+- barry/ |
|
310 |
+- bar/ # Barry's "bar" branch of "project" |
|
311 |
||
312 |
The idea is that no branch is "nested" underneath another one, just that each developer |
|
313 |
has his/her branches grouped together. |
|
314 |
||
315 |
A variant which is used by `Launchpad`_ is:: |
|
316 |
||
317 |
repository/ |
|
318 |
+- joe/ # Joe's branches |
|
319 |
| +- project1/ # Container for Joe's branches of "project1" |
|
320 |
| | +- foo/ # Joe's "foo" branch of "project1" |
|
321 |
| +- project2/ # Container for Joe's "project2" branches |
|
322 |
| +- bar/ # Joe's "bar" branch of "project2" |
|
323 |
| ... |
|
324 |
| |
|
325 |
+- barry/ |
|
326 |
| +- project1/ # Container for Barry's branches of "project1" |
|
327 |
| +- bug-10/ # Barry's "bug-10" branch of "project1" |
|
328 |
| ... |
|
329 |
+- group/ |
|
330 |
+- project1/ |
|
331 |
+- trunk/ # The main development focus for "project1" |
|
332 |
||
333 |
||
334 |
This lets you easily browse what each developer is working on. Focus branches |
|
335 |
are kept in a "group" directory, which lets you see what branches the "group" |
|
336 |
is working on. |
|
337 |
||
338 |
This keeps different people's work separated from each-other, but also makes it |
|
339 |
hard to find "all branches for project X". `Launchpad`_ compensates for this |
|
340 |
by providing a nice web interface with a database back end, which allows a |
|
341 |
"view" to be put on top of this layout. |
|
342 |
This is closer to the model of people's home pages, where each person has a |
|
343 |
"``~/public_html``" directory where they can publish their own web-pages. |
|
344 |
In general, though, when you are creating a shared repository for centralization |
|
345 |
of a project, you don't want to split it up by person and then project. |
|
346 |
Usually you would want to split it up by project and then by person. |
|
347 |
||
348 |
||
349 |
Summary |
|
2977.1.1
by Ian Clatworthy
First cut at new look User Guide including chapters 1 and 2 |
350 |
------- |
2476.1.1
by John Arbash Meinel
Add shared_repository_layouts.txt as a core document. |
351 |
|
352 |
In the end, no single naming scheme will work for everyone. It depends a lot on |
|
353 |
the number of developers, how often you create a new branch, what sort of |
|
354 |
lifecycles your branches go through. Some questions to ask yourself: |
|
355 |
||
356 |
1) Do you create a few long-lived branches, or do you create lots of "mini" feature branches |
|
357 |
(Along with this is: Would you *like* to create lots of mini feature branches, but can't |
|
358 |
because they are a pain in your current VCS?) |
|
359 |
||
360 |
2) Are you a single developer, or a large team? |
|
361 |
||
362 |
3) If a team, do you plan on generally having everyone working on the same branch at the same |
|
363 |
time? Or will you have a "stable" branch that people are expected to track. |
|
364 |