~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to doc/shared_repository_layouts.txt

Don't encode unicode messages to UTF-8 in mutter() (the stream writer does it).

Use a codec wrapped log file in tests to match the real environment.

Show diffs side-by-side

added added

removed removed

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