~bzr-pqm/bzr/bzr.dev

3250.4.1 by Martin Albisetti
Added integration guide for developers
1
=======================
2
Integrating with Bazaar
3
=======================
4
5225.2.13 by Martin Pool
More reorganization of the developer documentation
5
This document provides some general observations on integrating with
6
Bazaar and some recipes for typical tasks.  It is intended to be useful to
7
someone developing either a plugin or some other piece of software that
8
integrates with bzr.  If you want to know about a topic that's not covered
9
here, just ask us.
10
11
5225.2.4 by Martin Pool
ReST format fixes
12
13
5225.2.6 by Martin Pool
mention bzrlib.initialize and get_command
14
Starting with bzrlib
15
====================
16
17
Before doing anything else with bzrlib, you should run `bzrlib.initialize`
18
which sets up some global state.  
19
20
21
Running bzr commands
22
====================
23
24
To run command-line commands in-process::
25
26
  from bzrlib.commands import get_command
27
  
28
  cmd = get_command('version')
29
  cmd.run([])
30
  
31
This will send output through the current UIFactory; you can redirect this
32
elsewhere through the parameters to `bzrlib.initialize`.
33
5225.2.4 by Martin Pool
ReST format fixes
34
3250.4.1 by Martin Albisetti
Added integration guide for developers
35
Manipulating the Working Tree
36
=============================
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
37
Most objects in Bazaar are in files, named after the class they contain.
38
To manipulate the Working Tree we need a valid WorkingTree object, which
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
39
is loaded from the workingtree.py file, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
40
41
  from bzrlib import workingtree
42
  wt = workingtree.WorkingTree.open('/home/jebw/bzrtest')
43
44
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
45
This gives us a WorkingTree object, which has various methods spread over
46
itself, and its parent classes MutableTree and Tree - its worth having a
47
look through these three files (workingtree.py, mutabletree.py and tree.py)
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
48
to see which methods are available.
3250.4.1 by Martin Albisetti
Added integration guide for developers
49
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
50
Compare trees
5225.2.4 by Martin Pool
ReST format fixes
51
-------------
52
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
53
There are two methods for comparing trees: ``changes_from`` and
54
``iter_changes``.  ``iter_changes`` is more regular and precise, but it is
55
somewhat harder to work with.  See the API documentation for more details.
56
57
``changes_from`` creates a Delta object showing changes::
3250.4.1 by Martin Albisetti
Added integration guide for developers
58
59
  from bzrlib import delta
60
  changes = wt.changes_from(wt.basis_tree())
61
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
62
This gives us a Delta object, which has several lists of files for each type of
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
63
change, eg changes.added is a list of added files, changes.removed is list
64
of removed files, changes.modified is a list of modified files. The contents
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
65
of the lists aren't just filenames, but include other information as well.
3344.1.2 by Martin Pool
Fix ReST syntax in integration guide
66
To grab just the filename we want the first value, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
67
68
  print("list of newly added files")
69
  for filename in changes.added:
70
    print("%s has been added" % filename[0])
71
72
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
73
The exception to this is changes.renamed, where the list returned for each
74
renamed files contains both the old and new names -- one or both may interest
75
you, depending on what you're doing.
3250.4.1 by Martin Albisetti
Added integration guide for developers
76
77
For example::
78
79
  print("list of renamed files")
80
  for filename in changes.renamed:
81
    print("%s has been renamed to %s" % (filename[0], filename[1]))
82
83
84
Adding Files
5225.2.4 by Martin Pool
ReST format fixes
85
------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
86
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
87
If you want to add files the same way ``bzr add`` does, you can use
88
MutableTree.smart_add.  By default, this is recursive. Paths can either be
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
89
absolute or relative to the workingtree::
3250.4.1 by Martin Albisetti
Added integration guide for developers
90
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
91
  wt.smart_add(['dir1/filea.txt', 'fileb.txt',
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
92
                '/home/jebw/bzrtesttree/filec.txt'])
3250.4.1 by Martin Albisetti
Added integration guide for developers
93
94
95
For more precise control over which files to add, use MutableTree.add::
96
97
  wt.add(['dir1/filea.txt', 'fileb.txt', '/home/jebw/bzrtesttree/filec.txt'])
98
99
100
Removing Files
5225.2.4 by Martin Pool
ReST format fixes
101
--------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
102
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
103
You can remove multiple files at once.  The file paths need to be relative
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
104
to the workingtree::
3250.4.1 by Martin Albisetti
Added integration guide for developers
105
106
  wt.remove(['filea.txt', 'fileb.txt', 'dir1'])
107
108
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
109
By default, the files are not deleted, just removed from the inventory.
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
110
To delete them from the filesystem as well::
3250.4.1 by Martin Albisetti
Added integration guide for developers
111
112
  wt.remove(['filea.txt', 'fileb.txt', 'dir1'], keep_files=False)
113
114
115
Renaming a File
5225.2.4 by Martin Pool
ReST format fixes
116
---------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
117
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
118
You can rename one file to a different name using WorkingTree.rename_one.
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
119
You just provide the old and new names, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
120
121
  wt.rename_one('oldfile.txt','newfile.txt')
122
123
124
Moving Files
5225.2.4 by Martin Pool
ReST format fixes
125
------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
126
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
127
You can move multiple files from one directory into another using
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
128
WorkingTree.move::
3250.4.1 by Martin Albisetti
Added integration guide for developers
129
130
  wt.move(['olddir/file.txt'], 'newdir')
131
132
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
133
More complicated renames/moves can be done with transform.TreeTransform,
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
134
which is outside the scope of this document.
3250.4.1 by Martin Albisetti
Added integration guide for developers
135
136
137
Committing Changes
5225.2.4 by Martin Pool
ReST format fixes
138
------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
139
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
140
To commit _all_ the changes to our working tree we can just call the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
141
WorkingTree's commit method, giving it a commit message, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
142
143
  wt.commit('this is my commit message')
144
145
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
146
To commit only certain files, we need to provide a list of filenames which we
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
147
want committing, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
148
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
149
  wt.commit(message='this is my commit message', specific_files=['fileA.txt',
150
            'dir2/fileB.txt', 'fileD.txt'])
3250.4.1 by Martin Albisetti
Added integration guide for developers
151
152
153
Generating a Log for a File
154
===========================
155
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
156
Generating a log is, in itself, simple.  Grab a branch (see below) and pass
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
157
it to show_log together with a log formatter, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
158
159
  from bzrlib import log
160
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
161
3250.4.1 by Martin Albisetti
Added integration guide for developers
162
  b = branch.Branch.open('/path/to/bazaar/branch')
163
  lf = log.LongLogFormatter(to_file=sys.stdout)
164
  log.show_log(b, lf)
165
166
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
167
Three log formatters are included with bzrlib: LongLogFormatter,
168
ShortLogFormatter and LineLogFormatter.  These provide long, short and
169
single-line log output formats. It's also possible to write your own in
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
170
very little code.
3250.4.1 by Martin Albisetti
Added integration guide for developers
171
172
Annotating a File
173
=================
174
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
175
To annotate a file, we want to walk every line of a file, retrieving the
176
revision which last modified/created that line and then retrieving the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
177
information for that revision.
3250.4.1 by Martin Albisetti
Added integration guide for developers
178
179
First we get an annotation iterator for the file we are interested in::
180
181
  tree, relpath = workingtree.WorkingTree.open_containing('/path/to/file.txt')
182
  fileid = tree.path2id(relpath)
183
  annotation = list(tree.annotate_iter(fileid))
184
185
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
186
To avoid repeatedly retrieving the same revisions we grab all revisions
187
associated with the file at once and build up a map of id to revision
188
information. We also build an map of revision numbers, again indexed
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
189
by the revision id::
3250.4.1 by Martin Albisetti
Added integration guide for developers
190
191
  revision_ids = set(revision_id for revision_id, text in annotation)
192
  revisions = tree.branch.repository.get_revisions(revision_ids)
193
  revision_map = dict(izip(revision_ids, revisions))
194
  revno_map = tree.branch.get_revision_id_to_revno_map()
195
196
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
197
Finally, we use our annotation iterator to walk the lines of the file,
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
198
displaying the information from our revision maps as we go::
3250.4.1 by Martin Albisetti
Added integration guide for developers
199
200
  for revision_id, text in annotation :
201
      rev = revision_map[revision_id]
202
      revno = revno_map[revision_id]
203
      revno_string = '.'.join(str(i) for i in revno)
204
      print "%s, %s: %s" % (revno_string, rev.committer, text)
205
206
207
Working with branches
208
=====================
209
210
To work with a branch you need a branch object, created from your branch::
211
212
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
213
3250.4.1 by Martin Albisetti
Added integration guide for developers
214
  b = branch.Branch.open('/home/jebw/bzrtest')
215
216
217
Branching from an existing branch
5225.2.4 by Martin Pool
ReST format fixes
218
---------------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
219
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
220
To branch you create a branch object representing the branch you are
221
branching from, and supply a path/url to the new branch location.
222
The following code clones the bzr.dev branch (the latest copy of the Bazaar
223
source code) - be warned it has to download 60meg so takes a while to run
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
224
with no feedback::
3250.4.1 by Martin Albisetti
Added integration guide for developers
225
226
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
227
4675.2.2 by Robert Collins
Replace bazaar-vcs.org/bzr/ references with launchpad hosting urls in developer docs.
228
  b = branch.Branch.open('http://bazaar.launchpad.net/~bzr-pqm/bzr/bzr.dev')
3250.4.1 by Martin Albisetti
Added integration guide for developers
229
  nb = b.bzrdir.sprout('/tmp/newBzrBranch').open_branch()
230
231
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
232
This provides no feedback, since Bazaar automatically uses the 'silent' UI.
3250.4.1 by Martin Albisetti
Added integration guide for developers
233
234
235
Pushing and pulling branches
5225.2.4 by Martin Pool
ReST format fixes
236
----------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
237
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
238
To push a branch you need to open the source and destination branches, then
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
239
just call push with the other branch as a parameter::
3250.4.1 by Martin Albisetti
Added integration guide for developers
240
241
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
242
3250.4.1 by Martin Albisetti
Added integration guide for developers
243
  b1 = branch.Branch.open('file:///home/user/mybranch')
4675.2.2 by Robert Collins
Replace bazaar-vcs.org/bzr/ references with launchpad hosting urls in developer docs.
244
  b2 = branch.Branch.open('http://bazaar.launchpad.net/~bzr-pqm/bzr/bzr.dev')
3250.4.1 by Martin Albisetti
Added integration guide for developers
245
  b1.push(b2)
246
247
248
Pulling is much the same::
249
250
  b1.pull(b2)
251
252
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
253
If you have a working tree, as well as a branch, you should use
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
254
WorkingTree.pull, not Branch.pull.
3250.4.1 by Martin Albisetti
Added integration guide for developers
255
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
256
This won't handle conflicts automatically though, so any conflicts will be
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
257
left in the working tree for the user to resolve.
3250.4.1 by Martin Albisetti
Added integration guide for developers
258
259
260
Checkout from an existing branch
261
================================
262
263
This performs a Lightweight checkout from an existing Branch::
264
265
  from bzrlib import bzrdir
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
266
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
267
  accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch('http:URL')
3250.4.1 by Martin Albisetti
Added integration guide for developers
268
  source.create_checkout('/tmp/newBzrCheckout', None, True, accelerator_tree)
269
270
271
To make a heavyweight checkout, change the last line to::
272
273
  source.create_checkout('/tmp/newBzrCheckout', None, False, accelerator_tree
274
4634.39.32 by Ian Clatworthy
proper Contents panel in bzr-developers.chm
275
3250.4.1 by Martin Albisetti
Added integration guide for developers
276
History Operations
277
==================
278
279
Finding the last revision number or id
4634.39.32 by Ian Clatworthy
proper Contents panel in bzr-developers.chm
280
--------------------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
281
282
To get the last revision number and id of a branch use::
283
284
  revision_number, revision_id = branch.last_revision_info()
285
286
287
If all you care about is the revision_id there is also the
288
method::
289
290
  revision_id = branch.last_revision()
291
292
293
Getting the list of revision ids that make up a branch
4634.39.32 by Ian Clatworthy
proper Contents panel in bzr-developers.chm
294
------------------------------------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
295
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
296
IMPORTANT: This should be avoided wherever possible, as it scales with the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
297
length of history::
3250.4.1 by Martin Albisetti
Added integration guide for developers
298
299
  revisions = branch.revision_history()
300
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
301
now revisions[0] is the revision id of the first commit, and revs[-1] is the
302
revision id of the most recent. Note that if all you want is the last
303
revision then you should use branch.last_revision() as described above, as
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
304
it is vastly more efficient.
3250.4.1 by Martin Albisetti
Added integration guide for developers
305
306
307
Getting a Revision object from a revision id
4634.39.32 by Ian Clatworthy
proper Contents panel in bzr-developers.chm
308
--------------------------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
309
310
The Revision object has attributes like "message" to get the information
311
about the revision::
312
313
  repo = branch.repository
314
  revision = repo.get_revision(rev_id)
315
316
317
Accessing the files from a revision
4634.39.32 by Ian Clatworthy
proper Contents panel in bzr-developers.chm
318
-----------------------------------
3250.4.1 by Martin Albisetti
Added integration guide for developers
319
320
To get the file contents and tree shape for a specific revision you need
321
a RevisionTree. These are supplied by the repository for a specific
322
revision id::
323
324
  revtree = repo.revision_tree(rev_id)
325
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
326
RevisionTrees, like all trees, can be compared as described in "Comparing
327
Trees" above.
3250.4.1 by Martin Albisetti
Added integration guide for developers
328
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
329
The most common way to list files in a tree is ``Tree.iter_entries()``.
330
The simplest way to get file content is ``Tree.get_file()``.  The best way
331
to retrieve file content for large numbers of files `Tree.iter_files_bytes()``
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
332